Skip to content
Closed
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
6 changes: 5 additions & 1 deletion packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,8 @@ Program](https://bughunters.google.com/open-source-security).

## License

Apache 2.0 — see [LICENSE](LICENSE) for details.
Apache 2.0 — see [LICENSE](LICENSE) for details.
## Examples

Check out the [examples/](examples/) directory for practical workflows and agent skills:
- [Design to React Component](examples/design-to-react/) — An Agent Skill demonstrating how to convert Stitch designs into modular React components.
28 changes: 28 additions & 0 deletions packages/sdk/examples/design-to-react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Design to React Component

This is an **Agent Skill** example. It demonstrates how an AI agent can use the Stitch SDK to generate a UI design and then convert that raw HTML/Tailwind output into a clean, modular React component.

Converting raw design output to React requires intelligence—interpreting the semantic structure of the HTML, extracting the Tailwind configuration, and mapping it to JSX props. Because it requires judgment, this workflow is best suited for an Agent Skill rather than a static script.

## Files

- `SKILL.md` — Instructions you can give to an LLM agent to teach it this workflow.
- `scripts/extract-assets.ts` — A deterministic helper script the agent can run to extract the HTML and design tokens.

## Prerequisites

1. A valid `STITCH_API_KEY` set in your environment.
2. Install the required dependencies from the root directory: `bun install`.

## How to run

Since this is an Agent Skill, you don't "run" it directly. Instead, you point an agent at the `SKILL.md` file.

To test the helper script directly:

```bash
cd packages/sdk/examples/design-to-react
bun scripts/extract-assets.ts
```

This will generate a design, download the HTML, and parse out the Tailwind configuration and Google Fonts.
74 changes: 74 additions & 0 deletions packages/sdk/examples/design-to-react/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Skill: Design to React Component

This skill teaches you how to use the Stitch SDK to generate a UI design from a prompt, and then convert that raw HTML and Tailwind output into a clean, reusable React component.

## Context

The Stitch SDK outputs raw HTML that includes:
- Inline Tailwind CSS classes.
- A Tailwind configuration object embedded in a `<script id="tailwind-config">` tag.
- Google Fonts linked in the `<head>`.

To use this design in a React application, you must intelligently parse the HTML, extract the relevant configuration, and rewrite the markup as JSX.

## Workflow

When tasked with creating a React component from a design prompt, follow these steps:

1. **Generate the Design and Extract Assets:**
Use the provided `scripts/extract-assets.ts` helper script to generate the design and parse the output.

```bash
# You may need to specify the prompt depending on how the script is built
bun packages/sdk/examples/design-to-react/scripts/extract-assets.ts
```

*Note: If the script is hardcoded for a specific prompt, you can use the MCP tools directly (`create_project` then `generate_screen`), fetch the HTML URL, and parse it manually.*

2. **Review the Output:**
The script (or your manual parsing) will output the raw HTML, the Tailwind configuration object, and any required Google Fonts links. Review these assets carefully.

3. **Create the React Component:**
Translate the raw HTML into a functional React component (`.tsx` or `.jsx`).

* **Convert HTML to JSX:** Change `class` to `className`, `for` to `htmlFor`, and self-close tags like `<img>` and `<input>`.
* **Identify Props:** Look at the content (text, image URLs, button labels) and extract them into a standard React `Props` interface. Do not hardcode content if it should be dynamic.
* **Modularize:** If the design is complex, break it down into smaller, logical sub-components.

4. **Integrate Design Tokens:**
* Take the extracted Tailwind configuration and instruct the user on how to merge it into their project's `tailwind.config.ts` (or equivalent Tailwind v4 `@theme` block).
* Ensure the required Google Fonts are added to the project (e.g., in `index.html`, `_document.tsx`, or `layout.tsx`).

## Example Transformation

**Input (Raw HTML Snippet):**

```html
<div class="bg-[#1a1a1a] text-white p-6 rounded-lg font-['Inter']">
<img src="https://lh3.googleusercontent.com/.../img.png" alt="Profile" class="w-16 h-16 rounded-full">
<h2 class="text-xl font-bold mt-4">John Doe</h2>
<p class="text-gray-400">Software Engineer</p>
</div>
```

**Output (React Component):**

```tsx
import React from 'react';

interface ProfileCardProps {
name: string;
role: string;
imageUrl: string;
}

export const ProfileCard: React.FC<ProfileCardProps> = ({ name, role, imageUrl }) => {
return (
<div className="bg-[#1a1a1a] text-white p-6 rounded-lg font-['Inter']">
<img src={imageUrl} alt={`Profile for ${name}`} className="w-16 h-16 rounded-full" />
<h2 className="text-xl font-bold mt-4">{name}</h2>
<p className="text-gray-400">{role}</p>
</div>
);
};
```
60 changes: 60 additions & 0 deletions packages/sdk/examples/design-to-react/scripts/extract-assets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import "../../_require-key.js";
import { stitch } from "@google/stitch-sdk";

async function main() {
try {
const prompt = "A clean, modern SaaS dashboard with a sidebar, header, and some data cards. Include a user profile dropdown.";

console.log("🎨 Creating project...");
const project = await stitch.createProject("Design to React Example");

console.log(`✨ Generating screen for prompt: "${prompt}"`);
const screen = await project.generate(prompt);

console.log(`✅ Screen generated: ${screen.id}`);

const htmlUrl = await screen.getHtml();
console.log(`📥 Fetching HTML from ${htmlUrl}...`);

const response = await fetch(htmlUrl);
if (!response.ok) {
throw new Error(`Failed to fetch HTML: ${response.statusText}`);
}

const html = await response.text();

// Parse out the Tailwind configuration
console.log("\n🔍 Extracting Tailwind config...");
const configMatch = html.match(/<script id="tailwind-config">([\s\S]*?)<\/script>/);

if (configMatch) {
console.log("\n/* --- TAILWIND CONFIG --- */");
console.log(configMatch[1].trim());
console.log("/* ----------------------- */\n");
} else {
console.log("❌ No Tailwind config found.");
}

// Parse Google Fonts links
console.log("🔍 Extracting Google Fonts links...");
const fontsMatches = html.match(/<link[^>]*fonts\.googleapis\.com[^>]*>/g) || [];

if (fontsMatches.length > 0) {
console.log("\n<!-- --- GOOGLE FONTS --- -->");
fontsMatches.forEach(link => console.log(link));
console.log("<!-- -------------------- -->\n");
} else {
console.log("❌ No Google Fonts links found.");
}

// The Agent can now read the raw HTML to convert to JSX
console.log("📝 The agent should now read the raw HTML to convert to JSX.");
console.log(`HTML Length: ${html.length} characters`);

} catch (error) {
console.error("❌ Error:", error);
process.exit(1);
}
}

main();
Loading