@sun-asterisk/sungen 2.7.0-beta.1 → 3.0.0-beta.71

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 (245) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/commands/add.js +3 -3
  3. package/dist/cli/commands/add.js.map +1 -1
  4. package/dist/cli/commands/audit.d.ts +3 -0
  5. package/dist/cli/commands/audit.d.ts.map +1 -0
  6. package/dist/cli/commands/audit.js +134 -0
  7. package/dist/cli/commands/audit.js.map +1 -0
  8. package/dist/cli/commands/blindspot.d.ts +3 -0
  9. package/dist/cli/commands/blindspot.d.ts.map +1 -0
  10. package/dist/cli/commands/blindspot.js +58 -0
  11. package/dist/cli/commands/blindspot.js.map +1 -0
  12. package/dist/cli/commands/challenge.d.ts +3 -0
  13. package/dist/cli/commands/challenge.d.ts.map +1 -0
  14. package/dist/cli/commands/challenge.js +102 -0
  15. package/dist/cli/commands/challenge.js.map +1 -0
  16. package/dist/cli/commands/feedback.d.ts +3 -0
  17. package/dist/cli/commands/feedback.d.ts.map +1 -0
  18. package/dist/cli/commands/feedback.js +72 -0
  19. package/dist/cli/commands/feedback.js.map +1 -0
  20. package/dist/cli/commands/generate.d.ts.map +1 -1
  21. package/dist/cli/commands/generate.js +22 -0
  22. package/dist/cli/commands/generate.js.map +1 -1
  23. package/dist/cli/commands/ledger.d.ts +3 -0
  24. package/dist/cli/commands/ledger.d.ts.map +1 -0
  25. package/dist/cli/commands/ledger.js +71 -0
  26. package/dist/cli/commands/ledger.js.map +1 -0
  27. package/dist/cli/commands/manifest.d.ts +3 -0
  28. package/dist/cli/commands/manifest.d.ts.map +1 -0
  29. package/dist/cli/commands/manifest.js +101 -0
  30. package/dist/cli/commands/manifest.js.map +1 -0
  31. package/dist/cli/commands/script-check.d.ts +3 -0
  32. package/dist/cli/commands/script-check.d.ts.map +1 -0
  33. package/dist/cli/commands/script-check.js +97 -0
  34. package/dist/cli/commands/script-check.js.map +1 -0
  35. package/dist/cli/commands/trace.d.ts +3 -0
  36. package/dist/cli/commands/trace.d.ts.map +1 -0
  37. package/dist/cli/commands/trace.js +110 -0
  38. package/dist/cli/commands/trace.js.map +1 -0
  39. package/dist/cli/commands/update.d.ts.map +1 -1
  40. package/dist/cli/commands/update.js +22 -9
  41. package/dist/cli/commands/update.js.map +1 -1
  42. package/dist/cli/index.js +16 -0
  43. package/dist/cli/index.js.map +1 -1
  44. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/capture-variable.hbs +1 -0
  45. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-assertion.hbs +7 -0
  46. package/dist/generators/test-generator/patterns/capture-patterns.d.ts +16 -0
  47. package/dist/generators/test-generator/patterns/capture-patterns.d.ts.map +1 -0
  48. package/dist/generators/test-generator/patterns/capture-patterns.js +54 -0
  49. package/dist/generators/test-generator/patterns/capture-patterns.js.map +1 -0
  50. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  51. package/dist/generators/test-generator/patterns/index.js +2 -0
  52. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  53. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  54. package/dist/generators/test-generator/step-mapper.js +1 -0
  55. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  56. package/dist/generators/test-generator/utils/data-resolver.d.ts +5 -0
  57. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
  58. package/dist/generators/test-generator/utils/data-resolver.js +17 -0
  59. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
  60. package/dist/harness/audit.d.ts +24 -0
  61. package/dist/harness/audit.d.ts.map +1 -0
  62. package/dist/harness/audit.js +115 -0
  63. package/dist/harness/audit.js.map +1 -0
  64. package/dist/harness/blindspot.d.ts +15 -0
  65. package/dist/harness/blindspot.d.ts.map +1 -0
  66. package/dist/harness/blindspot.js +85 -0
  67. package/dist/harness/blindspot.js.map +1 -0
  68. package/dist/harness/catalog/universal-viewpoints.yaml +114 -0
  69. package/dist/harness/challenge.d.ts +21 -0
  70. package/dist/harness/challenge.d.ts.map +1 -0
  71. package/dist/harness/challenge.js +151 -0
  72. package/dist/harness/challenge.js.map +1 -0
  73. package/dist/harness/feedback.d.ts +29 -0
  74. package/dist/harness/feedback.d.ts.map +1 -0
  75. package/dist/harness/feedback.js +106 -0
  76. package/dist/harness/feedback.js.map +1 -0
  77. package/dist/harness/intent.d.ts +11 -0
  78. package/dist/harness/intent.d.ts.map +1 -0
  79. package/dist/harness/intent.js +86 -0
  80. package/dist/harness/intent.js.map +1 -0
  81. package/dist/harness/ledger.d.ts +42 -0
  82. package/dist/harness/ledger.d.ts.map +1 -0
  83. package/dist/harness/ledger.js +171 -0
  84. package/dist/harness/ledger.js.map +1 -0
  85. package/dist/harness/manifest.d.ts +42 -0
  86. package/dist/harness/manifest.d.ts.map +1 -0
  87. package/dist/harness/manifest.js +209 -0
  88. package/dist/harness/manifest.js.map +1 -0
  89. package/dist/harness/parse.d.ts +22 -0
  90. package/dist/harness/parse.d.ts.map +1 -0
  91. package/dist/harness/parse.js +163 -0
  92. package/dist/harness/parse.js.map +1 -0
  93. package/dist/harness/script-check.d.ts +16 -0
  94. package/dist/harness/script-check.d.ts.map +1 -0
  95. package/dist/harness/script-check.js +169 -0
  96. package/dist/harness/script-check.js.map +1 -0
  97. package/dist/harness/secret-scan.d.ts +8 -0
  98. package/dist/harness/secret-scan.d.ts.map +1 -0
  99. package/dist/harness/secret-scan.js +88 -0
  100. package/dist/harness/secret-scan.js.map +1 -0
  101. package/dist/harness/sensors.d.ts +88 -0
  102. package/dist/harness/sensors.d.ts.map +1 -0
  103. package/dist/harness/sensors.js +232 -0
  104. package/dist/harness/sensors.js.map +1 -0
  105. package/dist/harness/trace.d.ts +31 -0
  106. package/dist/harness/trace.d.ts.map +1 -0
  107. package/dist/harness/trace.js +173 -0
  108. package/dist/harness/trace.js.map +1 -0
  109. package/dist/orchestrator/ai-rules-updater.d.ts +1 -0
  110. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  111. package/dist/orchestrator/ai-rules-updater.js +55 -11
  112. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  113. package/dist/orchestrator/figma/spec-figma-renderer.d.ts +2 -2
  114. package/dist/orchestrator/figma/spec-figma-renderer.js +2 -2
  115. package/dist/orchestrator/figma/spec-figma-section-renderers.d.ts +1 -1
  116. package/dist/orchestrator/figma/spec-figma-section-renderers.js +1 -1
  117. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  118. package/dist/orchestrator/project-initializer.js +10 -6
  119. package/dist/orchestrator/project-initializer.js.map +1 -1
  120. package/dist/orchestrator/templates/ai-instructions/claude-agent-challenge.md +46 -0
  121. package/dist/orchestrator/templates/ai-instructions/claude-agent-discovery.md +32 -0
  122. package/dist/orchestrator/templates/ai-instructions/claude-agent-reviewer.md +37 -0
  123. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-flow.md +3 -3
  124. package/dist/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
  125. package/dist/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +36 -12
  126. package/dist/orchestrator/templates/ai-instructions/claude-cmd-design.md +12 -0
  127. package/dist/orchestrator/templates/ai-instructions/claude-cmd-feedback.md +36 -0
  128. package/dist/orchestrator/templates/ai-instructions/claude-cmd-review.md +27 -30
  129. package/dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +4 -1
  130. package/dist/orchestrator/templates/ai-instructions/claude-config.md +1 -4
  131. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +82 -0
  132. package/dist/orchestrator/templates/ai-instructions/{github-skill-sungen-figma-source.md → claude-skill-capture-mode-figma-pat.md} +14 -48
  133. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +60 -0
  134. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +38 -0
  135. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture.md +35 -0
  136. package/dist/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md +84 -0
  137. package/dist/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +40 -1
  138. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +3 -3
  139. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
  140. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +18 -10
  141. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-design.md +13 -0
  142. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +24 -0
  143. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +20 -30
  144. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +2 -1
  145. package/dist/orchestrator/templates/ai-instructions/copilot-config.md +1 -4
  146. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +82 -0
  147. package/{src/orchestrator/templates/ai-instructions/claude-skill-figma-source.md → dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md} +14 -48
  148. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +60 -0
  149. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +38 -0
  150. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +35 -0
  151. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +84 -0
  152. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +1 -1
  153. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +40 -1
  154. package/dist/orchestrator/templates/specs-test-data.ts +9 -0
  155. package/dist/tools/figma/figma-auth.d.ts +5 -2
  156. package/dist/tools/figma/figma-auth.d.ts.map +1 -1
  157. package/dist/tools/figma/figma-auth.js +19 -9
  158. package/dist/tools/figma/figma-auth.js.map +1 -1
  159. package/docs/orchestration-spec.md +267 -0
  160. package/package.json +10 -6
  161. package/src/cli/commands/add.ts +3 -3
  162. package/src/cli/commands/audit.ts +92 -0
  163. package/src/cli/commands/blindspot.ts +48 -0
  164. package/src/cli/commands/challenge.ts +55 -0
  165. package/src/cli/commands/feedback.ts +65 -0
  166. package/src/cli/commands/generate.ts +19 -0
  167. package/src/cli/commands/ledger.ts +61 -0
  168. package/src/cli/commands/manifest.ts +55 -0
  169. package/src/cli/commands/script-check.ts +50 -0
  170. package/src/cli/commands/trace.ts +60 -0
  171. package/src/cli/commands/update.ts +30 -10
  172. package/src/cli/index.ts +16 -0
  173. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/capture-variable.hbs +1 -0
  174. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-assertion.hbs +7 -0
  175. package/src/generators/test-generator/patterns/capture-patterns.ts +59 -0
  176. package/src/generators/test-generator/patterns/index.ts +2 -0
  177. package/src/generators/test-generator/step-mapper.ts +1 -0
  178. package/src/generators/test-generator/utils/data-resolver.ts +20 -0
  179. package/src/harness/audit.ts +112 -0
  180. package/src/harness/blindspot.ts +51 -0
  181. package/src/harness/catalog/universal-viewpoints.yaml +114 -0
  182. package/src/harness/challenge.ts +131 -0
  183. package/src/harness/feedback.ts +84 -0
  184. package/src/harness/intent.ts +58 -0
  185. package/src/harness/ledger.ts +155 -0
  186. package/src/harness/manifest.ts +173 -0
  187. package/src/harness/parse.ts +145 -0
  188. package/src/harness/script-check.ts +149 -0
  189. package/src/harness/secret-scan.ts +51 -0
  190. package/src/harness/sensors.ts +279 -0
  191. package/src/harness/trace.ts +138 -0
  192. package/src/orchestrator/ai-rules-updater.ts +57 -10
  193. package/src/orchestrator/figma/spec-figma-renderer.ts +2 -2
  194. package/src/orchestrator/figma/spec-figma-section-renderers.ts +1 -1
  195. package/src/orchestrator/project-initializer.ts +10 -7
  196. package/src/orchestrator/templates/ai-instructions/claude-agent-challenge.md +46 -0
  197. package/src/orchestrator/templates/ai-instructions/claude-agent-discovery.md +32 -0
  198. package/src/orchestrator/templates/ai-instructions/claude-agent-reviewer.md +37 -0
  199. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-flow.md +3 -3
  200. package/src/orchestrator/templates/ai-instructions/claude-cmd-add-screen.md +5 -5
  201. package/src/orchestrator/templates/ai-instructions/claude-cmd-create-test.md +36 -12
  202. package/src/orchestrator/templates/ai-instructions/claude-cmd-design.md +12 -0
  203. package/src/orchestrator/templates/ai-instructions/claude-cmd-feedback.md +36 -0
  204. package/src/orchestrator/templates/ai-instructions/claude-cmd-review.md +27 -30
  205. package/src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md +4 -1
  206. package/src/orchestrator/templates/ai-instructions/claude-config.md +1 -4
  207. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +82 -0
  208. package/{dist/orchestrator/templates/ai-instructions/copilot-skill-figma-source.md → src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-pat.md} +14 -48
  209. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +60 -0
  210. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +38 -0
  211. package/src/orchestrator/templates/ai-instructions/claude-skill-capture.md +35 -0
  212. package/src/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md +84 -0
  213. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-generation.md +40 -1
  214. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +3 -3
  215. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +4 -4
  216. package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +18 -10
  217. package/src/orchestrator/templates/ai-instructions/copilot-cmd-design.md +13 -0
  218. package/src/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +24 -0
  219. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +20 -30
  220. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +2 -1
  221. package/src/orchestrator/templates/ai-instructions/copilot-config.md +1 -4
  222. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +82 -0
  223. package/{dist/orchestrator/templates/ai-instructions/claude-skill-figma-source.md → src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md} +14 -48
  224. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +60 -0
  225. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +38 -0
  226. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +35 -0
  227. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +84 -0
  228. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md +1 -1
  229. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +40 -1
  230. package/src/orchestrator/templates/specs-test-data.ts +9 -0
  231. package/src/tools/figma/figma-auth.ts +20 -9
  232. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +0 -142
  233. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +0 -112
  234. package/dist/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +0 -73
  235. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +0 -142
  236. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +0 -112
  237. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +0 -73
  238. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-figma.md +0 -142
  239. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-live.md +0 -112
  240. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-local.md +0 -73
  241. package/src/orchestrator/templates/ai-instructions/copilot-skill-figma-source.md +0 -151
  242. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-figma.md +0 -142
  243. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-live.md +0 -112
  244. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-local.md +0 -73
  245. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-figma-source.md +0 -151
