@mthanh/vespercli 2.2.0 → 2.3.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 (157) hide show
  1. package/README.md +6 -3
  2. package/assets/CATALOG.md +9 -2
  3. package/assets/claude/.claude-plugin/marketplace.json +9 -9
  4. package/assets/claude/.claude-plugin/plugin.json +1 -1
  5. package/assets/claude/agents/code-planner.md +1 -1
  6. package/assets/claude/agents/code-reviewer.md +1 -1
  7. package/assets/claude/agents/code-tester.md +1 -1
  8. package/assets/claude/agents/copywriter.md +1 -1
  9. package/assets/claude/agents/feature-wrap-document.md +1 -1
  10. package/assets/claude/agents/janitor.md +1 -1
  11. package/assets/claude/agents/modernization.md +1 -1
  12. package/assets/claude/agents/principal-software-engineer.md +1 -1
  13. package/assets/claude/agents/refine-issue.md +1 -1
  14. package/assets/claude/agents/se-system-architecture-reviewer.md +1 -1
  15. package/assets/claude/agents/se-technical-writer.md +1 -1
  16. package/assets/claude/agents/skill-creator.md +1 -1
  17. package/assets/claude/agents/task-researcher.md +1 -1
  18. package/assets/claude/agents/technical-product-manager.md +1 -1
  19. package/assets/claude/agents/vision-analyst.md +1 -1
  20. package/assets/claude/agents/vitest.md +1 -1
  21. package/assets/claude/agents/workspace-learner.md +2 -2
  22. package/assets/claude/packs/backend/.claude-plugin/plugin.json +1 -1
  23. package/assets/claude/packs/backend/agents/firebase-developer.md +1 -1
  24. package/assets/claude/packs/backend/agents/nodejs-express-developer.md +1 -1
  25. package/assets/claude/packs/docs/.claude-plugin/plugin.json +1 -1
  26. package/assets/claude/packs/frontend/.claude-plugin/plugin.json +1 -1
  27. package/assets/claude/packs/frontend/agents/expert-nextjs-developer.md +1 -1
  28. package/assets/claude/packs/frontend/agents/expert-react-frontend-engineer.md +1 -1
  29. package/assets/claude/packs/frontend/agents/jest-react-component-analyzer.md +1 -1
  30. package/assets/claude/packs/frontend/agents/jest-react-scenario-scanner.md +1 -1
  31. package/assets/claude/packs/frontend/agents/jest-react-test-generator.md +1 -1
  32. package/assets/claude/packs/frontend/agents/jest-react-test-planner.md +1 -1
  33. package/assets/claude/packs/frontend/skills/design-taste-frontend/LICENSE +21 -0
  34. package/assets/claude/packs/frontend/skills/design-taste-frontend/SKILL.md +529 -0
  35. package/assets/claude/packs/frontend/skills/design-taste-frontend/UPSTREAM.json +7 -0
  36. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/app.css +216 -0
  37. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/base.css +105 -0
  38. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/base.js +37 -0
  39. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/charts.js +617 -0
  40. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.css +28 -0
  41. package/assets/claude/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.js +133 -0
  42. package/assets/claude/packs/frontend/skills/design-taste-frontend/evals/evals.json +76 -0
  43. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/app.json +1327 -0
  44. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/directions.json +1078 -0
  45. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/heroes.json +1086 -0
  46. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/motions.json +92 -0
  47. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/palettes.json +1485 -0
  48. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/photos.json +7240 -0
  49. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/sections.json +4429 -0
  50. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/sites.json +8350 -0
  51. package/assets/claude/packs/frontend/skills/design-taste-frontend/library/type.json +2024 -0
  52. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/app-screens.md +1199 -0
  53. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/colour.md +141 -0
  54. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/copy.md +177 -0
  55. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/critique.md +182 -0
  56. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/imagery.md +791 -0
  57. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/layout.md +292 -0
  58. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/motion.md +980 -0
  59. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/research.md +356 -0
  60. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/scenes.md +174 -0
  61. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/tells.md +115 -0
  62. package/assets/claude/packs/frontend/skills/design-taste-frontend/references/type.md +170 -0
  63. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/assets.mjs +865 -0
  64. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/draw.mjs +584 -0
  65. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/inspect.mjs +303 -0
  66. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/app-draw.mjs +203 -0
  67. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/cdp.mjs +248 -0
  68. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/probe.mjs +909 -0
  69. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lib/rules.mjs +243 -0
  70. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/lint.mjs +119 -0
  71. package/assets/claude/packs/frontend/skills/design-taste-frontend/scripts/scenes.mjs +124 -0
  72. package/assets/claude/packs/graphify/.claude-plugin/plugin.json +1 -1
  73. package/assets/claude/packs/integrations/.claude-plugin/plugin.json +1 -1
  74. package/assets/claude/packs/playwright/.claude-plugin/plugin.json +1 -1
  75. package/assets/claude/packs/playwright/agents/playwright-component-analyzer.md +1 -1
  76. package/assets/claude/packs/playwright/agents/playwright-scenario-scanner.md +1 -1
  77. package/assets/claude/packs/playwright/agents/playwright-test-generator.md +1 -1
  78. package/assets/claude/packs/playwright/agents/playwright-test-planner.md +1 -1
  79. package/assets/claude/packs/playwright/agents/playwright-tester.md +1 -1
  80. package/assets/claude/packs/polyglot/.claude-plugin/plugin.json +1 -1
  81. package/assets/claude/packs/styles/.claude-plugin/plugin.json +1 -1
  82. package/assets/copilot/agents/code-planner.agent.md +1 -1
  83. package/assets/copilot/agents/code-reviewer.agent.md +1 -1
  84. package/assets/copilot/agents/code-tester.agent.md +1 -1
  85. package/assets/copilot/agents/copywriter.agent.md +1 -1
  86. package/assets/copilot/agents/feature-wrap-document.agent.md +1 -1
  87. package/assets/copilot/agents/janitor.agent.md +1 -1
  88. package/assets/copilot/agents/modernization.agent.md +1 -1
  89. package/assets/copilot/agents/principal-software-engineer.agent.md +1 -1
  90. package/assets/copilot/agents/refine-issue.agent.md +1 -1
  91. package/assets/copilot/agents/se-system-architecture-reviewer.agent.md +1 -1
  92. package/assets/copilot/agents/se-technical-writer.agent.md +1 -1
  93. package/assets/copilot/agents/skill-creator.agent.md +1 -1
  94. package/assets/copilot/agents/task-researcher.agent.md +1 -1
  95. package/assets/copilot/agents/technical-product-manager.agent.md +1 -1
  96. package/assets/copilot/agents/vision-analyst.agent.md +1 -1
  97. package/assets/copilot/agents/vitest.agent.md +1 -1
  98. package/assets/copilot/agents/workspace-learner.agent.md +2 -2
  99. package/assets/copilot/packs/backend/agents/firebase-developer.agent.md +1 -1
  100. package/assets/copilot/packs/backend/agents/nodejs-express-developer.agent.md +1 -1
  101. package/assets/copilot/packs/frontend/agents/expert-nextjs-developer.agent.md +1 -1
  102. package/assets/copilot/packs/frontend/agents/expert-react-frontend-engineer.agent.md +1 -1
  103. package/assets/copilot/packs/frontend/agents/jest-react-component-analyzer.agent.md +1 -1
  104. package/assets/copilot/packs/frontend/agents/jest-react-scenario-scanner.agent.md +1 -1
  105. package/assets/copilot/packs/frontend/agents/jest-react-test-generator.agent.md +1 -1
  106. package/assets/copilot/packs/frontend/agents/jest-react-test-planner.agent.md +1 -1
  107. package/assets/copilot/packs/frontend/skills/design-taste-frontend/LICENSE +21 -0
  108. package/assets/copilot/packs/frontend/skills/design-taste-frontend/SKILL.md +529 -0
  109. package/assets/copilot/packs/frontend/skills/design-taste-frontend/UPSTREAM.json +7 -0
  110. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/app.css +216 -0
  111. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/base.css +105 -0
  112. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/base.js +37 -0
  113. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/charts.js +617 -0
  114. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.css +28 -0
  115. package/assets/copilot/packs/frontend/skills/design-taste-frontend/assets/scenes/stage.js +133 -0
  116. package/assets/copilot/packs/frontend/skills/design-taste-frontend/evals/evals.json +76 -0
  117. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/app.json +1327 -0
  118. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/directions.json +1078 -0
  119. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/heroes.json +1086 -0
  120. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/motions.json +92 -0
  121. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/palettes.json +1485 -0
  122. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/photos.json +7240 -0
  123. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/sections.json +4429 -0
  124. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/sites.json +8350 -0
  125. package/assets/copilot/packs/frontend/skills/design-taste-frontend/library/type.json +2024 -0
  126. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/app-screens.md +1199 -0
  127. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/colour.md +141 -0
  128. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/copy.md +177 -0
  129. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/critique.md +182 -0
  130. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/imagery.md +791 -0
  131. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/layout.md +292 -0
  132. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/motion.md +980 -0
  133. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/research.md +356 -0
  134. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/scenes.md +174 -0
  135. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/tells.md +115 -0
  136. package/assets/copilot/packs/frontend/skills/design-taste-frontend/references/type.md +170 -0
  137. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/assets.mjs +865 -0
  138. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/draw.mjs +584 -0
  139. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/inspect.mjs +303 -0
  140. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/app-draw.mjs +203 -0
  141. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/cdp.mjs +248 -0
  142. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/probe.mjs +909 -0
  143. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lib/rules.mjs +243 -0
  144. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/lint.mjs +119 -0
  145. package/assets/copilot/packs/frontend/skills/design-taste-frontend/scripts/scenes.mjs +124 -0
  146. package/assets/copilot/packs/playwright/agents/playwright-component-analyzer.agent.md +1 -1
  147. package/assets/copilot/packs/playwright/agents/playwright-scenario-scanner.agent.md +1 -1
  148. package/assets/copilot/packs/playwright/agents/playwright-test-generator.agent.md +1 -1
  149. package/assets/copilot/packs/playwright/agents/playwright-test-planner.agent.md +1 -1
  150. package/assets/copilot/packs/playwright/agents/playwright-tester.agent.md +1 -1
  151. package/assets/manifest.json +2 -0
  152. package/dist/cli.min.js +102 -102
  153. package/package.json +1 -1
  154. package/scripts/__snapshots__/generate-claude-assets.test.js.snap +1 -1
  155. package/scripts/generate-claude-assets.strict.test.js +1 -1
  156. package/scripts/generate-claude-assets.test.js +6 -6
  157. package/scripts/packs-layout.test.js +2 -1
