pm-workflow-studio 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. package/.claude/CLAUDE.md +31 -0
  2. package/.claude/agents/demand-analyst.md +26 -0
  3. package/.claude/agents/dev-planner.md +22 -0
  4. package/.claude/agents/product-manager.md +25 -0
  5. package/.claude/agents/quality-reviewer.md +31 -0
  6. package/.claude/agents/tech-architect.md +22 -0
  7. package/.claude/agents/ui-designer.md +39 -0
  8. package/.claude/commands/pm-workflow/analyze.md +6 -0
  9. package/.claude/commands/pm-workflow/architect.md +6 -0
  10. package/.claude/commands/pm-workflow/deliver.md +6 -0
  11. package/.claude/commands/pm-workflow/design.md +6 -0
  12. package/.claude/commands/pm-workflow/help.md +6 -0
  13. package/.claude/commands/pm-workflow/init.md +8 -0
  14. package/.claude/commands/pm-workflow/plan.md +6 -0
  15. package/.claude/commands/pm-workflow/review.md +6 -0
  16. package/.claude/commands/pm-workflow/status.md +6 -0
  17. package/.claude/commands/pm-workflow.md +13 -0
  18. package/.claude/settings.json +15 -0
  19. package/.claude/skills/demand-analysis/SKILL.md +50 -0
  20. package/.claude/skills/demand-analysis/templates/handoff-prd.md +39 -0
  21. package/.claude/skills/demand-analysis/templates/prd.md +85 -0
  22. package/.claude/skills/dev-task-planning/SKILL.md +37 -0
  23. package/.claude/skills/dev-task-planning/templates/dev-tasks.md +54 -0
  24. package/.claude/skills/impeccable/SKILL.md +169 -0
  25. package/.claude/skills/impeccable/reference/adapt.md +190 -0
  26. package/.claude/skills/impeccable/reference/animate.md +175 -0
  27. package/.claude/skills/impeccable/reference/audit.md +133 -0
  28. package/.claude/skills/impeccable/reference/bolder.md +113 -0
  29. package/.claude/skills/impeccable/reference/brand.md +118 -0
  30. package/.claude/skills/impeccable/reference/clarify.md +174 -0
  31. package/.claude/skills/impeccable/reference/codex.md +105 -0
  32. package/.claude/skills/impeccable/reference/cognitive-load.md +106 -0
  33. package/.claude/skills/impeccable/reference/color-and-contrast.md +105 -0
  34. package/.claude/skills/impeccable/reference/colorize.md +154 -0
  35. package/.claude/skills/impeccable/reference/craft.md +123 -0
  36. package/.claude/skills/impeccable/reference/critique.md +236 -0
  37. package/.claude/skills/impeccable/reference/delight.md +302 -0
  38. package/.claude/skills/impeccable/reference/distill.md +111 -0
  39. package/.claude/skills/impeccable/reference/document.md +427 -0
  40. package/.claude/skills/impeccable/reference/extract.md +69 -0
  41. package/.claude/skills/impeccable/reference/harden.md +347 -0
  42. package/.claude/skills/impeccable/reference/heuristics-scoring.md +234 -0
  43. package/.claude/skills/impeccable/reference/interaction-design.md +195 -0
  44. package/.claude/skills/impeccable/reference/layout.md +141 -0
  45. package/.claude/skills/impeccable/reference/live.md +622 -0
  46. package/.claude/skills/impeccable/reference/motion-design.md +109 -0
  47. package/.claude/skills/impeccable/reference/onboard.md +234 -0
  48. package/.claude/skills/impeccable/reference/optimize.md +258 -0
  49. package/.claude/skills/impeccable/reference/overdrive.md +130 -0
  50. package/.claude/skills/impeccable/reference/personas.md +179 -0
  51. package/.claude/skills/impeccable/reference/polish.md +242 -0
  52. package/.claude/skills/impeccable/reference/product.md +62 -0
  53. package/.claude/skills/impeccable/reference/quieter.md +99 -0
  54. package/.claude/skills/impeccable/reference/responsive-design.md +114 -0
  55. package/.claude/skills/impeccable/reference/shape.md +165 -0
  56. package/.claude/skills/impeccable/reference/spatial-design.md +100 -0
  57. package/.claude/skills/impeccable/reference/teach.md +156 -0
  58. package/.claude/skills/impeccable/reference/typeset.md +124 -0
  59. package/.claude/skills/impeccable/reference/typography.md +159 -0
  60. package/.claude/skills/impeccable/reference/ux-writing.md +107 -0
  61. package/.claude/skills/impeccable/scripts/cleanup-deprecated.mjs +284 -0
  62. package/.claude/skills/impeccable/scripts/command-metadata.json +94 -0
  63. package/.claude/skills/impeccable/scripts/critique-storage.mjs +242 -0
  64. package/.claude/skills/impeccable/scripts/design-parser.mjs +820 -0
  65. package/.claude/skills/impeccable/scripts/detect-csp.mjs +198 -0
  66. package/.claude/skills/impeccable/scripts/detect.mjs +21 -0
  67. package/.claude/skills/impeccable/scripts/detector/browser/injected/index.mjs +1688 -0
  68. package/.claude/skills/impeccable/scripts/detector/cli/main.mjs +232 -0
  69. package/.claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +4030 -0
  70. package/.claude/skills/impeccable/scripts/detector/detect-antipatterns.mjs +43 -0
  71. package/.claude/skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +251 -0
  72. package/.claude/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +420 -0
  73. package/.claude/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +954 -0
  74. package/.claude/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +174 -0
  75. package/.claude/skills/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +189 -0
  76. package/.claude/skills/impeccable/scripts/detector/findings.mjs +12 -0
  77. package/.claude/skills/impeccable/scripts/detector/node/file-system.mjs +198 -0
  78. package/.claude/skills/impeccable/scripts/detector/profile/profiler.mjs +166 -0
  79. package/.claude/skills/impeccable/scripts/detector/registry/antipatterns.mjs +278 -0
  80. package/.claude/skills/impeccable/scripts/detector/rules/checks.mjs +1948 -0
  81. package/.claude/skills/impeccable/scripts/detector/shared/color.mjs +124 -0
  82. package/.claude/skills/impeccable/scripts/detector/shared/constants.mjs +101 -0
  83. package/.claude/skills/impeccable/scripts/detector/shared/page.mjs +7 -0
  84. package/.claude/skills/impeccable/scripts/impeccable-paths.mjs +110 -0
  85. package/.claude/skills/impeccable/scripts/is-generated.mjs +69 -0
  86. package/.claude/skills/impeccable/scripts/live-accept.mjs +595 -0
  87. package/.claude/skills/impeccable/scripts/live-browser-session.js +123 -0
  88. package/.claude/skills/impeccable/scripts/live-browser.js +4860 -0
  89. package/.claude/skills/impeccable/scripts/live-complete.mjs +75 -0
  90. package/.claude/skills/impeccable/scripts/live-completion.mjs +18 -0
  91. package/.claude/skills/impeccable/scripts/live-inject.mjs +446 -0
  92. package/.claude/skills/impeccable/scripts/live-poll.mjs +200 -0
  93. package/.claude/skills/impeccable/scripts/live-resume.mjs +48 -0
  94. package/.claude/skills/impeccable/scripts/live-server.mjs +838 -0
  95. package/.claude/skills/impeccable/scripts/live-session-store.mjs +254 -0
  96. package/.claude/skills/impeccable/scripts/live-status.mjs +47 -0
  97. package/.claude/skills/impeccable/scripts/live-wrap.mjs +632 -0
  98. package/.claude/skills/impeccable/scripts/live.mjs +247 -0
  99. package/.claude/skills/impeccable/scripts/load-context.mjs +141 -0
  100. package/.claude/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  101. package/.claude/skills/impeccable/scripts/pin.mjs +214 -0
  102. package/.claude/skills/pm-workflow/SKILL.md +371 -0
  103. package/.claude/skills/pm-workflow/assets/design-themes/README.md +56 -0
  104. package/.claude/skills/pm-workflow/assets/design-themes/open-design/OPEN_DESIGN_COMMIT +1 -0
  105. package/.claude/skills/pm-workflow/assets/design-themes/open-design/OPEN_DESIGN_IMPORT.md +28 -0
  106. package/.claude/skills/pm-workflow/assets/design-themes/open-design/OPEN_DESIGN_LICENSE +201 -0
  107. package/.claude/skills/pm-workflow/assets/design-themes/open-design/README.md +103 -0
  108. package/.claude/skills/pm-workflow/assets/design-themes/open-design/agentic/DESIGN.md +71 -0
  109. package/.claude/skills/pm-workflow/assets/design-themes/open-design/airbnb/DESIGN.md +393 -0
  110. package/.claude/skills/pm-workflow/assets/design-themes/open-design/airbnb/examples.html +23 -0
  111. package/.claude/skills/pm-workflow/assets/design-themes/open-design/airtable/DESIGN.md +92 -0
  112. package/.claude/skills/pm-workflow/assets/design-themes/open-design/apple/DESIGN.md +250 -0
  113. package/.claude/skills/pm-workflow/assets/design-themes/open-design/apple/examples.html +23 -0
  114. package/.claude/skills/pm-workflow/assets/design-themes/open-design/application/DESIGN.md +71 -0
  115. package/.claude/skills/pm-workflow/assets/design-themes/open-design/arc/DESIGN.md +152 -0
  116. package/.claude/skills/pm-workflow/assets/design-themes/open-design/artistic/DESIGN.md +71 -0
  117. package/.claude/skills/pm-workflow/assets/design-themes/open-design/atelier-zero/DESIGN.md +316 -0
  118. package/.claude/skills/pm-workflow/assets/design-themes/open-design/bento/DESIGN.md +71 -0
  119. package/.claude/skills/pm-workflow/assets/design-themes/open-design/binance/DESIGN.md +348 -0
  120. package/.claude/skills/pm-workflow/assets/design-themes/open-design/bmw/DESIGN.md +183 -0
  121. package/.claude/skills/pm-workflow/assets/design-themes/open-design/bmw-m/DESIGN.md +246 -0
  122. package/.claude/skills/pm-workflow/assets/design-themes/open-design/bold/DESIGN.md +71 -0
  123. package/.claude/skills/pm-workflow/assets/design-themes/open-design/brutalism/DESIGN.md +71 -0
  124. package/.claude/skills/pm-workflow/assets/design-themes/open-design/bugatti/DESIGN.md +271 -0
  125. package/.claude/skills/pm-workflow/assets/design-themes/open-design/cafe/DESIGN.md +71 -0
  126. package/.claude/skills/pm-workflow/assets/design-themes/open-design/cal/DESIGN.md +262 -0
  127. package/.claude/skills/pm-workflow/assets/design-themes/open-design/canva/DESIGN.md +157 -0
  128. package/.claude/skills/pm-workflow/assets/design-themes/open-design/cisco/DESIGN.md +201 -0
  129. package/.claude/skills/pm-workflow/assets/design-themes/open-design/claude/DESIGN.md +315 -0
  130. package/.claude/skills/pm-workflow/assets/design-themes/open-design/clay/DESIGN.md +307 -0
  131. package/.claude/skills/pm-workflow/assets/design-themes/open-design/claymorphism/DESIGN.md +71 -0
  132. package/.claude/skills/pm-workflow/assets/design-themes/open-design/clean/DESIGN.md +71 -0
  133. package/.claude/skills/pm-workflow/assets/design-themes/open-design/clickhouse/DESIGN.md +284 -0
  134. package/.claude/skills/pm-workflow/assets/design-themes/open-design/cohere/DESIGN.md +269 -0
  135. package/.claude/skills/pm-workflow/assets/design-themes/open-design/coinbase/DESIGN.md +132 -0
  136. package/.claude/skills/pm-workflow/assets/design-themes/open-design/colorful/DESIGN.md +71 -0
  137. package/.claude/skills/pm-workflow/assets/design-themes/open-design/composio/DESIGN.md +310 -0
  138. package/.claude/skills/pm-workflow/assets/design-themes/open-design/contemporary/DESIGN.md +71 -0
  139. package/.claude/skills/pm-workflow/assets/design-themes/open-design/corporate/DESIGN.md +71 -0
  140. package/.claude/skills/pm-workflow/assets/design-themes/open-design/cosmic/DESIGN.md +71 -0
  141. package/.claude/skills/pm-workflow/assets/design-themes/open-design/creative/DESIGN.md +71 -0
  142. package/.claude/skills/pm-workflow/assets/design-themes/open-design/cursor/DESIGN.md +312 -0
  143. package/.claude/skills/pm-workflow/assets/design-themes/open-design/dashboard/DESIGN.md +71 -0
  144. package/.claude/skills/pm-workflow/assets/design-themes/open-design/default/DESIGN.md +62 -0
  145. package/.claude/skills/pm-workflow/assets/design-themes/open-design/discord/DESIGN.md +162 -0
  146. package/.claude/skills/pm-workflow/assets/design-themes/open-design/dithered/DESIGN.md +71 -0
  147. package/.claude/skills/pm-workflow/assets/design-themes/open-design/doodle/DESIGN.md +71 -0
  148. package/.claude/skills/pm-workflow/assets/design-themes/open-design/dramatic/DESIGN.md +71 -0
  149. package/.claude/skills/pm-workflow/assets/design-themes/open-design/duolingo/DESIGN.md +154 -0
  150. package/.claude/skills/pm-workflow/assets/design-themes/open-design/editorial/DESIGN.md +71 -0
  151. package/.claude/skills/pm-workflow/assets/design-themes/open-design/elegant/DESIGN.md +71 -0
  152. package/.claude/skills/pm-workflow/assets/design-themes/open-design/elevenlabs/DESIGN.md +268 -0
  153. package/.claude/skills/pm-workflow/assets/design-themes/open-design/energetic/DESIGN.md +72 -0
  154. package/.claude/skills/pm-workflow/assets/design-themes/open-design/enterprise/DESIGN.md +71 -0
  155. package/.claude/skills/pm-workflow/assets/design-themes/open-design/expo/DESIGN.md +284 -0
  156. package/.claude/skills/pm-workflow/assets/design-themes/open-design/expressive/DESIGN.md +71 -0
  157. package/.claude/skills/pm-workflow/assets/design-themes/open-design/fantasy/DESIGN.md +71 -0
  158. package/.claude/skills/pm-workflow/assets/design-themes/open-design/ferrari/DESIGN.md +317 -0
  159. package/.claude/skills/pm-workflow/assets/design-themes/open-design/figma/DESIGN.md +223 -0
  160. package/.claude/skills/pm-workflow/assets/design-themes/open-design/flat/DESIGN.md +71 -0
  161. package/.claude/skills/pm-workflow/assets/design-themes/open-design/framer/DESIGN.md +249 -0
  162. package/.claude/skills/pm-workflow/assets/design-themes/open-design/friendly/DESIGN.md +71 -0
  163. package/.claude/skills/pm-workflow/assets/design-themes/open-design/futuristic/DESIGN.md +71 -0
  164. package/.claude/skills/pm-workflow/assets/design-themes/open-design/glassmorphism/DESIGN.md +71 -0
  165. package/.claude/skills/pm-workflow/assets/design-themes/open-design/gradient/DESIGN.md +71 -0
  166. package/.claude/skills/pm-workflow/assets/design-themes/open-design/hashicorp/DESIGN.md +281 -0
  167. package/.claude/skills/pm-workflow/assets/design-themes/open-design/hud/DESIGN.md +173 -0
  168. package/.claude/skills/pm-workflow/assets/design-themes/open-design/huggingface/DESIGN.md +149 -0
  169. package/.claude/skills/pm-workflow/assets/design-themes/open-design/huggingface/examples.html +11 -0
  170. package/.claude/skills/pm-workflow/assets/design-themes/open-design/intercom/DESIGN.md +149 -0
  171. package/.claude/skills/pm-workflow/assets/design-themes/open-design/kami/DESIGN.md +410 -0
  172. package/.claude/skills/pm-workflow/assets/design-themes/open-design/kraken/DESIGN.md +128 -0
  173. package/.claude/skills/pm-workflow/assets/design-themes/open-design/lamborghini/DESIGN.md +291 -0
  174. package/.claude/skills/pm-workflow/assets/design-themes/open-design/levels/DESIGN.md +71 -0
  175. package/.claude/skills/pm-workflow/assets/design-themes/open-design/linear-app/DESIGN.md +370 -0
  176. package/.claude/skills/pm-workflow/assets/design-themes/open-design/linear-app/examples.html +56 -0
  177. package/.claude/skills/pm-workflow/assets/design-themes/open-design/lingo/DESIGN.md +71 -0
  178. package/.claude/skills/pm-workflow/assets/design-themes/open-design/loom/DESIGN.md +201 -0
  179. package/.claude/skills/pm-workflow/assets/design-themes/open-design/lovable/DESIGN.md +301 -0
  180. package/.claude/skills/pm-workflow/assets/design-themes/open-design/luxury/DESIGN.md +71 -0
  181. package/.claude/skills/pm-workflow/assets/design-themes/open-design/mastercard/DESIGN.md +368 -0
  182. package/.claude/skills/pm-workflow/assets/design-themes/open-design/material/DESIGN.md +71 -0
  183. package/.claude/skills/pm-workflow/assets/design-themes/open-design/material/examples.html +11 -0
  184. package/.claude/skills/pm-workflow/assets/design-themes/open-design/meta/DESIGN.md +369 -0
  185. package/.claude/skills/pm-workflow/assets/design-themes/open-design/minimal/DESIGN.md +71 -0
  186. package/.claude/skills/pm-workflow/assets/design-themes/open-design/minimax/DESIGN.md +260 -0
  187. package/.claude/skills/pm-workflow/assets/design-themes/open-design/mintlify/DESIGN.md +329 -0
  188. package/.claude/skills/pm-workflow/assets/design-themes/open-design/miro/DESIGN.md +111 -0
  189. package/.claude/skills/pm-workflow/assets/design-themes/open-design/mission-control/DESIGN.md +474 -0
  190. package/.claude/skills/pm-workflow/assets/design-themes/open-design/mistral-ai/DESIGN.md +264 -0
  191. package/.claude/skills/pm-workflow/assets/design-themes/open-design/modern/DESIGN.md +71 -0
  192. package/.claude/skills/pm-workflow/assets/design-themes/open-design/mongodb/DESIGN.md +269 -0
  193. package/.claude/skills/pm-workflow/assets/design-themes/open-design/mongodb/examples.html +14 -0
  194. package/.claude/skills/pm-workflow/assets/design-themes/open-design/mono/DESIGN.md +71 -0
  195. package/.claude/skills/pm-workflow/assets/design-themes/open-design/neobrutalism/DESIGN.md +71 -0
  196. package/.claude/skills/pm-workflow/assets/design-themes/open-design/neon/DESIGN.md +71 -0
  197. package/.claude/skills/pm-workflow/assets/design-themes/open-design/neumorphism/DESIGN.md +71 -0
  198. package/.claude/skills/pm-workflow/assets/design-themes/open-design/nike/DESIGN.md +366 -0
  199. package/.claude/skills/pm-workflow/assets/design-themes/open-design/notion/DESIGN.md +312 -0
  200. package/.claude/skills/pm-workflow/assets/design-themes/open-design/notion/examples.html +64 -0
  201. package/.claude/skills/pm-workflow/assets/design-themes/open-design/nvidia/DESIGN.md +296 -0
  202. package/.claude/skills/pm-workflow/assets/design-themes/open-design/ollama/DESIGN.md +270 -0
  203. package/.claude/skills/pm-workflow/assets/design-themes/open-design/openai/DESIGN.md +140 -0
  204. package/.claude/skills/pm-workflow/assets/design-themes/open-design/openai/examples.html +14 -0
  205. package/.claude/skills/pm-workflow/assets/design-themes/open-design/opencode-ai/DESIGN.md +284 -0
  206. package/.claude/skills/pm-workflow/assets/design-themes/open-design/pacman/DESIGN.md +71 -0
  207. package/.claude/skills/pm-workflow/assets/design-themes/open-design/paper/DESIGN.md +71 -0
  208. package/.claude/skills/pm-workflow/assets/design-themes/open-design/perspective/DESIGN.md +71 -0
  209. package/.claude/skills/pm-workflow/assets/design-themes/open-design/pinterest/DESIGN.md +233 -0
  210. package/.claude/skills/pm-workflow/assets/design-themes/open-design/playstation/DESIGN.md +367 -0
  211. package/.claude/skills/pm-workflow/assets/design-themes/open-design/posthog/DESIGN.md +259 -0
  212. package/.claude/skills/pm-workflow/assets/design-themes/open-design/premium/DESIGN.md +71 -0
  213. package/.claude/skills/pm-workflow/assets/design-themes/open-design/professional/DESIGN.md +71 -0
  214. package/.claude/skills/pm-workflow/assets/design-themes/open-design/publication/DESIGN.md +71 -0
  215. package/.claude/skills/pm-workflow/assets/design-themes/open-design/raycast/DESIGN.md +271 -0
  216. package/.claude/skills/pm-workflow/assets/design-themes/open-design/raycast/examples.html +11 -0
  217. package/.claude/skills/pm-workflow/assets/design-themes/open-design/refined/DESIGN.md +71 -0
  218. package/.claude/skills/pm-workflow/assets/design-themes/open-design/renault/DESIGN.md +314 -0
  219. package/.claude/skills/pm-workflow/assets/design-themes/open-design/replicate/DESIGN.md +264 -0
  220. package/.claude/skills/pm-workflow/assets/design-themes/open-design/resend/DESIGN.md +306 -0
  221. package/.claude/skills/pm-workflow/assets/design-themes/open-design/retro/DESIGN.md +71 -0
  222. package/.claude/skills/pm-workflow/assets/design-themes/open-design/revolut/DESIGN.md +188 -0
  223. package/.claude/skills/pm-workflow/assets/design-themes/open-design/runwayml/DESIGN.md +247 -0
  224. package/.claude/skills/pm-workflow/assets/design-themes/open-design/sanity/DESIGN.md +360 -0
  225. package/.claude/skills/pm-workflow/assets/design-themes/open-design/sentry/DESIGN.md +265 -0
  226. package/.claude/skills/pm-workflow/assets/design-themes/open-design/shadcn/DESIGN.md +71 -0
  227. package/.claude/skills/pm-workflow/assets/design-themes/open-design/shadcn/examples.html +24 -0
  228. package/.claude/skills/pm-workflow/assets/design-themes/open-design/shopify/DESIGN.md +353 -0
  229. package/.claude/skills/pm-workflow/assets/design-themes/open-design/shopify/examples.html +11 -0
  230. package/.claude/skills/pm-workflow/assets/design-themes/open-design/simple/DESIGN.md +71 -0
  231. package/.claude/skills/pm-workflow/assets/design-themes/open-design/skeumorphism/DESIGN.md +71 -0
  232. package/.claude/skills/pm-workflow/assets/design-themes/open-design/sleek/DESIGN.md +71 -0
  233. package/.claude/skills/pm-workflow/assets/design-themes/open-design/spacex/DESIGN.md +197 -0
  234. package/.claude/skills/pm-workflow/assets/design-themes/open-design/spacious/DESIGN.md +71 -0
  235. package/.claude/skills/pm-workflow/assets/design-themes/open-design/spotify/DESIGN.md +249 -0
  236. package/.claude/skills/pm-workflow/assets/design-themes/open-design/starbucks/DESIGN.md +583 -0
  237. package/.claude/skills/pm-workflow/assets/design-themes/open-design/storytelling/DESIGN.md +71 -0
  238. package/.claude/skills/pm-workflow/assets/design-themes/open-design/stripe/DESIGN.md +325 -0
  239. package/.claude/skills/pm-workflow/assets/design-themes/open-design/stripe/examples.html +58 -0
  240. package/.claude/skills/pm-workflow/assets/design-themes/open-design/supabase/DESIGN.md +258 -0
  241. package/.claude/skills/pm-workflow/assets/design-themes/open-design/supabase/examples.html +26 -0
  242. package/.claude/skills/pm-workflow/assets/design-themes/open-design/superhuman/DESIGN.md +255 -0
  243. package/.claude/skills/pm-workflow/assets/design-themes/open-design/tesla/DESIGN.md +289 -0
  244. package/.claude/skills/pm-workflow/assets/design-themes/open-design/tetris/DESIGN.md +71 -0
  245. package/.claude/skills/pm-workflow/assets/design-themes/open-design/theverge/DESIGN.md +342 -0
  246. package/.claude/skills/pm-workflow/assets/design-themes/open-design/together-ai/DESIGN.md +266 -0
  247. package/.claude/skills/pm-workflow/assets/design-themes/open-design/totality-festival/DESIGN.md +206 -0
  248. package/.claude/skills/pm-workflow/assets/design-themes/open-design/trading-terminal/DESIGN.md +178 -0
  249. package/.claude/skills/pm-workflow/assets/design-themes/open-design/uber/DESIGN.md +298 -0
  250. package/.claude/skills/pm-workflow/assets/design-themes/open-design/urdu/DESIGN.md +1002 -0
  251. package/.claude/skills/pm-workflow/assets/design-themes/open-design/vercel/DESIGN.md +313 -0
  252. package/.claude/skills/pm-workflow/assets/design-themes/open-design/vercel/examples.html +55 -0
  253. package/.claude/skills/pm-workflow/assets/design-themes/open-design/vibrant/DESIGN.md +71 -0
  254. package/.claude/skills/pm-workflow/assets/design-themes/open-design/vintage/DESIGN.md +71 -0
  255. package/.claude/skills/pm-workflow/assets/design-themes/open-design/vodafone/DESIGN.md +426 -0
  256. package/.claude/skills/pm-workflow/assets/design-themes/open-design/voltagent/DESIGN.md +326 -0
  257. package/.claude/skills/pm-workflow/assets/design-themes/open-design/warm-editorial/DESIGN.md +65 -0
  258. package/.claude/skills/pm-workflow/assets/design-themes/open-design/warp/DESIGN.md +256 -0
  259. package/.claude/skills/pm-workflow/assets/design-themes/open-design/webex/DESIGN.md +207 -0
  260. package/.claude/skills/pm-workflow/assets/design-themes/open-design/webflow/DESIGN.md +95 -0
  261. package/.claude/skills/pm-workflow/assets/design-themes/open-design/webflow/examples.html +11 -0
  262. package/.claude/skills/pm-workflow/assets/design-themes/open-design/wired/DESIGN.md +281 -0
  263. package/.claude/skills/pm-workflow/assets/design-themes/open-design/wise/DESIGN.md +176 -0
  264. package/.claude/skills/pm-workflow/assets/design-themes/open-design/x-ai/DESIGN.md +260 -0
  265. package/.claude/skills/pm-workflow/assets/design-themes/open-design/x-ai/examples.html +12 -0
  266. package/.claude/skills/pm-workflow/assets/design-themes/open-design/xiaohongshu/DESIGN.md +402 -0
  267. package/.claude/skills/pm-workflow/assets/design-themes/open-design/zapier/DESIGN.md +331 -0
  268. package/.claude/skills/pm-workflow/assets/design-themes/revenuecat/DESIGN.md +209 -0
  269. package/.claude/skills/pm-workflow/assets/design-themes/revenuecat/examples.html +122 -0
  270. package/.claude/skills/pm-workflow/assets/design-themes/vben/DESIGN.md +685 -0
  271. package/.claude/skills/pm-workflow/assets/design-themes/vben/examples.html +155 -0
  272. package/.claude/skills/pm-workflow/assets/vendor/flow-viewer/MERMAID_LICENSE +21 -0
  273. package/.claude/skills/pm-workflow/assets/vendor/flow-viewer/SVG_PAN_ZOOM_LICENSE +23 -0
  274. package/.claude/skills/pm-workflow/assets/vendor/flow-viewer/THIRD_PARTY_LICENSES.md +21 -0
  275. package/.claude/skills/pm-workflow/assets/vendor/flow-viewer/mermaid.min.js +3298 -0
  276. package/.claude/skills/pm-workflow/assets/vendor/flow-viewer/svg-pan-zoom.min.js +3 -0
  277. package/.claude/skills/pm-workflow/references/commands/analyze.md +39 -0
  278. package/.claude/skills/pm-workflow/references/commands/architect.md +41 -0
  279. package/.claude/skills/pm-workflow/references/commands/deliver.md +29 -0
  280. package/.claude/skills/pm-workflow/references/commands/design.md +92 -0
  281. package/.claude/skills/pm-workflow/references/commands/help.md +24 -0
  282. package/.claude/skills/pm-workflow/references/commands/init.md +40 -0
  283. package/.claude/skills/pm-workflow/references/commands/plan.md +41 -0
  284. package/.claude/skills/pm-workflow/references/commands/review.md +33 -0
  285. package/.claude/skills/pm-workflow/references/commands/status.md +20 -0
  286. package/.claude/skills/pm-workflow/scripts/package_delivery.js +195 -0
  287. package/.claude/skills/pm-workflow/scripts/review_stage.js +622 -0
  288. package/.claude/skills/quality-review/SKILL.md +49 -0
  289. package/.claude/skills/quality-review/templates/review-stage.md +39 -0
  290. package/.claude/skills/tech-architecture/SKILL.md +49 -0
  291. package/.claude/skills/tech-architecture/templates/handoff-architecture.md +28 -0
  292. package/.claude/skills/tech-architecture/templates/tech-architecture.md +54 -0
  293. package/.claude/skills/ui-prototype-design/SKILL.md +125 -0
  294. package/.claude/skills/ui-prototype-design/templates/handoff-ui.md +40 -0
  295. package/.claude/skills/ui-prototype-design/templates/prototype-review.md +57 -0
  296. package/.claude/skills/ui-prototype-design/templates/ui-design.md +142 -0
  297. package/.codex/SKILL.md +374 -0
  298. package/.codex/agents/demand-analyst.toml +87 -0
  299. package/.codex/agents/dev-planner.toml +47 -0
  300. package/.codex/agents/openai.yaml +4 -0
  301. package/.codex/agents/product-manager.toml +81 -0
  302. package/.codex/agents/quality-reviewer.toml +76 -0
  303. package/.codex/agents/tech-architect.toml +57 -0
  304. package/.codex/agents/ui-designer.toml +132 -0
  305. package/.codex/assets/design-themes/README.md +56 -0
  306. package/.codex/assets/design-themes/open-design/OPEN_DESIGN_COMMIT +1 -0
  307. package/.codex/assets/design-themes/open-design/OPEN_DESIGN_IMPORT.md +28 -0
  308. package/.codex/assets/design-themes/open-design/OPEN_DESIGN_LICENSE +201 -0
  309. package/.codex/assets/design-themes/open-design/README.md +103 -0
  310. package/.codex/assets/design-themes/open-design/agentic/DESIGN.md +71 -0
  311. package/.codex/assets/design-themes/open-design/airbnb/DESIGN.md +393 -0
  312. package/.codex/assets/design-themes/open-design/airbnb/examples.html +23 -0
  313. package/.codex/assets/design-themes/open-design/airtable/DESIGN.md +92 -0
  314. package/.codex/assets/design-themes/open-design/apple/DESIGN.md +250 -0
  315. package/.codex/assets/design-themes/open-design/apple/examples.html +23 -0
  316. package/.codex/assets/design-themes/open-design/application/DESIGN.md +71 -0
  317. package/.codex/assets/design-themes/open-design/arc/DESIGN.md +152 -0
  318. package/.codex/assets/design-themes/open-design/artistic/DESIGN.md +71 -0
  319. package/.codex/assets/design-themes/open-design/atelier-zero/DESIGN.md +316 -0
  320. package/.codex/assets/design-themes/open-design/bento/DESIGN.md +71 -0
  321. package/.codex/assets/design-themes/open-design/binance/DESIGN.md +348 -0
  322. package/.codex/assets/design-themes/open-design/bmw/DESIGN.md +183 -0
  323. package/.codex/assets/design-themes/open-design/bmw-m/DESIGN.md +246 -0
  324. package/.codex/assets/design-themes/open-design/bold/DESIGN.md +71 -0
  325. package/.codex/assets/design-themes/open-design/brutalism/DESIGN.md +71 -0
  326. package/.codex/assets/design-themes/open-design/bugatti/DESIGN.md +271 -0
  327. package/.codex/assets/design-themes/open-design/cafe/DESIGN.md +71 -0
  328. package/.codex/assets/design-themes/open-design/cal/DESIGN.md +262 -0
  329. package/.codex/assets/design-themes/open-design/canva/DESIGN.md +157 -0
  330. package/.codex/assets/design-themes/open-design/cisco/DESIGN.md +201 -0
  331. package/.codex/assets/design-themes/open-design/claude/DESIGN.md +315 -0
  332. package/.codex/assets/design-themes/open-design/clay/DESIGN.md +307 -0
  333. package/.codex/assets/design-themes/open-design/claymorphism/DESIGN.md +71 -0
  334. package/.codex/assets/design-themes/open-design/clean/DESIGN.md +71 -0
  335. package/.codex/assets/design-themes/open-design/clickhouse/DESIGN.md +284 -0
  336. package/.codex/assets/design-themes/open-design/cohere/DESIGN.md +269 -0
  337. package/.codex/assets/design-themes/open-design/coinbase/DESIGN.md +132 -0
  338. package/.codex/assets/design-themes/open-design/colorful/DESIGN.md +71 -0
  339. package/.codex/assets/design-themes/open-design/composio/DESIGN.md +310 -0
  340. package/.codex/assets/design-themes/open-design/contemporary/DESIGN.md +71 -0
  341. package/.codex/assets/design-themes/open-design/corporate/DESIGN.md +71 -0
  342. package/.codex/assets/design-themes/open-design/cosmic/DESIGN.md +71 -0
  343. package/.codex/assets/design-themes/open-design/creative/DESIGN.md +71 -0
  344. package/.codex/assets/design-themes/open-design/cursor/DESIGN.md +312 -0
  345. package/.codex/assets/design-themes/open-design/dashboard/DESIGN.md +71 -0
  346. package/.codex/assets/design-themes/open-design/default/DESIGN.md +62 -0
  347. package/.codex/assets/design-themes/open-design/discord/DESIGN.md +162 -0
  348. package/.codex/assets/design-themes/open-design/dithered/DESIGN.md +71 -0
  349. package/.codex/assets/design-themes/open-design/doodle/DESIGN.md +71 -0
  350. package/.codex/assets/design-themes/open-design/dramatic/DESIGN.md +71 -0
  351. package/.codex/assets/design-themes/open-design/duolingo/DESIGN.md +154 -0
  352. package/.codex/assets/design-themes/open-design/editorial/DESIGN.md +71 -0
  353. package/.codex/assets/design-themes/open-design/elegant/DESIGN.md +71 -0
  354. package/.codex/assets/design-themes/open-design/elevenlabs/DESIGN.md +268 -0
  355. package/.codex/assets/design-themes/open-design/energetic/DESIGN.md +72 -0
  356. package/.codex/assets/design-themes/open-design/enterprise/DESIGN.md +71 -0
  357. package/.codex/assets/design-themes/open-design/expo/DESIGN.md +284 -0
  358. package/.codex/assets/design-themes/open-design/expressive/DESIGN.md +71 -0
  359. package/.codex/assets/design-themes/open-design/fantasy/DESIGN.md +71 -0
  360. package/.codex/assets/design-themes/open-design/ferrari/DESIGN.md +317 -0
  361. package/.codex/assets/design-themes/open-design/figma/DESIGN.md +223 -0
  362. package/.codex/assets/design-themes/open-design/flat/DESIGN.md +71 -0
  363. package/.codex/assets/design-themes/open-design/framer/DESIGN.md +249 -0
  364. package/.codex/assets/design-themes/open-design/friendly/DESIGN.md +71 -0
  365. package/.codex/assets/design-themes/open-design/futuristic/DESIGN.md +71 -0
  366. package/.codex/assets/design-themes/open-design/glassmorphism/DESIGN.md +71 -0
  367. package/.codex/assets/design-themes/open-design/gradient/DESIGN.md +71 -0
  368. package/.codex/assets/design-themes/open-design/hashicorp/DESIGN.md +281 -0
  369. package/.codex/assets/design-themes/open-design/hud/DESIGN.md +173 -0
  370. package/.codex/assets/design-themes/open-design/huggingface/DESIGN.md +149 -0
  371. package/.codex/assets/design-themes/open-design/huggingface/examples.html +11 -0
  372. package/.codex/assets/design-themes/open-design/intercom/DESIGN.md +149 -0
  373. package/.codex/assets/design-themes/open-design/kami/DESIGN.md +410 -0
  374. package/.codex/assets/design-themes/open-design/kraken/DESIGN.md +128 -0
  375. package/.codex/assets/design-themes/open-design/lamborghini/DESIGN.md +291 -0
  376. package/.codex/assets/design-themes/open-design/levels/DESIGN.md +71 -0
  377. package/.codex/assets/design-themes/open-design/linear-app/DESIGN.md +370 -0
  378. package/.codex/assets/design-themes/open-design/linear-app/examples.html +56 -0
  379. package/.codex/assets/design-themes/open-design/lingo/DESIGN.md +71 -0
  380. package/.codex/assets/design-themes/open-design/loom/DESIGN.md +201 -0
  381. package/.codex/assets/design-themes/open-design/lovable/DESIGN.md +301 -0
  382. package/.codex/assets/design-themes/open-design/luxury/DESIGN.md +71 -0
  383. package/.codex/assets/design-themes/open-design/mastercard/DESIGN.md +368 -0
  384. package/.codex/assets/design-themes/open-design/material/DESIGN.md +71 -0
  385. package/.codex/assets/design-themes/open-design/material/examples.html +11 -0
  386. package/.codex/assets/design-themes/open-design/meta/DESIGN.md +369 -0
  387. package/.codex/assets/design-themes/open-design/minimal/DESIGN.md +71 -0
  388. package/.codex/assets/design-themes/open-design/minimax/DESIGN.md +260 -0
  389. package/.codex/assets/design-themes/open-design/mintlify/DESIGN.md +329 -0
  390. package/.codex/assets/design-themes/open-design/miro/DESIGN.md +111 -0
  391. package/.codex/assets/design-themes/open-design/mission-control/DESIGN.md +474 -0
  392. package/.codex/assets/design-themes/open-design/mistral-ai/DESIGN.md +264 -0
  393. package/.codex/assets/design-themes/open-design/modern/DESIGN.md +71 -0
  394. package/.codex/assets/design-themes/open-design/mongodb/DESIGN.md +269 -0
  395. package/.codex/assets/design-themes/open-design/mongodb/examples.html +14 -0
  396. package/.codex/assets/design-themes/open-design/mono/DESIGN.md +71 -0
  397. package/.codex/assets/design-themes/open-design/neobrutalism/DESIGN.md +71 -0
  398. package/.codex/assets/design-themes/open-design/neon/DESIGN.md +71 -0
  399. package/.codex/assets/design-themes/open-design/neumorphism/DESIGN.md +71 -0
  400. package/.codex/assets/design-themes/open-design/nike/DESIGN.md +366 -0
  401. package/.codex/assets/design-themes/open-design/notion/DESIGN.md +312 -0
  402. package/.codex/assets/design-themes/open-design/notion/examples.html +64 -0
  403. package/.codex/assets/design-themes/open-design/nvidia/DESIGN.md +296 -0
  404. package/.codex/assets/design-themes/open-design/ollama/DESIGN.md +270 -0
  405. package/.codex/assets/design-themes/open-design/openai/DESIGN.md +140 -0
  406. package/.codex/assets/design-themes/open-design/openai/examples.html +14 -0
  407. package/.codex/assets/design-themes/open-design/opencode-ai/DESIGN.md +284 -0
  408. package/.codex/assets/design-themes/open-design/pacman/DESIGN.md +71 -0
  409. package/.codex/assets/design-themes/open-design/paper/DESIGN.md +71 -0
  410. package/.codex/assets/design-themes/open-design/perspective/DESIGN.md +71 -0
  411. package/.codex/assets/design-themes/open-design/pinterest/DESIGN.md +233 -0
  412. package/.codex/assets/design-themes/open-design/playstation/DESIGN.md +367 -0
  413. package/.codex/assets/design-themes/open-design/posthog/DESIGN.md +259 -0
  414. package/.codex/assets/design-themes/open-design/premium/DESIGN.md +71 -0
  415. package/.codex/assets/design-themes/open-design/professional/DESIGN.md +71 -0
  416. package/.codex/assets/design-themes/open-design/publication/DESIGN.md +71 -0
  417. package/.codex/assets/design-themes/open-design/raycast/DESIGN.md +271 -0
  418. package/.codex/assets/design-themes/open-design/raycast/examples.html +11 -0
  419. package/.codex/assets/design-themes/open-design/refined/DESIGN.md +71 -0
  420. package/.codex/assets/design-themes/open-design/renault/DESIGN.md +314 -0
  421. package/.codex/assets/design-themes/open-design/replicate/DESIGN.md +264 -0
  422. package/.codex/assets/design-themes/open-design/resend/DESIGN.md +306 -0
  423. package/.codex/assets/design-themes/open-design/retro/DESIGN.md +71 -0
  424. package/.codex/assets/design-themes/open-design/revolut/DESIGN.md +188 -0
  425. package/.codex/assets/design-themes/open-design/runwayml/DESIGN.md +247 -0
  426. package/.codex/assets/design-themes/open-design/sanity/DESIGN.md +360 -0
  427. package/.codex/assets/design-themes/open-design/sentry/DESIGN.md +265 -0
  428. package/.codex/assets/design-themes/open-design/shadcn/DESIGN.md +71 -0
  429. package/.codex/assets/design-themes/open-design/shadcn/examples.html +24 -0
  430. package/.codex/assets/design-themes/open-design/shopify/DESIGN.md +353 -0
  431. package/.codex/assets/design-themes/open-design/shopify/examples.html +11 -0
  432. package/.codex/assets/design-themes/open-design/simple/DESIGN.md +71 -0
  433. package/.codex/assets/design-themes/open-design/skeumorphism/DESIGN.md +71 -0
  434. package/.codex/assets/design-themes/open-design/sleek/DESIGN.md +71 -0
  435. package/.codex/assets/design-themes/open-design/spacex/DESIGN.md +197 -0
  436. package/.codex/assets/design-themes/open-design/spacious/DESIGN.md +71 -0
  437. package/.codex/assets/design-themes/open-design/spotify/DESIGN.md +249 -0
  438. package/.codex/assets/design-themes/open-design/starbucks/DESIGN.md +583 -0
  439. package/.codex/assets/design-themes/open-design/storytelling/DESIGN.md +71 -0
  440. package/.codex/assets/design-themes/open-design/stripe/DESIGN.md +325 -0
  441. package/.codex/assets/design-themes/open-design/stripe/examples.html +58 -0
  442. package/.codex/assets/design-themes/open-design/supabase/DESIGN.md +258 -0
  443. package/.codex/assets/design-themes/open-design/supabase/examples.html +26 -0
  444. package/.codex/assets/design-themes/open-design/superhuman/DESIGN.md +255 -0
  445. package/.codex/assets/design-themes/open-design/tesla/DESIGN.md +289 -0
  446. package/.codex/assets/design-themes/open-design/tetris/DESIGN.md +71 -0
  447. package/.codex/assets/design-themes/open-design/theverge/DESIGN.md +342 -0
  448. package/.codex/assets/design-themes/open-design/together-ai/DESIGN.md +266 -0
  449. package/.codex/assets/design-themes/open-design/totality-festival/DESIGN.md +206 -0
  450. package/.codex/assets/design-themes/open-design/trading-terminal/DESIGN.md +178 -0
  451. package/.codex/assets/design-themes/open-design/uber/DESIGN.md +298 -0
  452. package/.codex/assets/design-themes/open-design/urdu/DESIGN.md +1002 -0
  453. package/.codex/assets/design-themes/open-design/vercel/DESIGN.md +313 -0
  454. package/.codex/assets/design-themes/open-design/vercel/examples.html +55 -0
  455. package/.codex/assets/design-themes/open-design/vibrant/DESIGN.md +71 -0
  456. package/.codex/assets/design-themes/open-design/vintage/DESIGN.md +71 -0
  457. package/.codex/assets/design-themes/open-design/vodafone/DESIGN.md +426 -0
  458. package/.codex/assets/design-themes/open-design/voltagent/DESIGN.md +326 -0
  459. package/.codex/assets/design-themes/open-design/warm-editorial/DESIGN.md +65 -0
  460. package/.codex/assets/design-themes/open-design/warp/DESIGN.md +256 -0
  461. package/.codex/assets/design-themes/open-design/webex/DESIGN.md +207 -0
  462. package/.codex/assets/design-themes/open-design/webflow/DESIGN.md +95 -0
  463. package/.codex/assets/design-themes/open-design/webflow/examples.html +11 -0
  464. package/.codex/assets/design-themes/open-design/wired/DESIGN.md +281 -0
  465. package/.codex/assets/design-themes/open-design/wise/DESIGN.md +176 -0
  466. package/.codex/assets/design-themes/open-design/x-ai/DESIGN.md +260 -0
  467. package/.codex/assets/design-themes/open-design/x-ai/examples.html +12 -0
  468. package/.codex/assets/design-themes/open-design/xiaohongshu/DESIGN.md +402 -0
  469. package/.codex/assets/design-themes/open-design/zapier/DESIGN.md +331 -0
  470. package/.codex/assets/design-themes/revenuecat/DESIGN.md +209 -0
  471. package/.codex/assets/design-themes/revenuecat/examples.html +122 -0
  472. package/.codex/assets/design-themes/vben/DESIGN.md +685 -0
  473. package/.codex/assets/design-themes/vben/examples.html +155 -0
  474. package/.codex/assets/vendor/flow-viewer/MERMAID_LICENSE +21 -0
  475. package/.codex/assets/vendor/flow-viewer/SVG_PAN_ZOOM_LICENSE +23 -0
  476. package/.codex/assets/vendor/flow-viewer/THIRD_PARTY_LICENSES.md +21 -0
  477. package/.codex/assets/vendor/flow-viewer/mermaid.min.js +3298 -0
  478. package/.codex/assets/vendor/flow-viewer/svg-pan-zoom.min.js +3 -0
  479. package/.codex/bundled-skills/impeccable/SKILL.md +163 -0
  480. package/.codex/bundled-skills/impeccable/agents/openai.yaml +4 -0
  481. package/.codex/bundled-skills/impeccable/reference/adapt.md +190 -0
  482. package/.codex/bundled-skills/impeccable/reference/animate.md +175 -0
  483. package/.codex/bundled-skills/impeccable/reference/audit.md +132 -0
  484. package/.codex/bundled-skills/impeccable/reference/bolder.md +113 -0
  485. package/.codex/bundled-skills/impeccable/reference/brand.md +118 -0
  486. package/.codex/bundled-skills/impeccable/reference/clarify.md +174 -0
  487. package/.codex/bundled-skills/impeccable/reference/codex.md +105 -0
  488. package/.codex/bundled-skills/impeccable/reference/cognitive-load.md +106 -0
  489. package/.codex/bundled-skills/impeccable/reference/color-and-contrast.md +105 -0
  490. package/.codex/bundled-skills/impeccable/reference/colorize.md +154 -0
  491. package/.codex/bundled-skills/impeccable/reference/craft.md +123 -0
  492. package/.codex/bundled-skills/impeccable/reference/critique.md +259 -0
  493. package/.codex/bundled-skills/impeccable/reference/delight.md +302 -0
  494. package/.codex/bundled-skills/impeccable/reference/distill.md +111 -0
  495. package/.codex/bundled-skills/impeccable/reference/document.md +427 -0
  496. package/.codex/bundled-skills/impeccable/reference/extract.md +68 -0
  497. package/.codex/bundled-skills/impeccable/reference/harden.md +347 -0
  498. package/.codex/bundled-skills/impeccable/reference/heuristics-scoring.md +234 -0
  499. package/.codex/bundled-skills/impeccable/reference/interaction-design.md +195 -0
  500. package/.codex/bundled-skills/impeccable/reference/layout.md +141 -0
  501. package/.codex/bundled-skills/impeccable/reference/live.md +622 -0
  502. package/.codex/bundled-skills/impeccable/reference/motion-design.md +109 -0
  503. package/.codex/bundled-skills/impeccable/reference/onboard.md +234 -0
  504. package/.codex/bundled-skills/impeccable/reference/optimize.md +258 -0
  505. package/.codex/bundled-skills/impeccable/reference/overdrive.md +130 -0
  506. package/.codex/bundled-skills/impeccable/reference/personas.md +179 -0
  507. package/.codex/bundled-skills/impeccable/reference/polish.md +242 -0
  508. package/.codex/bundled-skills/impeccable/reference/product.md +62 -0
  509. package/.codex/bundled-skills/impeccable/reference/quieter.md +99 -0
  510. package/.codex/bundled-skills/impeccable/reference/responsive-design.md +114 -0
  511. package/.codex/bundled-skills/impeccable/reference/shape.md +165 -0
  512. package/.codex/bundled-skills/impeccable/reference/spatial-design.md +100 -0
  513. package/.codex/bundled-skills/impeccable/reference/teach.md +156 -0
  514. package/.codex/bundled-skills/impeccable/reference/typeset.md +124 -0
  515. package/.codex/bundled-skills/impeccable/reference/typography.md +159 -0
  516. package/.codex/bundled-skills/impeccable/reference/ux-writing.md +107 -0
  517. package/.codex/bundled-skills/impeccable/scripts/cleanup-deprecated.mjs +284 -0
  518. package/.codex/bundled-skills/impeccable/scripts/command-metadata.json +94 -0
  519. package/.codex/bundled-skills/impeccable/scripts/critique-storage.mjs +242 -0
  520. package/.codex/bundled-skills/impeccable/scripts/design-parser.mjs +820 -0
  521. package/.codex/bundled-skills/impeccable/scripts/detect-csp.mjs +198 -0
  522. package/.codex/bundled-skills/impeccable/scripts/detect.mjs +21 -0
  523. package/.codex/bundled-skills/impeccable/scripts/detector/browser/injected/index.mjs +1688 -0
  524. package/.codex/bundled-skills/impeccable/scripts/detector/cli/main.mjs +232 -0
  525. package/.codex/bundled-skills/impeccable/scripts/detector/detect-antipatterns-browser.js +4030 -0
  526. package/.codex/bundled-skills/impeccable/scripts/detector/detect-antipatterns.mjs +43 -0
  527. package/.codex/bundled-skills/impeccable/scripts/detector/engines/browser/detect-url.mjs +251 -0
  528. package/.codex/bundled-skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +420 -0
  529. package/.codex/bundled-skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +954 -0
  530. package/.codex/bundled-skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs +174 -0
  531. package/.codex/bundled-skills/impeccable/scripts/detector/engines/visual/screenshot-contrast.mjs +189 -0
  532. package/.codex/bundled-skills/impeccable/scripts/detector/findings.mjs +12 -0
  533. package/.codex/bundled-skills/impeccable/scripts/detector/node/file-system.mjs +198 -0
  534. package/.codex/bundled-skills/impeccable/scripts/detector/profile/profiler.mjs +166 -0
  535. package/.codex/bundled-skills/impeccable/scripts/detector/registry/antipatterns.mjs +278 -0
  536. package/.codex/bundled-skills/impeccable/scripts/detector/rules/checks.mjs +1948 -0
  537. package/.codex/bundled-skills/impeccable/scripts/detector/shared/color.mjs +124 -0
  538. package/.codex/bundled-skills/impeccable/scripts/detector/shared/constants.mjs +101 -0
  539. package/.codex/bundled-skills/impeccable/scripts/detector/shared/page.mjs +7 -0
  540. package/.codex/bundled-skills/impeccable/scripts/impeccable-paths.mjs +110 -0
  541. package/.codex/bundled-skills/impeccable/scripts/is-generated.mjs +69 -0
  542. package/.codex/bundled-skills/impeccable/scripts/live-accept.mjs +595 -0
  543. package/.codex/bundled-skills/impeccable/scripts/live-browser-session.js +123 -0
  544. package/.codex/bundled-skills/impeccable/scripts/live-browser.js +4860 -0
  545. package/.codex/bundled-skills/impeccable/scripts/live-complete.mjs +75 -0
  546. package/.codex/bundled-skills/impeccable/scripts/live-completion.mjs +18 -0
  547. package/.codex/bundled-skills/impeccable/scripts/live-inject.mjs +446 -0
  548. package/.codex/bundled-skills/impeccable/scripts/live-poll.mjs +200 -0
  549. package/.codex/bundled-skills/impeccable/scripts/live-resume.mjs +48 -0
  550. package/.codex/bundled-skills/impeccable/scripts/live-server.mjs +838 -0
  551. package/.codex/bundled-skills/impeccable/scripts/live-session-store.mjs +254 -0
  552. package/.codex/bundled-skills/impeccable/scripts/live-status.mjs +47 -0
  553. package/.codex/bundled-skills/impeccable/scripts/live-wrap.mjs +632 -0
  554. package/.codex/bundled-skills/impeccable/scripts/live.mjs +247 -0
  555. package/.codex/bundled-skills/impeccable/scripts/load-context.mjs +141 -0
  556. package/.codex/bundled-skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  557. package/.codex/bundled-skills/impeccable/scripts/pin.mjs +214 -0
  558. package/.codex/references/commands/analyze.md +39 -0
  559. package/.codex/references/commands/architect.md +41 -0
  560. package/.codex/references/commands/deliver.md +29 -0
  561. package/.codex/references/commands/design.md +92 -0
  562. package/.codex/references/commands/help.md +24 -0
  563. package/.codex/references/commands/init.md +40 -0
  564. package/.codex/references/commands/plan.md +41 -0
  565. package/.codex/references/commands/review.md +33 -0
  566. package/.codex/references/commands/status.md +20 -0
  567. package/.codex/role-skills/demand-analysis/SKILL.md +50 -0
  568. package/.codex/role-skills/demand-analysis/templates/handoff-prd.md +39 -0
  569. package/.codex/role-skills/demand-analysis/templates/prd.md +85 -0
  570. package/.codex/role-skills/dev-task-planning/SKILL.md +37 -0
  571. package/.codex/role-skills/dev-task-planning/templates/dev-tasks.md +54 -0
  572. package/.codex/role-skills/quality-review/SKILL.md +49 -0
  573. package/.codex/role-skills/quality-review/templates/review-stage.md +39 -0
  574. package/.codex/role-skills/tech-architecture/SKILL.md +49 -0
  575. package/.codex/role-skills/tech-architecture/templates/handoff-architecture.md +28 -0
  576. package/.codex/role-skills/tech-architecture/templates/tech-architecture.md +54 -0
  577. package/.codex/role-skills/ui-prototype-design/SKILL.md +125 -0
  578. package/.codex/role-skills/ui-prototype-design/templates/handoff-ui.md +40 -0
  579. package/.codex/role-skills/ui-prototype-design/templates/prototype-review.md +57 -0
  580. package/.codex/role-skills/ui-prototype-design/templates/ui-design.md +142 -0
  581. package/.codex/scripts/package_delivery.js +195 -0
  582. package/.codex/scripts/review_stage.js +622 -0
  583. package/.codex/templates/AGENTS.md +44 -0
  584. package/.codex/templates/delivery-README.md +37 -0
  585. package/.codex/templates/framework-AGENTS.md +74 -0
  586. package/.codex/templates/framework-README.md +65 -0
  587. package/.codex/templates/project-config.md +117 -0
  588. package/.codex/templates/prototype-README.md +45 -0
  589. package/.codex/templates/workflow-state.json +47 -0
  590. package/README.md +28 -0
  591. package/bin/pmflow.js +463 -0
  592. package/package.json +30 -0
