Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
148 changes: 31 additions & 117 deletions docs/content/docs/api-reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ npx @openuidev/cli@latest create --name my-app --no-skill

## `openui generate`

Generates a system prompt or JSON schema from a file that exports a `createLibrary()` result.
Generates the system prompt **and** the serialized library spec from a file that exports a `createLibrary()` result. A single run emits both artifacts — they derive from the same `Library` instance, so they can never drift apart. Use the spec with `generateSystemPrompt` in backend routes; the prompt file supports static or legacy integrations.

```
openui generate [entry] [options]
Expand All @@ -167,27 +167,31 @@ openui generate [entry] [options]

**Options**

| Flag | Description |
| ------------------------- | -------------------------------------------------------------------- |
| `-o, --out <file>` | Write output to a file instead of stdout |
| `--json-schema` | Output JSON schema instead of a system prompt |
| `--export <name>` | Name of the export to use (auto-detected by default) |
| `--prompt-options <name>` | Name of the `PromptOptions` export to use (auto-detected by default) |
| `--no-interactive` | Fail instead of prompting for missing `entry` |
| `--agent-name <name>` | Declare the invoking coding-agent slug (default: `unknown`) |
| Flag | Description |
| ------------------------- | ------------------------------------------------------------------------------------------- |
| `-o, --out <file>` | Write the prompt to `<file>`; the spec uses the same basename with a `.spec.json` extension |
| `--json-schema` | Output only the JSON schema; it is not the input to `generateSystemPrompt` |
| `--spec` | Output only the serialized library spec |
| `--export <name>` | Name of the export to use (auto-detected by default) |
| `--prompt-options <name>` | Name of the `PromptOptions` export to use (auto-detected by default) |
| `--no-interactive` | Fail instead of prompting for missing `entry` |
| `--agent-name <name>` | Declare the invoking coding-agent slug (default: `unknown`) |

**Examples**

```bash tab="pnpm" tab-group="pkg"
# Print system prompt to stdout
pnpx @openuidev/cli@latest generate ./src/library.ts

# Write system prompt to a file
# Write both artifacts; use the sibling .spec.json file with generateSystemPrompt
pnpx @openuidev/cli@latest generate ./src/library.ts --out ./src/generated/system-prompt.txt

# Output JSON schema instead
# Output JSON schema for external tooling (not generateSystemPrompt)
pnpx @openuidev/cli@latest generate ./src/library.ts --json-schema

# Output only the spec file
pnpx @openuidev/cli@latest generate ./src/library.ts --spec

# Explicit export names
pnpx @openuidev/cli@latest generate ./src/library.ts --export myLibrary --prompt-options myOptions
```
Expand All @@ -196,12 +200,15 @@ pnpx @openuidev/cli@latest generate ./src/library.ts --export myLibrary --prompt
# Print system prompt to stdout
bunx @openuidev/cli@latest generate ./src/library.ts

# Write system prompt to a file
# Write both artifacts; use the sibling .spec.json file with generateSystemPrompt
bunx @openuidev/cli@latest generate ./src/library.ts --out ./src/generated/system-prompt.txt

# Output JSON schema instead
# Output JSON schema for external tooling (not generateSystemPrompt)
bunx @openuidev/cli@latest generate ./src/library.ts --json-schema

# Output only the spec file
bunx @openuidev/cli@latest generate ./src/library.ts --spec

# Explicit export names
bunx @openuidev/cli@latest generate ./src/library.ts --export myLibrary --prompt-options myOptions
```
Expand All @@ -210,12 +217,15 @@ bunx @openuidev/cli@latest generate ./src/library.ts --export myLibrary --prompt
# Print system prompt to stdout
yarn dlx @openuidev/cli@latest generate ./src/library.ts

# Write system prompt to a file
# Write both artifacts; use the sibling .spec.json file with generateSystemPrompt
yarn dlx @openuidev/cli@latest generate ./src/library.ts --out ./src/generated/system-prompt.txt

# Output JSON schema instead
# Output JSON schema for external tooling (not generateSystemPrompt)
yarn dlx @openuidev/cli@latest generate ./src/library.ts --json-schema

# Output only the spec file
yarn dlx @openuidev/cli@latest generate ./src/library.ts --spec