@@ -0,0 +1,28 @@
1
+ /* tasteskill / scenes / stage.css — the held stage under every scroll scene (references/scenes.md).
2
+ Without .is-live (no script, a failed CDN, reduced motion, a phone set to 'rest') a scene is an ordinary
3
+ section showing its finished composition. With it, the section is (hold + 1) screens tall and the
4
+ stage sticks to the viewport for the hold. */
5
+
6
+ .scene { position: relative; }
7
+ .scene > .scene-stage { position: relative; }
8
+
9
+ html.js .scene.is-live { height: calc((var(--hold, 2) + 1) * 100svh); }
10
+ html.js .scene.is-live > .scene-stage {
11
+ position: sticky;
12
+ top: 0;
13
+ height: 100svh;
14
+ overflow: clip; /* clip, not hidden: hidden would make the stage a scroll container */
15
+ contain: layout paint;
16
+ }
17
+
18
+ /* Everything a scene moves is composited; nothing it moves is laid out again. */
19
+ .scene.is-live [data-move] { will-change: transform, opacity; }
20
+
21
+ /* Lenis */
22
+ html.is-smooth { scroll-behavior: auto; }
23
+ html.is-smooth body { overscroll-behavior: none; }
24
+
25
+ @media (prefers-reduced-motion: reduce) {
26
+ html.js .scene.is-live { height: auto; }
27
+ html.js .scene.is-live > .scene-stage { position: relative; height: auto; }
28
+ }
@@ -0,0 +1,133 @@
1
+ // tasteskill / scenes / stage.js — the shared stage every scroll scene runs on (references/scenes.md).
2
+ //
3
+ // A scene is a tall section whose stage sticks to the viewport while the page scrolls past it; a GSAP
4
+ // timeline is scrubbed by that scroll. The page always scrolls natively (no wheel capture), the
5
+ // scrollbar always tells the truth, and the finished composition is what reduced motion, no script and
6
+ // a failed CDN all show.
7
+ //
8
+ // Load at the end of <body>, in this order (versions pinned):
9
+ // <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
10
+ // <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
11
+ // <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/SplitText.min.js"></script> (only if a scene splits text)
12
+ // <script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.min.js"></script> (optional smoothing)
13
+ // <script src="assets/scenes/stage.js"></script>
14
+ // <script src="assets/scenes/<scene>.js"></script>
15
+ // and keep the one-line <script>document.documentElement.classList.add('js')</script> in <head>.
16
+ //
17
+ // Stage.smooth() weighted wheel scrolling (Lenis), off for touch and reduced motion
18
+ // Stage.scene(root, { hold, scrub, build, phone, rest })
19
+ // Stage.split(el, 'lines' | 'words' | 'chars') masked split text, SplitText when loaded
20
+ // Stage.ready() resolves when fonts and the scenes' pictures are ready
21
+ // Stage.init() starts every <section class="scene" data-scene="<id>"> on the page
22
+ //
23
+ // A page: Stage.smooth(); Stage.init();
24
+ (() => {
25
+ const html = document.documentElement;
26
+ const mq = (q) => window.matchMedia(q).matches;
27
+ const live = !!(window.gsap && window.ScrollTrigger);
28
+ if (live) gsap.registerPlugin(ScrollTrigger);
29
+ if (live && window.SplitText) gsap.registerPlugin(SplitText);
30
+
31
+ const Stage = {
32
+ live,
33
+ get reduced() { return mq('(prefers-reduced-motion: reduce)'); },
34
+ get phone() { return mq('(max-width: 767px)'); },
35
+ get touch() { return mq('(pointer: coarse)'); },
36
+ lenis: null,
37
+ scenes: [],
38
+ };
39
+
40
+ // Weighted wheel scrolling. lerp 0.1-0.14 feels heavy without lagging behind the hand; touch keeps the
41
+ // phone's own scrolling, and reduced motion keeps the browser's.
42
+ Stage.smooth = ({ lerp = 0.12 } = {}) => {
43
+ if (!live || !window.Lenis || Stage.reduced || Stage.touch || Stage.lenis) return Stage.lenis;
44
+ const lenis = new Lenis({ lerp, smoothWheel: true, anchors: true, autoRaf: false });
45
+ lenis.on('scroll', ScrollTrigger.update);
46
+ gsap.ticker.add((t) => lenis.raf(t * 1000));
47
+ gsap.ticker.lagSmoothing(0);
48
+ html.classList.add('is-smooth');
49
+ Stage.lenis = lenis;
50
+ return lenis;
51
+ };
52
+
53
+ // One scroll scene.
54
+ // root <section class="scene"> holding one <div class="scene-stage">
55
+ // hold screens of scroll the stage is held for (1-4); the section is (hold + 1) screens tall
56
+ // scrub true = locked to the scrollbar; a number = seconds of catch-up (0.3-0.8 reads as weight)
57
+ // build(tl, ctx) add the tweens to tl; the timeline runs 0 → 1 over the hold. ctx: { root, stage, phone, q }
58
+ // phone 'same' (default) | 'rest' (the phone gets the finished composition) | { hold, build }
59
+ // rest(ctx) optional: anything extra the finished composition needs (most scenes need nothing)
60
+ // Sets --p (0-1) and data-beat on root, so CSS and captions can follow the scene too.
61
+ Stage.scene = (root, opts = {}) => {
62
+ if (!root) return null;
63
+ const { hold = 2, scrub = true, build, phone = 'same', rest, beats = 0 } = opts;
64
+ const stage = root.querySelector(':scope > .scene-stage') || root.firstElementChild;
65
+ const q = (sel) => [...root.querySelectorAll(sel)];
66
+ const toRest = (ctx) => { root.classList.remove('is-live'); root.classList.add('is-rest'); root.style.removeProperty('--hold'); if (rest) rest(ctx); };
67
+ if (!live) { toRest({ root, stage, phone: Stage.phone, q }); return null; }
68
+ const mm = gsap.matchMedia();
69
+ mm.add({ motion: '(prefers-reduced-motion: no-preference)', phone: '(max-width: 767px)' }, (c) => {
70
+ const isPhone = c.conditions.phone;
71
+ const ctx = { root, stage, phone: isPhone, q };
72
+ const plan = isPhone ? (phone === 'rest' ? null : phone === 'same' ? { hold, build } : { hold: phone.hold ?? hold, build: phone.build ?? build }) : { hold, build };
73
+ if (!c.conditions.motion || !plan || !plan.build) { toRest(ctx); return () => root.classList.remove('is-rest'); }
74
+ root.classList.remove('is-rest');
75
+ root.classList.add('is-live');
76
+ root.style.setProperty('--hold', plan.hold);
77
+ const tl = gsap.timeline({
78
+ defaults: { ease: 'none' },
79
+ scrollTrigger: {
80
+ trigger: root, start: 'top top', end: 'bottom bottom', scrub, invalidateOnRefresh: true,
81
+ onUpdate: (self) => {
82
+ root.style.setProperty('--p', self.progress.toFixed(4));
83
+ if (beats) root.dataset.beat = String(Math.min(beats - 1, Math.floor(self.progress * beats)));
84
+ },
85
+ },
86
+ });
87
+ plan.build(tl, ctx);
88
+ // pad the timeline to exactly 1 so positions in build() read as fractions of the hold
89
+ if (tl.duration() < 1) tl.to({}, { duration: 1 - tl.duration() }, tl.duration());
90
+ return () => { root.classList.remove('is-live'); root.style.removeProperty('--hold'); root.style.removeProperty('--p'); };
91
+ });
92
+ Stage.scenes.push(mm);
93
+ return mm;
94
+ };
95
+
96
+ // Masked split text. Lines rise out of their own mask; words and characters are for short headings.
97
+ Stage.split = (el, type = 'lines') => {
98
+ if (!el) return [];
99
+ if (window.SplitText && live) {
100
+ const s = SplitText.create(el, { type: type === 'lines' ? 'lines' : type === 'words' ? 'lines,words' : 'lines,words,chars', mask: 'lines', aria: 'auto', autoSplit: false });
101
+ return type === 'lines' ? s.lines : type === 'words' ? s.words : s.chars;
102
+ }
103
+ // fallback: words in inline-block spans, the full text kept for screen readers
104
+ if (!el.dataset.split) {
105
+ el.setAttribute('aria-label', el.textContent.trim());
106
+ el.innerHTML = el.textContent.trim().split(/\s+/).map((w) => `<span aria-hidden="true" style="display:inline-block">${w}</span>`).join(' ');
107
+ el.dataset.split = 'words';
108
+ }
109
+ return [...el.children];
110
+ };
111
+
112
+ // Fonts and the scenes' pictures decide every height a trigger measures; refresh once they are in.
113
+ Stage.ready = () => {
114
+ const imgs = [...document.querySelectorAll('.scene img')].map((i) => (i.complete ? null : i.decode().catch(() => {}))).filter(Boolean);
115
+ return Promise.all([document.fonts ? document.fonts.ready : null, ...imgs]).then(() => { if (live) ScrollTrigger.refresh(); });
116
+ };
117
+
118
+ // Every <section class="scene" data-scene="<id>" data-options='{"hold":3}'> on the page, started by
119
+ // the scene file of that id (assets/scenes/<id>.js registers Scenes['<id>']).
120
+ Stage.init = () => {
121
+ for (const el of document.querySelectorAll('.scene[data-scene]')) {
122
+ if (el.__scene) continue;
123
+ const make = window.Scenes[el.dataset.scene];
124
+ if (!make) { console.warn('No scene file loaded for data-scene="' + el.dataset.scene + '"'); continue; }
125
+ let o = {}; try { o = JSON.parse(el.dataset.options || '{}'); } catch {}
126
+ el.__scene = make(el, o) || true;
127
+ }
128
+ };
129
+
130
+ window.Scenes = window.Scenes || {};
131
+ window.Stage = Stage;
132
+ if (live) { window.addEventListener('load', () => Stage.ready()); }
133
+ })();
@@ -0,0 +1,76 @@
1
+ {
2
+ "skill_name": "design-taste-frontend",
3
+ "how_to_run": "For each eval, give the prompt to a fresh agent that has this skill, and to a second fresh agent without it (the baseline). Render both with scripts/inspect.mjs and have a judge who does not know which is which score the screenshots with references/critique.md. Record inspector FAIL counts for both. Evals 7 to 10 are app screens: inspect them with --app (a sheet dealt by draw.mjs --app switches it on by itself) and judge them with the app-screen passes in references/critique.md.",
4
+ "evals": [
5
+ {
6
+ "id": 1,
7
+ "name": "saas-invoicing",
8
+ "prompt": "Build a landing page for Ledgerly, an invoicing tool for freelance designers. What it does: you write an invoice in under a minute, the client pays by card or bank transfer, and it sends polite reminders by itself when an invoice is overdue. It costs 9 euros a month flat, with a 14-day free trial and no card needed. Include pricing and a short FAQ. There is no existing brand and no screenshots; the product name is all we have. Plain static HTML, CSS and JS in one folder.",
9
+ "expected_output": "A static landing page with a clear idea drawn from invoicing itself, headlines of two lines or fewer at 1440/768/390, no eyebrow labels, no monospace, no index numbering, no thin rules, no gradients or shadows, a non-default palette and type system, a pricing section that is not three cards, and no invented customers or statistics.",
10
+ "files": []
11
+ },
12
+ {
13
+ "id": 2,
14
+ "name": "restaurant-osteria",
15
+ "prompt": "Make a one-page website for Osteria Nove, a 38-seat Italian restaurant in Alfama, Lisbon. Handmade pasta, a short natural wine list, dinner only, Tuesday to Saturday from 19:00. Address: Rua dos Remédios 9. Reservations by phone (+351 21 000 0009) or email (mesa@osterianove.pt). The page needs the menu (invent a believable short one: antipasti, pasta, dolci, with prices in euros), hours, address and how to book. We have no photographs yet. Static HTML/CSS/JS.",
16
+ "expected_output": "A one-page restaurant site with a specific idea (for example the page as the menu itself), the menu set typographically without divider lines, practical information easy to find, bundled photographs used only as atmosphere and listed for replacement, and all house rules met.",
17
+ "files": []
18
+ },
19
+ {
20
+ "id": 3,
21
+ "name": "portfolio-designer",
22
+ "prompt": "I'm Mara Lindqvist, a product designer in Stockholm with eight years in fintech and health apps. I need a portfolio homepage: six selected projects (make up plausible names, clients, years and one-line descriptions), a short about paragraph, and a way to contact me (mara@lindqvist.studio). I don't have project images ready, so design it so it still looks finished without them, or use placeholders that I can swap. Static HTML/CSS/JS.",
23
+ "expected_output": "A portfolio page that looks finished without project imagery (a typographic index, a name-led hero, or atmosphere photographs clearly marked for replacement), with a designed footer, a phone layout that is its own composition, and all house rules met.",
24
+ "files": []
25
+ },
26
+ {
27
+ "id": 4,
28
+ "name": "product-ceramics",
29
+ "prompt": "Launch page for Kiln, a ceramic pour-over coffee set (dripper, carafe and two cups) that is hand-glazed in small batches in Porto. It costs 84 euros and ships across the EU within a week. The glaze is mixed by hand so no two sets are identical. We have not shot product photos yet, so there are no images of the set. One page, with a way to buy (a button is enough). Static HTML/CSS/JS.",
30
+ "expected_output": "A product page that does not fake product photography: it either commits to type and colour, uses one shape from the object as a motif, or uses atmosphere photographs honestly, with the price and purchase action clear, and all house rules met.",
31
+ "files": []
32
+ },
33
+ {
34
+ "id": 5,
35
+ "name": "guesthouse-ericeira",
36
+ "prompt": "Website for Casa Mirante, a six-room guesthouse on the cliffs above Ericeira, Portugal. Rooms from 140 euros a night with breakfast included; ten minutes' walk to the surf at Ribeira d'Ilhas; open March to November. One page: what it is, the rooms, what's nearby, and how to book (email reservas@casamirante.pt). We have no photographs yet. Static HTML/CSS/JS.",
37
+ "expected_output": "A calm, photograph-led or type-led one-pager whose hero is one clear thing, with rooms and booking information easy to find, bundled coast photographs used as atmosphere and listed for replacement, and all house rules met.",
38
+ "files": []
39
+ },
40
+ {
41
+ "id": 6,
42
+ "name": "conference-format",
43
+ "prompt": "Landing page for Format, a two-day design conference in Rotterdam on 14 and 15 May 2027. Twelve speakers (invent plausible names and talk titles), 400 seats, tickets at 390 euros, venue: Maassilo. Sections: what it is, the line-up, the schedule in brief, tickets, and a short FAQ. No brand exists yet beyond the name. Static HTML/CSS/JS.",
44
+ "expected_output": "An event page with a strong typographic or colour idea, the line-up and schedule set as structured text without divider lines or index numbers, a ticket section that is not three cards, and all house rules met.",
45
+ "files": []
46
+ },
47
+ {
48
+ "id": 7,
49
+ "name": "app-budget-overview",
50
+ "prompt": "Build the main screen of Ledgerly, a budgeting app for couples who share money: the October overview with their accounts and balances, the spending plan (planned against spent by category), bills due in the next 14 days and recent transactions. Two people use it, Mia and Tom. Desktop first, and it must work on a phone. Static HTML/CSS/JS.",
51
+ "expected_output": "An app screen, not a landing page: a quiet shell (sidebar or rail), a clear screen title, numbers that add up and are right-aligned with tabular figures, one chart per question, colour spent on data and status only, no icons in tinted squares, no gradients or glows, no placeholder names, and a phone layout where the navigation folds away. inspect.mjs --app passes.",
52
+ "files": []
53
+ },
54
+ {
55
+ "id": 8,
56
+ "name": "app-deploy-dashboard",
57
+ "prompt": "Dashboard for Relay, an edge deployment platform for web teams: one project's overview with recent deployments (status, branch, commit message, author, duration, region), requests and p95 latency over the last 24 hours, the error rate, and usage against the plan's limits. Dark theme. Static HTML/CSS/JS.",
58
+ "expected_output": "A dense, readable dark screen on a neutral (not navy) ground: one surface step or one hairline between regions, a deployments table with honest statuses and aligned numbers, charts with few gridlines and one series each, IDs in monospace at most, no rainbow series, no glow, and app inspector checks passing.",
59
+ "files": []
60
+ },
61
+ {
62
+ "id": 9,
63
+ "name": "app-settings-billing",
64
+ "prompt": "Workspace settings for Proofline, a design-review tool: general settings, members and roles (a members table with an invite form), billing (current plan, seats, invoices) and notifications. Static HTML/CSS/JS, desktop and phone.",
65
+ "expected_output": "A settings screen with a label column beside its fields (or stacked fields on a phone), labels above inputs, one control height, quiet borders, honest disabled states, a members table with right-aligned figures and one status pill per row, and no decorative icons or gradients.",
66
+ "files": []
67
+ },
68
+ {
69
+ "id": 10,
70
+ "name": "app-support-queue",
71
+ "prompt": "The queue screen of Hearth, a support inbox for a six-person SaaS team: the list of conversations with assignee, priority, channel and time to the SLA, the open conversation with the customer's details beside it, plus filters and saved views. Static HTML/CSS/JS.",
72
+ "expected_output": "A three-region work screen (navigation, list, conversation) that stays readable at 1440 and folds to one region at a time on a phone, with status shown once per row, times in words, no tinted icon squares or emoji, and app inspector checks passing.",
73
+ "files": []
74
+ }
75
+ ]
76
+ }