howone 0.1.28 → 0.1.30

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 (224) hide show
  1. package/package.json +1 -1
  2. package/templates/vite/.howone/skills/hallmark/SKILL.md +48 -42
  3. package/templates/vite/.howone/skills/hallmark/references/anti-patterns.md +12 -6
  4. package/templates/vite/.howone/skills/hallmark/references/assets.md +7 -0
  5. package/templates/vite/.howone/skills/hallmark/references/component-cookbook.md +19 -10
  6. package/templates/vite/.howone/skills/hallmark/references/components/f2-sticky-scroll-stack.md +1 -1
  7. package/templates/vite/.howone/skills/hallmark/references/components/ft6-letter-close.md +1 -1
  8. package/templates/vite/.howone/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +1 -1
  9. package/templates/vite/.howone/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +1 -1
  10. package/templates/vite/.howone/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +1 -1
  11. package/templates/vite/.howone/skills/hallmark/references/components/n11-mega-menu.md +40 -0
  12. package/templates/vite/.howone/skills/hallmark/references/components/n12-banner-retract.md +34 -0
  13. package/templates/vite/.howone/skills/hallmark/references/components/n13-inline-cmdk-pill.md +39 -0
  14. package/templates/vite/.howone/skills/hallmark/references/components/n1b-saas-three-section.md +35 -0
  15. package/templates/vite/.howone/skills/hallmark/references/components/n9-edge-aligned-minimal.md +1 -1
  16. package/templates/vite/.howone/skills/hallmark/references/components/s3-sticky-pinned.md +2 -2
  17. package/templates/vite/.howone/skills/hallmark/references/copy.md +8 -8
  18. package/templates/vite/.howone/skills/hallmark/references/custom-craft.md +2 -2
  19. package/templates/vite/.howone/skills/hallmark/references/custom-theme.md +50 -12
  20. package/templates/vite/.howone/skills/hallmark/references/export-formats.md +1 -1
  21. package/templates/vite/.howone/skills/hallmark/references/genres/atmospheric.md +11 -7
  22. package/templates/vite/.howone/skills/hallmark/references/genres/editorial.md +6 -4
  23. package/templates/vite/.howone/skills/hallmark/references/genres/modern-minimal.md +10 -6
  24. package/templates/vite/.howone/skills/hallmark/references/genres/playful.md +15 -10
  25. package/templates/vite/.howone/skills/hallmark/references/hero-enrichment.md +13 -12
  26. package/templates/vite/.howone/skills/hallmark/references/interaction-and-states.md +2 -1
  27. package/templates/vite/.howone/skills/hallmark/references/layout-and-space.md +4 -3
  28. package/templates/vite/.howone/skills/hallmark/references/macrostructures/04-stat-led.md +3 -1
  29. package/templates/vite/.howone/skills/hallmark/references/macrostructures/12-letter.md +1 -1
  30. package/templates/vite/.howone/skills/hallmark/references/macrostructures.md +1 -1
  31. package/templates/vite/.howone/skills/hallmark/references/microinteractions.md +1 -3
  32. package/templates/vite/.howone/skills/hallmark/references/preview-examples.md +12 -12
  33. package/templates/vite/.howone/skills/hallmark/references/responsive.md +8 -8
  34. package/templates/vite/.howone/skills/hallmark/references/slop-test.md +72 -85
  35. package/templates/vite/.howone/skills/hallmark/references/structure.md +9 -13
  36. package/templates/vite/.howone/skills/hallmark/references/study.md +40 -17
  37. package/templates/vite/.howone/skills/hallmark/references/themes/carnival.md +301 -0
  38. package/templates/vite/.howone/skills/hallmark/references/themes/cobalt.md +146 -0
  39. package/templates/vite/.howone/skills/hallmark/references/themes/hum.md +403 -0
  40. package/templates/vite/.howone/skills/hallmark/references/themes/lumen.md +478 -0
  41. package/templates/vite/.howone/skills/hallmark/references/typography.md +3 -3
  42. package/templates/vite/.howone/skills/hallmark/references/verbs/redesign.md +1 -1
  43. package/templates/vite/.howone/skills/howone/03-sdk/07-ai-action-calls.md +28 -86
  44. package/templates/vite/.howone/skills/howone/03-sdk/09-workflow-execute-sse.md +105 -0
  45. package/templates/vite/.howone/skills/howone/04-ai/03-ai-sdk-handoff.md +15 -13
  46. package/templates/vite/.howone/skills/howone/SKILL.md +2 -2
  47. package/templates/vite/package.json +1 -1
  48. package/templates/vite/.howone/skills/hallmark/LICENSE +0 -21
  49. package/templates/vite/.howone/skills/hallmark/README.md +0 -147
  50. package/templates/vite/.howone/skills/hallmark/ROADMAP.md +0 -201
  51. package/templates/vite/.howone/skills/hallmark/docs/recipes.md +0 -186
  52. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-anya.jpg +0 -0
  53. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-bananastudio.jpg +0 -0
  54. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-hyperlane.jpg +0 -0
  55. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-najm.jpg +0 -0
  56. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-slow-pour.jpg +0 -0
  57. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-soroe.jpg +0 -0
  58. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-tally.jpg +0 -0
  59. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-wayfare.jpg +0 -0
  60. package/templates/vite/.howone/skills/hallmark/docs/study-examples.md +0 -176
  61. package/templates/vite/.howone/skills/hallmark/docs/talk-slides.md +0 -364
  62. package/templates/vite/.howone/skills/hallmark/package.json +0 -36
  63. package/templates/vite/.howone/skills/hallmark/site/OG-hallmark.png +0 -0
  64. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/brief.md +0 -71
  65. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/index.html +0 -64
  66. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/style.css +0 -240
  67. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/brief.md +0 -65
  68. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/index.html +0 -105
  69. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/style.css +0 -250
  70. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/brief.md +0 -64
  71. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/index.html +0 -131
  72. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/style.css +0 -240
  73. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/brief.md +0 -67
  74. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/index.html +0 -86
  75. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/style.css +0 -262
  76. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/brief.md +0 -63
  77. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/index.html +0 -167
  78. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/style.css +0 -457
  79. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/brief.md +0 -65
  80. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/index.html +0 -159
  81. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/style.css +0 -288
  82. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/brief.md +0 -64
  83. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/index.html +0 -146
  84. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/style.css +0 -484
  85. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/brief.md +0 -64
  86. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/index.html +0 -116
  87. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/style.css +0 -354
  88. package/templates/vite/.howone/skills/hallmark/site/_tests/09-slow-pour/index.html +0 -638
  89. package/templates/vite/.howone/skills/hallmark/site/_tests/10-owl-hours/index.html +0 -515
  90. package/templates/vite/.howone/skills/hallmark/site/_tests/11-soroe-ceramics/index.html +0 -515
  91. package/templates/vite/.howone/skills/hallmark/site/_tests/12-loafer/index.html +0 -608
  92. package/templates/vite/.howone/skills/hallmark/site/_tests/13-alma/index.html +0 -587
  93. package/templates/vite/.howone/skills/hallmark/site/_tests/README.md +0 -157
  94. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/BananaStudio-loop.mp4 +0 -0
  95. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/BananaStudio-still.jpg +0 -0
  96. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Hyperlane-example.mp4 +0 -0
  97. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Hyperlane-still.jpg +0 -0
  98. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Najm-loop.mp4 +0 -0
  99. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Najm-still.jpg +0 -0
  100. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Podcast-loop.mp4 +0 -0
  101. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/SaaS-loop.mp4 +0 -0
  102. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/SaaS-still.jpg +0 -0
  103. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Soroe-loop.mp4 +0 -0
  104. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Soroe-still.jpg +0 -0
  105. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/after-quiet-hour.png +0 -0
  106. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/anya-loop.mp4 +0 -0
  107. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/anya-still.jpg +0 -0
  108. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/audit-example.png +0 -0
  109. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/before-quiet-hour.png +0 -0
  110. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/example-redesign-uractivation.png +0 -0
  111. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/slow-pour-loop.mp4 +0 -0
  112. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/slow-pour-still.jpg +0 -0
  113. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/study-example.png +0 -0
  114. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/uractivation-after-loop.mp4 +0 -0
  115. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/wayfare-loop.mp4 +0 -0
  116. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/wayfare-still.jpg +0 -0
  117. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/01-coffeebox/index.html +0 -77
  118. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/01-coffeebox/style.css +0 -238
  119. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/02-loop/index.html +0 -110
  120. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/02-loop/style.css +0 -326
  121. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/03-mossroot/index.html +0 -134
  122. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/03-mossroot/style.css +0 -262
  123. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/README.md +0 -30
  124. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/README.md +0 -17
  125. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/audit-report.md +0 -56
  126. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/input.html +0 -160
  127. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/notes.md +0 -29
  128. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/input.html +0 -63
  129. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/notes.md +0 -72
  130. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/output.html +0 -374
  131. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/diagnosis.md +0 -52
  132. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/input-description.md +0 -29
  133. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/notes.md +0 -61
  134. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/output.css +0 -193
  135. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/output.html +0 -66
  136. package/templates/vite/.howone/skills/hallmark/site/css/base.css +0 -194
  137. package/templates/vite/.howone/skills/hallmark/site/css/components.css +0 -4886
  138. package/templates/vite/.howone/skills/hallmark/site/css/sections.css +0 -2072
  139. package/templates/vite/.howone/skills/hallmark/site/css/tokens.css +0 -1129
  140. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/index.html +0 -475
  141. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/styles.css +0 -1584
  142. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/tokens.css +0 -96
  143. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/index.html +0 -344
  144. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/script.js +0 -103
  145. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/styles.css +0 -1103
  146. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/tokens.css +0 -83
  147. package/templates/vite/.howone/skills/hallmark/site/examples/najm/index.html +0 -368
  148. package/templates/vite/.howone/skills/hallmark/site/examples/najm/script.js +0 -133
  149. package/templates/vite/.howone/skills/hallmark/site/examples/najm/styles.css +0 -1062
  150. package/templates/vite/.howone/skills/hallmark/site/examples/najm/tokens.css +0 -97
  151. package/templates/vite/.howone/skills/hallmark/site/examples/tally/app.js +0 -84
  152. package/templates/vite/.howone/skills/hallmark/site/examples/tally/index.html +0 -446
  153. package/templates/vite/.howone/skills/hallmark/site/examples/tally/styles.css +0 -1087
  154. package/templates/vite/.howone/skills/hallmark/site/examples/tally/tokens.css +0 -101
  155. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/index.html +0 -359
  156. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/style.css +0 -1168
  157. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/tokens.css +0 -81
  158. package/templates/vite/.howone/skills/hallmark/site/favicon-dark.svg +0 -5
  159. package/templates/vite/.howone/skills/hallmark/site/favicon-light.svg +0 -5
  160. package/templates/vite/.howone/skills/hallmark/site/index.html +0 -1043
  161. package/templates/vite/.howone/skills/hallmark/site/js/main.js +0 -1175
  162. package/templates/vite/.howone/skills/hallmark/vercel.json +0 -6
  163. package/templates/vite/.howone/skills/impeccable/SKILL.md +0 -168
  164. package/templates/vite/.howone/skills/impeccable/agents/impeccable-asset-producer.md +0 -101
  165. package/templates/vite/.howone/skills/impeccable/reference/adapt.md +0 -190
  166. package/templates/vite/.howone/skills/impeccable/reference/animate.md +0 -175
  167. package/templates/vite/.howone/skills/impeccable/reference/audit.md +0 -133
  168. package/templates/vite/.howone/skills/impeccable/reference/bolder.md +0 -113
  169. package/templates/vite/.howone/skills/impeccable/reference/brand.md +0 -118
  170. package/templates/vite/.howone/skills/impeccable/reference/clarify.md +0 -174
  171. package/templates/vite/.howone/skills/impeccable/reference/codex.md +0 -105
  172. package/templates/vite/.howone/skills/impeccable/reference/cognitive-load.md +0 -106
  173. package/templates/vite/.howone/skills/impeccable/reference/color-and-contrast.md +0 -105
  174. package/templates/vite/.howone/skills/impeccable/reference/colorize.md +0 -154
  175. package/templates/vite/.howone/skills/impeccable/reference/craft.md +0 -123
  176. package/templates/vite/.howone/skills/impeccable/reference/critique.md +0 -273
  177. package/templates/vite/.howone/skills/impeccable/reference/delight.md +0 -302
  178. package/templates/vite/.howone/skills/impeccable/reference/distill.md +0 -111
  179. package/templates/vite/.howone/skills/impeccable/reference/document.md +0 -427
  180. package/templates/vite/.howone/skills/impeccable/reference/extract.md +0 -69
  181. package/templates/vite/.howone/skills/impeccable/reference/harden.md +0 -347
  182. package/templates/vite/.howone/skills/impeccable/reference/heuristics-scoring.md +0 -234
  183. package/templates/vite/.howone/skills/impeccable/reference/interaction-design.md +0 -195
  184. package/templates/vite/.howone/skills/impeccable/reference/layout.md +0 -141
  185. package/templates/vite/.howone/skills/impeccable/reference/live.md +0 -622
  186. package/templates/vite/.howone/skills/impeccable/reference/motion-design.md +0 -109
  187. package/templates/vite/.howone/skills/impeccable/reference/onboard.md +0 -234
  188. package/templates/vite/.howone/skills/impeccable/reference/optimize.md +0 -258
  189. package/templates/vite/.howone/skills/impeccable/reference/overdrive.md +0 -130
  190. package/templates/vite/.howone/skills/impeccable/reference/personas.md +0 -179
  191. package/templates/vite/.howone/skills/impeccable/reference/polish.md +0 -242
  192. package/templates/vite/.howone/skills/impeccable/reference/product.md +0 -62
  193. package/templates/vite/.howone/skills/impeccable/reference/quieter.md +0 -99
  194. package/templates/vite/.howone/skills/impeccable/reference/responsive-design.md +0 -114
  195. package/templates/vite/.howone/skills/impeccable/reference/shape.md +0 -165
  196. package/templates/vite/.howone/skills/impeccable/reference/spatial-design.md +0 -100
  197. package/templates/vite/.howone/skills/impeccable/reference/teach.md +0 -156
  198. package/templates/vite/.howone/skills/impeccable/reference/typeset.md +0 -124
  199. package/templates/vite/.howone/skills/impeccable/reference/typography.md +0 -159
  200. package/templates/vite/.howone/skills/impeccable/reference/ux-writing.md +0 -107
  201. package/templates/vite/.howone/skills/impeccable/scripts/cleanup-deprecated.mjs +0 -284
  202. package/templates/vite/.howone/skills/impeccable/scripts/command-metadata.json +0 -94
  203. package/templates/vite/.howone/skills/impeccable/scripts/critique-storage.mjs +0 -242
  204. package/templates/vite/.howone/skills/impeccable/scripts/design-parser.mjs +0 -820
  205. package/templates/vite/.howone/skills/impeccable/scripts/detect-csp.mjs +0 -198
  206. package/templates/vite/.howone/skills/impeccable/scripts/detect.mjs +0 -21
  207. package/templates/vite/.howone/skills/impeccable/scripts/impeccable-paths.mjs +0 -110
  208. package/templates/vite/.howone/skills/impeccable/scripts/is-generated.mjs +0 -69
  209. package/templates/vite/.howone/skills/impeccable/scripts/live-accept.mjs +0 -595
  210. package/templates/vite/.howone/skills/impeccable/scripts/live-browser-session.js +0 -123
  211. package/templates/vite/.howone/skills/impeccable/scripts/live-browser.js +0 -4860
  212. package/templates/vite/.howone/skills/impeccable/scripts/live-complete.mjs +0 -75
  213. package/templates/vite/.howone/skills/impeccable/scripts/live-completion.mjs +0 -18
  214. package/templates/vite/.howone/skills/impeccable/scripts/live-inject.mjs +0 -446
  215. package/templates/vite/.howone/skills/impeccable/scripts/live-poll.mjs +0 -200
  216. package/templates/vite/.howone/skills/impeccable/scripts/live-resume.mjs +0 -48
  217. package/templates/vite/.howone/skills/impeccable/scripts/live-server.mjs +0 -838
  218. package/templates/vite/.howone/skills/impeccable/scripts/live-session-store.mjs +0 -254
  219. package/templates/vite/.howone/skills/impeccable/scripts/live-status.mjs +0 -47
  220. package/templates/vite/.howone/skills/impeccable/scripts/live-wrap.mjs +0 -632
  221. package/templates/vite/.howone/skills/impeccable/scripts/live.mjs +0 -247
  222. package/templates/vite/.howone/skills/impeccable/scripts/load-context.mjs +0 -141
  223. package/templates/vite/.howone/skills/impeccable/scripts/modern-screenshot.umd.js +0 -14
  224. package/templates/vite/.howone/skills/impeccable/scripts/pin.mjs +0 -214