@@ -0,0 +1,838 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Live variant mode server (self-contained, zero dependencies).
4
+ *
5
+ * Serves the browser script (/live.js), the detection overlay (/detect.js),
6
+ * uses Server-Sent Events (SSE) for server→browser push, and HTTP POST for
7
+ * browser→server events. Agent communicates via HTTP long-poll (/poll).
8
+ *
9
+ * Usage:
10
+ * node <scripts_path>/live-server.mjs # start
11
+ * node <scripts_path>/live-server.mjs stop # stop + remove injected live.js tag
12
+ * node <scripts_path>/live-server.mjs stop --keep-inject # stop only
13
+ * node <scripts_path>/live-server.mjs --help
14
+ */
15
+
16
+ import http from 'node:http';
17
+ import { randomUUID } from 'node:crypto';
18
+ import { spawn, execFileSync } from 'node:child_process';
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ import net from 'node:net';
22
+ import { fileURLToPath } from 'node:url';
23
+ import { parseDesignMd } from './design-parser.mjs';
24
+ import { resolveContextDir } from './load-context.mjs';
25
+ import { createLiveSessionStore } from './live-session-store.mjs';
26
+ import {
27
+ getDesignSidecarPath,
28
+ getLiveAnnotationsDir,
29
+ readLiveServerInfo,
30
+ removeLiveServerInfo,
31
+ resolveDesignSidecarPath,
32
+ writeLiveServerInfo,
33
+ } from './impeccable-paths.mjs';
34
+
35
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
36
+ // PRODUCT.md / DESIGN.md live wherever load-context.mjs resolves. The generated
37
+ // DESIGN sidecar is project-local at .impeccable/design.json, with legacy
38
+ // DESIGN.json fallback for existing projects.
39
+ const CONTEXT_DIR = resolveContextDir(process.cwd());
40
+ const DEFAULT_POLL_TIMEOUT = 600_000; // 10 min — agent re-polls on timeout anyway
41
+ const SSE_HEARTBEAT_INTERVAL = 30_000; // keepalive ping every 30s
42
+
43
+ // ---------------------------------------------------------------------------
44
+ // Port detection
45
+ // ---------------------------------------------------------------------------
46
+
47
+ async function findOpenPort(start = 8400) {
48
+ return new Promise((resolve) => {
49
+ const srv = net.createServer();
50
+ srv.listen(start, '127.0.0.1', () => {
51
+ const port = srv.address().port;
52
+ srv.close(() => resolve(port));
53
+ });
54
+ srv.on('error', () => resolve(findOpenPort(start + 1)));
55
+ });
56
+ }
57
+
58
+ // ---------------------------------------------------------------------------
59
+ // Session state
60
+ // ---------------------------------------------------------------------------
61
+
62
+ const state = {
63
+ token: null,
64
+ port: null,
65
+ sseClients: new Set(), // SSE response objects (server→browser push)
66
+ pendingEvents: [], // browser events waiting for agent ack ({ event, leaseUntil })
67
+ pendingPolls: [], // agent poll callbacks waiting for browser events
68
+ exitTimer: null,
69
+ sessionDir: null, // per-session tmp dir for annotation screenshots
70
+ sessionStore: null,
71
+ leaseTimer: null,
72
+ };
73
+
74
+ // Cap per-annotation upload size. A full 1920×1080 PNG is typically <1 MB;
75
+ // cap at 10 MB to guard against runaway writes from a misbehaving client.
76
+ const MAX_ANNOTATION_BYTES = 10 * 1024 * 1024;
77
+
78
+ function enqueueEvent(event) {
79
+ if (!event || (event.id && state.pendingEvents.some((entry) => entry.event?.id === event.id && entry.event?.type === event.type))) return;
80
+ state.pendingEvents.push({ event, leaseUntil: 0 });
81
+ flushPendingPolls();
82
+ }
83
+
84
+ function restorePendingEventsFromStore() {
85
+ if (!state.sessionStore) return;
86
+ for (const snapshot of state.sessionStore.listActiveSessions()) {
87
+ if (snapshot.pendingEvent) enqueueEvent(snapshot.pendingEvent);
88
+ }
89
+ }
90
+
91
+ function findAvailablePendingEvent(now = Date.now()) {
92
+ return state.pendingEvents.find((entry) => !entry.leaseUntil || entry.leaseUntil <= now);
93
+ }
94
+
95
+ function leaseEvent(entry, leaseMs) {
96
+ if (!entry.event?.id) {
97
+ const idx = state.pendingEvents.indexOf(entry);
98
+ if (idx !== -1) state.pendingEvents.splice(idx, 1);
99
+ return entry.event;
100
+ }
101
+ entry.leaseUntil = Date.now() + leaseMs;
102
+ return entry.event;
103
+ }
104
+
105
+ function acknowledgePendingEvent(id) {
106
+ if (!id) return false;
107
+ const idx = state.pendingEvents.findIndex((entry) => entry.event?.id === id);
108
+ if (idx === -1) return false;
109
+ state.pendingEvents.splice(idx, 1);
110
+ scheduleLeaseFlush();
111
+ return true;
112
+ }
113
+
114
+ function scheduleLeaseFlush() {
115
+ if (state.leaseTimer) {
116
+ clearTimeout(state.leaseTimer);
117
+ state.leaseTimer = null;
118
+ }
119
+ if (state.pendingPolls.length === 0) return;
120
+ const now = Date.now();
121
+ const nextLeaseUntil = state.pendingEvents
122
+ .map((entry) => entry.leaseUntil || 0)
123
+ .filter((leaseUntil) => leaseUntil > now)
124
+ .sort((a, b) => a - b)[0];
125
+ if (!nextLeaseUntil) return;
126
+ state.leaseTimer = setTimeout(() => {
127
+ state.leaseTimer = null;
128
+ flushPendingPolls();
129
+ }, Math.max(0, nextLeaseUntil - now));
130
+ }
131
+
132
+ function flushPendingPolls() {
133
+ while (state.pendingPolls.length > 0) {
134
+ const entry = findAvailablePendingEvent();
135
+ if (!entry) {
136
+ scheduleLeaseFlush();
137
+ return;
138
+ }
139
+ const poll = state.pendingPolls.shift();
140
+ poll.resolve(leaseEvent(entry, poll.leaseMs));
141
+ }
142
+ scheduleLeaseFlush();
143
+ }
144
+
145
+ /** Push a message to all connected SSE clients. */
146
+ function broadcast(msg) {
147
+ const data = 'data: ' + JSON.stringify(msg) + '\n\n';
148
+ for (const res of state.sseClients) {
149
+ try { res.write(data); } catch { /* client gone */ }
150
+ }
151
+ }
152
+
153
+ // ---------------------------------------------------------------------------
154
+ // Load scripts
155
+ // ---------------------------------------------------------------------------
156
+
157
+ function loadBrowserScripts() {
158
+ // Detection script: prefer the skill-bundled detector, then fall back to
159
+ // source/npm package locations for local development and older installs.
160
+ // This one IS cached — detect.js rarely changes during a session.
161
+ const detectPaths = [
162
+ path.join(__dirname, 'detector', 'detect-antipatterns-browser.js'),
163
+ path.join(__dirname, '..', '..', 'cli', 'engine', 'detect-antipatterns-browser.js'),
164
+ path.join(__dirname, '..', '..', '..', '..', 'cli', 'engine', 'detect-antipatterns-browser.js'),
165
+ path.join(process.cwd(), 'node_modules', 'impeccable', 'cli', 'engine', 'detect-antipatterns-browser.js'),
166
+ ];
167
+ let detectScript = '';
168
+ for (const p of detectPaths) {
169
+ try { detectScript = fs.readFileSync(p, 'utf-8'); break; } catch { /* try next */ }
170
+ }
171
+
172
+ // live-browser.js: DO NOT cache. Return the path so the /live.js handler
173
+ // can re-read on every request. Editing the browser script during iteration
174
+ // should land on the next tab reload, not require a server restart.
175
+ const sessionPath = path.join(__dirname, 'live-browser-session.js');
176
+ const livePath = path.join(__dirname, 'live-browser.js');
177
+ for (const p of [sessionPath, livePath]) {
178
+ if (!fs.existsSync(p)) {
179
+ process.stderr.write('Error: live browser script not found at ' + p + '\n');
180
+ process.exit(1);
181
+ }
182
+ }
183
+
184
+ return { detectScript, sessionPath, livePath };
185
+ }
186
+
187
+ function hasProjectContext() {
188
+ // PRODUCT.md carries brand voice / anti-references — that's what determines
189
+ // whether variants are brand-aware. DESIGN.md (visual tokens) is a separate
190
+ // concern, surfaced by the design panel's own empty state. Legacy
191
+ // .impeccable.md is auto-migrated to PRODUCT.md by load-context.mjs.
192
+ try {
193
+ fs.accessSync(path.join(CONTEXT_DIR, 'PRODUCT.md'), fs.constants.R_OK);
194
+ return true;
195
+ } catch { return false; }
196
+ }
197
+
198
+ function statOrNull(filePath) {
199
+ try { return fs.statSync(filePath); } catch { return null; }
200
+ }
201
+
202
+ // ---------------------------------------------------------------------------
203
+ // Validation (inline — no external import needed for self-contained script)
204
+ // ---------------------------------------------------------------------------
205
+
206
+ const VISUAL_ACTIONS = [
207
+ 'impeccable', 'bolder', 'quieter', 'distill', 'polish', 'typeset',
208
+ 'colorize', 'layout', 'adapt', 'animate', 'delight', 'overdrive',
209
+ ];
210
+
211
+ // Browser generates ids via crypto.randomUUID().slice(0, 8) (8 hex chars)
212
+ // and variantIds via String(small integer). Restrict to those shapes so
213
+ // any value that reaches a downstream child_process or DOM selector is
214
+ // inert by construction.
215
+ const ID_PATTERN = /^[0-9a-f]{8}$/;
216
+ const VARIANT_ID_PATTERN = /^[0-9]{1,3}$/;
217
+
218
+ function isValidId(v) { return typeof v === 'string' && ID_PATTERN.test(v); }
219
+ function isValidVariantId(v) { return typeof v === 'string' && VARIANT_ID_PATTERN.test(v); }
220
+
221
+ function validateEvent(msg) {
222
+ if (!msg || typeof msg !== 'object' || !msg.type) return 'Missing or invalid message';
223
+ switch (msg.type) {
224
+ case 'generate':
225
+ if (!isValidId(msg.id)) return 'generate: missing or malformed id';
226
+ if (!msg.action || !VISUAL_ACTIONS.includes(msg.action)) return 'generate: invalid action';
227
+ if (!Number.isInteger(msg.count) || msg.count < 1 || msg.count > 8) return 'generate: count must be 1-8';
228
+ if (!msg.element || !msg.element.outerHTML) return 'generate: missing element context';
229
+ // Optional annotation fields (all-or-nothing: if any present, all must be well-formed).
230
+ if (msg.screenshotPath !== undefined && typeof msg.screenshotPath !== 'string') return 'generate: screenshotPath must be string';
231
+ if (msg.comments !== undefined && !Array.isArray(msg.comments)) return 'generate: comments must be array';
232
+ if (msg.strokes !== undefined && !Array.isArray(msg.strokes)) return 'generate: strokes must be array';
233
+ return null;
234
+ case 'accept':
235
+ if (!isValidId(msg.id)) return 'accept: missing or malformed id';
236
+ if (!isValidVariantId(msg.variantId)) return 'accept: missing or malformed variantId';
237
+ if (msg.paramValues !== undefined) {
238
+ if (typeof msg.paramValues !== 'object' || msg.paramValues === null || Array.isArray(msg.paramValues)) {
239
+ return 'accept: paramValues must be an object';
240
+ }
241
+ }
242
+ return null;
243
+ case 'discard':
244
+ return isValidId(msg.id) ? null : 'discard: missing or malformed id';
245
+ case 'checkpoint':
246
+ if (!isValidId(msg.id)) return 'checkpoint: missing or malformed id';
247
+ if (!Number.isInteger(msg.revision) || msg.revision < 0) return 'checkpoint: revision must be a non-negative integer';
248
+ if (msg.paramValues !== undefined && (typeof msg.paramValues !== 'object' || msg.paramValues === null || Array.isArray(msg.paramValues))) {
249
+ return 'checkpoint: paramValues must be an object';
250
+ }
251
+ return null;
252
+ case 'exit':
253
+ return null;
254
+ case 'prefetch':
255
+ if (!msg.pageUrl || typeof msg.pageUrl !== 'string') return 'prefetch: missing pageUrl';
256
+ return null;
257
+ default:
258
+ return 'Unknown event type: ' + msg.type;
259
+ }
260
+ }
261
+
262
+ // ---------------------------------------------------------------------------
263
+ // HTTP request handler
264
+ // ---------------------------------------------------------------------------
265
+
266
+ function createRequestHandler({ detectScript, sessionPath, livePath }) {
267
+ return (req, res) => {
268
+ const url = new URL(req.url, `http://localhost:${state.port}`);
269
+ res.setHeader('Access-Control-Allow-Origin', '*');
270
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
271
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
272
+ if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; }
273
+
274
+ const p = url.pathname;
275
+
276
+ // --- Scripts ---
277
+ if (p === '/live.js') {
278
+ // Re-read from disk each request so edits to live-browser.js land on
279
+ // the next tab reload. No-store headers prevent browser caching across
280
+ // sessions — during iteration, a cached old script silently breaks
281
+ // every subsequent session.
282
+ let sessionScript;
283
+ let liveScript;
284
+ try {
285
+ sessionScript = fs.readFileSync(sessionPath, 'utf-8');
286
+ liveScript = fs.readFileSync(livePath, 'utf-8');
287
+ } catch (err) {
288
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
289
+ res.end('Error reading live browser scripts: ' + err.message);
290
+ return;
291
+ }
292
+ const body =
293
+ `window.__IMPECCABLE_TOKEN__ = '${state.token}';\n` +
294
+ `window.__IMPECCABLE_PORT__ = ${state.port};\n` +
295
+ sessionScript + '\n' +
296
+ liveScript;
297
+ res.writeHead(200, {
298
+ 'Content-Type': 'application/javascript',
299
+ 'Cache-Control': 'no-store, no-cache, must-revalidate, max-age=0',
300
+ 'Pragma': 'no-cache',
301
+ });
302
+ res.end(body);
303
+ return;
304
+ }
305
+ if (p === '/detect.js' || p === '/') {
306
+ if (!detectScript) { res.writeHead(404); res.end('Not available'); return; }
307
+ res.writeHead(200, { 'Content-Type': 'application/javascript' });
308
+ res.end(detectScript);
309
+ return;
310
+ }
311
+
312
+ // --- Vendored modern-screenshot (UMD build) ---
313
+ // Lazy-loaded by live.js when the user clicks Go; exposes
314
+ // window.modernScreenshot.domToBlob(...) for capture.
315
+ if (p === '/modern-screenshot.js') {
316
+ const vendorPath = path.join(__dirname, 'modern-screenshot.umd.js');
317
+ try {
318
+ res.writeHead(200, {
319
+ 'Content-Type': 'application/javascript',
320
+ 'Cache-Control': 'public, max-age=31536000, immutable',
321
+ });
322
+ res.end(fs.readFileSync(vendorPath));
323
+ } catch {
324
+ res.writeHead(404); res.end('Vendor script not found');
325
+ }
326
+ return;
327
+ }
328
+
329
+ // --- Annotation upload (browser → server, raw PNG body) ---
330
+ // Client generates the eventId, POSTs the PNG, then POSTs the generate
331
+ // event with screenshotPath already set. Keeps bytes out of the SSE/poll
332
+ // bridge and preserves the "one shot from the user's POV" UX.
333
+ if (p === '/annotation' && req.method === 'POST') {
334
+ const token = url.searchParams.get('token');
335
+ if (token !== state.token) { res.writeHead(401); res.end('Unauthorized'); return; }
336
+ const eventId = url.searchParams.get('eventId');
337
+ if (!eventId || !/^[A-Za-z0-9_-]{1,64}$/.test(eventId)) {
338
+ res.writeHead(400, { 'Content-Type': 'application/json' });
339
+ res.end(JSON.stringify({ error: 'Invalid eventId' }));
340
+ return;
341
+ }
342
+ if ((req.headers['content-type'] || '').toLowerCase() !== 'image/png') {
343
+ res.writeHead(415, { 'Content-Type': 'application/json' });
344
+ res.end(JSON.stringify({ error: 'Content-Type must be image/png' }));
345
+ return;
346
+ }
347
+ if (!state.sessionDir) {
348
+ res.writeHead(500, { 'Content-Type': 'application/json' });
349
+ res.end(JSON.stringify({ error: 'Session dir unavailable' }));
350
+ return;
351
+ }
352
+ const chunks = [];
353
+ let total = 0;
354
+ let aborted = false;
355
+ req.on('data', (c) => {
356
+ if (aborted) return;
357
+ total += c.length;
358
+ if (total > MAX_ANNOTATION_BYTES) {
359
+ aborted = true;
360
+ res.writeHead(413, { 'Content-Type': 'application/json' });
361
+ res.end(JSON.stringify({ error: 'Payload too large' }));
362
+ req.destroy();
363
+ return;
364
+ }
365
+ chunks.push(c);
366
+ });
367
+ req.on('end', () => {
368
+ if (aborted) return;
369
+ const absPath = path.join(state.sessionDir, eventId + '.png');
370
+ try {
371
+ fs.writeFileSync(absPath, Buffer.concat(chunks));
372
+ } catch (err) {
373
+ res.writeHead(500, { 'Content-Type': 'application/json' });
374
+ res.end(JSON.stringify({ error: 'Write failed: ' + err.message }));
375
+ return;
376
+ }
377
+ res.writeHead(200, { 'Content-Type': 'application/json' });
378
+ res.end(JSON.stringify({ ok: true, path: absPath }));
379
+ });
380
+ req.on('error', () => {
381
+ if (!aborted) {
382
+ res.writeHead(500, { 'Content-Type': 'application/json' });
383
+ res.end(JSON.stringify({ error: 'Upload failed' }));
384
+ }
385
+ });
386
+ return;
387
+ }
388
+
389
+ // --- Health ---
390
+ if (p === '/status') {
391
+ const token = url.searchParams.get('token');
392
+ if (token !== state.token) { res.writeHead(401, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Unauthorized' })); return; }
393
+ const sessions = state.sessionStore ? state.sessionStore.listActiveSessions() : [];
394
+ res.writeHead(200, { 'Content-Type': 'application/json' });
395
+ res.end(JSON.stringify({
396
+ status: 'ok',
397
+ port: state.port,
398
+ connectedClients: state.sseClients.size,
399
+ pendingEvents: state.pendingEvents.map((entry) => ({
400
+ id: entry.event?.id,
401
+ type: entry.event?.type,
402
+ leased: !!(entry.leaseUntil && entry.leaseUntil > Date.now()),
403
+ leaseUntil: entry.leaseUntil || null,
404
+ })),
405
+ activeSessions: sessions,
406
+ }));
407
+ return;
408
+ }
409
+
410
+ if (p === '/health') {
411
+ res.writeHead(200, { 'Content-Type': 'application/json' });
412
+ res.end(JSON.stringify({
413
+ status: 'ok', port: state.port, mode: 'variant',
414
+ hasProjectContext: hasProjectContext(),
415
+ connectedClients: state.sseClients.size,
416
+ }));
417
+ return;
418
+ }
419
+
420
+ // --- Design system (unified v2 response) + raw ---
421
+ // /design-system.json returns both parsed DESIGN.md and .impeccable/design.json
422
+ // sidecar when present. Panel merges them:
423
+ // { present, parsed, sidecar, hasMd, hasSidecar,
424
+ // mdNewerThanJson, parseError?, sidecarError? }
425
+ // - parsed: output of parseDesignMd (frontmatter
426
+ // + six canonical sections) when DESIGN.md exists.
427
+ // - sidecar: .impeccable/design.json contents when present.
428
+ // Expected shape: schemaVersion 2, carrying
429
+ // extensions + components + narrative.
430
+ // /design-system/raw returns DESIGN.md markdown verbatim
431
+ if (p === '/design-system.json' || p === '/design-system/raw') {
432
+ const token = url.searchParams.get('token');
433
+ if (token !== state.token) { res.writeHead(401); res.end('Unauthorized'); return; }
434
+
435
+ const mdPath = path.join(CONTEXT_DIR, 'DESIGN.md');
436
+ const jsonPath = resolveDesignSidecarPath(process.cwd(), CONTEXT_DIR) || getDesignSidecarPath(process.cwd());
437
+ const mdStat = statOrNull(mdPath);
438
+ const jsonStat = statOrNull(jsonPath);
439
+
440
+ if (p === '/design-system/raw') {
441
+ if (!mdStat) { res.writeHead(404); res.end('Not found'); return; }
442
+ res.writeHead(200, { 'Content-Type': 'text/markdown; charset=utf-8' });
443
+ res.end(fs.readFileSync(mdPath, 'utf-8'));
444
+ return;
445
+ }
446
+
447
+ if (!mdStat && !jsonStat) {
448
+ res.writeHead(404, { 'Content-Type': 'application/json' });
449
+ res.end(JSON.stringify({ present: false }));
450
+ return;
451
+ }
452
+
453
+ const response = {
454
+ present: true,
455
+ hasMd: !!mdStat,
456
+ hasSidecar: !!jsonStat,
457
+ mdNewerThanJson: !!(mdStat && jsonStat && mdStat.mtimeMs > jsonStat.mtimeMs + 1000),
458
+ };
459
+
460
+ if (mdStat) {
461
+ try {
462
+ response.parsed = parseDesignMd(fs.readFileSync(mdPath, 'utf-8'));
463
+ } catch (err) {
464
+ response.parseError = err.message;
465
+ }
466
+ }
467
+
468
+ if (jsonStat) {
469
+ try {
470
+ response.sidecar = JSON.parse(fs.readFileSync(jsonPath, 'utf-8'));
471
+ } catch (err) {
472
+ response.sidecarError = 'Failed to parse .impeccable/design.json: ' + err.message;
473
+ }
474
+ }
475
+
476
+ res.writeHead(200, { 'Content-Type': 'application/json' });
477
+ res.end(JSON.stringify(response));
478
+ return;
479
+ }
480
+
481
+ // --- Source file (no-HMR fallback) ---
482
+ if (p === '/source') {
483
+ const token = url.searchParams.get('token');
484
+ if (token !== state.token) { res.writeHead(401); res.end('Unauthorized'); return; }
485
+ const filePath = url.searchParams.get('path');
486
+ if (!filePath || filePath.includes('..')) { res.writeHead(400); res.end('Bad path'); return; }
487
+ const absPath = path.resolve(process.cwd(), filePath);
488
+ if (!absPath.startsWith(process.cwd())) { res.writeHead(403); res.end('Forbidden'); return; }
489
+ let content;
490
+ try { content = fs.readFileSync(absPath, 'utf-8'); }
491
+ catch { res.writeHead(404); res.end('File not found'); return; }
492
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
493
+ res.end(content);
494
+ return;
495
+ }
496
+
497
+ // --- SSE: server→browser push (replaces WebSocket) ---
498
+ if (p === '/events' && req.method === 'GET') {
499
+ const token = url.searchParams.get('token');
500
+ if (token !== state.token) { res.writeHead(401); res.end('Unauthorized'); return; }
501
+ res.writeHead(200, {
502
+ 'Content-Type': 'text/event-stream',
503
+ 'Cache-Control': 'no-cache',
504
+ 'Connection': 'keep-alive',
505
+ });
506
+ res.write('data: ' + JSON.stringify({
507
+ type: 'connected',
508
+ hasProjectContext: hasProjectContext(),
509
+ }) + '\n\n');
510
+
511
+ state.sseClients.add(res);
512
+ clearTimeout(state.exitTimer);
513
+
514
+ // Keepalive: SSE comment every 30s prevents silent connection drops.
515
+ const heartbeat = setInterval(() => {
516
+ try { res.write(': keepalive\n\n'); } catch { clearInterval(heartbeat); }
517
+ }, SSE_HEARTBEAT_INTERVAL);
518
+
519
+ req.on('close', () => {
520
+ clearInterval(heartbeat);
521
+ state.sseClients.delete(res);
522
+ if (state.sseClients.size === 0) {
523
+ clearTimeout(state.exitTimer);
524
+ state.exitTimer = setTimeout(() => {
525
+ if (state.sseClients.size === 0) enqueueEvent({ type: 'exit' });
526
+ }, 8000);
527
+ }
528
+ });
529
+ return;
530
+ }
531
+
532
+ // --- Browser→server events (replaces WebSocket messages) ---
533
+ if (p === '/events' && req.method === 'POST') {
534
+ let body = '';
535
+ req.on('data', (c) => { body += c; });
536
+ req.on('end', () => {
537
+ let msg;
538
+ try { msg = JSON.parse(body); } catch {
539
+ res.writeHead(400, { 'Content-Type': 'application/json' });
540
+ res.end(JSON.stringify({ error: 'Invalid JSON' }));
541
+ return;
542
+ }
543
+ if (msg.token !== state.token) {
544
+ res.writeHead(401, { 'Content-Type': 'application/json' });
545
+ res.end(JSON.stringify({ error: 'Unauthorized' }));
546
+ return;
547
+ }
548
+ const error = validateEvent(msg);
549
+ if (error) {
550
+ res.writeHead(400, { 'Content-Type': 'application/json' });
551
+ res.end(JSON.stringify({ error }));
552
+ return;
553
+ }
554
+ if (state.sessionStore && msg.id) {
555
+ try {
556
+ state.sessionStore.appendEvent(msg);
557
+ } catch (err) {
558
+ res.writeHead(500, { 'Content-Type': 'application/json' });
559
+ res.end(JSON.stringify({ error: 'session_store_append_failed', message: err.message }));
560
+ return;
561
+ }
562
+ }
563
+ if (msg.type !== 'checkpoint') enqueueEvent(msg);
564
+ res.writeHead(200, { 'Content-Type': 'application/json' });
565
+ res.end(JSON.stringify({ ok: true }));
566
+ });
567
+ return;
568
+ }
569
+
570
+ // --- Stop ---
571
+ if (p === '/stop') {
572
+ const token = url.searchParams.get('token');
573
+ if (token !== state.token) { res.writeHead(401); res.end('Unauthorized'); return; }
574
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
575
+ res.end('stopping');
576
+ shutdown();
577
+ return;
578
+ }
579
+
580
+ // --- Agent poll ---
581
+ if (p === '/poll' && req.method === 'GET') {
582
+ handlePollGet(req, res, url);
583
+ return;
584
+ }
585
+ if (p === '/poll' && req.method === 'POST') {
586
+ handlePollPost(req, res);
587
+ return;
588
+ }
589
+
590
+ res.writeHead(404); res.end('Not found');
591
+ };
592
+ }
593
+
594
+ // ---------------------------------------------------------------------------
595
+ // Agent poll endpoints (unchanged from WS version)
596
+ // ---------------------------------------------------------------------------
597
+
598
+ function handlePollGet(req, res, url) {
599
+ const token = url.searchParams.get('token');
600
+ if (token !== state.token) {
601
+ res.writeHead(401, { 'Content-Type': 'application/json' });
602
+ res.end(JSON.stringify({ error: 'Unauthorized' }));
603
+ return;
604
+ }
605
+ const timeout = parseInt(url.searchParams.get('timeout') || DEFAULT_POLL_TIMEOUT, 10);
606
+ const leaseMs = parseInt(url.searchParams.get('leaseMs') || '30000', 10);
607
+ const available = findAvailablePendingEvent();
608
+ if (available) {
609
+ res.writeHead(200, { 'Content-Type': 'application/json' });
610
+ res.end(JSON.stringify(leaseEvent(available, leaseMs)));
611
+ return;
612
+ }
613
+ const poll = { resolve, leaseMs };
614
+ const timer = setTimeout(() => {
615
+ const idx = state.pendingPolls.indexOf(poll);
616
+ if (idx !== -1) state.pendingPolls.splice(idx, 1);
617
+ res.writeHead(200, { 'Content-Type': 'application/json' });
618
+ res.end(JSON.stringify({ type: 'timeout' }));
619
+ }, timeout);
620
+ function resolve(event) {
621
+ clearTimeout(timer);
622
+ res.writeHead(200, { 'Content-Type': 'application/json' });
623
+ res.end(JSON.stringify(event));
624
+ }
625
+ state.pendingPolls.push(poll);
626
+ scheduleLeaseFlush();
627
+ req.on('close', () => {
628
+ clearTimeout(timer);
629
+ const idx = state.pendingPolls.indexOf(poll);
630
+ if (idx !== -1) state.pendingPolls.splice(idx, 1);
631
+ });
632
+ }
633
+
634
+ function handlePollPost(req, res) {
635
+ let body = '';
636
+ req.on('data', (c) => { body += c; });
637
+ req.on('end', () => {
638
+ let msg;
639
+ try { msg = JSON.parse(body); } catch {
640
+ res.writeHead(400, { 'Content-Type': 'application/json' });
641
+ res.end(JSON.stringify({ error: 'Invalid JSON' }));
642
+ return;
643
+ }
644
+ if (msg.token !== state.token) {
645
+ res.writeHead(401, { 'Content-Type': 'application/json' });
646
+ res.end(JSON.stringify({ error: 'Unauthorized' }));
647
+ return;
648
+ }
649
+ acknowledgePendingEvent(msg.id);
650
+ if (state.sessionStore && msg.id) {
651
+ try {
652
+ const eventType = msg.type === 'discard' || msg.type === 'discarded'
653
+ ? 'discarded'
654
+ : msg.type === 'complete'
655
+ ? 'complete'
656
+ : msg.type === 'error'
657
+ ? 'agent_error'
658
+ : 'agent_done';
659
+ state.sessionStore.appendEvent({
660
+ type: eventType,
661
+ id: msg.id,
662
+ file: msg.file,
663
+ message: msg.message,
664
+ carbonize: msg.data?.carbonize === true,
665
+ });
666
+ } catch { /* keep reply path best-effort; browser still needs SSE */ }
667
+ }
668
+ flushPendingPolls();
669
+ // Forward the reply to the browser via SSE
670
+ broadcast({ type: msg.type || 'done', id: msg.id, message: msg.message, file: msg.file, data: msg.data });
671
+ res.writeHead(200, { 'Content-Type': 'application/json' });
672
+ res.end(JSON.stringify({ ok: true }));
673
+ });
674
+ }
675
+
676
+ // ---------------------------------------------------------------------------
677
+ // Lifecycle
678
+ // ---------------------------------------------------------------------------
679
+
680
+ let httpServer = null;
681
+
682
+ function shutdown() {
683
+ removeLiveServerInfo(process.cwd());
684
+ if (state.leaseTimer) clearTimeout(state.leaseTimer);
685
+ state.leaseTimer = null;
686
+ if (state.sessionDir) {
687
+ try { fs.rmSync(state.sessionDir, { recursive: true, force: true }); } catch {}
688
+ }
689
+ for (const res of state.sseClients) { try { res.end(); } catch {} }
690
+ state.sseClients.clear();
691
+ for (const poll of state.pendingPolls) poll.resolve({ type: 'exit' });
692
+ state.pendingPolls.length = 0;
693
+ if (httpServer) httpServer.close();
694
+ process.exit(0);
695
+ }
696
+
697
+ // ---------------------------------------------------------------------------
698
+ // Main
699
+ // ---------------------------------------------------------------------------
700
+
701
+ const args = process.argv.slice(2);
702
+
703
+ if (args.includes('--help') || args.includes('-h')) {
704
+ console.log(`Usage: node live-server.mjs [options]
705
+
706
+ Start the live variant mode server (zero dependencies).
707
+
708
+ Commands:
709
+ (default) Start the server (foreground)
710
+ stop Stop the server and remove the injected live.js script tag
711
+ stop --keep-inject Stop the server only (leave the script tag in the HTML entry)
712
+
713
+ Options:
714
+ --background Start detached, print connection JSON to stdout, then exit
715
+ --port=PORT Use a specific port (default: auto-detect starting at 8400)
716
+ --keep-inject Only with stop: skip live-inject.mjs --remove
717
+ --help Show this help
718
+
719
+ Endpoints:
720
+ /live.js Browser script (element picker + variant cycling)
721
+ /detect.js Detection overlay (backwards compatible)
722
+ /modern-screenshot.js Vendored modern-screenshot UMD build (lazy-loaded by live.js)
723
+ /annotation POST raw image/png to stage a variant screenshot
724
+ /events SSE stream (server→browser) + POST (browser→server)
725
+ /poll Long-poll for agent CLI
726
+ /source Raw source file reader (no-HMR fallback)
727
+ /status Durable recovery status (token-protected)
728
+ /health Health check`);
729
+ process.exit(0);
730
+ }
731
+
732
+ if (args.includes('stop')) {
733
+ const keepInject = args.includes('--keep-inject');
734
+ try {
735
+ const { info } = readLiveServerInfo(process.cwd()) || {};
736
+ const res = await fetch(`http://localhost:${info.port}/stop?token=${info.token}`);
737
+ if (res.ok) console.log(`Stopped live server on port ${info.port}.`);
738
+ } catch {
739
+ console.log('No running live server found.');
740
+ }
741
+ if (!keepInject) {
742
+ const injectPath = path.join(__dirname, 'live-inject.mjs');
743
+ try {
744
+ const out = execFileSync(process.execPath, [injectPath, '--remove'], {
745
+ encoding: 'utf-8',
746
+ cwd: process.cwd(),
747
+ });
748
+ const line = out.trim().split('\n').filter(Boolean).pop();
749
+ if (line) {
750
+ try {
751
+ const j = JSON.parse(line);
752
+ if (j.removed === true) {
753
+ console.log(`Removed live script tag from ${j.file}.`);
754
+ }
755
+ } catch {
756
+ /* ignore non-JSON lines */
757
+ }
758
+ }
759
+ } catch (err) {
760
+ const detail = err.stderr?.toString?.().trim?.()
761
+ || err.stdout?.toString?.().trim?.()
762
+ || err.message
763
+ || String(err);
764
+ console.warn(`Note: could not remove live script tag (${detail.split('\n')[0]})`);
765
+ }
766
+ }
767
+ process.exit(0);
768
+ }
769
+
770
+ // --background: spawn a detached child server, wait for it to be ready,
771
+ // print the connection JSON, then exit. This keeps the startup command
772
+ // simple (no shell backgrounding or chained commands).
773
+ if (args.includes('--background')) {
774
+ const childArgs = args.filter(a => a !== '--background');
775
+ const child = spawn(process.execPath, [fileURLToPath(import.meta.url), ...childArgs], {
776
+ detached: true,
777
+ stdio: 'ignore',
778
+ cwd: process.cwd(),
779
+ });
780
+ child.unref();
781
+
782
+ // Poll for the PID file (the child writes it once the HTTP server is listening).
783
+ const deadline = Date.now() + 10_000;
784
+ while (Date.now() < deadline) {
785
+ try {
786
+ const { info } = readLiveServerInfo(process.cwd()) || {};
787
+ if (info.pid !== process.pid) {
788
+ // Output JSON so the agent can read port + token from stdout.
789
+ console.log(JSON.stringify(info));
790
+ process.exit(0);
791
+ }
792
+ } catch { /* not ready yet */ }
793
+ await new Promise(r => setTimeout(r, 200));
794
+ }
795
+ console.error('Timed out waiting for live server to start.');
796
+ process.exit(1);
797
+ }
798
+
799
+ // Check for existing session
800
+ const existingRecord = readLiveServerInfo(process.cwd());
801
+ if (existingRecord?.info) {
802
+ const existing = existingRecord.info;
803
+ try {
804
+ process.kill(existing.pid, 0);
805
+ console.error(`Live server already running on port ${existing.port} (pid ${existing.pid}).`);
806
+ console.error('Stop it first with: node ' + path.basename(fileURLToPath(import.meta.url)) + ' stop');
807
+ process.exit(1);
808
+ } catch {
809
+ try { fs.unlinkSync(existingRecord.path); } catch {}
810
+ }
811
+ }
812
+
813
+ state.token = randomUUID();
814
+ state.sessionStore = createLiveSessionStore({ cwd: process.cwd() });
815
+ restorePendingEventsFromStore();
816
+ const portArg = args.find(a => a.startsWith('--port='));
817
+ state.port = portArg ? parseInt(portArg.split('=')[1], 10) : await findOpenPort();
818
+ // Annotation screenshots live in the project root so the agent's Read tool
819
+ // doesn't trip a per-file permission prompt. Sessioned by token so concurrent
820
+ // projects (or quick restarts) don't collide.
821
+ const annotRoot = getLiveAnnotationsDir(process.cwd());
822
+ fs.mkdirSync(annotRoot, { recursive: true });
823
+ state.sessionDir = fs.mkdtempSync(path.join(annotRoot, 'session-'));
824
+
825
+ const { detectScript, sessionPath, livePath } = loadBrowserScripts();
826
+ httpServer = http.createServer(createRequestHandler({ detectScript, sessionPath, livePath }));
827
+
828
+ httpServer.listen(state.port, '127.0.0.1', () => {
829
+ writeLiveServerInfo(process.cwd(), { pid: process.pid, port: state.port, token: state.token });
830
+ const url = `http://localhost:${state.port}`;
831
+ console.log(`\nImpeccable live server running on ${url}`);
832
+ console.log(`Token: ${state.token}\n`);
833
+ console.log(`Inject: <script src="${url}/live.js"><\/script>`);
834
+ console.log(`Stop: node ${path.basename(fileURLToPath(import.meta.url))} stop`);
835
+ });
836
+
837
+ process.on('SIGINT', shutdown);
838
+ process.on('SIGTERM', shutdown);