diff --git a/.gitignore b/.gitignore
index 6d431405f..21a866348 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,12 +28,5 @@ apps/website/public/demo/
out
.vercel
-# LangGraph
-.langgraph_api/
-langgraph-combined.json
-
-# Playwright
-test-results/
-
-# Deploy output
-deploy/
+# Whitepaper signup data
+apps/website/data/
diff --git a/apps/website/content/AGENTS.md.template b/apps/website/content/AGENTS.md.template
index 651fd245c..41817dde0 100644
--- a/apps/website/content/AGENTS.md.template
+++ b/apps/website/content/AGENTS.md.template
@@ -1,6 +1,6 @@
# stream-resource v@VERSION@
-Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — full parity with React's `useStream()`.
+Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — Signal-native streaming for Angular agents, built for LangGraph.
## Install
npm install stream-resource
diff --git a/apps/website/content/CLAUDE.md.template b/apps/website/content/CLAUDE.md.template
index 651fd245c..41817dde0 100644
--- a/apps/website/content/CLAUDE.md.template
+++ b/apps/website/content/CLAUDE.md.template
@@ -1,6 +1,6 @@
# stream-resource v@VERSION@
-Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — full parity with React's `useStream()`.
+Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — Signal-native streaming for Angular agents, built for LangGraph.
## Install
npm install stream-resource
diff --git a/apps/website/content/docs-v2/getting-started/introduction.mdx b/apps/website/content/docs-v2/getting-started/introduction.mdx
index 574c57b4d..e1c35bc0d 100644
--- a/apps/website/content/docs-v2/getting-started/introduction.mdx
+++ b/apps/website/content/docs-v2/getting-started/introduction.mdx
@@ -1,6 +1,6 @@
# Introduction
-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.
+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.
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.
diff --git a/apps/website/e2e/website.spec.ts b/apps/website/e2e/website.spec.ts
index e1bf0592e..870ebec25 100644
--- a/apps/website/e2e/website.spec.ts
+++ b/apps/website/e2e/website.spec.ts
@@ -12,10 +12,9 @@ test('landing page renders architecture section', async ({ page }) => {
await expect(page.getByText('Architecture').first()).toBeVisible();
});
-test('landing page renders 6 feature cards', async ({ page }) => {
+test('landing page renders fair comparison section', async ({ page }) => {
await page.goto('/');
- const featureSection = page.locator('section').filter({ hasText: 'Features' });
- await expect(featureSection).toBeVisible();
+ await expect(page.getByText('What Angular Stream Resource adds').first()).toBeVisible();
});
test('pricing page shows 4 plan cards', async ({ page }) => {
diff --git a/apps/website/public/whitepaper-preview.html b/apps/website/public/whitepaper-preview.html
new file mode 100644
index 000000000..4a840fd55
--- /dev/null
+++ b/apps/website/public/whitepaper-preview.html
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
StreamResource · Production Readiness Guide
+
From Prototype to Production
+
The Angular Agent Readiness Guide
+
cacheplane.io · 2026
+
⚠ PREVIEW — placeholder content. Set ANTHROPIC_API_KEY and run npm run generate-whitepaper for real content.
+
+
+
+
+
Contents
+
+
+ 01
+ Streaming State Management
+
+
+ 02
+ Thread Persistence
+
+
+ 03
+ Tool-Call Rendering
+
+
+ 04
+ Human Approval Flows
+
+
+ 05
+ Generative UI
+
+
+ 06
+ Deterministic Testing
+
+
+
+
+
+
+
Chapter 1
+
Streaming State Management
+
Overview
+
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.
+
The Signals-Native Approach
+
StreamResource provides a signals-native approach that eliminates the boilerplate:
Is isStreaming() driving your loading UI without polling?
+
Are you avoiding manual zone patching?
+
+
+
Chapter 2
+
Thread Persistence
+
Overview
+
Demos work with ephemeral state. Production agents need conversation history that survives page refreshes, tab switches, and navigation — wired to LangGraph's MemorySaver backend.
Does your agent UI resume threads correctly after a browser refresh?
+
Can users switch between conversations?
+
Is thread state scoped correctly per user?
+
+
+
Chapter 3
+
Tool-Call Rendering
+
Overview
+
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.
+
Progressive Disclosure
+
+
+
+
Production Checklist
+
Do your tool call cards handle partial step state during streaming?
+
Is tool history collapsible after completion?
+
Can you distinguish pending vs. completed tool calls?
+
+
+
Chapter 4
+
Human Approval Flows
+
Overview
+
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.
Can your agent UI recover gracefully if a user cancels an interrupt?
+
Are approve/edit/cancel actions clearly mapped to resume commands?
+
Is interrupt state persisted across refreshes?
+
+
+
Chapter 5
+
Generative UI
+
Overview
+
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.
Can your agent emit UI components without tight coupling to the frontend codebase?
+
Does JSON patch streaming enable progressive UI updates?
+
Is your component registry decoupled from agent logic?
+
+
+
Chapter 6
+
Deterministic Testing
+
Overview
+
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.
Do your agent component tests run offline and complete in under 100ms each?
+
Are streaming, interrupts, tool calls, and generative UI all tested in isolation?
+
Is MockStreamTransport used instead of mocking streamResource() itself?
+
+
+
+
\ No newline at end of file
diff --git a/apps/website/public/whitepaper.pdf b/apps/website/public/whitepaper.pdf
new file mode 100644
index 000000000..69bdf349b
Binary files /dev/null and b/apps/website/public/whitepaper.pdf differ
diff --git a/apps/website/scripts/generate-whitepaper.ts b/apps/website/scripts/generate-whitepaper.ts
new file mode 100644
index 000000000..07abe0ed8
--- /dev/null
+++ b/apps/website/scripts/generate-whitepaper.ts
@@ -0,0 +1,262 @@
+import Anthropic from '@anthropic-ai/sdk';
+import fs from 'fs';
+import path from 'path';
+import puppeteer from 'puppeteer';
+
+const client = new Anthropic();
+const MODEL = process.env['ANTHROPIC_MODEL'] ?? 'claude-opus-4-5';
+const OUTPUT_PDF = 'apps/website/public/whitepaper.pdf';
+const OUTPUT_HTML = 'apps/website/public/whitepaper-preview.html';
+
+// ── Chapter definitions ──────────────────────────────────────────────────
+const CHAPTERS = [
+ {
+ id: 'streaming-state',
+ title: 'Streaming State Management',
+ prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide".
+
+Chapter topic: Streaming State Management
+
+Context: Angular teams building LangGraph-powered agents must wire SSE event streams into reactive UI. Without the right primitives, they end up with custom zone-patching, manual subscription management, and brittle token accumulation logic that breaks under load.
+
+Cover:
+- Why streaming state is hard in Angular (zone.js, change detection, timing)
+- The signals-native approach: how streamResource() exposes messages() as Signal
+- How isStreaming() lets developers drive loading UI without polling
+- Code example: minimal streamResource() setup (TypeScript snippet, 8-12 lines)
+- Production checklist item: "Are your message signals OnPush-compatible?"
+
+Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engineers.`,
+ },
+ {
+ id: 'thread-persistence',
+ title: 'Thread Persistence',
+ prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide".
+
+Chapter topic: Thread Persistence
+
+Context: Demos work with ephemeral state. Production agents need conversation history that survives page refreshes, tab switches, and navigation — wired to LangGraph's MemorySaver backend.
+
+Cover:
+- Why stateless agent UIs fail in production
+- The threadId signal and onThreadId callback pattern
+- How to persist threadId to localStorage and restore on mount
+- Thread list UI and switching between conversations
+- Code example: provideStreamResource() with threadId (8-12 lines)
+- Production checklist item: "Does your agent UI resume threads correctly after a browser refresh?"
+
+Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engineers.`,
+ },
+ {
+ id: 'tool-call-rendering',
+ title: 'Tool-Call Rendering',
+ prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide".
+
+Chapter topic: Tool-Call Rendering
+
+Context: 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 — without parsing raw SSE events by hand.
+
+Cover:
+- What tool call events look like in the raw stream
+- Why hand-parsing is fragile and hard to test
+- The headless primitive and prebuilt option
+- Progressive disclosure: showing steps live, collapsing on completion
+- Code example: binding (8-12 lines of Angular template)
+- Production checklist item: "Do your tool call cards handle partial step state during streaming?"
+
+Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engineers.`,
+ },
+ {
+ id: 'human-approval-flows',
+ title: 'Human Approval Flows',
+ prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide".
+
+Chapter topic: Human Approval Flows (Interrupts)
+
+Context: Production agents that take consequential actions — sending emails, deploying services, modifying data — must pause for human approval before proceeding. This requires a tight loop between LangGraph's interrupt() primitive and Angular UI.
+
+Cover:
+- The LangGraph interrupt() and Command.RESUME pattern
+- Why polling and custom websocket approaches are brittle
+- The interrupt() signal in streamResource() and how it maps to approval state
+- headless and prebuilt
+- The three approval actions: approve, edit, cancel — and how each maps to a resume command
+- Code example: interrupt signal binding (8-12 lines)
+- Production checklist item: "Can your agent UI recover gracefully if a user cancels an interrupt?"
+
+Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engineers.`,
+ },
+ {
+ id: 'generative-ui',
+ title: 'Generative UI',
+ prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide".
+
+Chapter topic: Generative UI
+
+Context: 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. Without a framework for this, teams either hardcode component logic into the agent or skip the feature entirely.
+
+Cover:
+- The onCustomEvent pattern in LangGraph: how agents emit structured data
+- The @cacheplane/render approach: json-render specs, defineAngularRegistry(),
+- How JSON patch streaming enables progressive UI updates (rows appearing as data arrives)
+- The registry pattern: decoupling agent from component implementation
+- Code example: defineAngularRegistry() registration (8-12 lines)
+- Production checklist item: "Can your agent emit UI components without tight coupling to the frontend codebase?"
+
+Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engineers.`,
+ },
+ {
+ id: 'deterministic-testing',
+ title: 'Deterministic Testing',
+ prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide".
+
+Chapter topic: Deterministic Testing
+
+Context: 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.
+
+Cover:
+- Why testing agent components against real LLM APIs is impractical
+- The MockStreamTransport approach: scripted event sequences, no server needed
+- createMockStreamResourceRef(): writable signals you control directly in tests
+- How to test streaming, interrupts, tool calls, and generative UI in isolation
+- Code example: createMockStreamResourceRef() test pattern (10-14 lines)
+- Production checklist item: "Do your agent component tests run offline and complete in under 100ms each?"
+
+Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engineers.`,
+ },
+];
+
+// ── Markdown to HTML converter ───────────────────────────────────────────
+function mdToHTML(md: string): string {
+ return md
+ .replace(/```[\w]*\n([\s\S]*?)```/g, '
);
}
diff --git a/apps/website/src/app/pilot-to-prod/page.tsx b/apps/website/src/app/pilot-to-prod/page.tsx
new file mode 100644
index 000000000..d2b23ba64
--- /dev/null
+++ b/apps/website/src/app/pilot-to-prod/page.tsx
@@ -0,0 +1,74 @@
+import { PilotHero } from '../../components/landing/PilotHero';
+import { WhatIsIncluded } from '../../components/landing/WhatIsIncluded';
+import { HowItWorks } from '../../components/landing/HowItWorks';
+import { ProblemSection } from '../../components/landing/ProblemSection';
+import { PricingSignal } from '../../components/landing/PricingSignal';
+import { RiskRemoval } from '../../components/landing/RiskRemoval';
+import { WhitePaperGate } from '../../components/landing/WhitePaperGate';
+import { PilotFooterCTA } from '../../components/landing/PilotFooterCTA';
+import { tokens } from '../../../lib/design-tokens';
+
+export const metadata = {
+ title: 'Pilot to Production — Angular Stream Resource',
+ description: 'Close the last-mile gap. Purchase an app deployment license and we work alongside your Angular team for 3 months to ship your first agent to production.',
+};
+
+export default function PilotToProdPage() {
+ return (
+ <>
+
+
+
+
+
+ );
+}
diff --git a/apps/website/src/components/landing/HeroTwoCol.tsx b/apps/website/src/components/landing/HeroTwoCol.tsx
index af2bcbdd4..2803114ba 100644
--- a/apps/website/src/components/landing/HeroTwoCol.tsx
+++ b/apps/website/src/components/landing/HeroTwoCol.tsx
@@ -100,17 +100,7 @@ export async function HeroTwoCol() {
margin: 0,
marginBottom: 32,
}}>
- Full parity with React{' '}
- useStream()
- {' '}— built natively for Angular 20+.
+ Signal-native streaming for LangGraph — production patterns your Angular team can own.
diff --git a/apps/website/src/components/landing/HomePilotCTA.tsx b/apps/website/src/components/landing/HomePilotCTA.tsx
new file mode 100644
index 000000000..927f56878
--- /dev/null
+++ b/apps/website/src/components/landing/HomePilotCTA.tsx
@@ -0,0 +1,51 @@
+'use client';
+
+import { tokens } from '../../../lib/design-tokens';
+import { CitationBadge } from './CitationBadge';
+
+const citation77 = {
+ source: 'McKinsey — State of AI 2024',
+ url: 'https://www.mckinsey.com/capabilities/quantumblack/our-insights/the-state-of-ai',
+ stat: 'Most companies remain in experimentation or pilot phases',
+ note: 'Workflow redesign and human validation are what drive real production value.',
+};
+
+export function HomePilotCTA() {
+ return (
+
+
+
+ Ready to ship your agent?
+
+
+ Most Angular teams are 77% of the way there. Our structured 3-month co-pilot engagement closes the gap.
+
+
+ );
+}
diff --git a/apps/website/src/components/landing/HowItWorks.tsx b/apps/website/src/components/landing/HowItWorks.tsx
new file mode 100644
index 000000000..3597567b5
--- /dev/null
+++ b/apps/website/src/components/landing/HowItWorks.tsx
@@ -0,0 +1,224 @@
+'use client';
+
+import { motion } from 'framer-motion';
+import { tokens } from '../../../lib/design-tokens';
+
+interface Phase {
+ phaseLabel: string;
+ number: number;
+ title: string;
+ description: string;
+ deliverable: string;
+}
+
+const phases: Phase[] = [
+ {
+ phaseLabel: 'Week 1',
+ number: 1,
+ title: 'Integration Sprint',
+ description:
+ 'We install stream-resource into your Angular workspace, wire it to your LangGraph backend, and ship your first streamed response. Your team sees tokens flowing within days.',
+ deliverable: '✓ First stream live',
+ },
+ {
+ phaseLabel: 'Month 1',
+ number: 2,
+ title: 'First Agent in Staging',
+ description:
+ 'Build and deploy the first complete agent — tool calls, human approval flows, generative UI. Your team owns the code. We pair with your engineers throughout.',
+ deliverable: '✓ Agent in staging',
+ },
+ {
+ phaseLabel: 'Month 3',
+ number: 3,
+ title: 'Production Deployment',
+ description:
+ 'Harden for scale, deploy to production, hand off the pattern. Your team can now build the next agent without us — the license and the knowledge stay with you.',
+ deliverable: '✓ Production deployment',
+ },
+];
+
+export function HowItWorks() {
+ return (
+
+
+ {/* Section header */}
+
+
+ The Engagement
+
+
+ From first stream to production
+
+
+
+ {/* Timeline wrapper — relative for connector line positioning */}
+
@@ -316,6 +357,7 @@ export function ProblemSection() {
);
diff --git a/apps/website/src/components/landing/RiskRemoval.tsx b/apps/website/src/components/landing/RiskRemoval.tsx
new file mode 100644
index 000000000..d0cfc9d69
--- /dev/null
+++ b/apps/website/src/components/landing/RiskRemoval.tsx
@@ -0,0 +1,149 @@
+'use client';
+
+import { motion } from 'framer-motion';
+import { tokens } from '../../../lib/design-tokens';
+
+const commitments = [
+ {
+ icon: '📄',
+ title: 'One license, one app.',
+ desc: '$20,000 covers one application deployed to production. stream-resource is licensed for that app. Buy more licenses as you scale to more apps.',
+ },
+ {
+ icon: '👥',
+ title: 'We work alongside your team.',
+ desc: 'This is not a handoff. We pair with your engineers throughout the 3 months — code reviews, architecture calls, unblocking sessions. Your team drives; we co-pilot.',
+ },
+ {
+ icon: '⚡',
+ title: 'Fixed price. No scope creep.',
+ desc: '$20,000 flat. No hourly overruns, no change-order invoices. The engagement is scoped to ship your first agent — not open-ended consulting.',
+ },
+ {
+ icon: '🔒',
+ title: 'Your code. Your repo.',
+ desc: 'Everything we build lives in your codebase under your ownership. We leave you with patterns you can replicate across every future agent, not dependencies on us.',
+ },
+];
+
+export function RiskRemoval() {
+ return (
+
+
- Built natively for Angular 20+. No wrappers, no adapters, no compromises.
+ Signal-native APIs for streaming, interrupts, and testing — built natively for Angular 20+.
diff --git a/apps/website/src/components/landing/WhatIsIncluded.tsx b/apps/website/src/components/landing/WhatIsIncluded.tsx
new file mode 100644
index 000000000..bbcc77cb8
--- /dev/null
+++ b/apps/website/src/components/landing/WhatIsIncluded.tsx
@@ -0,0 +1,203 @@
+'use client';
+
+import { motion } from 'framer-motion';
+import { tokens } from '../../../lib/design-tokens';
+
+const cards = [
+ {
+ icon: '📦',
+ title: 'stream-resource',
+ description:
+ "The Angular streaming library. Token-by-token streaming, thread persistence, interrupt handling, and MockStreamTransport for deterministic testing. Purpose-built for LangGraph and Angular Signals.",
+ bullets: [
+ 'Signals-native API',
+ 'OnPush compatible',
+ 'Deterministic test transport',
+ ],
+ highlighted: false,
+ label: null,
+ },
+ {
+ icon: '🚀',
+ title: '3-Month Pilot',
+ description:
+ 'Structured engagement with your team. We define the scope, build the first agent together, and leave you with a production-ready pattern you can replicate.',
+ bullets: [
+ 'Week 1: Integration & first stream',
+ 'Month 1: First agent in staging',
+ 'Month 3: Production deployment',
+ ],
+ highlighted: true,
+ label: '★ Included',
+ },
+ {
+ icon: '📄',
+ title: 'App Deployment License',
+ description:
+ 'One license covers one Angular application in production. stream-resource is included for that app. The 3-month engagement is how we get you there together.',
+ bullets: [
+ '$20,000 · one app in production',
+ 'stream-resource license included',
+ 'Patterns your team can replicate',
+ ],
+ highlighted: false,
+ label: null,
+ },
+] as const;
+
+export function WhatIsIncluded() {
+ return (
+
+
+ Fill in the form and we'll reach out within one business day to
+ discuss your use case, timeline, and fit. No sales pressure — if
+ the pilot isn't right for you, we'll tell you.
+
+
+
+ {[
+ 'Response within 1 business day',
+ 'No commitment to proceed',
+ "We'll tell you if it's not a fit",
+ ].map((bullet) => (
+