Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
e7683c0
docs: add glassy gradient redesign spec
blove Apr 4, 2026
ced0d14
docs: add glassy gradient redesign implementation plan
blove Apr 4, 2026
0cd8f08
feat(website): update design tokens for glassy gradient redesign
blove Apr 4, 2026
147d47b
feat(website): update global CSS for light glassy theme
blove Apr 4, 2026
fac8a1e
feat(website): apply gradient background and glass to Hero
blove Apr 4, 2026
01b4dc6
feat(website): update ArchDiagram for light glassy theme
blove Apr 4, 2026
e311964
feat(website): apply glass cards to FeatureStrip
blove Apr 4, 2026
cfd9f3e
feat(website): apply glass treatment to ApiRefTable
blove Apr 4, 2026
c45520d
feat(website): apply glass border to CodeBlock
blove Apr 4, 2026
6a29276
feat(website): add gradient background to API reference page
blove Apr 4, 2026
82b89ec
feat(website): apply glass cards to PricingGrid
blove Apr 4, 2026
31edf81
feat(website): apply glass container to CompareTable
blove Apr 4, 2026
a7c3511
feat(website): apply glass treatment to LeadForm
blove Apr 4, 2026
313d834
feat(website): add gradient background to pricing page
blove Apr 4, 2026
130b7d5
feat(website): update GenerativeUIFrame outer frame for glass theme
blove Apr 4, 2026
db23168
feat(website): apply gradient background to landing page
blove Apr 4, 2026
35ec95a
feat(website): apply glass treatment to Nav
blove Apr 4, 2026
1592d30
feat(website): apply glass treatment to Footer
blove Apr 4, 2026
df5d777
feat(website): apply glass treatment to InstallStrip
blove Apr 4, 2026
8ecf4d5
feat(website): update CopyPromptButton to new accent colors
blove Apr 4, 2026
93abd62
feat(website): apply glass treatment to DocsSidebar
blove Apr 4, 2026
f2c04b6
feat(website): switch MdxRenderer to light prose theme
blove Apr 4, 2026
8eb216f
feat(website): add gradient background to docs page
blove Apr 4, 2026
dc008ba
fix(website): correct design-tokens import paths
blove Apr 4, 2026
b62e41d
fix(website): use unicode chars instead of HTML entities in JSX
blove Apr 4, 2026
2e06a77
feat(website): expand architecture diagram with two-row layout and de…
blove Apr 4, 2026
282ff5e
feat(website): redesign hero animation with multi-step agent UI
blove Apr 4, 2026
363fe36
fix(website): make API reference gradient fill full viewport
blove Apr 4, 2026
09044e7
feat(website): add GitHub link to nav bar
blove Apr 4, 2026
dca7943
feat(website): update hero copy button to full setup snippet
blove Apr 4, 2026
caa9793
feat(website): remove live demo section from landing page
blove Apr 4, 2026
5d7ccbb
docs: add homepage expansion implementation plan
blove Apr 4, 2026
a907450
feat(website): add interactive tabbed ValueProps section
blove Apr 4, 2026
1e1adee
feat(website): add reusable CapabilityCard component
blove Apr 4, 2026
93d10b3
feat(website): add CockpitCTA and StatsStrip sections
blove Apr 4, 2026
bd5578c
feat(website): add LangGraph and Deep Agents capability showcases
blove Apr 4, 2026
50bba92
feat(website): wire up all new homepage sections
blove Apr 4, 2026
98b8926
refactor(website): reorder homepage for optimal landing page flow
blove Apr 4, 2026
9375094
feat(website): redesign architecture as interactive vertical glass la…
blove Apr 4, 2026
03a585e
fix(website): mobile responsive polish
blove Apr 4, 2026
9579b70
feat(website): expand footer and add scroll animations
blove Apr 4, 2026
f3ea8a6
docs: add docs refresh design spec
blove Apr 4, 2026
1ff9212
docs: add docs infrastructure implementation plan
blove Apr 4, 2026
d49149e
feat(website): add docs navigation config
blove Apr 4, 2026
315e492
feat(website): add new docs loader (cockpit-independent)
blove Apr 4, 2026
189f33d
feat(website): add placeholder docs content (3 pages)
blove Apr 4, 2026
a6a62c7
feat(website): add custom MDX components (Callout, Steps, Tabs, Card,…
blove Apr 4, 2026
df5cafa
feat(website): add collapsible docs sidebar with section groups
blove Apr 4, 2026
71e3181
feat(website): add DocsBreadcrumb and DocsPrevNext components
blove Apr 4, 2026
9b051ae
feat(website): add Cmd+K search modal for docs
blove Apr 4, 2026
94c3b3e
feat(website): wire up new docs routing with MDX components and sidebar
blove Apr 4, 2026
4be67ca
fix(website): make Tabs items prop optional with fallback
blove Apr 4, 2026
29c1303
Merge remote-tracking branch 'origin/main' into claude/kind-margulis
blove Apr 4, 2026
33fdd44
fix(website): fix DocsSidebarNew type error in useState
blove Apr 4, 2026
4b53d64
refactor(website): remove old docs system and shadcn UI remnants
blove Apr 4, 2026
41a1e45
docs: add autogenerated API reference design spec
blove Apr 4, 2026
823a8e5
fix(website): update e2e and unit tests for new docs system
blove Apr 4, 2026
4105a2a
docs: add API reference autogen implementation plan
blove Apr 4, 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
11 changes: 11 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "website-dev",
"runtimeExecutable": "/bin/bash",
"runtimeArgs": ["-c", "export PATH=/Users/blove/.nvm/versions/node/v22.14.0/bin:$PATH && npx nx serve website"],
"port": 3000
}
]
}
38 changes: 38 additions & 0 deletions apps/website/content/docs-v2/api/stream-resource.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# streamResource()

