@invisibleloop/pulse 0.20.11 → 0.20.19

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 (266) hide show
  1. package/package.json +6 -5
  2. package/public/.pulse-ui-version +1 -1
  3. package/scripts/build.js +26 -0
  4. package/scripts/release-version.js +17 -8
  5. package/scripts/strip-server.test.js +60 -0
  6. package/src/agent/checklist.md +8 -12
  7. package/src/agent/commands/pulse-start.md +2 -0
  8. package/src/agent/commands/verify.md +30 -8
  9. package/src/agent/guide-components.md +7 -25
  10. package/src/agent/guide-routing.md +0 -12
  11. package/src/agent/guide-server.md +102 -1
  12. package/src/agent/guide-spec.md +8 -1
  13. package/src/agent/guide-styles.md +23 -0
  14. package/src/agent/identity.md +9 -0
  15. package/src/agent/workflow.md +4 -23
  16. package/src/cli/check-bundles.js +113 -0
  17. package/src/cli/check-bundles.test.js +137 -0
  18. package/src/cli/cli.test.js +105 -0
  19. package/src/cli/dev.js +48 -3
  20. package/src/cli/diagnose.js +105 -0
  21. package/src/cli/diagnose.test.js +124 -0
  22. package/src/cli/discover.js +9 -2
  23. package/src/cli/index.js +171 -9
  24. package/src/cli/process-utils.js +57 -0
  25. package/src/cli/process-utils.test.js +114 -0
  26. package/src/cli/review.js +391 -0
  27. package/src/cli/review.test.js +143 -0
  28. package/src/cli/scaffold.js +9 -4
  29. package/src/cli/stamp.js +102 -0
  30. package/src/cli/stamp.test.js +149 -0
  31. package/src/cli/start.js +15 -2
  32. package/src/cli/validate.js +184 -0
  33. package/src/cli/validate.test.js +153 -0
  34. package/src/mcp/mcp.test.js +261 -30
  35. package/src/mcp/server.js +207 -515
  36. package/src/mcp/validate-worker.js +18 -1
  37. package/src/runtime/index.js +144 -11
  38. package/src/runtime/runtime.test.js +199 -0
  39. package/src/runtime/ssr.js +13 -6
  40. package/src/runtime/ssr.test.js +31 -0
  41. package/src/server/index.js +162 -9
  42. package/src/server/server.test.js +225 -2
  43. package/src/spec/schema.js +1 -1
  44. package/src/ui/index.js +0 -5
  45. package/src/ui/ui.test.js +0 -75
  46. package/types/ui.d.ts +0 -21
  47. package/.claude/commands/build-page.md +0 -63
  48. package/.claude/commands/new-doc-page.md +0 -45
  49. package/.claude/commands/pulse-start.md +0 -11
  50. package/.claude/commands/pulse-stop.md +0 -5
  51. package/.claude/commands/verify.md +0 -118
  52. package/.claude/pulse-checklist.md +0 -189
  53. package/.github/workflows/ci.yml +0 -25
  54. package/.github/workflows/publish.yml +0 -45
  55. package/.pulse/load-reports/home/1773432711417.json +0 -22
  56. package/.pulse-verified +0 -1
  57. package/AGENTS.md +0 -697
  58. package/CLAUDE.md +0 -697
  59. package/README.md +0 -95
  60. package/benchmark/public/dist/counter.boot-PO6SNSJZ.js +0 -8
  61. package/benchmark/public/dist/home.boot-YK6VAEQI.js +0 -6
  62. package/benchmark/public/dist/manifest.json +0 -5
  63. package/benchmark/public/dist/runtime-5Y7ESAIB.js +0 -2
  64. package/benchmark/public/dist/runtime-KO4BHUQ3.js +0 -49
  65. package/benchmark/results/2026-03-27-09-20.json +0 -188
  66. package/benchmark/results/2026-03-27-09-21.json +0 -188
  67. package/benchmark/results/2026-03-27-09-29.json +0 -188
  68. package/benchmark/results/2026-03-27-10-14.json +0 -188
  69. package/benchmark/results/2026-03-27-10-18.json +0 -232
  70. package/benchmark/src/pages/counter.js +0 -37
  71. package/benchmark/src/pages/home.js +0 -21
  72. package/docs/.claude/commands/pulse-build.md +0 -7
  73. package/docs/.claude/commands/pulse-dev.md +0 -7
  74. package/docs/.claude/commands/pulse-start.md +0 -9
  75. package/docs/.claude/commands/pulse-stop.md +0 -5
  76. package/docs/.claude/commands/verify.md +0 -84
  77. package/docs/.claude/coverage-check.js +0 -196
  78. package/docs/.claude/pulse-checklist.md +0 -189
  79. package/docs/public/.pulse-ui-version +0 -1
  80. package/docs/public/andypixel.css +0 -237
  81. package/docs/public/bookworms.css +0 -422
  82. package/docs/public/coutumes.css +0 -561
  83. package/docs/public/docs.css +0 -2388
  84. package/docs/public/favicon.svg +0 -4
  85. package/docs/public/home-brut.css +0 -982
  86. package/docs/public/images/bookworms/hero-books.jpg +0 -0
  87. package/docs/public/images/bookworms/how-we-read-now.jpg +0 -0
  88. package/docs/public/images/bookworms/lantern-keepers.jpg +0 -0
  89. package/docs/public/images/bookworms/provincial-bookseller.jpg +0 -0
  90. package/docs/public/images/journey/178.jpg +0 -0
  91. package/docs/public/images/journey/29.jpg +0 -0
  92. package/docs/public/images/retrowheels/hero.jpg +0 -0
  93. package/docs/public/images/shop/devbook-pro.jpg +0 -0
  94. package/docs/public/images/suzukibento/1015.jpg +0 -0
  95. package/docs/public/images/suzukibento/1025.jpg +0 -0
  96. package/docs/public/images/suzukibento/1043.jpg +0 -0
  97. package/docs/public/images/suzukibento/1059.jpg +0 -0
  98. package/docs/public/images/suzukibento/1062.jpg +0 -0
  99. package/docs/public/images/suzukibento/1084.jpg +0 -0
  100. package/docs/public/images/swish/1469334031218-e382a71b716b.jpg +0 -0
  101. package/docs/public/images/swish/1483985988355-763728e1935b.jpg +0 -0
  102. package/docs/public/images/swish/1485518882345-15568b007407.jpg +0 -0
  103. package/docs/public/images/swish/1490481651871-ab68de25d43d.jpg +0 -0
  104. package/docs/public/images/swish/1496747611176-843222e1e57c.jpg +0 -0
  105. package/docs/public/images/swish/1502716119720-b23a93e5fe1b.jpg +0 -0
  106. package/docs/public/images/swish/1539109136881-3be0616acf4b.jpg +0 -0
  107. package/docs/public/images/swish/1551803091-e20673f15770.jpg +0 -0
  108. package/docs/public/images/swish/1558769132-cb1aea458c5e.jpg +0 -0
  109. package/docs/public/images/swish/1572804013309-59a88b7e92f1.jpg +0 -0
  110. package/docs/public/img/heic1501a.jpg +0 -0
  111. package/docs/public/img/placeholder-landscape.svg +0 -18
  112. package/docs/public/img/placeholder-square.svg +0 -14
  113. package/docs/public/img/placeholder-tall.svg +0 -22
  114. package/docs/public/journey.css +0 -528
  115. package/docs/public/menu.js +0 -327
  116. package/docs/public/pulse-ui.css +0 -3028
  117. package/docs/public/pulse-ui.js +0 -257
  118. package/docs/public/retrowheels.css +0 -425
  119. package/docs/public/shop.css +0 -269
  120. package/docs/public/sparkys.css +0 -382
  121. package/docs/public/suzukibento.css +0 -517
  122. package/docs/public/swish.css +0 -394
  123. package/docs/public/theme.css +0 -52
  124. package/docs/public/themes/lumio.css +0 -50
  125. package/docs/public/themes/observatory.css +0 -104
  126. package/docs/server.js +0 -161
  127. package/docs/src/lib/component-page.js +0 -49
  128. package/docs/src/lib/highlight.js +0 -2
  129. package/docs/src/lib/layout.js +0 -190
  130. package/docs/src/lib/metrics-store.js +0 -6
  131. package/docs/src/lib/nav.js +0 -171
  132. package/docs/src/lib/stats.js +0 -81
  133. package/docs/src/pages/accessibility.js +0 -157
  134. package/docs/src/pages/actions.js +0 -194
  135. package/docs/src/pages/auth.js +0 -176
  136. package/docs/src/pages/caching.js +0 -95
  137. package/docs/src/pages/components/accordion.js +0 -48
  138. package/docs/src/pages/components/alert.js +0 -35
  139. package/docs/src/pages/components/app-badge.js +0 -41
  140. package/docs/src/pages/components/avatar.js +0 -35
  141. package/docs/src/pages/components/badge.js +0 -36
  142. package/docs/src/pages/components/breadcrumbs.js +0 -94
  143. package/docs/src/pages/components/button.js +0 -84
  144. package/docs/src/pages/components/card.js +0 -225
  145. package/docs/src/pages/components/charts.js +0 -283
  146. package/docs/src/pages/components/checkbox.js +0 -129
  147. package/docs/src/pages/components/cluster.js +0 -47
  148. package/docs/src/pages/components/container.js +0 -40
  149. package/docs/src/pages/components/cta.js +0 -54
  150. package/docs/src/pages/components/divider.js +0 -37
  151. package/docs/src/pages/components/empty.js +0 -36
  152. package/docs/src/pages/components/feature.js +0 -60
  153. package/docs/src/pages/components/fieldset.js +0 -65
  154. package/docs/src/pages/components/fileupload.js +0 -128
  155. package/docs/src/pages/components/footer.js +0 -58
  156. package/docs/src/pages/components/grid.js +0 -169
  157. package/docs/src/pages/components/heading.js +0 -107
  158. package/docs/src/pages/components/hero.js +0 -123
  159. package/docs/src/pages/components/icons.js +0 -410
  160. package/docs/src/pages/components/image.js +0 -71
  161. package/docs/src/pages/components/input.js +0 -51
  162. package/docs/src/pages/components/media.js +0 -51
  163. package/docs/src/pages/components/modal.js +0 -111
  164. package/docs/src/pages/components/nav.js +0 -136
  165. package/docs/src/pages/components/phone-frame.js +0 -74
  166. package/docs/src/pages/components/progress.js +0 -102
  167. package/docs/src/pages/components/prose.js +0 -111
  168. package/docs/src/pages/components/pullquote.js +0 -71
  169. package/docs/src/pages/components/radio.js +0 -194
  170. package/docs/src/pages/components/rating.js +0 -106
  171. package/docs/src/pages/components/search.js +0 -61
  172. package/docs/src/pages/components/section.js +0 -98
  173. package/docs/src/pages/components/segmented.js +0 -121
  174. package/docs/src/pages/components/select.js +0 -45
  175. package/docs/src/pages/components/slider.js +0 -115
  176. package/docs/src/pages/components/spinner.js +0 -73
  177. package/docs/src/pages/components/stack.js +0 -48
  178. package/docs/src/pages/components/stat.js +0 -55
  179. package/docs/src/pages/components/stepper.js +0 -66
  180. package/docs/src/pages/components/table.js +0 -45
  181. package/docs/src/pages/components/textarea.js +0 -31
  182. package/docs/src/pages/components/toggle.js +0 -84
  183. package/docs/src/pages/components/tooltip.js +0 -48
  184. package/docs/src/pages/components.js +0 -200
  185. package/docs/src/pages/config.js +0 -193
  186. package/docs/src/pages/constraints.js +0 -100
  187. package/docs/src/pages/deploy.js +0 -233
  188. package/docs/src/pages/error-pages.js +0 -99
  189. package/docs/src/pages/extending.js +0 -198
  190. package/docs/src/pages/faq.js +0 -99
  191. package/docs/src/pages/forms.js +0 -129
  192. package/docs/src/pages/getting-started.js +0 -147
  193. package/docs/src/pages/guard.js +0 -120
  194. package/docs/src/pages/home.js +0 -350
  195. package/docs/src/pages/how-it-works.js +0 -244
  196. package/docs/src/pages/hydration.js +0 -108
  197. package/docs/src/pages/images.js +0 -120
  198. package/docs/src/pages/markdown.js +0 -156
  199. package/docs/src/pages/meta.js +0 -193
  200. package/docs/src/pages/mutations.js +0 -107
  201. package/docs/src/pages/navigation.js +0 -85
  202. package/docs/src/pages/performance.js +0 -157
  203. package/docs/src/pages/persist.js +0 -89
  204. package/docs/src/pages/project-structure.js +0 -91
  205. package/docs/src/pages/prompt-examples.js +0 -186
  206. package/docs/src/pages/raw-responses.js +0 -122
  207. package/docs/src/pages/routing.js +0 -120
  208. package/docs/src/pages/server-api.js +0 -291
  209. package/docs/src/pages/server-data.js +0 -203
  210. package/docs/src/pages/slash-commands.js +0 -55
  211. package/docs/src/pages/spec.js +0 -207
  212. package/docs/src/pages/state.js +0 -102
  213. package/docs/src/pages/store.js +0 -203
  214. package/docs/src/pages/streaming.js +0 -107
  215. package/docs/src/pages/stripe.js +0 -194
  216. package/docs/src/pages/supabase.js +0 -324
  217. package/docs/src/pages/templates/andypixel.js +0 -260
  218. package/docs/src/pages/templates/blog-post.js +0 -226
  219. package/docs/src/pages/templates/bookworms.js +0 -227
  220. package/docs/src/pages/templates/coutumes.js +0 -237
  221. package/docs/src/pages/templates/journey.js +0 -186
  222. package/docs/src/pages/templates/mobile-app.js +0 -371
  223. package/docs/src/pages/templates/retrowheels.js +0 -355
  224. package/docs/src/pages/templates/shop.js +0 -268
  225. package/docs/src/pages/templates/sparkys.js +0 -264
  226. package/docs/src/pages/templates/suzukibento.js +0 -200
  227. package/docs/src/pages/templates/swish.js +0 -313
  228. package/docs/src/pages/templates.js +0 -534
  229. package/docs/src/pages/testing.js +0 -199
  230. package/docs/src/pages/validation.js +0 -138
  231. package/examples/.claude/commands/pulse-build.md +0 -7
  232. package/examples/.claude/commands/pulse-dev.md +0 -7
  233. package/examples/.claude/commands/pulse-start.md +0 -9
  234. package/examples/.claude/commands/pulse-stop.md +0 -5
  235. package/examples/.claude/commands/verify.md +0 -84
  236. package/examples/.claude/coverage-check.js +0 -196
  237. package/examples/.claude/pulse-checklist.md +0 -189
  238. package/examples/andypixel.css +0 -237
  239. package/examples/andypixel.js +0 -258
  240. package/examples/bookworms.css +0 -422
  241. package/examples/bookworms.js +0 -225
  242. package/examples/contact.js +0 -166
  243. package/examples/counter.js +0 -94
  244. package/examples/dev.server.js +0 -110
  245. package/examples/examples.test.js +0 -394
  246. package/examples/journey.css +0 -528
  247. package/examples/journey.js +0 -186
  248. package/examples/pricing.js +0 -262
  249. package/examples/products.js +0 -190
  250. package/examples/public/.pulse-ui-version +0 -1
  251. package/examples/public/pulse-ui.css +0 -3028
  252. package/examples/public/pulse-ui.js +0 -257
  253. package/examples/quiz.js +0 -208
  254. package/examples/retrowheels.css +0 -425
  255. package/examples/retrowheels.js +0 -353
  256. package/examples/shared.js +0 -84
  257. package/examples/suzukibento.css +0 -513
  258. package/examples/suzukibento.js +0 -200
  259. package/examples/swish.css +0 -394
  260. package/examples/swish.js +0 -311
  261. package/examples/todos.js +0 -162
  262. package/src/ui/fieldset.js +0 -37
  263. package/src/ui/phone-frame.js +0 -40
  264. package/src/ui/search.js +0 -78
  265. package/src/ui/segmented.js +0 -50
  266. package/src/ui/tooltip.js +0 -28
