Skip to content

Commit 8129596

Browse files
authored
feat(website): add narrative sections, pilot-to-prod page, and rebrand integration (#29)
* fix(website): add track shake animation to ProblemSection stall phase * fix(website): ProblemSection quality fixes — timer cleanup, unique SVG ID, aria-hidden, correct import - Store setTimeout IDs and clear them on unmount (prevents state updates on unmounted component) - Use useId() to generate unique hatchId per instance (prevents SVG pattern id collision) - Add role=progressbar + aria-valuenow to track container for screen readers - Add aria-hidden=true to decorative animated elements (pins, labels, badge, counter) - Fix import: use local lib/design-tokens instead of unresolved @cacheplane/design-tokens - Add invariant comment for done-timeout vs counter-duration coupling * feat: add FullStackSection with animated stack diagram and roadmap strip * feat: add ChatFeaturesSection with 4 interactive chat scenarios * feat: add FairComparisonSection comparison table * feat: wire ProblemSection, FullStackSection, ChatFeaturesSection, FairComparisonSection into landing page - Insert ProblemSection + FullStackSection + ChatFeaturesSection after StatsStrip - Insert FairComparisonSection after DeepAgentsShowcase - Add two ambient gradient blobs for extended page height - Task 5 (FeatureStrip copy): no-op — the problematic 'no established pattern' copy was not present in this branch * chore: add puppeteer devDependency and generate-whitepaper script * feat: add whitepaper signup API route with NDJSON persistence * feat: add whitepaper generation script * feat: add WhitePaperSection with free download and optional lead-gen form * feat: add WhitePaperSection to landing page; remove useStream parity copy from FeatureStrip * fix(whitepaper): add JetBrains Mono to Google Fonts URL and regenerate preview Fixes missing code font in whitepaper output. Regenerates whitepaper-preview.html with correct 'EB Garamond' and 'JetBrains Mono' font references throughout. * feat: add PilotHero component and /pilot-to-prod page skeleton * fix: PilotHero responsive padding, eyebrow style conflict, page metadata * feat: add WhatIsIncluded 3-column component for pilot-to-prod page * feat: add HowItWorks 3-phase timeline for pilot-to-prod page * feat: add PricingSignal pricing callout for pilot-to-prod page * feat: add WhitePaperGate 5-field lead gen form for pilot-to-prod page * fix: change role=alert to role=status to match aria-live=polite in WhitePaperGate * feat: add PilotFooterCTA and wire complete pilot-to-prod page * fix: use tokens.colors.accent in PilotFooterCTA, add aria-hidden to page blobs * feat: add Pilot to Prod nav link and restructure homepage (remove FeatureStrip/CockpitCTA/CodeBlock, add PilotProgram CTA) * fix: correct design-tokens import path in pilot-to-prod page (3 levels up) * fix: apply full review findings — messaging, mobile, UX, and RiskRemoval section - Remove useStream() parity messaging from HeroTwoCol, WhatIsIncluded, StatsStrip - Fix PricingSignal: remove ambiguous '/year', clarify as fixed fee + pilot included - Add PricingSignal mobile padding reduction via media query - Fix ProblemSection stat grid to collapse on mobile (auto-fit minmax) - Add RiskRemoval section to pilot-to-prod page (between PricingSignal and WhitePaperGate) - Fix Nav Examples link: external=true, target=_blank, rel=noopener noreferrer - Fix WhitePaperGate: role field sent in message body, not merged into company string - Fix PilotFooterCTA: replace broken whileHover borderColor with CSS class hover - Fix PilotHero: remove opacity from initial animations (prevents blank hero flash) - Increase PilotHero CTA padding to meet 44px touch target * fix: remove remaining useStream parity messaging from layout, Footer, and ValueProps * fix: second review pass — docs messaging, title, broken link, a11y labels - introduction.mdx: remove parity/useStream opening line, use Signal-native positioning - AGENTS.md.template + CLAUDE.md.template: update tagline to Signal-native - layout.tsx: update <title> from LangChain to LangGraph - Footer.tsx: fix /api-reference → /docs/api/stream-resource (was 404) - PilotHero.tsx: add aria-hidden to decorative gradient blobs - WhitePaperSection.tsx: add sr-only labels + aria-label to name/email inputs - LeadForm.tsx (pricing): add sr-only labels + aria-label to all four form inputs * feat: add whitepaper.pdf to public directory Generated from whitepaper-preview.html via Puppeteer. All 6 chapters present (Streaming State Management, Thread Persistence, Tool-Call Rendering, Human Approval Flows, Generative UI, Deterministic Testing). Fixes dead 'Download the Guide' CTAs on pilot-to-prod and homepage. * feat: citation badges on stats, pricing reframe to app deployment license Citation badges: - New CitationBadge component — click-to-open popover with source, stat, note, and link - 66% stat → Stack Overflow Developer Survey 2025 - 31% stat → ISG AI Adoption Reports - 75% stat → Stack Overflow Developer Survey 2025 - Keyboard (Escape) and outside-click dismissal, ARIA dialog role Pricing reframe (app deployment license): - Remove ALL refund/money-back/guarantee language site-wide - PilotHero: trust line → "App deployment license · $20,000 · 3-month co-pilot engagement" - PilotHero: subheadline removes "guaranteed outcome" - WhatIsIncluded: card 3 renamed from "Production Guarantee" → "App Deployment License" - HowItWorks: phase 3 removes "full refund" language, deliverable → "Production deployment" - PricingSignal: subtitle + features list updated to license/co-pilot framing - RiskRemoval: section reframed from guarantee → "What's included in the license" Replaces money-back card with "We work alongside your team" card - PilotFooterCTA: fine print updated - pilot-to-prod/page.tsx: meta description updated * feat: subtler citation badge + citations on all 77% claims CitationBadge: - Reduced to 13px, transparent background, faint border (rgba 0.2) - Text color rgba(0,64,144,0.35) at rest — nearly invisible until hovered - No fill on idle state, border-only approach New citation placements: - PilotHero subheadline: 77% → McKinsey State of AI 2024 - PilotFooterCTA body copy: 77% → McKinsey State of AI 2024 - HomePilotCTA (new component): extracts inline pilot CTA from page.tsx so it can be a client component with CitationBadge on the 77% claim - page.tsx: replaces inline section with <HomePilotCTA /> * docs: add FullStackSection redesign spec (EM/CTO layer narrative + Gen UI bug fix) * feat(website): redesign FullStackSection for EM/CTO audience * docs: apply Angular Stream Resource rebrand to narrative components * chore: sync package-lock.json after merge * fix(website): update e2e test for new landing page structure
1 parent e4c0589 commit 8129596

36 files changed

Lines changed: 3979 additions & 111 deletions

.gitignore

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,5 @@ apps/website/public/demo/
2828
out
2929
.vercel
3030

31-
# LangGraph
32-
.langgraph_api/
33-
langgraph-combined.json
34-
35-
# Playwright
36-
test-results/
37-
38-
# Deploy output
39-
deploy/
31+
# Whitepaper signup data
32+
apps/website/data/

apps/website/content/AGENTS.md.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# stream-resource v@VERSION@
22

3-
Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — full parity with React's `useStream()`.
3+
Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — Signal-native streaming for Angular agents, built for LangGraph.
44

55
## Install
66
npm install stream-resource

apps/website/content/CLAUDE.md.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# stream-resource v@VERSION@
22

3-
Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — full parity with React's `useStream()`.
3+
Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — Signal-native streaming for Angular agents, built for LangGraph.
44

55
## Install
66
npm install stream-resource

apps/website/content/docs-v2/getting-started/introduction.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Introduction
22

3-
StreamResource brings full parity with React's `useStream()` hook to Angular 20+. Build streaming AI applications with Angular Signals, connect to LangGraph agents, and ship production-ready frontends for your AI products.
3+
StreamResource is the Signal-native streaming library for Angular 20+ — built natively for LangGraph, without React translation layers. Build streaming AI applications with Angular Signals, connect to LangGraph agents, and ship production-ready frontends for your AI products.
44

55
<Callout type="info" title="What you'll learn">
66
This guide walks you through the complete workflow: build a LangGraph agent in Python, run it locally, connect it to an Angular app with streamResource(), and deploy to production.

apps/website/e2e/website.spec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ test('landing page renders architecture section', async ({ page }) => {
1212
await expect(page.getByText('Architecture').first()).toBeVisible();
1313
});
1414

15-
test('landing page renders 6 feature cards', async ({ page }) => {
15+
test('landing page renders fair comparison section', async ({ page }) => {
1616
await page.goto('/');
17-
const featureSection = page.locator('section').filter({ hasText: 'Features' });
18-
await expect(featureSection).toBeVisible();
17+
await expect(page.getByText('What Angular Stream Resource adds').first()).toBeVisible();
1918
});
2019

2120
test('pricing page shows 4 plan cards', async ({ page }) => {
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<link rel="preconnect" href="https://fonts.googleapis.com">
6+
<link href="https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,700;1,400&family=Inter:wght@400;600&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet">
7+
<style>
8+
*{box-sizing:border-box;margin:0;padding:0}
9+
body{font-family:'Inter',sans-serif;color:#1a1a2e;background:#fff}
10+
.chapter-body p{font-size:15px;line-height:1.75;color:#333;margin-bottom:18px}
11+
.chapter-body h3{font-family:'EB Garamond',serif;font-size:22px;font-weight:700;color:#1a1a2e;margin:28px 0 12px}
12+
.chapter-body ul{margin:0 0 18px 20px}
13+
.chapter-body li{font-size:15px;line-height:1.7;color:#333;margin-bottom:6px}
14+
.chapter-body pre{background:#1a1b26;color:#c8ccee;padding:20px 24px;border-radius:8px;font-size:13px;line-height:1.65;overflow-x:auto;margin:24px 0;white-space:pre-wrap}
15+
.chapter-body code{font-family:'JetBrains Mono',monospace;font-size:13px}
16+
.chapter-body strong{font-weight:600}
17+
</style>
18+
</head>
19+
<body>
20+
21+
<!-- Cover -->
22+
<div style="height:100vh;display:flex;flex-direction:column;justify-content:flex-end;padding:80px 80px 100px;background:linear-gradient(135deg,#fef0f3 0%,#f4f0ff 45%,#eaf3ff 70%,#e6f4ff 100%);page-break-after:always">
23+
<div style="font-family:monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.12em;color:#004090;font-weight:700;margin-bottom:24px">StreamResource · Production Readiness Guide</div>
24+
<h1 style="font-family:'EB Garamond',serif;font-size:52px;font-weight:800;line-height:1.1;color:#1a1a2e;margin-bottom:20px">From Prototype<br>to Production</h1>
25+
<p style="font-family:'EB Garamond',serif;font-style:italic;font-size:20px;color:#555770;margin-bottom:40px">The Angular Agent Readiness Guide</p>
26+
<div style="font-size:13px;color:#888;font-family:monospace">cacheplane.io · 2026</div>
27+
<div style="margin-top:16px;padding:8px 14px;background:rgba(255,160,50,.12);border:1px solid rgba(255,160,50,.3);border-radius:6px;font-family:monospace;font-size:11px;color:#c47a00;display:inline-block">⚠ PREVIEW — placeholder content. Set ANTHROPIC_API_KEY and run npm run generate-whitepaper for real content.</div>
28+
</div>
29+
30+
<!-- TOC -->
31+
<div style="padding:80px;page-break-after:always">
32+
<h2 style="font-family:'EB Garamond',serif;font-size:32px;font-weight:700;color:#1a1a2e;margin-bottom:32px">Contents</h2>
33+
34+
<div style="display:flex;align-items:baseline;gap:8px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.06);font-size:15px;color:#444">
35+
<span style="font-family:monospace;font-size:11px;color:#004090;font-weight:700;min-width:24px">01</span>
36+
<span style="flex:1">Streaming State Management</span>
37+
</div>
38+
<div style="display:flex;align-items:baseline;gap:8px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.06);font-size:15px;color:#444">
39+
<span style="font-family:monospace;font-size:11px;color:#004090;font-weight:700;min-width:24px">02</span>
40+
<span style="flex:1">Thread Persistence</span>
41+
</div>
42+
<div style="display:flex;align-items:baseline;gap:8px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.06);font-size:15px;color:#444">
43+
<span style="font-family:monospace;font-size:11px;color:#004090;font-weight:700;min-width:24px">03</span>
44+
<span style="flex:1">Tool-Call Rendering</span>
45+
</div>
46+
<div style="display:flex;align-items:baseline;gap:8px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.06);font-size:15px;color:#444">
47+
<span style="font-family:monospace;font-size:11px;color:#004090;font-weight:700;min-width:24px">04</span>
48+
<span style="flex:1">Human Approval Flows</span>
49+
</div>
50+
<div style="display:flex;align-items:baseline;gap:8px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.06);font-size:15px;color:#444">
51+
<span style="font-family:monospace;font-size:11px;color:#004090;font-weight:700;min-width:24px">05</span>
52+
<span style="flex:1">Generative UI</span>
53+
</div>
54+
<div style="display:flex;align-items:baseline;gap:8px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.06);font-size:15px;color:#444">
55+
<span style="font-family:monospace;font-size:11px;color:#004090;font-weight:700;min-width:24px">06</span>
56+
<span style="flex:1">Deterministic Testing</span>
57+
</div>
58+
</div>
59+
60+
<!-- Chapters -->
61+
62+
<section style="padding:80px;page-break-before:always">
63+
<div style="font-family:monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.1em;color:#004090;font-weight:700;margin-bottom:16px">Chapter 1</div>
64+
<h2 style="font-family:'EB Garamond',serif;font-size:36px;font-weight:800;color:#1a1a2e;margin-bottom:28px;line-height:1.15">Streaming State Management</h2>
65+
<div class="chapter-body"><h3>Overview</h3>
66+
<p>When you move from prototype to production, the requirements change fundamentally. What worked in a demo — direct API calls, synchronous state, manual zone management — falls apart at scale.</p>
67+
<h3>The Signals-Native Approach</h3>
68+
<p>StreamResource provides a signals-native approach that eliminates the boilerplate:</p>
69+
<pre><code>@Component({...})
70+
export class ChatComponent {
71+
chat = streamResource<{ messages: BaseMessage[] }>({
72+
assistantId: 'chat_agent',
73+
});
74+
}
75+
</code></pre>
76+
<h3>Production Checklist</h3>
77+
<ul><li>Are your message signals OnPush-compatible?</li>
78+
<li>Is isStreaming() driving your loading UI without polling?</li>
79+
<li>Are you avoiding manual zone patching?</li></ul></div>
80+
</section>
81+
<section style="padding:80px;page-break-before:always">
82+
<div style="font-family:monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.1em;color:#004090;font-weight:700;margin-bottom:16px">Chapter 2</div>
83+
<h2 style="font-family:'EB Garamond',serif;font-size:36px;font-weight:800;color:#1a1a2e;margin-bottom:28px;line-height:1.15">Thread Persistence</h2>
84+
<div class="chapter-body"><h3>Overview</h3>
85+
<p>Demos work with ephemeral state. Production agents need conversation history that survives page refreshes, tab switches, and navigation — wired to LangGraph's MemorySaver backend.</p>
86+
<h3>The threadId Pattern</h3>
87+
<pre><code>provideStreamResource({
88+
apiUrl: 'http://localhost:2024',
89+
threadId: signal(localStorage.getItem('threadId')),
90+
onThreadId: (id) => localStorage.setItem('threadId', id),
91+
})
92+
</code></pre>
93+
<h3>Production Checklist</h3>
94+
<ul><li>Does your agent UI resume threads correctly after a browser refresh?</li>
95+
<li>Can users switch between conversations?</li>
96+
<li>Is thread state scoped correctly per user?</li></ul></div>
97+
</section>
98+
<section style="padding:80px;page-break-before:always">
99+
<div style="font-family:monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.1em;color:#004090;font-weight:700;margin-bottom:16px">Chapter 3</div>
100+
<h2 style="font-family:'EB Garamond',serif;font-size:36px;font-weight:800;color:#1a1a2e;margin-bottom:28px;line-height:1.15">Tool-Call Rendering</h2>
101+
<div class="chapter-body"><h3>Overview</h3>
102+
<p>LangGraph agents invoke tools mid-stream. The UI needs to show tool execution state in real time — steps appearing as the tool runs, a final result, and collapsible history.</p>
103+
<h3>Progressive Disclosure</h3>
104+
<pre><code><chat-tool-call-card
105+
[toolCall]="msg.tool_calls[0]"
106+
[collapsed]="!isStreaming()">
107+
</chat-tool-call-card>
108+
</code></pre>
109+
<h3>Production Checklist</h3>
110+
<ul><li>Do your tool call cards handle partial step state during streaming?</li>
111+
<li>Is tool history collapsible after completion?</li>
112+
<li>Can you distinguish pending vs. completed tool calls?</li></ul></div>
113+
</section>
114+
<section style="padding:80px;page-break-before:always">
115+
<div style="font-family:monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.1em;color:#004090;font-weight:700;margin-bottom:16px">Chapter 4</div>
116+
<h2 style="font-family:'EB Garamond',serif;font-size:36px;font-weight:800;color:#1a1a2e;margin-bottom:28px;line-height:1.15">Human Approval Flows</h2>
117+
<div class="chapter-body"><h3>Overview</h3>
118+
<p>Production agents that take consequential actions must pause for human approval before proceeding. This requires a tight loop between LangGraph's interrupt() primitive and Angular UI.</p>
119+
<h3>The Interrupt Pattern</h3>
120+
<pre><code>// In your component
121+
approved = computed(() => this.chat.interrupt()?.approved ?? false);
122+
onApprove() {
123+
this.chat.submit(null, { command: { resume: true } });
124+
}
125+
</code></pre>
126+
<h3>Production Checklist</h3>
127+
<ul><li>Can your agent UI recover gracefully if a user cancels an interrupt?</li>
128+
<li>Are approve/edit/cancel actions clearly mapped to resume commands?</li>
129+
<li>Is interrupt state persisted across refreshes?</li></ul></div>
130+
</section>
131+
<section style="padding:80px;page-break-before:always">
132+
<div style="font-family:monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.1em;color:#004090;font-weight:700;margin-bottom:16px">Chapter 5</div>
133+
<h2 style="font-family:'EB Garamond',serif;font-size:36px;font-weight:800;color:#1a1a2e;margin-bottom:28px;line-height:1.15">Generative UI</h2>
134+
<div class="chapter-body"><h3>Overview</h3>
135+
<p>The most advanced production agents emit structured UI specs — not just text. A data analysis agent might render a live table. A booking agent might render a reservation form.</p>
136+
<h3>The Registry Pattern</h3>
137+
<pre><code>defineAngularRegistry({
138+
'data-table': DataTableComponent,
139+
'booking-form': BookingFormComponent,
140+
'chart-widget': ChartWidgetComponent,
141+
});
142+
</code></pre>
143+
<h3>Production Checklist</h3>
144+
<ul><li>Can your agent emit UI components without tight coupling to the frontend codebase?</li>
145+
<li>Does JSON patch streaming enable progressive UI updates?</li>
146+
<li>Is your component registry decoupled from agent logic?</li></ul></div>
147+
</section>
148+
<section style="padding:80px;page-break-before:always">
149+
<div style="font-family:monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.1em;color:#004090;font-weight:700;margin-bottom:16px">Chapter 6</div>
150+
<h2 style="font-family:'EB Garamond',serif;font-size:36px;font-weight:800;color:#1a1a2e;margin-bottom:28px;line-height:1.15">Deterministic Testing</h2>
151+
<div class="chapter-body"><h3>Overview</h3>
152+
<p>Agent UIs are notoriously hard to test because they depend on live LLM responses. Flaky tests, slow CI, and inability to reproduce edge cases are the main reasons agent UIs ship with low confidence.</p>
153+
<h3>The MockStreamTransport Approach</h3>
154+
<pre><code>const ref = createMockStreamResourceRef<ChatState>();
155+
ref.messages.set([{ role: 'assistant', content: 'Hello' }]);
156+
ref.isStreaming.set(false);
157+
expect(fixture.nativeElement.querySelector('.message').textContent)
158+
.toBe('Hello');
159+
</code></pre>
160+
<h3>Production Checklist</h3>
161+
<ul><li>Do your agent component tests run offline and complete in under 100ms each?</li>
162+
<li>Are streaming, interrupts, tool calls, and generative UI all tested in isolation?</li>
163+
<li>Is MockStreamTransport used instead of mocking streamResource() itself?</li></ul></div>
164+
</section>
165+
166+
</body>
167+
</html>

apps/website/public/whitepaper.pdf

254 KB
Binary file not shown.

0 commit comments

Comments
 (0)