Creates a streaming resource connected to a LangGraph agent. Must be called within an Angular injection context.

## Signature

```typescript
function streamResource<TState>(options: StreamResourceOptions<TState>): StreamResource<TState>
```

## Options

| Parameter | Type | Description |
|-----------|------|-------------|
| `assistantId` | `string` | Agent or graph identifier |
| `apiUrl` | `string` | LangGraph Platform base URL |
| `threadId` | `Signal<string \| null> \| string \| null` | Thread to connect to |
| `onThreadId` | `(id: string) => void` | Called when a new thread is created |
| `onInterrupt` | `(data: unknown) => void` | Called when the agent pauses for input |
| `transport` | `StreamTransport` | Custom transport (default: FetchStreamTransport) |

## Return type

streamResource() returns an object with these Signal properties:

| Property | Type | Description |
|----------|------|-------------|
| `messages()` | `Signal<BaseMessage[]>` | Current message list |
| `status()` | `Signal<'idle' \| 'streaming' \| 'error'>` | Stream status |
| `error()` | `Signal<Error \| null>` | Last error, if any |
| `threadId()` | `Signal<string \| null>` | Current thread ID |

## Methods

| Method | Description |
|--------|-------------|
| `submit(input)` | Send a message or resume from interrupt |
| `history()` | Get execution history for time travel |
28 changes: 28 additions & 0 deletions apps/website/content/docs-v2/getting-started/introduction.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Introduction

StreamResource brings full parity with React's `useStream()` hook to Angular 20+. It's the enterprise streaming resource for LangChain and Angular — built natively with Angular Signals, not wrapped or adapted.

<Callout type="info" title="Who is this for?">
StreamResource serves two audiences: Angular developers building AI-powered apps, and AI/agent developers who need an Angular frontend.
</Callout>

## What you'll build

With streamResource(), you can build Angular applications that connect to LangGraph agents with:

- **Token-by-token streaming** via SSE
- **Thread persistence** across sessions
- **Human-in-the-loop** interrupts and approvals
- **Time travel** debugging
- **Deterministic testing** with MockStreamTransport

## Next steps

<CardGroup cols={2}>
<Card title="Quick Start" href="/docs/getting-started/quickstart">
Build your first streaming chat in 5 minutes
</Card>
<Card title="Installation" href="/docs/getting-started/installation">
Detailed setup and configuration guide
</Card>
</CardGroup>
53 changes: 53 additions & 0 deletions apps/website/content/docs-v2/guides/streaming.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Streaming