@@ -1,350 +0,0 @@
1
- // component-free — creative override: asymmetric typography-driven layout (wide headline column + narrower supporting column), a solid gold mark treatment on "page.", and a light/dark section rhythm that component patterns cannot express
2
- import { highlight } from '../lib/highlight.js'
3
- import { iconZap, iconShield, iconSettings } from '../../../src/ui/icons.js'
4
- import { metricsStore } from '../lib/metrics-store.js'
5
- import pkg from '../../../package.json' with { type: 'json' }
6
-
7
- // macOS-style code window chrome — raw HTML (creative override), replacing
8
- // the removed codeWindow() component. Reuses the same .ui-code-window*
9
- // CSS classes still defined in pulse-ui.css.
10
- const codeWindow = ({ content = '', filename = '', lang = '' }) => `
11
- <div class="ui-code-window" role="region"${filename ? ` aria-label="${filename}"` : ''}>
12
- <div class="ui-code-window-chrome" aria-hidden="true">
13
- <span class="ui-code-window-dot"></span>
14
- <span class="ui-code-window-dot"></span>
15
- <span class="ui-code-window-dot"></span>
16
- ${filename ? `<span class="ui-code-window-filename">${filename}</span>` : ''}
17
- ${lang ? `<span class="ui-code-window-lang">${lang}</span>` : ''}
18
- </div>
19
- <pre class="ui-code-window-pre"><code class="ui-code-window-code">${content}</code></pre>
20
- </div>
21
- `
22
-
23
- const { version } = pkg
24
-
25
- const exampleSpec = highlight(`export default {
26
- route: '/dashboard',
27
- meta: {
28
- title: 'Dashboard — My App',
29
- styles: ['/app.css'],
30
- },
31
- server: {
32
- data: async (ctx) => {
33
- const user = await db.users.find(ctx.cookies.userId)
34
- return { user, stats: await db.stats.forUser(user.id) }
35
- },
36
- },
37
- state: { filter: 'all' },
38
- mutations: {
39
- setFilter: (state, event) => ({ filter: event.target.value }),
40
- },
41
- view: (state, server) => \`
42
- <main id="main-content">
43
- <h1>Hello, \${server.data.user.name}</h1>
44
- <select data-event="change:setFilter">
45
- <option value="all">All time</option>
46
- <option value="week">This week</option>
47
- </select>
48
- <p>\${server.data.stats[state.filter].total} requests</p>
49
- </main>
50
- \`,
51
- }`, 'js')
52
-
53
- export default {
54
- route: '/',
55
- meta: {
56
- title: 'Pulse — The spec-first web framework',
57
- description: 'Pulse is a server-first Node.js framework with zero runtime dependencies. One spec object per page: server data, state, mutations, and view in plain JS. Streaming SSR, security headers, and production caching are enforced by the architecture.',
58
- theme: 'light',
59
- styles: ['/pulse-ui.css', '/theme.css', '/docs.css', '/home-brut.css'],
60
- // Loaded via JS after initial parse — non-render-blocking. The preconnect
61
- // hints below still warm the connection up early, and display=swap in the
62
- // URL means the browser paints with a fallback font immediately and swaps
63
- // to Inter once it arrives, so there's no invisible-text window either way.
64
- deferredStyles: ['https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800;900&display=swap'],
65
- schema: {
66
- '@context': 'https://schema.org',
67
- '@type': 'SoftwareApplication',
68
- name: 'Pulse',
69
- applicationCategory: 'DeveloperApplication',
70
- operatingSystem: 'Node.js ≥ 22',
71
- offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },
72
- license: 'https://opensource.org/licenses/MIT',
73
- description: 'Spec-first Node.js web framework. Zero runtime dependencies. Streaming SSR, built-in security headers, and production caching enforced by the architecture.',
74
- url: 'https://pulse.invisibleloop.com',
75
- codeRepository: 'https://github.com/invisibleloop/pulse-framework',
76
- },
77
- },
78
- state: {},
79
- server: {
80
- metrics: () => metricsStore.current,
81
- },
82
- view: (state, server) => `
83
- <div class="brut">
84
-
85
- <nav class="brut-nav" aria-label="Site navigation">
86
- <a href="/" class="brut-nav-logo" aria-label="Pulse home">
87
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
88
- <path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linejoin="round"/>
89
- </svg>
90
- <span>PULSE</span>
91
- </a>
92
- <div class="brut-nav-links">
93
- <a href="/getting-started">Docs</a>
94
- <a href="https://github.com/invisibleloop/pulse-framework" target="_blank" rel="noopener" aria-label="GitHub (opens in new tab)">GitHub</a>
95
- <a href="/getting-started" class="brut-nav-cta">Get Started</a>
96
- </div>
97
- </nav>
98
-
99
- <main id="main-content">
100
-
101
- <section class="brut-hero">
102
- <div class="brut-hero-tag">v${version} — EARLY ACCESS</div>
103
- <h1 class="brut-hero-h1">
104
- <span class="brut-hero-kicker">with Pulse</span>
105
- <span class="brut-hero-line1">The spec is</span>
106
- <span class="brut-hero-line2">the <span class="brut-hero-mark">page.</span></span>
107
- </h1>
108
- <div class="brut-hero-aside">
109
- <p class="brut-hero-tag-inline">ONE SPEC. ONE WAY TO BUILD.</p>
110
- <p class="brut-hero-desc">One plain JS object — server data, state, mutations, and view. No split files, no hidden conventions.</p>
111
- <p class="brut-hero-sub"><strong>So constrained that doing it wrong isn't an option.<br>Whether you write it or an AI&nbsp;does.</strong></p>
112
- <div class="brut-hero-ctas">
113
- <a href="/getting-started" class="brut-btn-primary">Get Started</a>
114
- <a href="/spec" class="brut-btn-ghost">Read the Spec</a>
115
- </div>
116
- </div>
117
- </section>
118
-
119
- <div class="brut-stats-bar">
120
- <div class="brut-stat">
121
- <span class="brut-stat-val">4 kB</span>
122
- <span class="brut-stat-lbl">Runtime JS · first visit</span>
123
- </div>
124
- <div class="brut-stat">
125
- <span class="brut-stat-val">0.00</span>
126
- <span class="brut-stat-lbl">Cumulative Layout Shift</span>
127
- </div>
128
- <div class="brut-stat">
129
- <span class="brut-stat-val">100</span>
130
- <span class="brut-stat-lbl">Lighthouse · by design</span>
131
- </div>
132
- <div class="brut-stat">
133
- <span class="brut-stat-val">0</span>
134
- <span class="brut-stat-lbl">Runtime dependencies</span>
135
- </div>
136
- </div>
137
-
138
- <section class="brut-idea">
139
- <div class="brut-idea-label">THE IDEA</div>
140
- <div class="brut-idea-grid">
141
- <div class="brut-idea-step">
142
- <div class="brut-idea-num" aria-hidden="true">01</div>
143
- <h2>The spec is the page</h2>
144
- <p>Everything a page needs lives in one plain JS object: server data, client state, mutations, and view. One format. No split files. No hidden conventions.</p>
145
- </div>
146
- <div class="brut-idea-step">
147
- <div class="brut-idea-num" aria-hidden="true">02</div>
148
- <h2>The schema is the contract</h2>
149
- <p>Every spec is validated at startup. Either it's correct or it's rejected. No ambiguity, no misconfiguration that surfaces later in production.</p>
150
- </div>
151
- <div class="brut-idea-step">
152
- <div class="brut-idea-num" aria-hidden="true">03</div>
153
- <h2>The framework is the guarantee</h2>
154
- <p>Streaming SSR, security headers, and production caching come from the architecture. You write the product logic. The framework ships the quality.</p>
155
- </div>
156
- </div>
157
- </section>
158
-
159
- <section class="brut-code-section">
160
- <div class="brut-code-header">
161
- <h2>Everything a page needs.<br>Nothing it doesn't.</h2>
162
- <p>Server fetchers, client state, mutations, and view. All co-located in one object. The spec <em>is</em> the page.</p>
163
- </div>
164
- <div class="brut-code-block">
165
- ${codeWindow({ content: exampleSpec, filename: 'src/pages/dashboard.js', lang: 'JavaScript' })}
166
- </div>
167
- </section>
168
-
169
- <section class="brut-constraint">
170
- <div class="brut-constraint-inner">
171
- <div class="brut-constraint-label">AI + PULSE</div>
172
- <h2 class="brut-constraint-h2">Constrained enough<br>to be trusted.<br>Free enough<br>to be creative.</h2>
173
- <p class="brut-constraint-lead">The spec format tells an agent exactly how to wire up data, state, and behaviour. What it doesn't do is dictate the design. Layout, typography, CSS — those are still real decisions. The agent makes them. Pulse just makes sure the page it builds actually works.</p>
174
- <div class="brut-constraint-cols">
175
- <div class="brut-col">
176
- <div class="brut-col-head">The structure is fixed</div>
177
- <ul class="brut-col-list">
178
- <li>One spec format. No ambiguity about how a page should be built</li>
179
- <li>Schema validation at startup. Bad output is rejected before it ships</li>
180
- <li>Security, SSR, and caching are part of the architecture. Not optional</li>
181
- <li>Consistent, reviewable output across every agent and every session</li>
182
- </ul>
183
- </div>
184
- <div class="brut-col brut-col--hi">
185
- <div class="brut-col-head brut-col-head--hi">The design is not</div>
186
- <ul class="brut-col-list">
187
- <li>The view is a plain JS function. The agent writes whatever HTML it wants</li>
188
- <li>CSS, layout, and typography are entirely up to the agent</li>
189
- <li>A component library is there when needed. Custom HTML when it isn't</li>
190
- <li>The result looks considered because the agent had room to make it so</li>
191
- </ul>
192
- </div>
193
- </div>
194
- </div>
195
- </section>
196
-
197
- <section class="brut-versus">
198
- <div class="brut-versus-header">
199
- <div class="brut-versus-label">HOW PULSE COMPARES</div>
200
- <h2 class="brut-versus-h2">Constraints enforced.<br>Not recommended.</h2>
201
- </div>
202
- <div class="versus-table-wrap table-sticky-col">
203
- <table class="brut-table">
204
- <thead>
205
- <tr>
206
- <th></th>
207
- <th class="brut-th-pulse">
208
- <svg width="12" height="12" viewBox="0 0 24 24" fill="none" aria-hidden="true" style="vertical-align:middle;margin-right:.3rem">
209
- <path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linejoin="round"/>
210
- </svg>PULSE
211
- </th>
212
- <th>Next.js / Remix</th>
213
- <th>SvelteKit</th>
214
- </tr>
215
- </thead>
216
- <tbody>
217
- <tr>
218
- <th scope="row">Ways to write a page</th>
219
- <td class="v-yes">One: the spec schema</td>
220
- <td class="v-no">App Router, Pages Router, RSC, client components, loaders…</td>
221
- <td class="v-no">+page.svelte, +page.server.js, load(), form actions…</td>
222
- </tr>
223
- <tr>
224
- <th scope="row">Agent-readable structure</th>
225
- <td class="v-yes">One JS object per page</td>
226
- <td class="v-no">Files, folders, magic exports spread across dirs</td>
227
- <td class="v-no">Files, folders, Svelte syntax</td>
228
- </tr>
229
- <tr>
230
- <th scope="row">SSR out of the box</th>
231
- <td class="v-yes">Streaming SSR, zero config</td>
232
- <td class="v-partial">Yes, but client hydration adds JS on every page</td>
233
- <td class="v-partial">Yes, but requires an adapter and client runtime on every page</td>
234
- </tr>
235
- <tr>
236
- <th scope="row">Client JS shipped</th>
237
- <td class="v-yes">~4 kB brotli on first visit; 0 kB on static pages</td>
238
- <td class="v-no">50–200 kB+ depending on features used</td>
239
- <td class="v-partial">~15 kB brotli</td>
240
- </tr>
241
- <tr>
242
- <th scope="row">Security headers</th>
243
- <td class="v-yes">On every response, built in</td>
244
- <td class="v-no">Manual middleware or plugin</td>
245
- <td class="v-no">Manual hooks setup</td>
246
- </tr>
247
- <tr>
248
- <th scope="row">Runtime dependencies</th>
249
- <td class="v-yes">Zero. Pure Node.js HTTP</td>
250
- <td class="v-no">React, 50+ transitive packages</td>
251
- <td class="v-no">Svelte runtime + adapters</td>
252
- </tr>
253
- <tr>
254
- <th scope="row">Production build step</th>
255
- <td class="v-yes">Server needs none. <code>node server.js</code> is production</td>
256
- <td class="v-no">Required: <code>next build</code></td>
257
- <td class="v-no">Required: <code>vite build</code></td>
258
- </tr>
259
- </tbody>
260
- </table>
261
- </div>
262
- </section>
263
-
264
- <section class="brut-pillars">
265
- <div class="brut-pillar">
266
- <div class="brut-pillar-icon">${iconZap({ size: 36 })}</div>
267
- <div class="brut-pillar-body">
268
- <h3>Performance by design</h3>
269
- <p>The shell streams to the browser instantly. Deferred segments arrive as data resolves. ~4 kB of JS on first visit. Zero CLS. Immutable bundle caching on deploy. Not configured. Structural.</p>
270
- </div>
271
- </div>
272
- <div class="brut-pillar brut-pillar--alt">
273
- <div class="brut-pillar-icon">${iconShield({ size: 36 })}</div>
274
- <div class="brut-pillar-body">
275
- <h3>Safe by design</h3>
276
- <p>Security headers on every response, including 404 and 500. Declarative constraints enforce state bounds after every mutation. Guard runs before any server fetcher. Not a plugin. Part of the pipeline.</p>
277
- </div>
278
- </div>
279
- <div class="brut-pillar">
280
- <div class="brut-pillar-icon">${iconSettings({ size: 36 })}</div>
281
- <div class="brut-pillar-body">
282
- <h3>Nothing to configure</h3>
283
- <p>No bundler config. No runtime dependencies to install, audit, or upgrade. <code>node server.js</code> is production. No breaking upgrades. Page files have no framework imports to version.</p>
284
- </div>
285
- </div>
286
- </section>
287
-
288
- ${server.metrics ? `<section class="brut-metrics">
289
- <div class="brut-metrics-label">BY THE NUMBERS</div>
290
- <h2 class="brut-metrics-h2">Performance you can measure.</h2>
291
- <p class="brut-metrics-sub">Report generated ${server.metrics.generatedAt} · measured from a real Pulse build</p>
292
- <div class="brut-metrics-grid">
293
- <div class="brut-metrics-group">
294
- <div class="brut-metrics-group-label">Lighthouse</div>
295
- ${server.metrics.lighthouse.map(m => `
296
- <div class="brut-metric">
297
- <span class="brut-metric-val brut-metric-val--hi">${m.value}</span>
298
- <span class="brut-metric-lbl">${m.label}</span>
299
- </div>`).join('')}
300
- </div>
301
- <div class="brut-metrics-group">
302
- <div class="brut-metrics-group-label">Bundle sizes</div>
303
- ${server.metrics.bundles.map(m => `
304
- <div class="brut-metric">
305
- <span class="brut-metric-val">${m.value}</span>
306
- <span class="brut-metric-lbl">${m.label}</span>
307
- </div>`).join('')}
308
- </div>
309
- <div class="brut-metrics-group">
310
- <div class="brut-metrics-group-label">Web Vitals</div>
311
- ${server.metrics.vitals.map(m => `
312
- <div class="brut-metric">
313
- <span class="brut-metric-val brut-metric-val--hi">${m.value}</span>
314
- <span class="brut-metric-lbl">${m.label}</span>
315
- </div>`).join('')}
316
- </div>
317
- <div class="brut-metrics-group">
318
- <div class="brut-metrics-group-label">Architecture</div>
319
- ${server.metrics.architecture.map(m => `
320
- <div class="brut-metric">
321
- <span class="brut-metric-val brut-metric-val--accent">${m.value}</span>
322
- <span class="brut-metric-lbl">${m.label}</span>
323
- </div>`).join('')}
324
- </div>
325
- </div>
326
- </section>` : ''}
327
-
328
- <section class="brut-cta">
329
- <h2 class="brut-cta-h2">Your first page<br>in under<br>2 minutes.</h2>
330
- <p class="brut-cta-lead">One spec object. Server data, client state, mutations, and view. In one place. Streaming SSR, security headers, and 100 Lighthouse scores come with it. Nothing to configure.</p>
331
- <p class="brut-cta-note">Pulse is in early access. The goal is not to compete on features. It is to eliminate the class of problems that come from having too many of them.</p>
332
- <div class="brut-cta-actions">
333
- <a href="/getting-started" class="brut-btn-primary brut-btn-primary--inv">Get Started</a>
334
- <a href="/spec" class="brut-btn-ghost brut-btn-ghost--light">Read the Spec</a>
335
- </div>
336
- </section>
337
-
338
- </main>
339
-
340
- <footer class="brut-footer">
341
- <span>MIT License</span>
342
- <span class="brut-footer-sep">·</span>
343
- <a href="https://github.com/invisibleloop/pulse-framework" target="_blank" rel="noopener" aria-label="GitHub (opens in new tab)">GitHub</a>
344
- <span class="brut-footer-sep">·</span>
345
- <a href="/getting-started">Get started in 2 minutes</a>
346
- </footer>
347
-
348
- </div>
349
- `,
350
- }
@@ -1,244 +0,0 @@
1
- import { renderLayout, h1, lead, section, callout } from '../lib/layout.js'
2
- import { prevNext } from '../lib/nav.js'
3
- import { card } from '../../../src/ui/index.js'
4
-
5
- const { prev, next } = prevNext('/how-it-works')
6
-
7
- // Numbered vertical flow diagram — raw HTML (creative override), replacing
8
- // the removed timeline()/timelineItem() components. Styled via .hiw-flow*
9
- // classes in docs.css.
10
- const flowStep = ({ dot, label, content }) => `
11
- <li class="hiw-flow-item">
12
- <div class="hiw-flow-side">
13
- <div class="hiw-flow-connector hiw-flow-connector--before"></div>
14
- <div class="hiw-flow-dot" aria-hidden="true">${dot}</div>
15
- <div class="hiw-flow-connector hiw-flow-connector--after"></div>
16
- </div>
17
- <div class="hiw-flow-main">
18
- <span class="hiw-flow-label">${label}</span>
19
- <div class="hiw-flow-body">${content}</div>
20
- </div>
21
- </li>
22
- `
23
-
24
- const agentFlow = `<ol class="hiw-flow">${[
25
- {
26
- dot: '1',
27
- label: 'Understand',
28
- content: card({ content: `<strong style="color:var(--ui-text)">Read the guide and inspect the project</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The agent fetches <code>pulse://workflow</code> and the relevant <code>pulse://guide/*</code> sections, then calls <code>pulse_list_structure</code> to see every existing page, component, and store. Ambiguities are surfaced before any files are touched.</p>` }),
29
- },
30
- {
31
- dot: '2',
32
- label: 'Plan',
33
- content: card({ content: `<strong style="color:var(--ui-text)">Present a plan — wait for confirmation</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Before writing anything the agent describes what it intends to build: the route, state shape, server data, interactions, and any components or integrations it will use. The task does not proceed until you confirm.</p>` }),
34
- },
35
- {
36
- dot: '3',
37
- label: 'Build',
38
- content: card({ content: `<strong style="color:var(--ui-text)">Write the spec and any supporting files</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The spec is written as a plain JS object: route, state, server data, mutations, actions, view. The guide constrains every decision — where state lives, how validation is wired, how the view is structured.</p>` }),
39
- },
40
- {
41
- dot: '4',
42
- label: 'Validate',
43
- content: card({ content: `<strong style="color:var(--ui-text)">Call <code>pulse_validate</code> — fix all errors and warnings</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The spec is checked against the Pulse schema. Every error and warning is resolved before moving on — missing hydrate, heading order violations, missing escaping, structural mistakes. A clean output is the gate to the next phase.</p>` }),
44
- },
45
- {
46
- dot: '5',
47
- label: 'Browser',
48
- content: card({ content: `<strong style="color:var(--ui-text)">Screenshot + Lighthouse — desktop and mobile</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The agent navigates to the route, takes a screenshot to confirm the rendered output, then runs Lighthouse on both desktop and mobile. Accessibility, Best Practices, and SEO must all be 100. Any failure is fixed and re-verified before continuing.</p>` }),
49
- },
50
- {
51
- dot: '6',
52
- label: 'Tests',
53
- content: card({ content: `<strong style="color:var(--ui-text)">Write tests, run them, fix failures</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Unit tests cover any pure logic extracted from the spec. View tests use <code>renderSync</code> / <code>render</code> to assert HTML output. All tests must pass. When fixing a bug, a failing test is written first to pin the behaviour.</p>` }),
54
- },
55
- {
56
- dot: '7',
57
- label: 'Review',
58
- content: card({ content: `<strong style="color:var(--ui-text)">Call <code>pulse_review</code> — only after phases 4–6 all pass</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">The agent switches into reviewer mode — reading the source and rendered output against the full spec checklist. Accessibility, empty states, error handling, component usage, and security are all checked. The review agent is always last.</p>` }),
59
- },
60
- {
61
- dot: '8',
62
- label: 'Fix and re-verify',
63
- content: card({ content: `<strong style="color:var(--ui-text)">Fix every review issue — re-run affected gates</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Every issue raised in review is resolved. Validate, Lighthouse, and tests are re-run to confirm all gates still pass. The task is complete only when every phase clears cleanly.</p>` }),
64
- },
65
- {
66
- dot: '✓',
67
- label: 'Done',
68
- content: card({ content: `<strong style="color:var(--ui-text)">The spec is the source of truth</strong><p style="color:var(--ui-muted);margin:.25rem 0 0">Validate clean. Lighthouse 100. Tests passing. Review clear. When all four gates pass, the page is done.</p>` }),
69
- },
70
- ].map(flowStep).join('')}</ol>`
71
-
72
- export default {
73
- route: '/how-it-works',
74
- meta: {
75
- theme: 'light',
76
- title: 'How It Works — Pulse Docs',
77
- description: 'How the Pulse MCP server gives an AI agent the knowledge and tools to build Pulse apps correctly.',
78
- styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
79
- },
80
- view: () => renderLayout({
81
- currentHref: '/how-it-works',
82
- prev,
83
- next,
84
- content: `
85
- ${h1('How It Works')}
86
- ${lead('When you run <code>pulse</code> in a project directory, a Model Context Protocol (MCP) server starts alongside the dev server. That MCP server is what gives your AI agent the knowledge, tools, and guardrails to build Pulse pages correctly — without you having to explain the framework in every prompt.')}
87
-
88
- ${section('mcp', 'The Pulse MCP server')}
89
- <p>MCP is a standard protocol that connects AI agents to external tools and knowledge. When Claude (or any MCP-compatible agent) opens a Pulse project, the MCP server is automatically detected and two things happen:</p>
90
- <ul>
91
- <li>The agent gains access to <strong>resources</strong> — read-only documents it can fetch at any time</li>
92
- <li>The agent gains access to <strong>tools</strong> — functions it can call to inspect and modify the project</li>
93
- </ul>
94
- <p>Together these replace the need to paste documentation into a system prompt or rely on the agent's training data to know how Pulse works.</p>
95
-
96
- ${section('resources', 'Resources: what the agent knows')}
97
- <p>The MCP server exposes read-only documents the agent fetches at any time. There are two top-level resources and a set of focused guide sections:</p>
98
-
99
- <dl class="definition-list">
100
- <dt><code>pulse://quickstart</code></dt>
101
- <dd>Workflow phases, spec skeleton, component rules, and theming essentials combined into a single fetch. Used for targeted edits, bug fixes, or simple one-shot page builds — avoids loading the full guide for small tasks.</dd>
102
-
103
- <dt><code>pulse://workflow</code></dt>
104
- <dd>The full build workflow — every phase, pass gate, and ordering rule. The agent reads this before starting any new page or project.</dd>
105
-
106
- <dt><code>pulse://persona</code></dt>
107
- <dd>The quality bar the agent holds itself to: always write correct SSR, always handle errors, never skip empty states, never hardcode colours, never use <code>data-event</code> on text inputs. The persona defines what "done" means.</dd>
108
- </dl>
109
-
110
- <p>The guide is split into topic sections the agent fetches as needed:</p>
111
- <dl class="definition-list">
112
- <dt><code>pulse://guide/spec</code></dt>
113
- <dd>Spec format — state, mutations, actions, streaming SSR, validation, key rules, and form layout.</dd>
114
-
115
- <dt><code>pulse://guide/server</code></dt>
116
- <dd>Server data fetchers, global store, persist, cookies, redirects, and POST handling.</dd>
117
-
118
- <dt><code>pulse://guide/styles</code></dt>
119
- <dd>CSS tokens, theming, custom fonts, and utility classes.</dd>
120
-
121
- <dt><code>pulse://guide/routing</code></dt>
122
- <dd>Client-side navigation, page discovery, and dynamic routes.</dd>
123
-
124
- <dt><code>pulse://guide/components</code></dt>
125
- <dd>All UI components and their props, icons, charts, and composition patterns.</dd>
126
-
127
- <dt><code>pulse://guide/examples</code></dt>
128
- <dd>Complete working page examples covering common patterns.</dd>
129
-
130
- <dt><code>pulse://guide/templates</code></dt>
131
- <dd>Pre-built landing page templates, adaptation rules, and theme CSS patterns. Fetched when building a new branded site or landing page.</dd>
132
-
133
- <dt><code>pulse://guide/design-references</code></dt>
134
- <dd>Twelve design directions with vibes, component combinations, palette patterns, and signature moves. Fetched during intake to pick the right aesthetic rather than defaulting to a generic SaaS look.</dd>
135
-
136
- <dt><code>pulse://guide/design-gallery</code></dt>
137
- <dd>All templates with visual descriptions and key components. Includes critical prop-name references and component recipes for cards, stat strips, and forms. Fetched when adapting a template or combining components.</dd>
138
-
139
- <dt><code>pulse://guide/explore</code></dt>
140
- <dd>Zone-based layout thinking, seven structural gestures, raw HTML patterns without components, and an anti-pattern checklist. Fetched when a distinctive or unusual layout is needed.</dd>
141
- </dl>
142
-
143
- ${callout('note', 'The guide is authoritative. When there is a question about how something should be structured — where state lives, how validation is wired, how streaming works — the guide answers it. The agent does not guess.')}
144
-
145
- ${section('tools', 'Tools: what the agent can do')}
146
- <p>The MCP server provides tools across five categories:</p>
147
-
148
- <h3 class="doc-h3">Design &amp; intake</h3>
149
- <dl class="definition-list">
150
- <dt><code>pulse_extract_inspiration</code></dt>
151
- <dd>Extracts a structured design brief from a URL or image shared as inspiration. Called before <code>pulse_intake</code> when the user says "I like the look of X" — it tells the agent exactly what to observe and capture.</dd>
152
-
153
- <dt><code>pulse_intake</code></dt>
154
- <dd>Captures the product name, pitch, features, palette, vibe, and anti-style before scaffolding any new page or branded template. Returns a structured brief with copy-ready content, early contrast warnings, and component suggestions. Always runs before <code>pulse_sketch</code>.</dd>
155
-
156
- <dt><code>pulse_sketch</code></dt>
157
- <dd>Generates three structurally distinct layout directions (full-bleed, asymmetric split, editorial flow, etc.) before any code is written. Called after <code>pulse_intake</code> — prevents every project from defaulting to the same centred-hero layout.</dd>
158
-
159
- <dt><code>pulse_intent</code></dt>
160
- <dd>Intent engine — describe what you want to build and get back a matched archetype, recommended components, a ready-to-adapt spec scaffold, and which guide sections to read first. An alternative entry point to <code>pulse://workflow</code> for targeted tasks.</dd>
161
-
162
- <dt><code>pulse_design_review</code></dt>
163
- <dd>Reviews the built page's visual design against the original product brief from <code>pulse_intake</code>. Checks whether the design looks and feels appropriate for the product, audience, and vibe. Runs after screenshot, before Lighthouse.</dd>
164
-
165
- <dt><code>pulse_layout_review</code></dt>
166
- <dd>Multi-viewport layout review — checks for overflow, collapsed sections, and broken images at different screen widths. Runs after design approval but before Lighthouse, catching layout issues that Lighthouse doesn't flag.</dd>
167
-
168
- <dt><code>pulse_tokens</code></dt>
169
- <dd>Lists all available <code>--ui-*</code> CSS custom property tokens from the installed <code>pulse-ui.css</code>. Used before writing theme overrides to avoid guessing token names.</dd>
170
-
171
- <dt><code>pulse_check_contrast</code></dt>
172
- <dd>Static WCAG contrast checker. Extracts colour variable definitions from a theme file and checks common foreground/background pairings for WCAG AA compliance. Run immediately after writing a theme file to catch palette mistakes before Lighthouse.</dd>
173
- </dl>
174
-
175
- <h3 class="doc-h3">Scaffolding</h3>
176
- <dl class="definition-list">
177
- <dt><code>pulse_create_page</code></dt>
178
- <dd>Creates a new page spec file from a correct template. The filename determines the route — <code>about.js</code> becomes <code>/about</code>, <code>posts/[slug].js</code> becomes <code>/posts/:slug</code>. The file is written to <code>src/pages/</code> and picked up by the server automatically.</dd>
179
-
180
- <dt><code>pulse_create_component</code></dt>
181
- <dd>Creates a reusable view component in <code>src/components/</code>. Components export named functions that return HTML strings — no classes, no JSX, no lifecycle hooks.</dd>
182
-
183
- <dt><code>pulse_create_store</code></dt>
184
- <dd>Creates a global store module in <code>src/store/</code>. Stores hold shared state (cart, user session, theme) that multiple pages can subscribe to and mutate.</dd>
185
-
186
- <dt><code>pulse_create_action</code></dt>
187
- <dd>Scaffolds a reusable server action — useful for shared form submission logic, API calls, or mutations that appear on more than one page.</dd>
188
- </dl>
189
-
190
- <h3 class="doc-h3">Inspection</h3>
191
- <dl class="definition-list">
192
- <dt><code>pulse_status</code></dt>
193
- <dd>Project health snapshot — pages, routes, server status, last build. Called at the start of a session to orient quickly without reading files individually.</dd>
194
-
195
- <dt><code>pulse_list_structure</code></dt>
196
- <dd>Lists every page, component, and store that already exists in the project. The agent calls this before creating anything — to avoid duplication and to understand what the codebase already provides.</dd>
197
-
198
- <dt><code>pulse_fetch_page</code></dt>
199
- <dd>Reads the full source of an existing spec file. Used when the agent needs to understand an existing page before editing it, or when a review of the current state is needed.</dd>
200
-
201
- <dt><code>pulse_list_icons</code></dt>
202
- <dd>Lists all available Pulse UI icon names, grouped by category. Called before importing icons — the agent never guesses a name.</dd>
203
- </dl>
204
-
205
- <h3 class="doc-h3">Validation &amp; review</h3>
206
- <dl class="definition-list">
207
- <dt><code>pulse_validate</code></dt>
208
- <dd>Validates a spec against the Pulse schema. Returns errors (which block progress) and warnings (which must also be resolved). The agent calls this after writing or editing every spec file.</dd>
209
-
210
- <dt><code>pulse_suggest</code></dt>
211
- <dd>Draft-mode feedback — paste a partial or complete spec and get constructive suggestions before running the hard validator. Unlike <code>pulse_validate</code>, it is collaborative rather than a gate: it notices patterns, spots likely omissions, and offers ideas. Used mid-build for a second opinion.</dd>
212
-
213
- <dt><code>pulse_review</code></dt>
214
- <dd>Switches the agent into reviewer mode. Returns the spec source, the rendered HTML output, and a structured checklist covering accessibility, empty states, error handling, component usage, security, and correctness. The agent reads its own output critically and fixes every issue before continuing.</dd>
215
-
216
- <dt><code>pulse_run_tests</code></dt>
217
- <dd>Runs the project test suite (<code>npm test</code>) and returns the full output. Called after writing or editing specs to verify nothing is broken.</dd>
218
- </dl>
219
-
220
- <h3 class="doc-h3">Server &amp; maintenance</h3>
221
- <dl class="definition-list">
222
- <dt><code>pulse_restart_server</code></dt>
223
- <dd>Restarts the Pulse dev server. Called after structural changes — adding a new page, modifying the server entry — to reload all specs and re-register routes.</dd>
224
-
225
- <dt><code>pulse_build</code></dt>
226
- <dd>Builds the project for production. Bundles specs, hashes assets, and writes the manifest. Called when the agent needs to verify the production build or prepare a release.</dd>
227
-
228
- <dt><code>pulse_check_version</code></dt>
229
- <dd>Reports the installed Pulse version and whether an update is available.</dd>
230
-
231
- <dt><code>pulse_update</code></dt>
232
- <dd>Updates the Pulse package to the latest version and copies the latest UI assets and agent files into the project.</dd>
233
- </dl>
234
-
235
- ${section('flow', 'What happens when you ask for something')}
236
-
237
- ${agentFlow}
238
-
239
- ${section('why-mcp', 'Why MCP instead of a system prompt')}
240
- <p>A system prompt is static — it cannot see your project, cannot validate your code, and cannot guarantee the agent uses the right version of the framework. The MCP server is dynamic: it reads the guide from the installed version of Pulse, inspects the actual files in your project, and calls real validation on the spec the agent just wrote.</p>
241
- <p>The result is that the agent builds correctly on the first attempt far more often — not because it is smarter, but because the feedback loop is tighter and the knowledge is always current.</p>
242
- `,
243
- }),
244
- }