# Explicit export names
yarn dlx @openuidev/cli@latest generate ./src/library.ts --export myLibrary --prompt-options myOptions
```
Expand All @@ -224,12 +234,15 @@ yarn dlx @openuidev/cli@latest generate ./src/library.ts --export myLibrary --pr
# Print system prompt to stdout
npx @openuidev/cli@latest generate ./src/library.ts

# Write system prompt to a file
# Write both artifacts; use the sibling .spec.json file with generateSystemPrompt
npx @openuidev/cli@latest generate ./src/library.ts --out ./src/generated/system-prompt.txt

# Output JSON schema instead
# Output JSON schema for external tooling (not generateSystemPrompt)
npx @openuidev/cli@latest generate ./src/library.ts --json-schema

# Output only the spec file
npx @openuidev/cli@latest generate ./src/library.ts --spec

# Explicit export names
npx @openuidev/cli@latest generate ./src/library.ts --export myLibrary --prompt-options myOptions
```
Expand Down Expand Up @@ -302,104 +315,6 @@ yarn dlx @openuidev/cli@latest generate ./src/library.ts --out src/generated/sys
npx @openuidev/cli@latest generate ./src/library.ts --out src/generated/system-prompt.txt
```

## `openui generate-spec`

Generates a serialized library spec as JSON — component signatures, component groups, and the library's JSON schema — from a file that exports a `createLibrary()` result.

```
openui generate-spec [entry] [options]
```

The spec is a handover artifact: the team that owns the component library generates it once and hands the JSON to whoever configures the model server — for example as the `chatLibrary` config value in OpenUI Cloud. The server rebuilds the system prompt, response validation, and sanitization from the spec, so the model can only be prompted with components the library actually registers.

**Arguments**

| Argument | Description |
| --------- | ----------------------------------------------------------------------- |
| `[entry]` | Path to a `.ts`, `.tsx`, `.js`, or `.jsx` file that exports a `Library` |

**Options**

| Flag | Description |
| --------------------- | ----------------------------------------------------------- |
| `-o, --out <file>` | Write output to a file instead of stdout |
| `--export <name>` | Name of the export to use (auto-detected by default) |
| `--no-interactive` | Fail instead of prompting for missing `entry` |
| `--agent-name <name>` | Declare the invoking coding-agent slug (default: `unknown`) |

Entry bundling and library detection work the same as [`openui generate`](#export-auto-detection). `PromptOptions` exports are not folded into the spec — the spec is pure library data; consumers apply prompt customisation separately when they build the system prompt.

**Output**

{/* prettier-ignore */}
```jsonc
{
// Optional root component the response must start with
"root": "Page",
// Pre-rendered signatures, for review and inspection
"components": {
"Metric": {
"signature": "Metric(label: string, value: string, trend?: \"up\" | \"down\")",
"description": "A single KPI stat"
}
},
// Optional grouping, mirrored into the generated prompt
"componentGroups": [{ "name": "Data display", "components": ["Metric"] }],
// JSON schema of every registered component ($defs keyed by component name)
"schema": {
"$defs": {
"Metric": { "type": "object", "description": "A single KPI stat", "properties": { /* … */ } }
}
}
}
```

**Examples**

```bash tab="pnpm" tab-group="pkg"
# Print the spec to stdout
pnpx @openuidev/cli@latest generate-spec ./src/library.ts

# Write the handover file
pnpx @openuidev/cli@latest generate-spec ./src/library.ts --out ./library-spec.json

# Explicit export name
pnpx @openuidev/cli@latest generate-spec ./src/library.ts --export myLibrary
```

```bash tab="bun" tab-group="pkg"
# Print the spec to stdout
bunx @openuidev/cli@latest generate-spec ./src/library.ts

# Write the handover file
bunx @openuidev/cli@latest generate-spec ./src/library.ts --out ./library-spec.json

# Explicit export name
bunx @openuidev/cli@latest generate-spec ./src/library.ts --export myLibrary
```

```bash tab="yarn" tab-group="pkg"
# Print the spec to stdout
yarn dlx @openuidev/cli@latest generate-spec ./src/library.ts

# Write the handover file
yarn dlx @openuidev/cli@latest generate-spec ./src/library.ts --out ./library-spec.json

# Explicit export name
yarn dlx @openuidev/cli@latest generate-spec ./src/library.ts --export myLibrary
```

```bash tab="npm" tab-group="pkg"
# Print the spec to stdout
npx @openuidev/cli@latest generate-spec ./src/library.ts

# Write the handover file
npx @openuidev/cli@latest generate-spec ./src/library.ts --out ./library-spec.json

# Explicit export name
npx @openuidev/cli@latest generate-spec ./src/library.ts --export myLibrary
```

## Coding-agent attribution

When a coding agent invokes any CLI command, it should pass `--agent-name` using its stable,
Expand All @@ -418,7 +333,6 @@ manager selected for dependency installation (`npm`, `pnpm`, `yarn`, or `bun`).

<Cards>
<Card title="@openuidev/react-lang" href="/docs/api-reference/react-lang">
`createLibrary`, `PromptOptions`, and the `Library` interface that `openui generate` and `openui
generate-spec` read.
`createLibrary`, `PromptOptions`, and the `Library` interface that `openui generate` read.
</Card>
</Cards>
2 changes: 1 addition & 1 deletion docs/content/docs/api-reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The OpenUI SDK is split into packages that build on each other:
CDN, iframe, and no-build browser bundle for the renderer, UI library, React, and styles.
</Card>
<Card title="@openuidev/cli" href="/docs/api-reference/cli">
openui create (scaffold a Next.js app) and openui generate (system prompt / JSON schema from a
openui create (scaffold a Next.js app) and openui generate (system prompt + library spec from a
library definition).
</Card>
</Cards>
10 changes: 4 additions & 6 deletions docs/content/docs/openui-lang/how-it-works.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,12 @@ const tools: ToolSpec[] = [

```ts
// route.ts
import { generatePrompt } from "@openuidev/lang-core";
import { generateSystemPrompt, type LibrarySpec } from "@openuidev/lang-core";
import componentSpec from "./generated/component-spec.json";