@@ -1,18 +1,6 @@
1
- ---
2
- name: sungen-figma-source
3
- description: 'Figma URL → spec_figma.md envelope + LLM-synthesized narrative from cached raw node JSON. Auto-loaded when --figma flag present or spec_figma.md exists.'
4
- user-invocable: false
5
- ---
1
+ # Capture mode: figma-pat
6
2
 
7
- ## When This Skill Loads
8
-
9
- Auto-load triggers (any one is sufficient):
10
-
11
- - Any sungen AI command invoked with `--figma` flag
12
- - `requirements/spec_figma.md` exists in the screen directory
13
- - User mentions a Figma URL or says "generate from Figma"
14
-
15
- ---
3
+ Figma URL → `spec_figma.md` envelope + LLM-synthesized narrative from cached raw node JSON. This mode is the active one when any of these is true: a sungen command was invoked with `--figma`, `requirements/spec_figma.md` exists, or the user says "generate from Figma".
16
4
 
17
5
  ## Prerequisites
18
6
 
@@ -22,8 +10,6 @@ Auto-load triggers (any one is sufficient):
22
10
 
23
11
  **Never paste the PAT into any transcript, spec file, or commit.**
24
12
 
25
- ---
26
-
27
13
  ## Two-Layer Architecture
28
14
 
