canicode 0.10.0 → 0.10.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canicode",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "mcpName": "io.github.let-sunny/canicode",
5
5
  "description": "Score your Figma designs with AI-calibrated rules. CLI + MCP server.",
6
6
  "type": "module",
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: canicode-gotchas
3
- description: Run a gotcha survey for a Figma design and save answers as a Claude Code skill file for code generation reference
3
+ description: Gotcha survey workflow plus accumulating per-design answers one Workflow region on top, numbered sections appended per Figma design
4
4
  ---
5
5
 
6
6
  # CanICode Gotchas -- Design Gotcha Survey & Skill Writer
7
7
 
8
- Run a gotcha survey on a Figma design to identify implementation pitfalls, collect developer answers, and save them as a skill file that code generation agents can reference automatically.
8
+ Run a gotcha survey on a Figma design to identify implementation pitfalls, collect developer answers, and upsert them into this skill file so code generation agents can reference them automatically. The file has two regions: the **Workflow** below (installed by `canicode init`, never overwritten) and the **Collected Gotchas** region at the bottom (one numbered section per design, replaced in place on re-runs).
9
9
 
10
10
  ## Prerequisites
11
11
 
@@ -38,7 +38,7 @@ Either channel returns:
38
38
 
39
39
  If `isReadyForCodeGen` is `true` or `questions` is empty:
40
40
  - Tell the user: "This design scored **{designGrade}** and is ready for code generation — no gotchas to resolve."
41
- - Do NOT write a skill file.
41
+ - Do NOT write to the skill file.
42
42
  - Stop here.
43
43
 
44
44
  ### Step 3: Present questions to the user
@@ -59,41 +59,54 @@ Wait for the user's answer before moving to the next question. The user may:
59
59
  - Say "skip" to skip a question
60
60
  - Say "n/a" if the question is not applicable
61
61
 
62
- ### Step 4: Write the gotcha skill file
62
+ ### Step 4: Upsert the gotcha section
63
63
 
64
- After collecting all answers, write the completed file to:
64
+ After collecting all answers, **upsert** this design's section into the `# Collected Gotchas` region at the bottom of this file:
65
65
 
66
66
  ```
67
67
  .claude/skills/canicode-gotchas/SKILL.md
68
68
  ```
69
69
 
70
- This file goes in the **user's project** (current working directory), NOT in the canicode repo.
70
+ This file goes in the **user's project** (current working directory), NOT in the canicode repo. The Workflow region above **must never be modified** — only the `# Collected Gotchas` region below is touched.
71
71
 
72
- Always overwrite any existing file at this path — each run produces a fresh file based on the latest analysis.
72
+ #### Step 4a: Compute `designKey`
73
73
 
74
- ## Output Template
74
+ `designKey` uniquely identifies the design so re-running on the same URL replaces the existing section in place. Parse it from the survey input:
75
75
 
76
- The written SKILL.md must follow this exact format:
76
+ - **Figma URL** — extract `fileKey` and `nodeId` from the URL and join them as `<fileKey>#<nodeId>`. Example: `https://figma.com/design/abc123XYZ/My-File?node-id=42-100` `designKey = "abc123XYZ#42:100"` (convert `-` to `:` in nodeId, the same normalization the Figma MCP uses). Drop any other query-string parameters — only `node-id` matters for the key.
77
+ - **Fixture path** — use the absolute path, e.g. `/Users/me/project/fixtures/simple.json`.
77
78
 
78
- ````markdown
79
- ---
80
- name: canicode-gotchas
81
- description: Design gotcha answers for {designName} — reference during code generation
82
- ---
79
+ Do **not** use the raw survey input URL as the key: trailing query parameters (`?t=...`, `?mode=...`) break string matching on re-runs.
83
80
 
84
- # Design Gotchas {designName}
81
+ #### Step 4b: Read the existing file and locate the target section
85
82
 