const systemPrompt = generatePrompt({
...componentSpec,
tools,
toolCalls: true,
bindings: true,
const systemPrompt = generateSystemPrompt({
library: componentSpec as LibrarySpec,
promptOptions: { tools, toolCalls: true, bindings: true },
});

const completion = await openai.chat.completions.create({
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/openui-lang/incremental-editing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ const config: PromptSpec = {

**`inlineMode`** lets the LLM respond with explanation text alongside the code. The parser extracts code from fenced blocks (` ```openui-lang `) and ignores everything else. This way the LLM can say "I added a pie chart for the status breakdown" before the patch, which gives the user context about what changed.

Both flags are passed to `generatePrompt()` via your `PromptSpec`. See [System Prompts](/docs/openui-lang/system-prompts) for the full reference.
Both flags are passed to `generateSystemPrompt()` via `promptOptions`. See [System Prompts](/docs/openui-lang/system-prompts) for the full reference.
18 changes: 14 additions & 4 deletions docs/content/docs/openui-lang/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,26 @@ src/
route.ts # Backend route with OpenAI streaming + example tools
library.ts # Re-exports openuiChatLibrary and openuiChatPromptOptions
generated/
system-prompt.txt # Auto-generated at build time via `openui generate`
system-prompt.txt # Generated for static or legacy prompt integrations
system-prompt.spec.json # Generated library spec
```

- **`page.tsx`**: Renders the `AgentInterface` chat (an artifact chat surface with thread history) with `openuiChatLibrary` for Generative UI rendering. It provides an `llm` whose `send` posts messages to the route and whose `streamProtocol` is `openAIAdapter()`. Storage is optional — omit it and threads are kept in memory (wiped on reload).
- **`route.ts`**: A backend API route that sends the system prompt to the LLM and streams the response back.
- **`library.ts`**: Your component library entrypoint. The `openui generate` CLI reads this file to produce the system prompt.
- **`route.ts`**: A backend API route that uses `generateSystemPrompt` with the generated spec, then streams the response from the LLM.
- **`library.ts`**: Your component library entrypoint. The `openui generate` CLI reads this file to produce both the prompt and the library spec.

The `dev` and `build` scripts automatically regenerate the system prompt before starting:
The `dev` and `build` scripts automatically regenerate both artifacts before starting. Use the emitted spec in your route:

```json
"generate:prompt": "openui generate src/library.ts --out src/generated/system-prompt.txt",
"dev": "pnpm generate:prompt && next dev"
```

```ts
import { generateSystemPrompt, type LibrarySpec } from "@openuidev/lang-core";
import librarySpec from "../../../generated/system-prompt.spec.json";

const systemPrompt = generateSystemPrompt({
library: librarySpec as LibrarySpec,
});
```
15 changes: 9 additions & 6 deletions docs/content/docs/openui-lang/standard-library.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ import { openuiLibrary } from "@openuidev/react-ui";
<Renderer library={openuiLibrary} response={streamedText} isStreaming={isStreaming} />;
```

## Generate prompt
## Generate a spec and build the prompt

Use the CLI to generate the system prompt at build time:
Use the CLI to generate the prompt and serialized library spec at build time. In your backend, use the spec with `generateSystemPrompt`:

```bash tab="pnpm" tab-group="pkg"
pnpx @openuidev/cli@latest generate ./src/library.ts --out src/generated/system-prompt.txt
Expand All @@ -53,12 +53,15 @@ yarn dlx @openuidev/cli@latest generate ./src/library.ts --out src/generated/sys
npx @openuidev/cli@latest generate ./src/library.ts --out src/generated/system-prompt.txt
```

Or generate programmatically:
The command writes `src/generated/system-prompt.spec.json` beside the prompt file. Import that spec in your backend:

```ts
import { openuiLibrary, openuiPromptOptions } from "@openuidev/react-ui";
import { generateSystemPrompt, type LibrarySpec } from "@openuidev/lang-core";
import librarySpec from "./generated/system-prompt.spec.json";

const systemPrompt = openuiLibrary.prompt(openuiPromptOptions);
const systemPrompt = generateSystemPrompt({
library: librarySpec as LibrarySpec,
});
```

## Extend it
Expand Down Expand Up @@ -89,4 +92,4 @@ const myLibrary = createLibrary({

- Default root component is `Stack`.
- `Form` requires explicit `buttons`.
- Signature truth source is `openuiLibrary.prompt(openuiPromptOptions)`.
- The generated library spec is the backend prompt source of truth
Loading
Loading