29
15
  `spec_figma.md` has two layers separated by the `<!-- SYNTHESIS-BELOW -->` marker:
@@ -31,34 +17,27 @@ Auto-load triggers (any one is sufficient):
31
17
  | Layer | Producer | Overwrite Rule |
32
18
  |---|---|---|
33
19
  | **Envelope** (above marker) | sungen CLI | Regenerated each `sungen figma` run — deterministic |
34
- | **Narrative** (below marker) | This skill (LLM) | Replaced on re-synthesis — everything from marker to EOF |
20
+ | **Narrative** (below marker) | This mode (LLM) | Replaced on re-synthesis — everything from marker to EOF |
35
21
 
36
22
  The envelope contains: YAML frontmatter, Frame metadata, Screenshots. The narrative is synthesized by YOU from the cached raw Figma node JSON.
37
23
 
38
- ---
39
-
40
24
  ## Inputs You Read
41
25
 
42
26
  The scaffolder persists a raw (unfiltered) Figma node tree to:
43
-
44
27
  ```
45
28
  .sungen/figma-cache/<fileKey>/<versionId>/<nodeId>-raw.json
46
29
  ```
47
-
48
30
  Read this file + the envelope frontmatter of `requirements/spec_figma.md` + any PNGs under `requirements/ui/`. You MUST NOT call the Figma REST API directly — the PAT is not available to you.
49
31
 
50
- ---
51
-
52
32
  ## Synthesis Task
53
33
 
54
- Append 7 narrative sections below `<!-- SYNTHESIS-BELOW -->`. Each section is inferred from the raw node tree (names, types, `characters`, layout bounds, auto-layout direction, componentProperties):
34
+ Append 7 narrative sections below `<!-- SYNTHESIS-BELOW -->`. Each is inferred from the raw node tree (names, types, `characters`, layout bounds, auto-layout direction, componentProperties):
55
35
 
56
36
  ### 1. Purpose
57
37
  One paragraph. What screen is this? Primary user goal? Infer from frame name + top-level text + dominant CTA.
58
38
 
59
39
  ### 2. ASCII Layout
60
- Rough spatial sketch using box characters. Reflect top-bottom / left-right ordering from absoluteBoundingBox. Keep under ~20 lines. Example:
61
-
40
+ Rough spatial sketch using box characters. Reflect top-bottom / left-right ordering from absoluteBoundingBox. Keep under ~20 lines:
62
41
  ```
63
42
  ┌──────────────────────────────────────┐
64
43
  │ [Logo] [Sign In] │
@@ -72,55 +51,46 @@ Rough spatial sketch using box characters. Reflect top-bottom / left-right order
72
51
  ```
73
52
 
74
53
  ### 3. Regions
75
- Bulleted list of the major layout regions (header, sidebar, main, footer, modal, etc.) with a one-line purpose each. Use auto-layout frames as region hints.
54
+ Bulleted list of major layout regions (header, sidebar, main, footer, modal) with a one-line purpose each. Use auto-layout frames as region hints.
76
55
 
77
56
  ### 4. Actions
78
- Every interactive element the user can trigger. Derive from nodes whose name/type suggests a button, link, icon-button, menu-item, toggle, etc. Format:
79
-
57
+ Every interactive element the user can trigger (button, link, icon-button, menu-item, toggle…):
80
58
  ```
81
59
  - **<Action name>** — <what it does> (source: <node name>)
82
60
  ```
83
61
 
84
62
  ### 5. Form Fields
