Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ba89f13
feat(chat): ship-readiness polish — Tailwind, auto-scroll, markdown, …
blove Apr 6, 2026
2dccb0a
Rebrand to Angular Stream Resource (#28)
blove Apr 6, 2026
65f13df
feat(website): add narrative sections, pilot-to-prod page, and rebran…
blove Apr 6, 2026
1c9e7b6
fix(website): replace unsourced stats with verified Gartner and Stack…
blove Apr 6, 2026
16d37f7
merge: resolve conflicts with main
blove Apr 6, 2026
40a967b
docs: add website audit and lead generation specs
blove Apr 6, 2026
5e52aeb
docs: add implementation plans for lead gen and website audit
blove Apr 6, 2026
b8e8ba2
chore: install resend and react-email dependencies
blove Apr 6, 2026
e53d86d
feat: add shared resend module with audience helper
blove Apr 6, 2026
fd13886
feat: add lead notification email template
blove Apr 6, 2026
7f16a19
feat: add whitepaper download email template
blove Apr 6, 2026
e41dd9f
feat: add newsletter welcome email template
blove Apr 6, 2026
c948d1a
feat: wire /api/leads to Resend email + audience
blove Apr 6, 2026
c33e2e1
feat: wire /api/whitepaper-signup to Resend email delivery
blove Apr 6, 2026
4b5d310
feat: add /api/newsletter route with Resend welcome email
blove Apr 6, 2026
5c700cf
fix: convert email templates to plain HTML to avoid React dual-instan…
blove Apr 6, 2026
fba8c65
fix: lazy-init Resend client to gracefully handle missing API key
blove Apr 6, 2026
3092ca4
fix: make ChatFeaturesSection responsive on mobile
blove Apr 6, 2026
150ca98
fix: stack FairComparisonSection rows vertically on mobile
blove Apr 6, 2026
1aaaec2
fix: increase touch targets to meet WCAG 44px minimum
blove Apr 6, 2026
5975f8f
fix: enforce 12px minimum font size on progress bar labels
blove Apr 6, 2026
b65d9e2
feat: add social proof badge strip below stats
blove Apr 6, 2026
fcfe07b
feat: add newsletter signup form to footer
blove Apr 6, 2026
5f62f73
feat: restructure white paper section with soft gate
blove Apr 6, 2026
32b2221
feat: add OpenGraph and Twitter Card meta tags
blove Apr 6, 2026
888701c
merge: resolve ProblemSection conflict with main (keep our stat + fon…
blove Apr 6, 2026
8f6ec67
feat: rebrand from streamResource to agent() — @cacheplane/angular
blove Apr 7, 2026
5dbeb85
merge: resolve conflicts with main (keep renamed versions)
blove Apr 7, 2026
7353ae7
merge: pull latest main
blove Apr 7, 2026
e439b03
fix: complete rebrand audit — nav bug, hero copy, templates, footer
blove Apr 7, 2026
b96574c
fix: remove $20k from pilot program, include with app license, annual…
blove Apr 7, 2026
0b4e127
fix: resolve API docs slug mismatch after rename
blove Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions apps/website/content/AGENTS.md.template
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
# stream-resource v@VERSION@
# Angular Agent Framework v@VERSION@

Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — Signal-native streaming for Angular agents, built for LangGraph.
Angular agent framework for LangChain/LangGraph. Provides `agent()` — Signal-native streaming for Angular agents, built for LangGraph.

## Install
npm install stream-resource
npm install @cacheplane/angular

## Key requirement
`streamResource()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".
`agent()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".

## Basic usage
```typescript
// app.config.ts
import { provideStreamResource } from 'stream-resource';
import { provideAgent } from '@cacheplane/angular';
export const appConfig: ApplicationConfig = {
providers: [provideStreamResource({ apiUrl: 'http://localhost:2024' })]
providers: [provideAgent({ apiUrl: 'http://localhost:2024' })]
};

// chat.component.ts
import { streamResource } from 'stream-resource';
import { agent } from '@cacheplane/angular';
import type { BaseMessage } from '@langchain/core/messages';

@Component({ template: `
@for (msg of chat.messages(); track $index) { <p>{{ msg.content }}</p> }
<button (click)="send()">Send</button>
`})
export class ChatComponent {
chat = streamResource<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' });
chat = agent<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' });
send() { this.chat.submit({ messages: [{ role: 'human', content: 'Hello' }] }); }
}
```

## Key patterns
- Thread persistence: `threadId: signal(localStorage.getItem('t'))` + `onThreadId: (id) => localStorage.setItem('t', id)`
- Global config: `provideStreamResource({ apiUrl })` in app.config.ts
- Per-call override: pass `apiUrl` directly to `streamResource()`
- Testing: use `MockStreamTransport` — never mock `streamResource()` itself
- Global config: `provideAgent({ apiUrl })` in app.config.ts
- Per-call override: pass `apiUrl` directly to `agent()`
- Testing: use `MockAgentTransport` — never mock `agent()` itself

## MCP server (for tool access)
Add to ~/.claude/settings.json:
{"mcpServers":{"stream-resource":{"command":"npx","args":["@stream-resource/mcp"]}}}
{"mcpServers":{"angular-agent":{"command":"npx","args":["@cacheplane/angular-mcp"]}}}

## Version check
If this file is stale, fetch the latest: https://stream-resource.dev/llms-full.txt
24 changes: 12 additions & 12 deletions apps/website/content/CLAUDE.md.template
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
# stream-resource v@VERSION@
# Angular Agent Framework v@VERSION@

Angular streaming library for LangChain/LangGraph. Provides `streamResource()` — Signal-native streaming for Angular agents, built for LangGraph.
Angular agent framework for LangChain/LangGraph. Provides `agent()` — Signal-native streaming for Angular agents, built for LangGraph.

## Install
npm install stream-resource
npm install @cacheplane/angular

## Key requirement
`streamResource()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".
`agent()` MUST be called within an Angular injection context (component constructor or field initializer). Calling it in ngOnInit or any async context throws "NG0203: inject() must be called from an injection context".

## Basic usage
```typescript
// app.config.ts
import { provideStreamResource } from 'stream-resource';
import { provideAgent } from '@cacheplane/angular';
export const appConfig: ApplicationConfig = {
providers: [provideStreamResource({ apiUrl: 'http://localhost:2024' })]
providers: [provideAgent({ apiUrl: 'http://localhost:2024' })]
};

// chat.component.ts
import { streamResource } from 'stream-resource';
import { agent } from '@cacheplane/angular';
import type { BaseMessage } from '@langchain/core/messages';

@Component({ template: `
@for (msg of chat.messages(); track $index) { <p>{{ msg.content }}</p> }
<button (click)="send()">Send</button>
`})
export class ChatComponent {
chat = streamResource<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' });
chat = agent<{ messages: BaseMessage[] }>({ assistantId: 'chat_agent' });
send() { this.chat.submit({ messages: [{ role: 'human', content: 'Hello' }] }); }
}
```

## Key patterns
- Thread persistence: `threadId: signal(localStorage.getItem('t'))` + `onThreadId: (id) => localStorage.setItem('t', id)`
- Global config: `provideStreamResource({ apiUrl })` in app.config.ts
- Per-call override: pass `apiUrl` directly to `streamResource()`
- Testing: use `MockStreamTransport` — never mock `streamResource()` itself
- Global config: `provideAgent({ apiUrl })` in app.config.ts
- Per-call override: pass `apiUrl` directly to `agent()`
- Testing: use `MockAgentTransport` — never mock `agent()` itself

## MCP server (for tool access)
Add to ~/.claude/settings.json:
{"mcpServers":{"stream-resource":{"command":"npx","args":["@stream-resource/mcp"]}}}
{"mcpServers":{"angular-agent":{"command":"npx","args":["@cacheplane/angular-mcp"]}}}

## Version check
If this file is stale, fetch the latest: https://stream-resource.dev/llms-full.txt
2 changes: 1 addition & 1 deletion apps/website/public/assets/hero.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions apps/website/src/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ function loadApiDocs(): ApiDocEntry[] {
}

const API_NAME_MAP: Record<string, string> = {
'angular': 'agent',
'provide-angular': 'provideAgent',
'agent': 'agent',
'provide-agent': 'provideAgent',
'fetch-stream-transport': 'FetchStreamTransport',
'mock-stream-transport': 'MockAgentTransport',
};
Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const mono = JetBrains_Mono({

export const metadata: Metadata = {
title: 'Angular Agent Framework — Signal-Native Streaming for Angular + LangGraph',
description: 'The Enterprise Streaming Resource for LangChain and Angular. Signal-native streaming, thread persistence, and production patterns for Angular 20+.',
description: 'The enterprise Angular agent framework for LangChain. Signal-native streaming, thread persistence, and production patterns for Angular 20+.',
openGraph: {
title: 'Angular Agent Framework',
description: 'Signal-native streaming for LangGraph — production patterns your Angular team can own.',
Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/app/pilot-to-prod/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { tokens } from '../../../lib/design-tokens';

export const metadata = {
title: 'Pilot to Production — Angular Agent Framework',
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.',
description: 'Close the last-mile gap. The 3-month pilot engagement is included with every app deployment license. We work alongside your Angular team to ship your first agent to production.',
};

export default function PilotToProdPage() {
Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/components/landing/HeroTwoCol.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export async function HeroTwoCol() {
margin: 0,
marginBottom: 20,
}}>
The Enterprise Streaming Resource for LangChain and{' '}
The Enterprise Agent Framework for LangChain and{' '}
<span style={{ color: tokens.colors.angularRed }}>Angular</span>
</h1>

Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/components/landing/PilotHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export function PilotHero() {
letterSpacing: '0.02em',
}}
>
App deployment license · $20,000 · 3-month co-pilot engagement
Included with every app deployment license · 3-month co-pilot engagement
</motion.p>
</div>
</section>
Expand Down
4 changes: 2 additions & 2 deletions apps/website/src/components/landing/PricingSignal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function PricingSignal() {
lineHeight: 1,
}}
>
$20,000
Included
</span>
<span
style={{
Expand All @@ -78,7 +78,7 @@ export function PricingSignal() {
marginTop: '8px',
}}
>
App deployment license. Includes angular + 3-month co-pilot engagement.
The 3-month pilot engagement is included with every app deployment license.
</span>
</div>

Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/components/landing/WhatIsIncluded.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const cards = [
description:
'One license covers one Angular application in production. angular is included for that app. The 3-month engagement is how we get you there together.',
bullets: [
'$20,000 · one app in production',
'One app in production',
'angular license included',
'Patterns your team can replicate',
],
Expand Down
4 changes: 2 additions & 2 deletions apps/website/src/components/pricing/PricingGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ const PLANS = [
{
name: 'App Deployment',
price: '$2,000',
period: '/app one-time',
features: ['Per-application license', 'All environments covered', 'No seat limits', 'Perpetual for version'],
period: '/app/year',
features: ['Per-application license', 'All environments covered', 'No seat limits', '12-month license term'],
highlight: false,
cta: 'Buy License',
ctaHref: '#lead-form',
Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/components/shared/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function Footer() {
<div className="md:col-span-2">
<p className="font-garamond text-xl font-bold mb-2" style={{ color: tokens.colors.textPrimary }}>Angular Agent Framework</p>
<p className="text-sm mb-4" style={{ color: tokens.colors.textMuted, maxWidth: '36ch', lineHeight: 1.6 }}>
The enterprise streaming resource for LangChain and Angular. Signal-native streaming built for production Angular 20+.
The enterprise Angular agent framework for LangChain. Signal-native streaming built for production Angular 20+.
</p>
<NewsletterForm />
{/* Social links */}
Expand Down
6 changes: 3 additions & 3 deletions apps/website/src/components/shared/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { tokens } from '@cacheplane/design-tokens';
const links = [
{ label: 'Pilot to Prod', href: '/pilot-to-prod', external: false },
{ label: 'Docs', href: '/docs', external: false },
{ label: 'API', href: '/docs/api/angular', external: false },
{ label: 'API', href: '/docs/api/agent', external: false },
{ label: 'Examples', href: 'https://cockpit.stream-resource.dev', external: true },
{ label: 'Pricing', href: '/pricing', external: false },
];
Expand Down Expand Up @@ -95,10 +95,10 @@ export function Nav() {

{/* Mobile hamburger */}
<button
className="md:hidden"
className="flex md:hidden items-center justify-center"
onClick={() => setOpen(!open)}
aria-label={open ? 'Close menu' : 'Open menu'}
style={{ color: tokens.colors.textPrimary, minWidth: 44, minHeight: 44, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
style={{ color: tokens.colors.textPrimary, minWidth: 44, minHeight: 44 }}>
{open ? <CloseIcon /> : <MenuIcon />}
</button>
</div>
Expand Down
4 changes: 2 additions & 2 deletions apps/website/src/lib/docs-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ export const docsConfig: DocsSection[] = [
id: 'api',
color: 'blue',
pages: [
{ title: 'agent()', slug: 'angular', section: 'api' },
{ title: 'provideAgent()', slug: 'provide-angular', section: 'api' },
{ title: 'agent()', slug: 'agent', section: 'api' },
{ title: 'provideAgent()', slug: 'provide-agent', section: 'api' },
{ title: 'FetchStreamTransport', slug: 'fetch-stream-transport', section: 'api' },
{ title: 'MockAgentTransport', slug: 'mock-stream-transport', section: 'api' },
],
Expand Down