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
15 changes: 14 additions & 1 deletion docs/content/docs/api-reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ openui create [options]
| Flag | Description |
|---|---|
| `-n, --name <string>` | Project name (directory to create) |
| `--skill` | Install the OpenUI agent skill for AI coding assistants |
| `--no-skill` | Skip installing the OpenUI agent skill |
| `--no-interactive` | Fail instead of prompting for missing input |

When run interactively (default), the CLI prompts for any missing options. Pass `--no-interactive` in CI or scripted environments to surface missing required flags as errors instead.
Expand All @@ -41,18 +43,29 @@ When run interactively (default), the CLI prompts for any missing options. Pass
2. Rewrites `workspace:*` dependency versions to `latest`
3. Auto-detects your package manager (npm, pnpm, yarn, bun)
4. Installs dependencies
5. Optionally installs the [OpenUI agent skill](/docs/openui-lang/agent-skill) for AI coding assistants (e.g. Claude, Cursor, Copilot)

The generated project includes a `generate:prompt` script that runs `openui generate` as part of `dev` and `build`.

**Agent skill**

When run interactively, `openui create` asks whether to install the OpenUI agent skill. The skill teaches AI coding assistants how to build with OpenUI Lang — covering component definitions, system prompts, the Renderer, and debugging.

Pass `--skill` or `--no-skill` to skip the prompt. In `--no-interactive` mode the skill is skipped unless `--skill` is explicitly passed.

**Examples**

```bash
# Interactive — prompts for project name
# Interactive — prompts for project name and skill installation
openui create

# Non-interactive
openui create --name my-app
openui create --no-interactive --name my-app

# Explicitly install or skip the agent skill
openui create --name my-app --skill
openui create --name my-app --no-skill
```

## `openui generate`
Expand Down
15 changes: 11 additions & 4 deletions packages/openui-cli/src/commands/create-chat-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import * as fs from "fs";
import * as path from "path";

import { detectPackageManager } from "../lib/detect-package-manager";
import { runSkillInstall, shouldInstallSkill } from "../lib/install-skill";
import { resolveArgs } from "../lib/resolve-args";

export interface CreateChatAppOptions {
name?: string;
skill?: boolean;
noInteractive?: boolean;
}

Expand Down Expand Up @@ -93,6 +95,11 @@ export async function runCreateChatApp(options: CreateChatAppOptions): Promise<v
process.exit(1);
}

const installSkill = await shouldInstallSkill(options.skill, !options.noInteractive);
if (installSkill) {
runSkillInstall(targetDir);
}

const devCmd =
runner === "pnpm dlx"
? "pnpm"
Expand All @@ -102,13 +109,13 @@ export async function runCreateChatApp(options: CreateChatAppOptions): Promise<v
? "bun"
: "npm";

console.info(getStartedMessage(name, devCmd));
console.info(getStartedMessage(name, devCmd, installSkill));
}

const getStartedMessage = (name: string, devCmd: string) =>
const getStartedMessage = (name: string, devCmd: string, skillInstalled: boolean) =>
`
Done!
Get started:
Get started:

cd ${name}

Expand All @@ -118,4 +125,4 @@ Add your API key to .env:
OPENAI_API_KEY=sk-your-key-here

${devCmd} run dev
`;
${skillInstalled ? "\nThe OpenUI agent skill was installed.\nAI coding assistants will use it to help you build with OpenUI.\n" : ""}`;
10 changes: 8 additions & 2 deletions packages/openui-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ program
.command("create")
.description("Scaffold a new Next.js app with OpenUI Chat")
.option("-n, --name <string>", "Project name")
.option("--skill", "Install the OpenUI agent skill for AI coding assistants")
.option("--no-skill", "Skip installing the OpenUI agent skill")
.option("--no-interactive", "Fail with error if required args are missing")
.action(async (options: { name?: string; interactive: boolean }) => {
await runCreateChatApp({ name: options.name, noInteractive: !options.interactive });
.action(async (options: { name?: string; skill?: boolean; interactive: boolean }) => {
await runCreateChatApp({
name: options.name,
skill: options.skill,
noInteractive: !options.interactive,
});
});

program
Expand Down
39 changes: 39 additions & 0 deletions packages/openui-cli/src/lib/install-skill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { execSync } from "child_process";

export async function shouldInstallSkill(
option: boolean | undefined,
interactive: boolean,
): Promise<boolean> {
if (option !== undefined) return option;
if (!interactive) return false;

try {
const { confirm } = await import("@inquirer/prompts");
return await confirm({
message: "Install the OpenUI agent skill for AI coding assistants?",
default: true,
});
} catch (err) {
const { ExitPromptError } = await import("@inquirer/core");
if (err instanceof ExitPromptError) {
process.exit(0);
}
throw err;
}
}

export function runSkillInstall(targetDir: string): void {
console.info("\nInstalling OpenUI agent skill...\n");
try {
execSync("npx -y skills add thesysdev/openui --skill openui -y", {
stdio: "inherit",
cwd: targetDir,
});
} catch {
console.warn(
"\nCould not install the OpenUI agent skill automatically.\n" +
"You can install it manually later with:\n\n" +
" npx skills add thesysdev/openui --skill openui\n",
);
}
}
Loading