85
- Every input the user can fill. Include label, type (text/email/password/select/checkbox/radio/textarea/date), required hint if inferable, and placeholder.
86
-
63
+ Every input. Include label, type (text/email/password/select/checkbox/radio/textarea/date), required hint if inferable, placeholder:
87
64
  ```
88
65
  | Label | Type | Required | Placeholder |
89
66
  |---|---|---|---|
90
67
  ```
91
-
92
- Omit entirely (write `_none_`) if no inputs exist.
68
+ Omit (write `_none_`) if no inputs exist.
93
69
 
94
70
  ### 6. Data Columns
95
- If the screen shows a table, list, or card grid — enumerate the columns/fields displayed per row. Otherwise write `_none_`.
71
+ If the screen shows a table/list/card grid — enumerate the columns/fields per row. Otherwise `_none_`.
96
72
 
97
73
  ### 7. Navigation
98
- Outgoing links, tab bars, breadcrumbs, back buttons — anything that moves the user to another screen. Include both explicit navigation components and implicit CTAs that navigate.
99
-
100
- ---
74
+ Outgoing links, tab bars, breadcrumbs, back buttons — anything that moves to another screen. Include explicit nav components and implicit CTAs that navigate.
101
75
 
102
76
  ## Synthesis Workflow
103
77
 
104
78
  1. Read `requirements/spec_figma.md` — note `file_key`, `node_id`, `figma_version_id` from frontmatter
105
79
  2. Read `.sungen/figma-cache/<file_key>/<figma_version_id>/<safe_node_id>-raw.json` (colons in node_id become underscores)
106
- 3. Traverse the tree. Collect: names, types, `characters`, `componentProperties`, `absoluteBoundingBox`
80
+ 3. Traverse the tree. Collect names, types, `characters`, `componentProperties`, `absoluteBoundingBox`
107
81
  4. Produce the 7 sections above
108
82
  5. **Locate the insertion point** in `spec_figma.md`:
109
83
  - **If `<!-- SYNTHESIS-BELOW -->` is present** → replace everything from the marker (inclusive) to EOF with: the marker line, a blank line, then the 7 sections.
110
- - **If the marker is NOT present** (older `spec_figma.md` pre-envelope-refactor, or hand-edited file) → locate the last non-empty line of the envelope (usually the end of `## Screenshots`), append a blank line, then write the marker, another blank line, then the 7 sections. Do NOT delete any existing envelope content.
84
+ - **If the marker is NOT present** (older file or hand-edited) → locate the last non-empty line of the envelope (usually the end of `## Screenshots`), append a blank line, then the marker, another blank line, then the 7 sections. Do NOT delete any envelope content.
111
85
  - **If the file is missing entirely** → advise the user to re-run `sungen add --screen <screen> --figma <url> --refresh` to regenerate the envelope first. Do not fabricate one.
112
86
  6. Preserve the envelope (frontmatter + Frame + Screenshots) byte-for-byte. Never touch content above the marker.
113
87
 
114
- ---
115
-
116
88
  ## Re-synthesis
117
89
 
118
90
  - If the envelope's `figma_version_id` changed → envelope is fresh; re-run synthesis
119
- - If only the narrative is stale (user wants a rewrite) → truncate from marker to EOF and regenerate
91
+ - If only the narrative is stale → truncate from marker to EOF and regenerate
120
92
  - Never edit content ABOVE the marker — that is the scaffolder's territory
121
93
 
122
- ---
123
-
124
94
  ## Selector Heuristics (for downstream `run-test`)
125
95
 
126
96
  During `run-test` Phase 0, provisional selectors can be seeded from the raw JSON:
@@ -135,15 +105,11 @@ During `run-test` Phase 0, provisional selectors can be seeded from the raw JSON
135
105
  | Node name ends `Icon` | `role: img` + `name: "<accessible name>"` |
136
106
 
137
107
  Every provisional entry MUST carry:
138
-
139
108
  ```
140
109
  # @needs-live-verify source=figma node_id=<id>
141
110
  ```
142
-
143
111
  Provisional selectors feed `selectors.yaml` as candidates. `run-test` Phase 0 verifies them against the live page and overwrites incorrect entries.
144
112
 
145
- ---
146
-
147
113
  ## Security
148
114
 
149
115
  - Never include the PAT in `spec_figma.md`, selectors, test data, or any committed file