StreamResource provides token-by-token streaming from LangGraph agents via Server-Sent Events (SSE). Every update lands directly in Angular Signals.

<Callout type="tip" title="Prerequisites">
Make sure you've completed the Installation guide first.
</Callout>

## Basic streaming

<Tabs items={['TypeScript', 'Template']}>
<Tab>

```typescript
// chat.component.ts
const chat = streamResource<{ messages: BaseMessage[] }>({
assistantId: 'chat_agent',
});

// Status updates as streaming progresses
const isStreaming = computed(() => chat.status() === 'streaming');
```

</Tab>
<Tab>

```html
<!-- chat.component.html -->
@for (msg of chat.messages(); track $index) {
<p [class.streaming]="$last && isStreaming()">
{{ msg.content }}
</p>
}
```

</Tab>
</Tabs>

## Stream status

The `status()` signal reports the current state:

<Steps>
<Step title="idle">
No active stream. Ready to send a message.
</Step>
<Step title="streaming">
Tokens are arriving. Messages update in real-time.
</Step>
<Step title="error">
Something went wrong. Check the error() signal for details.
</Step>
</Steps>
14 changes: 6 additions & 8 deletions apps/website/e2e/website.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ test('landing page renders hero headline', async ({ page }) => {
expect(headline).toContain('Angular');
});

