Skill: duvancode/stitch-design-agent (version 1.0.2)

--- name: stitch-design-agent description: > Skill for an agent that integrates designs generated by Google Stitch directly into an app under development. Use this skill whenever the agent needs to: authenticate with Google Stitch via an OAuth token, send a design prompt to the Stitch API, retrieve the generated component/design, and automatically integrate it into the active codebase (React, NestJS, etc.). Always trigger when the user mentions "Stitch", "design from Stitch", "integrate UI from Stitch", or "ask Stitch for the design". --- # Stitch Design Agent Autonomous agent that requests designs from **Google Stitch** via its API and integrates them into the active project. The full flow is: ``` OAuth Token → Design Prompt → Stitch API → Generated Code → Project Integration ``` --- ## 1. Prerequisites | Resource | Where to get it | |---|---| | Google OAuth 2.0 token with `cloud-platform` scope | Step 2 below | | Active project (React / NestJS / any stack) | Must already be in the workspace | | `STITCH_TOKEN` environment variable | `.env` file or agent secret | --- ## 2. Obtaining the Google Stitch Token ### Option A — User token (interactive flow) ```bash # 1. Redirect the user to the authorization URL GET https://accounts.google.com/o/oauth2/v2/auth ?client_id=<CLIENT_ID> &redirect_uri=<REDIRECT_URI> &response_type=code &scope=https://www.googleapis.com/auth/cloud-platform &access_type=offline # 2. Exchange the authorization code for tokens POST https://oauth2.googleapis.com/token grant_type=authorization_code &code=<CODE> &client_id=<CLIENT_ID> &client_secret=<CLIENT_SECRET> &redirect_uri=<REDIRECT_URI> # Response: # { "access_token": "ya29.xxx", "refresh_token": "1//xxx", "expires_in": 3599 } ``` ### Option B — Service Account (headless / CI flow) ```bash # Generate a signed JWT with the service account key and exchange it: POST https://oauth2.googleapis.com/token grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer &assertion=<SIGNED_JWT> ``` > **The agent must always read the token from the `STITCH_TOKEN` environment variable.** > Never hardcode tokens in source code. --- ## 3. Calling the Stitch API with a Design Prompt ### Main endpoint ``` POST https://stitch.googleapis.com/v1/designs:generate Authorization: Bearer {STITCH_TOKEN} Content-Type: application/json ``` ### Request payload ```json { "prompt": "<natural language description of the desired design>", "output_format": "react_component", // "html" | "react_component" | "vue_component" "theme": { "primary_color": "#3B82F6", "font_family": "Inter" }, "context": { "framework": "react", "styling": "tailwind" // "css_modules" | "tailwind" | "styled_components" } } ``` ### Example of an effective prompt ``` "Create a financial summary card component with: - Total balance prominently displayed at the top - Small bar chart showing the last 7 days - Two action buttons: Income and Expense - Minimalist style with a soft shadow - Dark mode compatible" ``` ### Expected response ```json { "design_id": "dsgn_abc123", "component_name": "FinancialSummaryCard", "code": "import React from 'react';\n\nexport const FinancialSummaryCard = ...", "assets": [], "metadata": { "tokens_used": 840, "framework": "react" } } ``` --- ## 4. Integrating the Design into the Active Project ### 4.1 — Save the component ```typescript // The agent must: // 1. Extract `response.code` from the Stitch response // 2. Determine the correct path based on the project structure const componentName = response.component_name; // e.g. "FinancialSummaryCard" const targetPath = `src/components/${componentName}.tsx`; // 3. Write the file fs.writeFileSync(targetPath, response.code, 'utf-8'); ``` ### 4.2 — Detect where to import it The agent should scan the project to find the most logical integration point: ```bash # Find files that are likely to use the new component grep -r "Dashboard\|Overview\|Home\|Layout" src/pages --include="*.tsx" -l ``` ### 4.3 — Insert the import and usage ```typescript // Add to the target file: import { FinancialSummaryCard } from '../components/FinancialSummaryCard'; // And in the JSX: <FinancialSummaryCard /> ``` ### 4.4 — Verify it compiles ```bash npx tsc --noEmit # Check TypeScript types npm run lint -- --fix # Auto-fix linting issues ``` --- ## 5. Full Agent Flow (pseudocode) ```typescript async function stitchDesignFlow(userPrompt: string) { // Step 1: Read token const [REDACTED_SECRET]; if (!token) throw new Error('STITCH_TOKEN is not configured'); // Step 2: Request design from Stitch const stitchResponse = await fetch( 'https://stitch.googleapis.com/v1/designs:generate', { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ prompt: userPrompt, output_format: 'react_component', context: { framework: 'react', styling: 'tailwind' }, }), } ); const design = await stitchResponse.json(); // Step 3: Save the component const filePath = `src/components/${design.component_name}.tsx`; fs.writeFileSync(filePath, design.code); // Step 4: Find the integration point const integrationTarget = await detectIntegrationPoint(design.component_name); // Step 5: Inject import and JSX await injectComponent(integrationTarget, design.component_name); // Step 6: Verify build execSync('npx tsc --noEmit'); return { filePath, integrationTarget }; } ``` --- ## 6. Error Handling | Error | Likely cause | Agent action | |---|---|---| | `401 Unauthorized` | Token expired or invalid | Ask the user for a new token or refresh automatically | | `400 Bad Request` | Prompt too vague or invalid payload | Refine the prompt and retry | | `429 Too Many Requests` | Rate limit reached | Wait 60s and retry | | `TypeScript errors` | Generated component has incorrect types | Fix types manually or request regeneration | | `Import conflicts` | Component name already exists in the project | Rename with a `_v2` suffix | --- ## 7. OpenClaw Configuration ```yaml # openclaw.config.yml (relevant section) agents: stitch-designer: skill: stitch-design-agent env: STITCH_TOKEN: ${secrets.GOOGLE_STITCH_TOKEN} tools: - file_write - file_read - bash - web_fetch triggers: - "design a component" - "ask stitch for the design" - "integrate UI from stitch" - "generate the view for" - "create a screen for" ``` --- ## 8. Important Notes for the Agent - **Always** ask the user for a design prompt before calling Stitch if one was not explicitly provided. - Tokens live for ~1 hour. If the token expires, use the `refresh_token` to renew it automatically before retrying. - Check whether the generated component uses libraries not yet installed (e.g. `recharts`, `framer-motion`) and run `npm install <pkg>` before integrating. - Respect the project architecture: in hexagonal/modular layouts, components belong in `src/modules/<domain>/components/`, not at the `src/components/` root. - If the project has its own design system, include in the prompt: *"follow the app's existing design system and use its CSS tokens"*. - If the generated code references hardcoded colors or sizes that conflict with the existing theme, replace them with the project's CSS variables before saving.


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)