@@ -0,0 +1,60 @@
1
+ # Capture mode: live
2
+
3
+ Navigate a running application, take **one accessibility snapshot** and **one screenshot**, and save them as visual context for test generation. Use when the app is live (dev, staging, or production with read-only access) and you want tests grounded in the actual rendered UI. Handles auth gracefully: if the page redirects to login, ask the user to sign in manually rather than injecting cookies.
4
+
5
+ ## Prerequisites
6
+
7
+ - Playwright MCP connected.
8
+ - Dev/staging server reachable (or a public URL).
9
+ - `playwright.config.ts` exists at the project root (for `baseURL` fallback).
10
+
11
+ ## Steps
12
+
13
+ ### 1. Resolve target URL
14
+
15
+ 1. `Live URL` field in `requirements/spec.md` (Overview section)
16
+ 2. `baseURL` from `playwright.config.ts` + `URL Path` from `spec.md`
17
+ 3. Neither → `AskUserQuestion`: *"Paste the full URL for the page to scan"*
18
+
19
+ ### 2. Navigate
20
+
21
+ `browser_navigate` to the resolved URL.
22
+
23
+ ### 3. Handle auth redirect
24
+
25
+ If the page redirects to a login route (URL contains `/login`, `/signin`, `/auth`, or content indicates a login screen):
26
+ 1. Tell the user which login URL they landed on.
27
+ 2. `AskUserQuestion`:
28
+ - **I'll log in manually** — wait for confirmation, then re-navigate to the target URL
29
+ - **Skip live scan** — switch to mode `local`
30
+ - **Cancel**
31
+ 3. **Never** inject cookies or localStorage via `browser_evaluate` / `browser_run_code`. Auth belongs to the user.
32
+
33
+ ### 4. Snapshot
34
+
35
+ Take **ONE** `browser_snapshot`. This accessibility tree is the primary AI context — roles, names, text, structure that tc-generation uses to identify sections and fields.
36
+
37
+ ### 5. Screenshot (recommended)
38
+
39
+ Take **ONE** `browser_take_screenshot` with `fullPage: true`. Save to `requirements/ui/live-<timestamp>.png`, where `<timestamp>` is `YYYYMMDD-HHMM` local time (e.g. `live-20260421-1430.png`).
40
+
41
+ ### 6a. Verify unauthenticated redirect target (flow capture only)
42
+
43
+ When capturing for a **flow** with security scenarios (e.g. "unauthenticated user cannot access X"):
44
+ 1. Open a **fresh incognito/unauthenticated** context (no storage state).
45
+ 2. `browser_navigate` to the protected route.
46
+ 3. Record the **actual redirect URL** — do NOT assume `/login`; it may be `/register`, `/`, etc.
47
+ 4. Report the redirect target: *"Unauthenticated access to `/dashboard` redirects to `/register`"*.
48
+ 5. The caller must use the **actual redirect URL** in Gherkin assertions, never an assumed one.
49
+
50
+ Skip if the flow has no security scenarios or the user says to skip.
51
+
52
+ ### 6. Detect discrepancies vs spec
53
+
54
+ If `spec.md` exists, cross-check the snapshot against spec sections: fields in spec but not in snapshot → *missing in UI*; elements in snapshot but not in spec → *missing in spec*. Report findings but **do not** auto-edit `spec.md`.
55
+
56
+ ### 7. Report back
57
+
58
+ > Captured live page `<URL>`: Snapshot N interactive elements · Screenshot `requirements/ui/live-<timestamp>.png` · Discrepancies vs spec: <count or "none">
59
+
60
+ Hand back to the calling command. Scans **exactly one** page per invocation.
@@ -0,0 +1,38 @@
1
+ # Capture mode: local
2
+
3
+ Use **pre-existing images** in `requirements/ui/` as visual context. No network, no MCP, no live site — works for any design tool (Figma export, Sketch, Penpot, Zeplin, hand-drawn, staging screenshots). This is the **baseline fallback**: if the live domain is down and Figma MCP isn't configured, this always works as long as the user drops images in the folder.
4
+
5
+ ## Steps
6
+
7
+ ### 1. List available images
8
+
9
+ Glob `requirements/ui/*.{png,jpg,jpeg,webp,gif}` and report count + filenames. Filter out metadata files (e.g. `figma-meta.md` written by mode figma-mcp) — those are read by `tc-generation` separately, not treated as images here.
10
+
11
+ ### 2. Handle empty folder
12
+
13
+ If no images found:
14
+ 1. Tell the user the folder is empty, with the full path so they can open it in Finder.
15
+ 2. `AskUserQuestion`:
16
+ - **I'll drop images now** — wait for confirmation, then re-glob
17
+ - **Switch to Figma** — switch to mode `figma-mcp`
18
+ - **Switch to live page scan** — switch to mode `live`
19
+ - **Cancel** — abort create-test
20
+ 3. If "drop images now", wait for confirmation (e.g. "done") then re-run step 1.
21
+
22
+ ### 3. Read images for context
23
+
24
+ Use the `Read` tool on each image — Claude Code reads PNG/JPG/WebP directly as visual context. For large sets (>10 images), ask which are primary and which are states/variants to avoid loading too much at once.
25
+
26
+ ### 4. Summarize
27
+
28
+ > Loaded N image(s) from `requirements/ui/`:
29
+ > - `<filename-1>` — <one-line description of what's visible>
30
+ > - `<filename-2>` — <one-line description>
31
+
32
+ Hand back to the calling command.
33
+
34
+ ## File naming hints for users
35
+
36
+ Nudge users toward consistent filenames (don't enforce):
37
+ - `<section>-default.png` / `-error.png` / `-loading.png` / `-empty.png` — section states
38
+ - `full-page.png` / `viewport.png` — whole screen (auto-generated by `sungen add --capture`)
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: sungen-capture
3
+ description: 'Acquire visual/design context for test generation from one of four sources (modes): figma-mcp, figma-pat, live, local. Auto-loaded by create-test/add-screen when a visual source is needed, or when --figma flag / spec_figma.md is present. Router skill — read only the mode file you need.'
4
+ user-invocable: false
5
+ ---
6
+
7
+ ## Purpose
8
+
9
+ Bring **visual + design context** into test generation so `sungen-tc-generation` can author Gherkin + test-data grounded in the real UI. This is a **router**: pick exactly **one mode** for the run, then read only that mode's file. Do **not** read all four.
10
+
11
+ This skill never generates Gherkin or `selectors.yaml` — it only acquires context and reports back to the calling command.
12
+
13
+ ## Pick the mode
14
+
15
+ | Mode | Read | Use when | Needs |
16
+ |---|---|---|---|
17
+ | **figma-mcp** | `mode-figma-mcp.md` | Pre-launch / Figma is source of truth, **Figma Dev Mode MCP** connected | Figma MCP + frame URL |
18
+ | **figma-pat** | `mode-figma-pat.md` | `--figma` flag was used, or `requirements/spec_figma.md` exists (synthesize narrative from cached raw node JSON) | `sungen figma auth` PAT |
19
+ | **live** | `mode-live.md` | App is running (dev/staging/prod read-only) and you want the actual rendered UI | Playwright MCP + reachable URL |
20
+ | **local** | `mode-local.md` | Images already dropped in `requirements/ui/` (any design tool, screenshots, mockups) — baseline fallback, no network | nothing |
21
+
22
+ ### How the mode is chosen (when the caller didn't specify)
23
+
24
+ 1. `requirements/spec_figma.md` exists → **figma-pat** (PAT flow already ran during `add-screen`).
25
+ 2. `requirements/ui/` has images → **local**.
26
+ 3. Neither → ask the user which source (figma-mcp / live / local), then load that one mode file.
27
+
28
+ Modes are **mutually exclusive per run**, but the user can run `create-test` again with a different mode to layer context. All modes write to `requirements/ui/` and report back.
29
+
30
+ ## What this skill (any mode) does NOT do
31
+
32
+ - Does not generate Gherkin — that's `sungen-tc-generation`.
33
+ - Does not write `selectors.yaml` — that's `/sungen:run-test`.
34
+ - Does not inject auth/cookies — the user logs in manually (see `live`).
35
+ - Does not crawl or generate images.
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: sungen-harness-audit
3
+ description: 'How to read `sungen audit` output and repair test-design findings. Auto-loaded by the design orchestrator.'
4
+ user-invocable: false
5
+ ---
6
+
7
+ ## What `sungen audit` measures
8
+
9
+ `sungen audit --screen <name>` runs deterministic sensors over `features/<name>.feature` + `requirements/test-viewpoint.md` and writes `.sungen/reports/<name>-audit.json`. It is the **gate** the orchestrator repairs against. Run with `--json` to parse it.
10
+
11
+ ### Report shape (key fields)
12
+ ```jsonc
13
+ {
14
+ "score": { "overall": 3.9, "coverage": 0.4, "businessDepth": 0.18, "balance": 0.5, "traceability": 0.7 },
15
+ "gateStatus": "PASS" | "FAIL",
16
+ "gate": { "pageType": "ecommerce-list", "themesCovered": 2, "themesTotal": 5,
17
+ "gaps": [ { "theme": "cart-correctness", "keywords": [...] } ] },
18
+ "depth": { "businessCriticalShallow": 9, "businessCriticalTotal": 11,
19
+ "shallowBusinessCritical": [ { "name": "...", "category": "PRODUCT" } ] },
20
+ "balance": { "imbalanced": true, "coreCount": 11, "secondaryCount": 22, "byBucket": {...} },
21
+ "duplicates": { "clusters": [ { "sameDataLikely": false, "scenarios": [...] } ] },
22
+ "trace": { "mappedRatio": 0.4, "note": "..." },
23
+ "findings": [ "GATE: ...", "DEPTH: ...", "BALANCE: ...", "TRACE: ..." ]
24
+ }
25
+ ```
26
+ - **`overall` score is business-weighted** (coverage 0.4 + businessDepth 0.3 + balance 0.15 + traceability 0.15). It is intentionally strict on business value — a high count with shallow business coverage scores low. Don't optimize the count; optimize coverage + depth.
27
+ - Exit code **2** when `gateStatus == FAIL` (usable in CI / loop).
28
+
29
+ ## Finding → repair mapping
30
+
31
+ | Finding prefix | Meaning | Repair action |
32
+ |---|---|---|
33
+ | **GATE** | a critical theme for the page-type has no covering scenario | Generate scenarios for that theme. **If cross-screen** (cart-correctness, product-detail-consistency, filter-result-correctness, multi-item cart) → do NOT fake it on a single screen; plan a **flow** (`/sungen:add-flow`) and record the deferral. |
34
+ | **DEPTH** | business-critical scenarios assert only visibility/navigation | Replace `Then User see [X] page/section` with **observable data assertions**: `Then User see [X] with {{value}}`, `Then User see [T] table match data:`. Capture real expected values into `test-data.yaml`. |
35
+ | **BALANCE** | secondary viewpoints (UI/validation/security) outweigh business-core | **Stop expanding** secondary viewpoints; generate the missing business-core scenarios first. Do not add more subscription/UI variants while core is thin. |
36
+ | **TRACE** | scenarios use ad-hoc `VP-<CAT>-NNN` codes not linked to the viewpoint-overview | Make each scenario map to a viewpoint-overview id (align category codes, or add a mapping comment). |
37
+ | **UNIVERSAL** | a universal theme (error/empty-state, accessibility) is absent | Low priority — add if in scope; otherwise note as out-of-scope with reason. |
38
+
39
+ ## P5 steps for deep cross-screen / list coverage
40
+
41
+ Use these when repairing GATE/DEPTH findings for the hard viewpoints (cart/detail/filter correctness). They need **runtime data mode** (the default).
42
+
43
+ - **Capture a value to compare across screens** (product-detail-consistency, cart-correctness):
44
+ ```gherkin
45
+ When User remember [Product Name] text as {{selected_product_name}}
46
+ And User remember [Product Price] text as {{selected_product_price}}
47
+ And User click [View Product] link
48
+ Then User see [Detail Product Name] header with {{selected_product_name}}
49
+ And User see [Detail Product Price] text with {{selected_product_price}}
50
+ ```
51
+ `remember` stores the element's text/value at runtime; later `{{var}}` resolves to it. This proves the detail/cart shows the SAME product, not a random one.
52
+
53
+ - **Assert every item in a result matches** (category/brand-filter-correctness):
54
+ ```gherkin
55
+ When User click [Women] link
56
+ And User click [Dress] link
57
+ Then User see all [Result Product Name] contain {{selected_category}}
58
+ ```
59
+ `see all [X] contain {{v}}` asserts EVERY matching element contains the value → "all displayed products belong to the selected category/brand", not just one.
60
+
61
+ > Cross-screen flows (home → detail/cart): if the target screen is a separate screen, prefer a **flow** (`/sungen:add-flow`) so the journey is one test. On a single screen, keep the cross-screen assertion but tag `@manual` with a `# Deferred to a flow` comment.
62
+
63
+ ## Repair loop rules
64
+
65
+ 1. **Budget = 3 rounds.** Re-run `sungen audit` after each repair; track score delta.
66
+ 2. **Stop when** `gateStatus == PASS` AND `findings` empty — or budget exhausted.
67
+ 3. **Never fake a pass.** A shallow `see [Cart] page` does not satisfy `cart-correctness`. If a gap is genuinely cross-screen or needs capabilities the DSL lacks (e.g. capture an element value to compare elsewhere), **report it as a residual gap / flow item** instead of forcing a green gate.
68
+ 4. **EP/data families are OK.** A `duplicates` cluster with `sameDataLikely=false` is an intentional equivalence-partition family (e.g. many invalid-email cases) — keep it; only collapse `sameDataLikely=true` exact duplicates.
69
+
70
+ ## Discovery / fallback tree (when input is limited)
71
+
72
+ ```
73
+ spec.md đủ tốt? → YES: Spec-first
74
+ │ NO
75
+ source code có? → YES: Source-first (mine behavior từ code)
76
+ │ NO
77
+ testcase cũ tương tự?→ YES: History-first
78
+ │ NO
79
+ domain rủi ro+defect?→ YES: Defect-first
80
+ │ NO
81
+ → hỏi QA; QA chưa phản hồi → OUTPUT kèm ASSUMPTION LIST rõ ràng (không stall)
82
+ ```
83
+
84
+ See `docs/orchestration-spec.md` for the full flow and `reports/sungen_refactor_spec.md` for the design rationale.
@@ -117,7 +117,7 @@ When running Phase 0 for a **flow** (`qa/flows/<name>/`), check existing screen
117
117
  | 5 | `text` | Plain text node (not inside interactive component) |
118
118
  | 6 | `locator` (CSS) | Last resort — `#id` or `[attr=value]` only, never classes or XPath |
119
119
 
120
- See `sungen-figma-source` skill for the authoritative heuristics table mapping Figma signals to YAML entry types.
120
+ See `sungen-capture` skill (mode figma-pat) for the authoritative heuristics table mapping Figma signals to YAML entry types.
121
121
 
122
122
  4. **Write entries**: add each entry to `selectors.yaml`, prefixed with the required comment:
123
123
  ```yaml
@@ -7,7 +7,7 @@ user-invocable: false
7
7
  ## ⚠️ Gotchas — read before generating
8
8
 
9
9
  - `spec_figma.md` exists → read file only, **NEVER** call `mcp__figma__*`
10
- → PAT auth flow already done by `sungen-figma-source`; re-calling fails or duplicates work.
10
+ → PAT auth flow already done by `sungen-capture` (mode figma-pat); re-calling fails or duplicates work.
11
11
 
12
12
  - `selectors.yaml` → do **NOT** generate — handled by `run-test`
13
13
  → Selectors need live DOM inspection via Playwright MCP, only `run-test` triggers it.
@@ -208,6 +208,45 @@ Security: [S1 – admin only]
208
208
 
209
209
  **✅ Good** — see admin notice example above: `Display surfaces` lists every URL spec mentions as output, `Cross-surface rules` maps each admin action to its user-facing outcome, `Inclusive bounds` flags every `<=`/`>=` for BVA. Every item maps to a VP-ID in `Tier 1 output`.
210
210
 
211
+ #### Critical business-viewpoint pre-gate — pass `sungen audit` on the FIRST pass
212
+
213
+ > The harness gate FAILS (and forces repair rounds → wasted tokens) when a page-type's critical **business** viewpoints are missing or **shallow**. Generate them correctly the first time. A business-critical `Then` must assert **DATA**, never just `see [X] page/section/modal`.
214
+
215
+ **By page-type, generate a DEEP scenario for each (before expanding UI/validation/subscription):**
216
+
217
+ | Page-type | Must-cover viewpoints (each with a data assertion) |
218
+ |---|---|
219
+ | **e-commerce list / home** | list-data (card has image+name+price+add) · product-detail-consistency · cart-correctness · category-filter-correctness · **brand-filter-correctness (separate from category)** · add-to-cart success · nav-core |
220
+ | **form** | required-validation · format/boundary · submit-success |
221
+ | **auth** | valid-login · invalid-credential · access-control |
222
+
223
+ **Required assertion shapes (use these, not bare visibility):**
224
+ - Card info: assert at **card level** (image+name+price together), e.g. `User see all [Product Card] contain {{...}}` — not `see [Section]`.
225
+ - Cross-screen consistency (detail/cart): **capture then compare** —
226
+ ```gherkin
227
+ When User remember [Product Name] text as {{selected_product_name}}
228
+ And User remember [Product Price] text as {{selected_product_price}}
229
+ And User click [View Product] link
230
+ Then User see [Detail Product Name] header with {{selected_product_name}}
231
+ And User see [Detail Product Price] text contains {{selected_product_price}}
232
+ ```
233
+ Cross-screen target → tag `@manual` + `# Deferred to a flow (home -> detail)`.
234
+ - Filter result (category AND brand, separately): `Then User see all [Result Product Name] contain {{selected_category}}` — proves EVERY item belongs, not one.
235
+
236
+ **Depth is a GATE dimension (harness-roadmap P1) — self-raise, never silently go shallow:**
237
+ - For every data-correctness theme the catalog marks `depth.requires: data-assertion`, emit its `depth.template` shape by **default** — don't wait for the repair loop. `sungen audit` measures `businessDepth` (ratio of these scenarios that assert data) against an intent threshold (functional ≥ 0.70); below it the **gate FAILs**.
238
+ - `depth.cross_screen: true` (cart / detail / filter / brand correctness) → write the deep capture/compare shape but tag `@manual` + `# Deferred to a flow (...)`. These are excluded from the ratio (they're correctly deferred), so they don't hurt depth.
239
+ - **If the spec lacks the concrete value** a deep assertion needs (exact message, price, count): still write the deep shape with a `{{var}}` placeholder and leave a `# SPEC-GAP: <field> value not in spec` comment — do **not** downgrade to `see [X] section`. A visible gap is better than a silent shallow pass.
240
+ - **Blind-Spot Memory:** before finishing, run `sungen blindspot list --prompt` (Bash) and make sure the suite satisfies each recorded pattern (e.g. "for any Add/Create action: check success + resulting data state + duplicate/double-submit"). These are gaps QA hit before — don't repeat them.
241
+
242
+ **First-pass anti-patterns (exactly what the gate/reviewer reject — avoid them):**
243
+ - Title↔steps mismatch (e.g. a "no-result" scenario that clicks a query which returns products).
244
+ - Tautology `Then`: `click [Next Slide]` → `see [Carousel] section` (proves nothing).
245
+ - Business-critical scenario ending at `see [Added] modal` / `see [Cart] page` with no data assertion.
246
+ - Brand filter covered only as navigation (must assert products belong to the brand).
247
+
248
+ **Balance:** cover all the above (deep) BEFORE expanding subscription / UI-presence / extra validation edge cases.
249
+
211
250
  #### Tier 1 guard — minimum before writing scenarios
212
251
 
213
252
  | Spec section | Minimum requirement | Tag |
@@ -54,6 +54,15 @@ export class TestDataLoader {
54
54
  }
55
55
  return String(current);
56
56
  }
57
+
58
+ /**
59
+ * Set a value at runtime (used by captured-variable steps:
60
+ * `User remember [X] text as {{var}}`). Stored at top level so a later
61
+ * `{{var}}` reference resolves via get().
62
+ */
63
+ set(key: string, value: string): void {
64
+ this.data[key] = value;
65
+ }
57
66
  }