@@ -1,198 +0,0 @@
1
- /**
2
- * Scan a project tree for Content-Security-Policy signals and classify the
3
- * shape so the agent knows which patch template to propose.
4
- *
5
- * Used at first-time `live.mjs` setup. Mechanical (grep-based) — no network,
6
- * no dev server, no JS evaluation. The classification drives a user-facing
7
- * consent prompt; the agent does the actual patch writing.
8
- *
9
- * Shapes are named by patch mechanism, not framework origin:
10
- * - "append-arrays": CSP defined as structured directive arrays. Patch
11
- * appends a dev-only localhost entry. Covers:
12
- * - Monorepo helpers with additional*Src options
13
- * (e.g. createBaseNextConfig for Next)
14
- * - SvelteKit kit.csp.directives
15
- * - nuxt-security module's contentSecurityPolicy
16
- * - "append-string": CSP built as a literal value string. Patch splices
17
- * a dev-only token into script-src and connect-src.
18
- * Covers:
19
- * - Inline Next.js headers() with CSP string
20
- * - Nuxt routeRules / nitro.routeRules CSP headers
21
- * - "middleware": CSP set dynamically in middleware.{ts,js}.
22
- * Detected but not auto-patched in v1.
23
- * - "meta-tag": <meta http-equiv="Content-Security-Policy"> in
24
- * layout files. Detected but not auto-patched in v1.
25
- * - null: no CSP signals found; no patch needed.
26
- */
27
-
28
- import fs from 'node:fs';
29
- import path from 'node:path';
30
-
31
- const SKIP_DIRS = new Set([
32
- 'node_modules',
33
- '.git',
34
- '.next',
35
- '.turbo',
36
- '.svelte-kit',
37
- '.nuxt',
38
- '.astro',
39
- 'dist',
40
- 'build',
41
- 'out',
42
- '.vercel',
43
- ]);
44
-
45
- const SCAN_EXTS = new Set(['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts', '.tsx', '.jsx']);
46
- const LAYOUT_EXTS = new Set(['.tsx', '.jsx', '.astro', '.vue', '.svelte', '.html']);
47
- const MAX_DEPTH = 6;
48
- const MAX_READ_BYTES = 64 * 1024;
49
-
50
- // append-arrays signals: CSP expressed as structured directive arrays
51
- const MONOREPO_HELPER_SIGNALS = [
52
- /\bbuildCSPConfig\b/,
53
- /\bbuildSecurityHeaders\b/,
54
- /\badditionalScriptSrc\b/,
55
- /\badditionalConnectSrc\b/,
56
- /\bcreateBaseNextConfig\b/,
57
- ];
58
- const SVELTEKIT_CSP_SIGNALS = [
59
- /\bkit\s*:/,
60
- /\bcsp\s*:/,
61
- /\bdirectives\s*:/,
62
- ];
63
- const NUXT_SECURITY_SIGNALS = [
64
- /['"]nuxt-security['"]/,
65
- /\bcontentSecurityPolicy\b/,
66
- ];
67
-
68
- // append-string signals: CSP written as a literal value string
69
- const INLINE_HEADER_SIGNALS = [
70
- /["']Content-Security-Policy["']/i,
71
- /\bscript-src\b/,
72
- /\bconnect-src\b/,
73
- ];
74
- const NUXT_ROUTE_RULES_SIGNALS = [
75
- /\brouteRules\b/,
76
- /Content-Security-Policy/i,
77
- /\bscript-src\b/,
78
- ];
79
-
80
- const MIDDLEWARE_HINT = /headers\.set\(\s*["']Content-Security-Policy["']/i;
81
- const META_TAG_HINT = /http-equiv\s*=\s*["']Content-Security-Policy["']/i;
82
-
83
- /**
84
- * @param {string} cwd Project root.
85
- * @returns {{ shape: string|null, signals: string[] }}
86
- */
87
- export function detectCsp(cwd = process.cwd()) {
88
- const hits = { appendArrays: [], appendString: [], middleware: [], metaTag: [] };
89
-
90
- walk(cwd, cwd, 0, (absPath, relPath, body) => {
91
- const ext = path.extname(absPath);
92
- const base = path.basename(absPath).toLowerCase();
93
- const isConfig = (name) =>
94
- new RegExp('(^|/)' + name + '\\.config\\.').test(relPath);
95
-
96
- // === append-arrays candidates ===
97
-
98
- // Monorepo CSP helper: packages/*/src/.../(config|security)/*
99
- if (SCAN_EXTS.has(ext) &&
100
- /packages\/[^/]+\/src\/.*(config|next-config|security)/.test(relPath) &&
101
- MONOREPO_HELPER_SIGNALS.some((re) => re.test(body))) {
102
- hits.appendArrays.push(relPath);
103
- return;
104
- }
105
-
106
- // SvelteKit kit.csp.directives
107
- if (SCAN_EXTS.has(ext) && isConfig('svelte') &&
108
- SVELTEKIT_CSP_SIGNALS.every((re) => re.test(body))) {
109
- hits.appendArrays.push(relPath);
110
- return;
111
- }
112
-
113
- // Nuxt nuxt-security module
114
- if (SCAN_EXTS.has(ext) && isConfig('nuxt') &&
115
- NUXT_SECURITY_SIGNALS.every((re) => re.test(body))) {
116
- hits.appendArrays.push(relPath);
117
- return;
118
- }
119
-
120
- // === append-string candidates ===
121
-
122
- // Inline headers in Next/Nuxt/SvelteKit/Astro/Vite config
123
- if (SCAN_EXTS.has(ext) &&
124
- /(^|\/)(next|nuxt|vite|astro|svelte)\.config\./.test(relPath) &&
125
- INLINE_HEADER_SIGNALS.every((re) => re.test(body))) {
126
- // Nuxt routeRules is a sub-shape of append-string; we already covered
127
- // nuxt-security above via return, so any remaining Nuxt CSP match here
128
- // is a route-rules / inline-headers case. Either way, same patch
129
- // mechanism.
130
- hits.appendString.push(relPath);
131
- return;
132
- }
133
-
134
- // === detect-only shapes ===
135
-
136
- if ((base === 'middleware.ts' || base === 'middleware.js' || base === 'middleware.mjs') &&
137
- MIDDLEWARE_HINT.test(body)) {
138
- hits.middleware.push(relPath);
139
- }
140
-
141
- if (LAYOUT_EXTS.has(ext) && META_TAG_HINT.test(body)) {
142
- hits.metaTag.push(relPath);
143
- }
144
- });
145
-
146
- // Priority: append-arrays > append-string > middleware > meta-tag.
147
- // Structured patches are safer than string splices; runtime and HTML
148
- // injection patches are less reliable and v1 doesn't auto-apply them.
149
- if (hits.appendArrays.length > 0) {
150
- return { shape: 'append-arrays', signals: hits.appendArrays };
151
- }
152
- if (hits.appendString.length > 0) {
153
- return { shape: 'append-string', signals: hits.appendString };
154
- }
155
- if (hits.middleware.length > 0) {
156
- return { shape: 'middleware', signals: hits.middleware };
157
- }
158
- if (hits.metaTag.length > 0) {
159
- return { shape: 'meta-tag', signals: hits.metaTag };
160
- }
161
- return { shape: null, signals: [] };
162
- }
163
-
164
- function walk(root, dir, depth, visit) {
165
- if (depth > MAX_DEPTH) return;
166
- let entries;
167
- try { entries = fs.readdirSync(dir, { withFileTypes: true }); }
168
- catch { return; }
169
-
170
- for (const entry of entries) {
171
- const abs = path.join(dir, entry.name);
172
- if (entry.isDirectory()) {
173
- if (SKIP_DIRS.has(entry.name)) continue;
174
- walk(root, abs, depth + 1, visit);
175
- continue;
176
- }
177
- if (!entry.isFile()) continue;
178
- const ext = path.extname(entry.name);
179
- if (!SCAN_EXTS.has(ext) && !LAYOUT_EXTS.has(ext)) continue;
180
- let body;
181
- try {
182
- const fd = fs.openSync(abs, 'r');
183
- try {
184
- const buf = Buffer.alloc(MAX_READ_BYTES);
185
- const n = fs.readSync(fd, buf, 0, MAX_READ_BYTES, 0);
186
- body = buf.slice(0, n).toString('utf-8');
187
- } finally { fs.closeSync(fd); }
188
- } catch { continue; }
189
- visit(abs, path.relative(root, abs), body);
190
- }
191
- }
192
-
193
- // CLI mode
194
- const _running = process.argv[1];
195
- if (_running?.endsWith('detect-csp.mjs') || _running?.endsWith('detect-csp.mjs/')) {
196
- const result = detectCsp(process.cwd());
197
- console.log(JSON.stringify(result, null, 2));
198
- }
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { pathToFileURL, fileURLToPath } from 'node:url';
6
-
7
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
- const candidates = [
9
- path.join(__dirname, 'detector', 'detect-antipatterns.mjs'),
10
- path.join(__dirname, '..', '..', 'cli', 'engine', 'detect-antipatterns.mjs'),
11
- ];
12
- const detectorPath = candidates.find(p => fs.existsSync(p));
13
-
14
- if (!detectorPath) {
15
- process.stderr.write('Error: bundled detector not found.\n');
16
- process.exit(1);
17
- }
18
-
19
- const { detectCli } = await import(pathToFileURL(detectorPath));
20
-
21
- await detectCli();
@@ -1,110 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
-
4
- export const IMPECCABLE_DIR = '.impeccable';
5
- export const LIVE_DIR = 'live';
6
- export const CRITIQUE_DIR = 'critique';
7
-
8
- export function getImpeccableDir(cwd = process.cwd()) {
9
- return path.join(cwd, IMPECCABLE_DIR);
10
- }
11
-
12
- export function getDesignSidecarPath(cwd = process.cwd()) {
13
- return path.join(getImpeccableDir(cwd), 'design.json');
14
- }
15
-
16
- export function getDesignSidecarCandidates(cwd = process.cwd(), contextDir = cwd) {
17
- const candidates = [
18
- getDesignSidecarPath(cwd),
19
- path.join(cwd, 'DESIGN.json'),
20
- ];
21
- const contextLegacy = path.join(contextDir, 'DESIGN.json');
22
- if (!candidates.includes(contextLegacy)) candidates.push(contextLegacy);
23
- return candidates;
24
- }
25
-
26
- export function resolveDesignSidecarPath(cwd = process.cwd(), contextDir = cwd) {
27
- return firstExisting(getDesignSidecarCandidates(cwd, contextDir));
28
- }
29
-
30
- export function getLiveDir(cwd = process.cwd()) {
31
- return path.join(getImpeccableDir(cwd), LIVE_DIR);
32
- }
33
-
34
- export function getLiveConfigPath(cwd = process.cwd()) {
35
- return path.join(getLiveDir(cwd), 'config.json');
36
- }
37
-
38
- export function getLegacyLiveConfigPath(scriptsDir) {
39
- return path.join(scriptsDir, 'config.json');
40
- }
41
-
42
- export function resolveLiveConfigPath({ cwd = process.cwd(), scriptsDir, env = process.env } = {}) {
43
- if (env.IMPECCABLE_LIVE_CONFIG && env.IMPECCABLE_LIVE_CONFIG.trim()) {
44
- const configured = env.IMPECCABLE_LIVE_CONFIG.trim();
45
- return path.isAbsolute(configured) ? configured : path.resolve(cwd, configured);
46
- }
47
- const primary = getLiveConfigPath(cwd);
48
- if (fs.existsSync(primary)) return primary;
49
- if (scriptsDir) {
50
- const legacy = getLegacyLiveConfigPath(scriptsDir);
51
- if (fs.existsSync(legacy)) return legacy;
52
- }
53
- return primary;
54
- }
55
-
56
- export function getLiveServerPath(cwd = process.cwd()) {
57
- return path.join(getLiveDir(cwd), 'server.json');
58
- }
59
-
60
- export function getLegacyLiveServerPath(cwd = process.cwd()) {
61
- return path.join(cwd, '.impeccable-live.json');
62
- }
63
-
64
- export function readLiveServerInfo(cwd = process.cwd()) {
65
- for (const filePath of [getLiveServerPath(cwd), getLegacyLiveServerPath(cwd)]) {
66
- try {
67
- return { info: JSON.parse(fs.readFileSync(filePath, 'utf-8')), path: filePath };
68
- } catch {
69
- /* try next */
70
- }
71
- }
72
- return null;
73
- }
74
-
75
- export function writeLiveServerInfo(cwd = process.cwd(), info) {
76
- const filePath = getLiveServerPath(cwd);
77
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
78
- fs.writeFileSync(filePath, JSON.stringify(info));
79
- return filePath;
80
- }
81
-
82
- export function removeLiveServerInfo(cwd = process.cwd()) {
83
- for (const filePath of [getLiveServerPath(cwd), getLegacyLiveServerPath(cwd)]) {
84
- try { fs.unlinkSync(filePath); } catch {}
85
- }
86
- }
87
-
88
- export function getLiveSessionsDir(cwd = process.cwd()) {
89
- return path.join(getLiveDir(cwd), 'sessions');
90
- }
91
-
92
- export function getLegacyLiveSessionsDir(cwd = process.cwd()) {
93
- return path.join(cwd, '.impeccable-live', 'sessions');
94
- }
95
-
96
- export function getLiveAnnotationsDir(cwd = process.cwd()) {
97
- return path.join(getLiveDir(cwd), 'annotations');
98
- }
99
-
100
- export function getCritiqueDir(cwd = process.cwd()) {
101
- return path.join(getImpeccableDir(cwd), CRITIQUE_DIR);
102
- }
103
-
104
- export function getLegacyLiveAnnotationsDir(cwd = process.cwd()) {
105
- return path.join(cwd, '.impeccable-live', 'annotations');
106
- }
107
-
108
- function firstExisting(paths) {
109
- return paths.find((filePath) => fs.existsSync(filePath)) || null;
110
- }
@@ -1,69 +0,0 @@
1
- /**
2
- * Decide whether a given file is "generated" (regenerated by a build step,
3
- * unsafe to write variants into) or "source" (safe to edit, changes persist).
4
- *
5
- * Why this matters: when the user picks an element on a page whose underlying
6
- * file is regenerated by a build step (e.g. `scripts/build-sub-pages.js`
7
- * rewriting `public/docs/*.html`), writing variants or accepted changes into
8
- * that file is silent data loss — the next build wipes them.
9
- *
10
- * Signals, in order of reliability:
11
- * 1. Git check-ignore: gitignored files are assumed generated.
12
- * 2. File-header markers ("GENERATED", "DO NOT EDIT", "AUTO-GENERATED")
13
- * within the first ~300 characters — catches non-git projects.
14
- */
15
-
16
- import { execSync } from 'node:child_process';
17
- import fs from 'node:fs';
18
- import path from 'node:path';
19
-
20
- const HEADER_SCAN_BYTES = 300;
21
- const HEADER_MARKERS = [
22
- /@generated\b/i,
23
- /\bGENERATED\s+FILE\b/,
24
- /\bAUTO-?GENERATED\b/i,
25
- /\bDO\s+NOT\s+EDIT\b/i,
26
- ];
27
-
28
- /**
29
- * @param {string} filePath - absolute or cwd-relative path
30
- * @param {object} [options]
31
- * @param {string} [options.cwd] - project root (defaults to process.cwd())
32
- */
33
- export function isGeneratedFile(filePath, options = {}) {
34
- const cwd = options.cwd || process.cwd();
35
- const absPath = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
36
-
37
- if (isGitIgnored(absPath, cwd)) return true;
38
- if (hasGeneratedHeader(absPath)) return true;
39
- return false;
40
- }
41
-
42
- function isGitIgnored(absPath, cwd) {
43
- try {
44
- execSync(`git check-ignore --quiet ${JSON.stringify(absPath)}`, {
45
- cwd,
46
- stdio: 'ignore',
47
- });
48
- return true; // exit 0 = ignored
49
- } catch (err) {
50
- // Exit code 1 = not ignored. Exit code 128 = not a git repo or other error.
51
- // In both cases, treat as "not known to be ignored."
52
- return false;
53
- }
54
- }
55
-
56
- function hasGeneratedHeader(absPath) {
57
- let fd;
58
- try {
59
- fd = fs.openSync(absPath, 'r');
60
- const buf = Buffer.alloc(HEADER_SCAN_BYTES);
61
- const bytesRead = fs.readSync(fd, buf, 0, HEADER_SCAN_BYTES, 0);
62
- const head = buf.slice(0, bytesRead).toString('utf-8');
63
- return HEADER_MARKERS.some((re) => re.test(head));
64
- } catch {
65
- return false;
66
- } finally {
67
- if (fd !== undefined) { try { fs.closeSync(fd); } catch {} }
68
- }
69
- }