Skip to content

Commit 7d0174d

Browse files
bloveclaude
andauthored
docs: voice pass on getting-started — chat, render, ag-ui, licensing, telemetry (#585)
* docs(spec): voice pass — getting-started batch 2 (chat/render/ag-ui/licensing/telemetry) Reuse the approved getting-started voice rubric + guardrails (prose-only, diff-gated) across the remaining libraries' getting-started pages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(plan): voice pass — getting-started batch 2 implementation plan Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(chat): voice pass on getting-started pages * docs(render): voice pass on getting-started pages * docs(ag-ui): voice pass on getting-started pages * docs(licensing,telemetry): voice pass on getting-started intros --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent ea2b6e8 commit 7d0174d

13 files changed

Lines changed: 383 additions & 32 deletions

File tree

apps/website/content/docs/ag-ui/getting-started/installation.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const appConfig: ApplicationConfig = {
8787
};
8888
```
8989

90-
`FakeAgent` extends `AbstractAgent` and emits a canned `RUN_STARTED -> TEXT_MESSAGE_START -> TEXT_MESSAGE_CONTENT x N -> TEXT_MESSAGE_END -> RUN_FINISHED` sequence. Drop-in replacement for `provideAgent({ url })` while you're prototyping.
90+
`FakeAgent` extends `AbstractAgent` and emits a canned `RUN_STARTED -> TEXT_MESSAGE_START -> TEXT_MESSAGE_CONTENT x N -> TEXT_MESSAGE_END -> RUN_FINISHED` sequence. It's a drop-in replacement for `provideAgent({ url })` while you're prototyping.
9191

9292
## Custom transport
9393

apps/website/content/docs/ag-ui/getting-started/introduction.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
> **Picking an adapter?** This guide covers `@threadplane/ag-ui` — the AG-UI protocol adapter. If you're talking to LangGraph Platform directly via the LangGraph SDK, use [`@threadplane/langgraph`](/langgraph) instead. See [Choosing an adapter](/docs/choosing-an-adapter) for a side-by-side comparison.
44
5-
`@threadplane/ag-ui` is the runtime adapter that wraps an [AG-UI](https://github.com/ag-ui-protocol/ag-ui) `AbstractAgent` into the runtime-neutral `Agent` contract from `@threadplane/chat`. The chat UI primitives consume the Agent contract; the AG-UI adapter translates between the contract and the AG-UI event protocol.
5+
`@threadplane/ag-ui` is the runtime adapter that wraps an [AG-UI](https://github.com/ag-ui-protocol/ag-ui) `AbstractAgent` into the runtime-neutral `Agent` contract from `@threadplane/chat`. The chat UI primitives consume the Agent contract, and the AG-UI adapter translates between the contract and the AG-UI event protocol.
66

77
<Callout type="info" title="What is AG-UI?">
88
AG-UI is the open agent-to-UI protocol from the CopilotKit ecosystem. It standardizes how agent runtimes stream events (messages, tool calls, state updates) to a frontend. Used by **CrewAI**, **Mastra**, **Microsoft Agent Framework**, **AG2**, **Pydantic AI**, **AWS Strands**, and the **CopilotKit runtime**. One adapter unlocks all of them.
@@ -32,7 +32,7 @@ AG-UI is the open agent-to-UI protocol from the CopilotKit ecosystem. It standar
3232

3333
## What's covered
3434

35-
Scope of the first release:
35+
Here's what the first release handles:
3636
- `messages` (streaming token deltas via `TEXT_MESSAGE_*` events)
3737
- `status` / `isLoading` / `error` (lifecycle via `RUN_STARTED/FINISHED/ERROR`)
3838
- `toolCalls` (streaming tool calls via `TOOL_CALL_*` events)

apps/website/content/docs/ag-ui/getting-started/quickstart.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Quick Start
22

3-
Bind `<chat>` from `@threadplane/chat` to an AG-UI backend in 5 minutes.
3+
Let's bind `<chat>` from `@threadplane/chat` to an AG-UI backend in 5 minutes.
44

55
<Callout type="info" title="Prerequisites">
66
Angular 20+ project with Node.js 22+. If you need setup help, see the [Installation](/docs/ag-ui/getting-started/installation) guide.
@@ -30,7 +30,7 @@ export const appConfig: ApplicationConfig = {
3030
};
3131
```
3232

33-
For offline development without a backend, swap to `provideFakeAgent({})` - it serves canned streaming responses for UI work.
33+
No backend yet? Swap to `provideFakeAgent({})` - it serves canned streaming responses so you can build UI offline.
3434

3535
</Step>
3636
<Step title="Use in a component">
@@ -67,7 +67,9 @@ That's it. The `<chat>` composition handles streaming messages, tool calls, erro
6767

6868
## Switching backends without changing UI
6969

70-
The point of the runtime-neutral `Agent` contract is that swapping backends is a one-line change in `app.config.ts`. The component code stays the same:
70+
For me, the runtime-neutral `Agent` contract is the whole payoff: your component never learns which protocol it's talking to. The cost is a thin translation layer per adapter, but you pay it once and your UI code stops caring.
71+
72+
So swapping backends is a one-line change in `app.config.ts`, and the component code stays the same:
7173

7274
```diff
7375
- providers: [provideAgent({ apiUrl: '...' })], // LangGraph

apps/website/content/docs/chat/getting-started/installation.mdx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
A complete walkthrough for installing `@threadplane/chat` in an Angular 20+ application, activating a commercial license, and rendering your first chat in under 30 minutes.
44

5+
This guide goes deeper than the Quick Start: license activation, peer dependencies, and the warnings you'll see in the console.
6+
57
<Callout type="info" title="Just bought a license?">
68
This guide is written for customers who purchased a Developer Seat, Team, or Enterprise plan and received a `THREADPLANE_LICENSE` token by email. If you're evaluating `@threadplane/chat` for noncommercial use, you can skip the license steps — the library runs without a token (with a one-time advisory warning).
79
</Callout>
@@ -16,7 +18,7 @@ This guide is written for customers who purchased a Developer Seat, Team, or Ent
1618
Required for the Angular build toolchain. `node --version` should report `v18` or newer.
1719
</Step>
1820
<Step title="A running agent backend (or a mock)">
19-
You need something for the chat UI to talk to. Two officially supported adapters cover virtually every backend:
21+
The chat UI needs something to talk to. Two officially supported adapters cover virtually every backend:
2022

2123
- **`@threadplane/langgraph`** — pick this if your backend is LangGraph or LangGraph Platform.
2224
- **`@threadplane/ag-ui`** — pick this for any AG-UI compatible backend (CrewAI, Mastra, Microsoft Agent Framework, AG2, Pydantic AI, AWS Strands, CopilotKit runtime).
@@ -53,7 +55,7 @@ eyJzdWIiOiJjdXN0QGV4YW1wbGUuY29tIiwidGllciI6ImRldmVsb3Blci1zZWF0IiwiaWF0IjoxNzM
5355

5456
The token is signed with Ed25519. Verification is **offline** and **advisory** — a missing or expired token logs one `console.warn` line on first boot and the chat keeps working. There is no kill switch, no network call, no telemetry.
5557

56-
That makes how you store the token a matter of secret-management preference rather than runtime correctness. Pick whichever flow fits your team.
58+
So how you store the token is a matter of secret-management preference, not runtime correctness. Pick whichever flow fits your team.
5759

5860
### Option A: `.env` file (recommended for local dev)
5961

@@ -95,7 +97,7 @@ provideChat({
9597
});
9698
```
9799

98-
This is the lowest-friction path for small teams. Do **not** commit the token to a public repository — anyone with the token can use the seats it grants.
100+
For me, this is the lowest-friction path for a small team — the tradeoff is that everyone with repo access also gets the token. Do **not** commit it to a public repository — anyone with the token can use the seats it grants.
99101

100102
## 3. Wire `provideChat()` and `provideAgent()`
101103

@@ -132,7 +134,7 @@ provideChat({
132134
});
133135
```
134136

135-
`provideChat()` itself is optional — chat components fall back to sensible defaults — but you'll want it once you start passing a license, an `assistantName`, or other global config.
137+
`provideChat()` itself is optional — chat components fall back to sensible defaults — but you'll want it once you start passing a license, an `assistantName`, or any other global config.
136138

137139
## 4. Render your first chat
138140

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Introduction
22

3-
`@threadplane/chat` is the Angular UI component library for building chat interfaces on top of a runtime-neutral `Agent` contract. It provides a complete set of composable, Signal-driven components that render messages, handle user input, display tool calls, manage interrupts, and support generative UI -- all styled with CSS custom properties and built for Angular 20+.
3+
`@threadplane/chat` is the Angular UI component library for building chat interfaces on top of a runtime-neutral `Agent` contract. It's a set of composable, Signal-driven components that render messages, handle user input, display tool calls, manage interrupts, and support generative UI -- all styled with CSS custom properties and built for Angular 20+.
44

55
<Callout type="info" title="What you'll learn">
66
This guide explains the library's two-tier architecture, how it relates to the rest of the Threadplane stack, and when to reach for the all-in-one composition versus assembling primitives yourself.
@@ -12,7 +12,7 @@ The library is organized into two layers: **primitives** and **compositions**.
1212

1313
### Primitives
1414

15-
Primitives are low-level, headless components that read from an `Agent` and expose their state through content projection (`ng-template`). They carry no opinion about layout or styling. Use them when you need full control over how chat elements render.
15+
Primitives are low-level, headless components that read from an `Agent` and expose their state through content projection (`ng-template`). They carry no opinion about layout or styling. Reach for them when you need full control over how chat elements render.
1616

1717
| Primitive | Selector | Purpose |
1818
|-----------|----------|---------|
@@ -64,7 +64,7 @@ LangGraph Platform
6464

6565
## When to Use `ChatComponent` vs. Custom Assembly
6666

67-
**Use `ChatComponent`** when you want a complete, styled chat interface with minimal setup. It includes message rendering (with markdown), a text input, typing indicator, error display, interrupt banner, and an optional thread sidebar. Drop it in, pass an `Agent`, and you have a working chat.
67+
**Use `ChatComponent`** when you want a complete, styled chat interface with minimal setup. It includes message rendering (with markdown), a text input, typing indicator, error display, interrupt banner, and an optional thread sidebar. Drop it in, pass an `Agent`, and you've got a working chat.
6868

6969
```html
7070
<chat [agent]="chatRef" />

apps/website/content/docs/chat/getting-started/quickstart.mdx

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

3-
Build a streaming chat UI with `@threadplane/chat` in 5 minutes.
3+
Let's build a streaming chat UI with `@threadplane/chat` in 5 minutes.
44

55
<Callout type="info" title="Prerequisites">
66
Angular 20+ project with an agent provider configured. See [Agent Installation](/docs/langgraph/getting-started/installation) if you need help.

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
`@threadplane/licensing` is the shared license-check helper used by `@threadplane/chat` and by custom integrations that opt into the same warning behavior. It verifies compact Ed25519-signed tokens offline, evaluates the result into a small status set, and emits non-blocking warnings when appropriate.
44

5-
The package itself is MIT licensed. `COMMERCIAL.md` states that the libraries in this repository are free to use, modify, and distribute in commercial and noncommercial projects. The proprietary part called out there is the internal minting service, not this package.
5+
The package itself is MIT licensed. `COMMERCIAL.md` says the libraries in this repository are free to use, modify, and distribute in commercial and noncommercial projects. The proprietary part it calls out is the internal minting service, not this package.
66

77
## Public API shape
88

@@ -61,10 +61,10 @@ The default grace window is 14 days.
6161

6262
## Runtime posture
6363

64-
The higher-level check is designed not to block app startup:
64+
The higher-level check is built not to block app startup:
6565

6666
- signature verification is local;
6767
- warning output goes through `console.warn` unless a custom `warn` function is supplied;
6868
- no network request is made by the licensing check.
6969

70-
The code returns statuses instead of throwing for normal license states. Consumers can choose what to do with the status, and `@threadplane/chat` uses it as a warning and visibility mechanism, not as an app kill switch.
70+
The code returns statuses instead of throwing for normal license states. For me, that's the right default here: you get to decide what a missing or expired license means for your app instead of having the check make that call for you. The tradeoff is that nothing stops a consumer from ignoring the status entirely. `@threadplane/chat` treats it as a warning and visibility mechanism, not an app kill switch.

apps/website/content/docs/render/getting-started/installation.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ The library requires the following peer dependencies:
3030
| `@json-render/core` | `^0.16.0` |
3131

3232
<Callout type="info" title="Angular packages">
33-
`@angular/core` and `@angular/common` are already part of any Angular 20+ project. You only need to install `@json-render/core` as an additional dependency if your package manager does not install peer dependencies automatically.
33+
`@angular/core` and `@angular/common` are already part of any Angular 20+ project. You only need to install `@json-render/core` yourself if your package manager doesn't install peer dependencies automatically.
3434
</Callout>
3535

3636
## Configure the Provider
3737

38-
Add `provideRender()` to your application configuration. This sets global defaults for all `<render-spec>` instances in your application.
38+
Add `provideRender()` to your application config. This sets global defaults for every `<render-spec>` instance in your app.
3939

4040
```typescript
4141
// app.config.ts
@@ -57,12 +57,12 @@ export const appConfig: ApplicationConfig = {
5757
```
5858

5959
<Callout type="tip" title="provideRender() is optional">
60-
`provideRender()` is a convenience for setting global defaults. You can skip it entirely and pass `registry`, `store`, `functions`, and `handlers` as inputs directly to `<render-spec>`. Inputs always take precedence over provider config.
60+
`provideRender()` is just a convenience for setting global defaults. You can skip it entirely and pass `registry`, `store`, `functions`, and `handlers` as inputs directly to `<render-spec>`. Inputs always win over provider config.
6161
</Callout>
6262

6363
## Minimal App Setup
6464

65-
Here is a complete minimal application setup:
65+
Here's a complete minimal setup:
6666

6767
<Tabs>
6868
<Tab label="app.config.ts">
@@ -132,13 +132,13 @@ export class AppComponent {
132132

133133
## Verify Installation
134134

135-
After setting up, run your application and verify the rendered output:
135+
Once you're set up, run your app and check the rendered output:
136136

137137
```bash
138138
ng serve
139139
```
140140

141-
If you see your component rendered with the expected props, the installation is complete.
141+
If you see your component rendered with the expected props, you're done.
142142

143143
## Troubleshooting
144144

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
## Why @threadplane/render?
66

7-
Building dynamic UIs from server-driven specifications is a common pattern in AI applications, form builders, and CMS-powered frontends. `@threadplane/render` bridges the gap between `@json-render/core` (a framework-agnostic spec evaluation engine) and Angular's component model.
7+
Building dynamic UIs from server-driven specs shows up everywhere -- AI apps, form builders, CMS-powered frontends. `@threadplane/render` bridges `@json-render/core` (a framework-agnostic spec evaluation engine) and Angular's component model.
88

9-
Instead of writing imperative rendering logic, you describe your UI as a JSON spec and let the library handle the rest:
9+
You don't write imperative rendering logic. You describe your UI as a JSON spec and let the library handle the rest:
1010

1111
```typescript
1212
const spec: Spec = {
@@ -25,7 +25,7 @@ const spec: Spec = {
2525
<render-spec [spec]="spec" [registry]="registry" />
2626
```
2727

28-
The library resolves `Text` from your component registry, evaluates the `$state` expression against the state store, and renders your `TextComponent` with `label` set to `"Hello, world!"`. When the state changes, the component updates automatically via Angular Signals.
28+
The library resolves `Text` from your component registry, evaluates the `$state` expression against the state store, and renders your `TextComponent` with `label` set to `"Hello, world!"`. When the state changes, the component updates on its own via Angular Signals.
2929

3030
## How It Relates to @json-render/core
3131

apps/website/content/docs/render/getting-started/quickstart.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Angular 20+ project with `@threadplane/render` installed. See the [Installation]
99
<Steps>
1010
<Step title="Create a component to render">
1111

12-
Define a simple Angular component that will be rendered by the spec. Every rendered component receives inputs matching the `AngularComponentInputs` interface -- your custom props are spread alongside the standard inputs.
12+
Let's start with a simple Angular component for the spec to render. Every rendered component receives inputs matching the `AngularComponentInputs` interface -- your custom props are spread alongside the standard inputs.
1313

1414
```typescript
1515
// text.component.ts
@@ -46,7 +46,7 @@ export const uiRegistry = defineAngularRegistry({
4646
</Step>
4747
<Step title="Build a spec">
4848

49-
A spec describes the UI tree as a flat map of elements. The `root` key points to the entry element.
49+
Now let's describe the UI tree itself. A spec is a flat map of elements, and the `root` key points to the entry element.
5050

5151
```typescript
5252
// app.component.ts
@@ -93,7 +93,7 @@ Open `http://localhost:4200`. You should see "Hello from @threadplane/render!" r
9393

9494
## Adding Reactive State
9595

96-
Specs become powerful when you connect them to a state store. Props with `$state` expressions read from the store reactively.
96+
Specs get a lot more interesting once you connect them to a state store. Props with `$state` expressions read from the store reactively.
9797

9898
```typescript
9999
import { Component, ChangeDetectionStrategy } from '@angular/core';
@@ -135,7 +135,7 @@ Clicking the button updates the store, which reactively updates the rendered `Te
135135

136136
## Using Spec-Embedded State
137137

138-
You can also embed initial state directly in the spec. When no external store is provided, `RenderSpecComponent` automatically creates an internal `signalStateStore` from `spec.state`:
138+
You can also embed initial state right in the spec. When you don't pass an external store, `RenderSpecComponent` creates an internal `signalStateStore` from `spec.state` for you:
139139

140140
```typescript
141141
spec: Spec = {

0 commit comments

Comments
 (0)