58
67
 
59
68
  function loadYamlSync(filePath: string): Record<string, any> | null {
@@ -6,7 +6,9 @@
6
6
  *
7
7
  * Safeguards enforced on every save AND every assertSafeToUse call:
8
8
  * 1. .env must appear in .gitignore (abort if not).
9
- * 2. No tracked file may contain "FIGMA_PAT=" (git grep scan).
9
+ * 2. No tracked file may contain an assigned token value (FIGMA_PAT=<token>).
10
+ * The scan matches a token-shaped value, not bare mentions of the key in
11
+ * code or docs (those are not secrets).
10
12
  */
11
13
  /**
12
14
  * Load the Figma PAT.
@@ -28,7 +30,8 @@ export declare function savePat(cwd: string, token: string): Promise<void>;
28
30
  export declare function clearPat(cwd: string): void;
29
31
  /**
30
32
  * Run tracked-file scan on every Figma CLI / skill invocation.
31
- * Aborts with actionable message if FIGMA_PAT= is found in any tracked file.
33
+ * Aborts with an actionable message if an assigned token value is found in any
34
+ * tracked file (bare mentions of the key name are ignored).
32
35
  *
33
36
  * @throws Error with remediation instructions on safeguard failure.
34
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"figma-auth.d.ts","sourceRoot":"","sources":["../../../src/tools/figma/figma-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiEH;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWvD;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCvE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAM1C;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAShE"}
1
+ {"version":3,"file":"figma-auth.d.ts","sourceRoot":"","sources":["../../../src/tools/figma/figma-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAyEH;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWvD;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCvE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAM1C;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAShE"}
@@ -7,7 +7,9 @@
7
7
  *
8
8
  * Safeguards enforced on every save AND every assertSafeToUse call:
9
9
  * 1. .env must appear in .gitignore (abort if not).
10
- * 2. No tracked file may contain "FIGMA_PAT=" (git grep scan).
10
+ * 2. No tracked file may contain an assigned token value (FIGMA_PAT=<token>).
11
+ * The scan matches a token-shaped value, not bare mentions of the key in
12
+ * code or docs (those are not secrets).
11
13
  */
12
14
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
15
  if (k2 === undefined) k2 = k;
@@ -53,6 +55,13 @@ const exec_file_no_throw_1 = require("../../utils/exec-file-no-throw");
53
55
  const PAT_KEY = 'FIGMA_PAT';
54
56
  const ENV_FILE = '.env';
55
57
  const GITIGNORE_FILE = '.gitignore';
58
+ // A real leak is an assigned token value (`FIGMA_PAT=<token>`), not a bare
59
+ // mention of the key name in code or documentation. Figma PATs are long
60
+ // (~40+ chars), so we only flag an assignment whose value looks like an actual
61
+ // token: at least 16 non-space characters after `=` (an optional quote allowed).
62
+ // This is an ERE pattern for `git grep -E`; it deliberately does NOT match this
63
+ // file's own comments or template literals (`${PAT_KEY}=...`).
64
+ const PAT_VALUE_PATTERN = `${PAT_KEY}=['"]?[^[:space:]]{16,}`;
56
65
  // ---------------------------------------------------------------------------
57
66
  // Internal helpers
58
67
  // ---------------------------------------------------------------------------
@@ -89,11 +98,11 @@ function isEnvIgnored(cwd) {
89
98
  return /^\s*(\.env[\w.*]*|\*\.env)\s*$/m.test(content);
90
99
  }
91
100
  /**
92
- * Run `git grep -l "FIGMA_PAT="` in cwd.
101
+ * Scan tracked files for an assigned Figma token value (not bare key mentions).
93
102
  * Returns list of matching tracked file paths (empty = safe).
94
103
  */
95
104
  async function findTrackedFilesWithPat(cwd) {
96
- const result = await (0, exec_file_no_throw_1.execFileNoThrow)('git', ['grep', '-l', `${PAT_KEY}=`], cwd);
105
+ const result = await (0, exec_file_no_throw_1.execFileNoThrow)('git', ['grep', '-lE', PAT_VALUE_PATTERN], cwd);
97
106
  if (result.status === 0 && result.stdout.trim()) {
98
107
  return result.stdout.trim().split('\n').filter(Boolean);
99
108
  }
@@ -131,12 +140,12 @@ async function savePat(cwd, token) {
131
140
  throw new Error(`Refusing to save FIGMA_PAT: ".env" is not listed in ${GITIGNORE_FILE}.\n` +
132
141
  `Add the following line to ${path.join(cwd, GITIGNORE_FILE)} and re-run:\n\n .env\n`);
133
142
  }
134
- // Safeguard 2: no tracked file may contain FIGMA_PAT=
143
+ // Safeguard 2: no tracked file may contain an assigned token value
135
144
  const leakedFiles = await findTrackedFilesWithPat(cwd);
136
145
  if (leakedFiles.length > 0) {
137
- throw new Error(`Refusing to save FIGMA_PAT: token key found in tracked file(s):\n` +
146
+ throw new Error(`Refusing to save FIGMA_PAT: a token value appears in tracked file(s):\n` +
138
147
  leakedFiles.map((f) => ` ${f}`).join('\n') +
139
- `\n\nRemove FIGMA_PAT from those files, commit the removal, then re-run.\n`);
148
+ `\n\nRemove the token from those files, commit the removal, then re-run.\n`);
140
149
  }
141
150
  // Upsert: replace existing line or append
142
151
  const lines = readEnvLines(cwd);
@@ -167,16 +176,17 @@ function clearPat(cwd) {
167
176
  }
168
177
  /**
169
178
  * Run tracked-file scan on every Figma CLI / skill invocation.
170
- * Aborts with actionable message if FIGMA_PAT= is found in any tracked file.
179
+ * Aborts with an actionable message if an assigned token value is found in any
180
+ * tracked file (bare mentions of the key name are ignored).
171
181
  *
172
182
  * @throws Error with remediation instructions on safeguard failure.
173
183
  */
174
184
  async function assertSafeToUse(cwd) {
175
185
  const leakedFiles = await findTrackedFilesWithPat(cwd);
176
186
  if (leakedFiles.length > 0) {
177
- throw new Error(`Security check failed: FIGMA_PAT found in tracked file(s):\n` +
187
+ throw new Error(`Security check failed: a Figma token value appears in tracked file(s):\n` +
178
188
  leakedFiles.map((f) => ` ${f}`).join('\n') +
179
- `\n\nRemove FIGMA_PAT from those files and commit the removal before using Figma commands.\n`);
189
+ `\n\nRemove the token from those files and commit the removal before using Figma commands.\n`);
180
190
  }
181
191
  }
182
192
  //# sourceMappingURL=figma-auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"figma-auth.js","sourceRoot":"","sources":["../../../src/tools/figma/figma-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"figma-auth.js","sourceRoot":"","sources":["../../../src/tools/figma/figma-auth.ts"],"names":[],"mappings":"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"}