86
- Collected from canicode gotcha survey. Reference these answers when implementing this design.
83
+ 1. Read `.claude/skills/canicode-gotchas/SKILL.md` if it exists.
84
+ 2. Detect the file's state using the two structural markers that uniquely identify each case — the YAML frontmatter (present on every `canicode init` install) and the `# Collected Gotchas` heading (present on every post-#340 install):
85
+ - **File missing** → tell the user to run `canicode init` first, then re-invoke this skill. Stop here.
86
+ - **File has YAML frontmatter AND a `# Collected Gotchas` heading** (the default shipped shape since #340) → proceed to step 3 below.
87
+ - **File has YAML frontmatter but no `# Collected Gotchas` heading** (an older workflow install, or a user-edited workflow that dropped the trailing heading) → preserve everything above unchanged and append a new `# Collected Gotchas` heading at the bottom, then proceed to step 3.
88
+ - **File missing the YAML frontmatter** (a pre-#340 single-design clobber — the old overwrite rewrote the frontmatter's `description` to the per-design variant, so a well-formed canicode frontmatter is the cleanest discriminator) → **do not attempt to reconstruct the workflow inline**. Tell the user: "Your gotchas SKILL.md looks like the pre-#340 single-design format. Run `canicode init --force` to restore the workflow, then re-run this survey — your answers will land in a clean numbered section." Stop here.
89
+ 3. Walk the existing `## #NNN — ...` sections under `# Collected Gotchas` and look for one whose `- **Design key**:` bullet matches the `designKey` from Step 4a. Substring match against the bullet value is sufficient.
90
+ - **Found** → replace that section in place. **Preserve its `#NNN` number** so external references (downstream skills, user notes) remain stable.
91
+ - **Not found** → append a new section at the bottom of the region. `#NNN = (highest existing number) + 1`, zero-padded to three digits. Never reuse a number that appeared earlier and was deleted; numbering is monotonic.
87
92
 
88
- ## Metadata
93
+ The Workflow region above must never be touched. Do NOT copy Workflow prose into the per-design section; the section only carries metadata + gotcha answers.
94
+
95
+ ## Output Template
96
+
97
+ Each per-design section in the `# Collected Gotchas` region has this exact shape:
98
+
99
+ ````markdown
100
+ ## #NNN — {designName} — {YYYY-MM-DD}
89
101
 
90
102
  - **Figma URL**: {figmaUrl}
103
+ - **Design key**: {designKey}
91
104
  - **Grade**: {designGrade}
92
105
  - **Analyzed at**: {analyzedAt}
93
106
 
94
- ## Gotchas
107
+ ### Gotchas
95
108
 
96
- ### {ruleId} — {nodeName}
109
+ #### {ruleId} — {nodeName}
97
110
 
98
111
  - **Severity**: {severity}
99
112
  - **Node ID**: {nodeId}
@@ -108,8 +121,11 @@ Collected from canicode gotcha survey. Reference these answers when implementing
108
121
 
109
122
  | Field | Source |
110
123
  |-------|--------|
124
+ | `NNN` | `sectionNumber` — zero-padded three-digit index. Preserved on re-run, incremented on append. |
111
125
  | `designName` | Figma file name or fixture name from the input |
126
+ | `YYYY-MM-DD` | Today's date (the day you are running the survey) |
112
127
  | `figmaUrl` | The input URL or fixture path provided by the user |
128
+ | `designKey` | `<fileKey>#<nodeId>` for Figma URLs, absolute path for fixtures (see Step 4a) |
113
129
  | `designGrade` | `designGrade` from gotcha-survey response |
114
130
  | `analyzedAt` | Current timestamp (ISO 8601) |
115
131
  | `ruleId` | `ruleId` from each question |
@@ -122,7 +138,7 @@ Collected from canicode gotcha survey. Reference these answers when implementing
122
138
 
123
139
  ### Skipped questions
124
140
 
125
- If the user skipped a question or said "n/a", still include it in the output with:
141
+ If the user skipped a question or said "n/a", still include it in the section with:
126
142
 
127
143
  ```markdown
128
144
  - **Answer**: _(skipped)_
@@ -132,7 +148,13 @@ This ensures the code generation agent knows the gotcha exists even if no answer
132
148
 
133
149
  ## Edge Cases
134
150
 
135
- - **No questions returned**: The design is ready for code generation. Inform the user and stop (Step 2).
136
- - **User wants to re-run**: Always overwrite the existing file. No merge or appendfresh output each time.
151
+ - **No questions returned**: The design is ready for code generation. Inform the user and stop (Step 2). Do not touch the file.
152
+ - **Re-run on the same design**: Replace that design's section in place (matched by `Design key`) preserve the original `#NNN` number. Do NOT append a duplicate.
153
+ - **Re-run on a different design**: Append a new section with the next `#NNN`. Prior designs' sections are untouched.
154
+ - **Workflow region**: Never modified. If you notice the Workflow region has been edited by the user, leave their edits alone — only the `# Collected Gotchas` region is under skill control.
155
+ - **Pre-#340 clobbered file** (the YAML frontmatter was rewritten to a per-design variant, so the canonical `canicode-gotchas` frontmatter is missing): tell the user to run `canicode init --force` to restore the workflow, then re-run the survey. The prior single-design content cannot be automatically migrated into a `## #001` section — the user re-runs and gets a clean section.
137
156
  - **MCP tool not available**: Fall back to `npx canicode gotcha-survey <input> --json` — the CLI returns the same `GotchaSurvey` shape. If the CLI is also unavailable (e.g. no node runtime), tell the user to install the canicode MCP server or the `canicode` npm package (see Prerequisites).
138
- - **Partial answers**: If the user stops mid-survey, write the file with answers collected so far. Mark remaining questions as _(skipped)_.
157
+ - **Partial answers**: If the user stops mid-survey, upsert the section with answers collected so far. Mark remaining questions as _(skipped)_.
158
+ - **Manual section deletion**: If the user deletes a middle section by hand, do not renumber existing sections. The next new section still gets `(highest existing number) + 1`; numeric gaps are acceptable (same pattern as `.claude/docs/ADR.md`).
159
+
160
+ # Collected Gotchas
@@ -18,6 +18,18 @@ Orchestrate the full design-to-code roundtrip: analyze a Figma design for readin
18
18
 
19
19
  ## Workflow
20
20
 
21
+ ### Step 0: Verify Figma MCP tools are loaded
22
+
23
+ Before Step 1, verify that `use_figma` is callable in **this** session — not merely listed in `.mcp.json`. Newly registered MCP servers (e.g. via `claude mcp add -s project -t http figma https://mcp.figma.com/mcp`) require a Claude Code restart to load their tools; reading `.mcp.json` is not a substitute for checking the live tool list you have access to right now.
24
+
25
+ If `use_figma` is unavailable in the current session, **Do NOT proceed to Step 1**. Steps 1 (analyze) and 3 (gotcha-survey) spend real Figma API calls and 5–15 minutes of human survey time before Step 4 would otherwise discover `use_figma` is missing. Halt immediately and tell the user:
26
+
27
+ 1. Confirm `.mcp.json` registers the Figma MCP entry (e.g. `figma` under `mcpServers`).
28
+ 2. Restart Claude Code so the newly registered tools load.
29
+ 3. Re-invoke `/canicode-roundtrip <url>`.
30
+
31
+ See the Edge Case **No Figma MCP server** below for the one-way fallback when Figma MCP genuinely cannot be installed — the precheck above is for the common "installed but not restarted" case, not a replacement for that fallback.
32
+
21
33
  ### Step 1: Analyze the design
22
34
 
23
35
  If the `analyze` MCP tool is available, call it with the user's Figma URL:
@@ -94,7 +106,7 @@ Wait for the user's answer before moving to the next question. The user may:
94
106
  - Say "skip" to skip a question
95
107
  - Say "n/a" if the question is not applicable
96
108
 
97
- After all questions are answered, **save gotcha answers to file** at `.claude/skills/canicode-gotchas/SKILL.md` in the user's project. Always overwrite any existing file each run produces a fresh file. Follow the format from the `/canicode-gotchas` skill.
109
+ After all questions are answered, **upsert this design's gotcha section** into `.claude/skills/canicode-gotchas/SKILL.md` in the user's project. Read the existing file, then either replace the section whose `Design key` matches this run (same Figma URL → fileKey+nodeId) or append a new numbered section under `# Collected Gotchas`. Never modify anything above the `# Collected Gotchas` heading — the region above it (frontmatter + workflow prose) is the skill loader contract installed by `canicode init`. See the `/canicode-gotchas` skill's "Upsert the gotcha section" step (Step 4) for the exact section format and matching rule.
98
110
 
99
111
  Then proceed to **Step 4** to apply answers to the Figma design.
100
112
 
@@ -309,7 +321,7 @@ Applied {N} changes to the Figma design:
309
321
  - 📝 {nodeName}: annotation added to canicode:auto-fix — raw color needs token binding (raw-value)
310
322
  ```
311
323
 
312
- ### Step 5: Re-analyze and verify
324
+ ### Step 5: Re-analyze and report what the roundtrip addressed
313
325
 
314
326
  Run `analyze` again on the same Figma URL:
315
327
 
@@ -317,10 +329,32 @@ Run `analyze` again on the same Figma URL:
317
329
  analyze({ input: "<figma-url>" })
318
330
  ```
319
331
 
320
- Compare the new grade with the original:
332
+ Under ADR-012's annotate-by-default policy, most instance-child gotchas route to 📝 annotations and do **not** move the numeric grade so the headline for this step is the **issues-delta** (what the roundtrip captured), not a grade comparison. Grade is kept as a footnote so the Row 8 regression guardrail still applies.
333
+
334
+ **Tally inputs** — derive the counts from the data you already have:
335
+ - `X` (✅ resolved): count of ✅ + 🔧 + 🔗 markers from the Step 4 report block you just emitted (scene/instance-child writes, auto-fix renames, and variable bindings all successfully landed the value).
336
+ - `Y` (📝 annotated): count of 📝 markers from Step 4 — gotcha answers captured as Figma annotations for code-gen reference.
337
+ - `Z` (🌐 definition writes): count of 🌐 markers from Step 4 — only non-zero when the orchestrator opted in with `allowDefinitionWrite: true` (helper context option, not a CLI flag).
338
+ - `W` (⏭️ skipped): count of ⏭️ markers from Step 4 plus any Step 3 questions the user answered with `skip` or `n/a`.
339
+ - `V` (remaining): `issues.length` from the re-analyze response — unresolved gotchas plus non-actionable rules still flagged by the design.
340
+ - `N` (addressed) = `X + Y + Z + W`.
321
341
 
322
- **All gotcha issues resolved** (new grade is S, A+, or A):
323
- - Tell the user: "Design improved from **{oldGrade}** to **{newGrade}** — all gotcha issues resolved. Ready for code generation."
342
+ If Step 4 produced no report block (e.g. user skipped every question, or no gotcha survey ran), all four counts are zero — that is a legitimate outcome; report the breakdown with zeros rather than treating it as an error.
343
+
344
+ **All gotcha issues resolved** (`V == 0`, i.e. re-analyze surfaces no remaining issues — note this is independent of grade since ADR-012 annotations do not move the score):
345
+ - Tell the user (fill in the counts from the tally above):
346
+
347
+ ```
348
+ Roundtrip complete — N issues addressed:
349
+ ✅ X resolved (auto-fix or property write succeeded)
350
+ 📝 Y annotated on Figma (gotcha answers captured for code-gen)
351
+ 🌐 Z definition writes propagated (only when allowDefinitionWrite: true)
352
+ ⏭️ W skipped (user declined or "skip")
353
+
354
+ V issues remaining (unresolved gotchas + non-actionable rules)
355
+
356
+ Grade: {oldGrade} → {newGrade}. Ready for code generation.
357
+ ```
324
358
  - Clean up canicode annotations: remove annotations with `[canicode]` prefix from fixed nodes via `use_figma`. Apply `stripAnnotations` to avoid the D1 mutex:
325
359
  ```javascript
326
360
  const nodeIds = ["id1", "id2"]; // nodes that now pass
@@ -335,9 +369,20 @@ for (const id of nodeIds) {
335
369
  ```
336
370
  - Proceed to **Step 6**.
337
371
 
338
- **Some issues remain**:
339
- - Show what improved and what still needs attention.
340
- - Ask: "Design improved from **{oldGrade}** to **{newGrade}**. {remainingCount} issues remain. Proceed to code generation?"
372
+ **Some issues remain** (`V > 0`):
373
+ - Show the same breakdown and ask whether to proceed:
374
+
375
+ ```
376
+ Roundtrip complete — N issues addressed:
377
+ ✅ X resolved (auto-fix or property write succeeded)
378
+ 📝 Y annotated on Figma (gotcha answers captured for code-gen)
379
+ 🌐 Z definition writes propagated (only when allowDefinitionWrite: true)
380
+ ⏭️ W skipped (user declined or "skip")
381
+
382
+ V issues remaining (unresolved gotchas + non-actionable rules)
383
+
384
+ Grade: {oldGrade} → {newGrade}. Proceed to code generation with remaining context?
385
+ ```
341
386
  - If yes → proceed to **Step 6** with remaining gotcha context.
342
387
  - If no → stop and let the user address remaining issues manually.
343
388
 
@@ -350,6 +395,7 @@ Follow the **figma-implement-design** skill workflow to generate code from the F
350
395
  - Gotchas with severity **blocking** MUST be addressed — the design cannot be implemented correctly without this information
351
396
  - Gotchas with severity **risk** SHOULD be addressed — they indicate potential issues that will surface later
352
397
  - Reference the specific node IDs from gotcha answers to locate the affected elements in the design
398
+ - Pass the Figma URL (or `designKey` = `<fileKey>#<nodeId>`) to `figma-implement-design` so it can grep the matching `## #NNN — …` section in `.claude/skills/canicode-gotchas/SKILL.md` instead of reading the whole accumulated file
353
399
 
354
400
  **If all issues were resolved in Steps 4-5**, no additional gotcha context is needed — the design speaks for itself.
355
401