test('landing page renders architecture diagram', async ({ page }) => {
test('landing page renders architecture section', async ({ page }) => {
await page.goto('/');
await expect(page.locator('svg[aria-label*="Architecture"]')).toBeVisible();
await expect(page.getByText('Architecture').first()).toBeVisible();
});

test('landing page renders 6 feature cards', async ({ page }) => {
await page.goto('/');
// Feature section contains h2 "Features" and 6 cards
const featureSection = page.locator('section').filter({ hasText: 'Features' });
await expect(featureSection).toBeVisible();
});
Expand All @@ -30,19 +29,18 @@ test('pricing page shows 4 plan cards', async ({ page }) => {
test('pricing page lead form validates required fields', async ({ page }) => {
await page.goto('/pricing');
await page.click('button[type="submit"]');
// HTML5 validation prevents submit — form should still be visible
await expect(page.locator('form')).toBeVisible();
});

test('docs page renders sidebar and content', async ({ page }) => {
await page.goto('/docs/deep-agents/getting-started/overview/overview/python');
await page.goto('/docs/getting-started/introduction');
await expect(page.locator('aside')).toBeVisible();
await expect(page.locator('article')).toBeVisible();
});

test('api reference page renders', async ({ page }) => {
await page.goto('/api-reference');
await expect(page.getByText('streamResource()', { exact: true }).first()).toBeVisible();
test('api reference renders in docs', async ({ page }) => {
await page.goto('/docs/api/stream-resource');
await expect(page.getByText('streamResource()').first()).toBeVisible();
});

test('nav has pricing link', async ({ page }) => {
Expand Down
44 changes: 29 additions & 15 deletions apps/website/lib/design-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,37 @@
*/
export const tokens = {
colors: {
bg: '#080B14',
accent: '#6C8EFF',
accentGlow: 'rgba(108, 142, 255, 0.35)',
accentBorder: 'rgba(108, 142, 255, 0.15)',
accentBorderHover: 'rgba(108, 142, 255, 0.40)',
accentSurface: 'rgba(108, 142, 255, 0.08)',
textPrimary: '#EEF1FF',
textSecondary: '#8B96C8',
textMuted: '#4A527A',
sidebarBg: '#0A0D18',
bg: '#f8f9fc',
accent: '#004090',
accentLight: '#64C3FD',
accentGlow: 'rgba(0, 64, 144, 0.2)',
accentBorder: 'rgba(0, 64, 144, 0.15)',
accentBorderHover: 'rgba(0, 64, 144, 0.3)',
accentSurface: 'rgba(0, 64, 144, 0.06)',
textPrimary: '#1a1a2e',
textSecondary: '#555770',
textMuted: '#8b8fa3',
sidebarBg: 'rgba(255, 255, 255, 0.45)',
angularRed: '#DD0031',
},
glass: {
bg: 'rgba(255, 255, 255, 0.45)',
bgHover: 'rgba(255, 255, 255, 0.55)',
blur: '16px',
border: 'rgba(255, 255, 255, 0.6)',
shadow: '0 4px 24px rgba(0, 0, 0, 0.06)',
},
gradient: {
warm: 'radial-gradient(circle, rgba(221, 0, 49, 0.18), transparent 70%)',
cool: 'radial-gradient(circle, rgba(0, 64, 144, 0.18), transparent 70%)',
coolLight: 'radial-gradient(circle, rgba(100, 195, 253, 0.15), transparent 70%)',
bgFlow: 'linear-gradient(135deg, #fef0f3 0%, #f4f0ff 45%, #eaf3ff 70%, #e6f4ff 100%)',
},
glow: {
hero: '0 0 40px rgba(108, 142, 255, 0.5)',
demo: '0 0 30px rgba(108, 142, 255, 0.25)',
card: '0 0 24px rgba(108, 142, 255, 0.3)',
border: '0 0 12px rgba(108, 142, 255, 0.2)',
button: '0 0 16px rgba(108, 142, 255, 0.4)',
hero: '0 0 60px rgba(0, 64, 144, 0.15)',
demo: '0 0 30px rgba(0, 64, 144, 0.1)',
card: '0 0 24px rgba(0, 64, 144, 0.1)',
border: '0 0 12px rgba(0, 64, 144, 0.08)',
button: '0 0 16px rgba(0, 64, 144, 0.15)',
},
} as const;
43 changes: 0 additions & 43 deletions apps/website/src/app/api-reference/page.tsx

This file was deleted.

32 changes: 17 additions & 15 deletions apps/website/src/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import { notFound } from 'next/navigation';
import { DocsSidebar } from '../../../components/docs/DocsSidebar';
import { MdxRenderer } from '../../../components/docs/MdxRenderer';
import { OpenInCockpit } from '../../../components/docs/open-in-cockpit';
import { getDocBySlug, getAllDocSlugs, getPromptBySlug } from '../../../lib/docs';
import { DocsSidebarNew } from '../../../components/docs/DocsSidebarNew';
import { MdxRendererNew } from '../../../components/docs/MdxRenderer';
import { DocsSearch } from '../../../components/docs/DocsSearch';
import { getDocBySlug, getAllDocSlugs } from '../../../lib/docs-new';

export function generateStaticParams() {
return getAllDocSlugs().map((slug) => ({ slug }));
return getAllDocSlugs().map(({ section, slug }) => ({ slug: [section, slug] }));
}

export default async function DocsPage({ params }: { params: Promise<{ slug?: string[] }> }) {
const { slug: rawSlug } = await params;
const slug = rawSlug ?? ['deep-agents', 'getting-started', 'overview', 'overview', 'python'];
const doc = getDocBySlug(slug);
const slugParts = rawSlug ?? ['getting-started', 'introduction'];

const [section, slug] = slugParts.length >= 2
? [slugParts[0], slugParts[1]]
: ['getting-started', 'introduction'];

const doc = getDocBySlug(section, slug);
if (!doc) notFound();
const prompt = getPromptBySlug(slug) ?? undefined;

return (
<div className="flex min-h-screen pt-16">
<DocsSidebar activeSlug={slug.join('/')} />
<div className="flex-1">
<div className="px-8 pt-8">
<OpenInCockpit bundle={doc.bundle} />
</div>
<MdxRenderer source={doc.content} prompt={prompt} />
<div className="flex min-h-screen pt-16" style={{ background: 'var(--gradient-bg-flow)' }}>
<DocsSearch />
<DocsSidebarNew activeSection={section} activeSlug={slug} />
<div className="flex-1" style={{ background: 'rgba(255, 255, 255, 0.85)' }}>
<MdxRendererNew source={doc.content} section={section} slug={slug} title={doc.title} />
</div>
</div>
);
Expand Down
Loading