From 4c0922797073a7edafa912d0252681120092ab44 Mon Sep 17 00:00:00 2001 From: Gabi Date: Mon, 20 Jul 2026 20:03:00 +0200 Subject: [PATCH] feat: accept local HTML and URLs as conversion sources, not just Stitch screens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The six framework-conversion skills each demanded a Stitch project and a generated screen before they'd do anything. That gate was never structural: every one of them downloads to a single local file at `temp/source.html`, and not one references Stitch MCP after Step 1. The coupling lived entirely in how the source got fetched. So Step 1 now resolves from any of three sources — a Stitch screen, a local HTML file, or a URL — and everything downstream is untouched. Point any of these skills at a template you bought or a page you already built and you get the same output: production components with dark mode, design tokens, TypeScript, and ARIA. Only the Stitch route needs an API key. `stitch-html-components` is the sharpest case of the old problem — it billed itself as the platform-agnostic target and still required a Google account. - Add the three-source Step 1 to all six conversion skills, with a documented fallback for screenshots via stitch-mcp-upload-screens-from-images - Keep genuine per-skill prerequisites (Xcode 15+, Expo, Svelte 5 runes, next-themes) and the mobile-layout check on React Native and SwiftUI, which previously rode on Stitch's deviceType and now applies to all routes - Route "user already has HTML" straight to conversion in the orchestrator instead of pushing them through generation for a screen they didn't want - Collapse fetch-stitch.sh from three drifted copies to one; the variants differed only in comments, so nothing functional was lost - State in the README which half needs a Google account and which doesn't React Native and SwiftUI read the source as a structural reference rather than converting markup, so their wording says that rather than implying HTML output. --- README.md | 8 +-- .../stitch-design-md/scripts/fetch-stitch.sh | 12 ++++- skills/stitch-html-components/SKILL.md | 35 +++++++++++-- .../scripts/fetch-stitch.sh | 12 ++++- skills/stitch-nextjs-components/SKILL.md | 43 +++++++++++++--- skills/stitch-orchestrator/SKILL.md | 1 + skills/stitch-react-components/SKILL.md | 45 +++++++++++++--- .../scripts/fetch-stitch.sh | 12 ++++- .../stitch-react-native-components/SKILL.md | 49 +++++++++++++++--- skills/stitch-svelte-components/SKILL.md | 43 +++++++++++++--- .../scripts/fetch-stitch.sh | 9 ++++ skills/stitch-swiftui-components/SKILL.md | 51 ++++++++++++++++--- 12 files changed, 271 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 7112553..ce4ce78 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ All four of these came out of stitch-kit. Different briefs, genuinely different --- -> **Needs Google Stitch access.** Everything here runs through Stitch, so sort that out first — sign in at [stitch.withgoogle.com](https://stitch.withgoogle.com) with any Google account, then grab an API key from [settings](https://stitch.withgoogle.com/settings). +> **Generating designs needs Google Stitch.** Sign in at [stitch.withgoogle.com](https://stitch.withgoogle.com) with any Google account, then grab an API key from [settings](https://stitch.withgoogle.com/settings). No waitlist, no invite, free as of mid-2026 — but there are monthly generation limits and Google has signalled paid tiers, so treat the allowance as generous-but-finite. > -> No waitlist, no invite, free to use as of mid-2026. There are monthly generation limits, and Google has signalled paid tiers are coming — so treat the free allowance as generous-but-finite rather than unlimited. +> **Converting to code doesn't.** The framework conversion skills take a local HTML file or a URL just as happily as a Stitch screen. If you already have markup and only want production components out of it, you need no Google account at all. ## Install @@ -152,7 +152,9 @@ Without stitch-kit, your agent sends Stitch a half-baked prompt, gets confused b ## Ship to any framework -Once your design is ready, pick your target: +**Works on any HTML, not just Stitch output.** Each conversion skill takes a Stitch screen, a local HTML file, or a URL — point it at a template you bought, a page you already built, or something a different tool generated, and you get the same production components with dark mode, design tokens, TypeScript, and ARIA. Only the Stitch route needs an API key. + +Pick your target: | Target | Skill | What you get | |--------|-------|-------------| diff --git a/skills/stitch-design-md/scripts/fetch-stitch.sh b/skills/stitch-design-md/scripts/fetch-stitch.sh index ccc6cfe..e0e7993 100644 --- a/skills/stitch-design-md/scripts/fetch-stitch.sh +++ b/skills/stitch-design-md/scripts/fetch-stitch.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # fetch-stitch.sh # Reliably downloads Stitch HTML from Google Cloud Storage URLs. -# GCS URLs require redirect handling and security handshakes that AI fetch tools fail on. +# GCS URLs require redirect handling and specific security handshakes that +# AI fetch tools often fail on. This script handles both. # # Usage: # bash scripts/fetch-stitch.sh "" "" @@ -14,8 +15,16 @@ set -euo pipefail URL="${1:?Usage: fetch-stitch.sh }" OUTPUT="${2:?Usage: fetch-stitch.sh }" +# Create output directory if it doesn't exist mkdir -p "$(dirname "$OUTPUT")" +# Use curl with: +# -L : follow redirects (GCS uses multiple redirect hops) +# -A : set User-Agent to avoid bot blocking +# --compressed : handle gzip responses +# --retry 3 : retry on transient failures +# --retry-delay 1 : wait 1s between retries +# --max-time 30 : don't hang forever curl -L \ -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \ --compressed \ @@ -27,6 +36,7 @@ curl -L \ --output "$OUTPUT" \ "$URL" +# Verify the download succeeded and is not empty if [ ! -s "$OUTPUT" ]; then echo "Error: Downloaded file is empty. URL may be expired or invalid." >&2 exit 1 diff --git a/skills/stitch-html-components/SKILL.md b/skills/stitch-html-components/SKILL.md index 3b87758..43a2b42 100644 --- a/skills/stitch-html-components/SKILL.md +++ b/skills/stitch-html-components/SKILL.md @@ -1,6 +1,6 @@ --- name: stitch-html-components -description: Converts Stitch designs into clean, platform-agnostic HTML5 + CSS — semantic markup, CSS custom properties for theming, dark mode via prefers-color-scheme, mobile-first responsive, zero framework dependencies. Works in browsers, WebViews, Capacitor, and Ionic. +description: Converts a Stitch screen, a local HTML file, or a URL into clean, platform-agnostic HTML5 + CSS — semantic markup, CSS custom properties for theming, dark mode via prefers-color-scheme, mobile-first responsive, zero framework dependencies. Works in browsers, WebViews, Capacitor, and Ionic. Only the Stitch route needs an API key. allowed-tools: - "stitch*:*" - "Bash" @@ -23,10 +23,17 @@ Use this skill when: ## Prerequisites -- Access to Stitch MCP server -- A Stitch project with at least one generated screen +An HTML source. Any one of these works: -## Step 1: Retrieve the design +- A **Stitch screen** — needs Stitch MCP access and a generated screen +- A **local HTML file** — no Stitch account required +- A **URL** — no Stitch account required + +## Step 1: Resolve the source + +Everything downstream reads one file: `temp/source.html`. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from. + +**From a Stitch screen:** 1. **Namespace discovery** — `list_tools` to find the Stitch MCP prefix 2. **Fetch metadata** — `[prefix]:get_screen` for the design JSON @@ -34,7 +41,25 @@ Use this skill when: ```bash bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" ``` -4. **Visual audit** — check `screenshot.downloadUrl` before rewriting +4. **Visual audit** — check `screenshot.downloadUrl` before rewriting. Append `=s0` to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the `width`/`height` the API reports. + +**From a local HTML file:** + +```bash +mkdir -p temp && cp "path/to/design.html" temp/source.html +``` + +**From a URL:** + +```bash +bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html" +``` + +Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. + +**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above. + +> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all. ## Step 2: File structure diff --git a/skills/stitch-mcp-get-screen/scripts/fetch-stitch.sh b/skills/stitch-mcp-get-screen/scripts/fetch-stitch.sh index ccc6cfe..e0e7993 100644 --- a/skills/stitch-mcp-get-screen/scripts/fetch-stitch.sh +++ b/skills/stitch-mcp-get-screen/scripts/fetch-stitch.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # fetch-stitch.sh # Reliably downloads Stitch HTML from Google Cloud Storage URLs. -# GCS URLs require redirect handling and security handshakes that AI fetch tools fail on. +# GCS URLs require redirect handling and specific security handshakes that +# AI fetch tools often fail on. This script handles both. # # Usage: # bash scripts/fetch-stitch.sh "" "" @@ -14,8 +15,16 @@ set -euo pipefail URL="${1:?Usage: fetch-stitch.sh }" OUTPUT="${2:?Usage: fetch-stitch.sh }" +# Create output directory if it doesn't exist mkdir -p "$(dirname "$OUTPUT")" +# Use curl with: +# -L : follow redirects (GCS uses multiple redirect hops) +# -A : set User-Agent to avoid bot blocking +# --compressed : handle gzip responses +# --retry 3 : retry on transient failures +# --retry-delay 1 : wait 1s between retries +# --max-time 30 : don't hang forever curl -L \ -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \ --compressed \ @@ -27,6 +36,7 @@ curl -L \ --output "$OUTPUT" \ "$URL" +# Verify the download succeeded and is not empty if [ ! -s "$OUTPUT" ]; then echo "Error: Downloaded file is empty. URL may be expired or invalid." >&2 exit 1 diff --git a/skills/stitch-nextjs-components/SKILL.md b/skills/stitch-nextjs-components/SKILL.md index 5a7b390..9a00285 100644 --- a/skills/stitch-nextjs-components/SKILL.md +++ b/skills/stitch-nextjs-components/SKILL.md @@ -1,6 +1,6 @@ --- name: stitch-nextjs-components -description: Converts Stitch designs into production-ready Next.js 15 App Router components — Server vs Client split, dark mode via CSS variables, TypeScript strict, ARIA, and responsive mobile-first layout. +description: Converts a Stitch screen, a local HTML file, or a URL into production-ready Next.js 15 App Router components — Server vs Client split, dark mode via CSS variables, TypeScript strict, ARIA, and responsive mobile-first layout. Only the Stitch route needs an API key. allowed-tools: - "stitch*:*" - "Bash" @@ -21,19 +21,46 @@ Use this skill (not `react-components`) when: ## Prerequisites -- Access to the Stitch MCP server -- A Stitch project with at least one generated screen +An HTML source. Any one of these works: + +- A **Stitch screen** — needs Stitch MCP access and a generated screen +- A **local HTML file** — no Stitch account required +- A **URL** — no Stitch account required + +Also: - Target project has `next-themes` installed for dark mode (or user approves adding it) -## Step 1: Retrieve the Stitch design +## Step 1: Resolve the source + +Everything downstream reads one file: `temp/source.html`. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from. + +**From a Stitch screen:** -1. **Namespace discovery** — Run `list_tools` to find the Stitch MCP prefix (e.g., `stitch:`). Use this prefix for all subsequent calls. -2. **Fetch screen metadata** — Call `[prefix]:get_screen` with the `projectId` and `screenId`. -3. **Download HTML** — GCS URLs need a reliable downloader: +1. **Namespace discovery** — `list_tools` to find the Stitch MCP prefix +2. **Fetch metadata** — `[prefix]:get_screen` for the design JSON +3. **Download HTML** — GCS URLs need the reliable downloader: ```bash bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" ``` -4. **Visual audit** — Check `screenshot.downloadUrl` to understand layout intent before writing code. +4. **Visual audit** — check `screenshot.downloadUrl` before rewriting. Append `=s0` to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the `width`/`height` the API reports. + +**From a local HTML file:** + +```bash +mkdir -p temp && cp "path/to/design.html" temp/source.html +``` + +**From a URL:** + +```bash +bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html" +``` + +Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. + +**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above. + +> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all. ## Step 2: Decide Server Component vs Client Component diff --git a/skills/stitch-orchestrator/SKILL.md b/skills/stitch-orchestrator/SKILL.md index 67089cc..61d2c8f 100644 --- a/skills/stitch-orchestrator/SKILL.md +++ b/skills/stitch-orchestrator/SKILL.md @@ -119,6 +119,7 @@ Determine what the user wants: | **Upload screenshot** — import existing UI | Call `stitch-mcp-upload-screens-from-images`, then offer edit or convert (Step 5b). | | **Refine existing** — iterate on a screen | Skip Step 2 (reuse project ID). Preserve layout structure in new prompt. | | **Export existing** — just get the code | Skip Steps 2-5. Go to Step 6 (get screen) → Step 8 (convert). | +| **Convert non-Stitch HTML** — user already has markup | Skip Steps 2-7 entirely. Go straight to Step 8. The conversion skills accept a local HTML file or a URL as well as a Stitch screen, and that route needs no Stitch account. Do not push the user through generation to manufacture a screen they didn't ask for. | | **Variants** — explore design directions | Call `stitch-mcp-generate-variants` natively (1 API call). Present results, then Step 5b. | | **Delete project** — clean up | Call `stitch-mcp-delete-project` with confirmation gate. Stop after deletion. | diff --git a/skills/stitch-react-components/SKILL.md b/skills/stitch-react-components/SKILL.md index a6352ce..437e8c9 100644 --- a/skills/stitch-react-components/SKILL.md +++ b/skills/stitch-react-components/SKILL.md @@ -1,6 +1,6 @@ --- name: stitch-react-components -description: Converts Stitch designs into modular Vite + React components — TypeScript, theme-mapped Tailwind, dark mode via CSS variables, and clean component architecture. Use this for Vite/React apps without App Router. For Next.js 15 App Router, use stitch-nextjs-components instead. +description: Converts a Stitch screen, a local HTML file, or a URL into modular Vite + React components — TypeScript, theme-mapped Tailwind, dark mode via CSS variables, and clean component architecture. Use this for Vite/React apps without App Router. For Next.js 15 App Router, use stitch-nextjs-components instead. Only the Stitch route needs an API key. allowed-tools: - "stitch*:*" - "Bash" @@ -25,16 +25,47 @@ You are a frontend engineer converting Stitch mobile/desktop designs into clean, ## Prerequisites -- Stitch MCP Server configured (or use downloaded HTML directly) +An HTML source. Any one of these works: + +- A **Stitch screen** — needs Stitch MCP access and a generated screen +- A **local HTML file** — no Stitch account required +- A **URL** — no Stitch account required + +Also: - Node.js + npm/pnpm - Vite + React project initialized: `npm create vite@latest my-app -- --template react-ts` -## Step 1: Retrieve the design +## Step 1: Resolve the source + +Everything downstream reads one file: `temp/source.html`. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from. + +**From a Stitch screen:** + +1. **Namespace discovery** — `list_tools` to find the Stitch MCP prefix +2. **Fetch metadata** — `[prefix]:get_screen` with numeric `projectId` and `screenId` +3. **Download HTML** — GCS URLs need the reliable downloader: + ```bash + bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" + ``` +4. **Visual audit** — check `screenshot.downloadUrl` before rewriting. Append `=s0` to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the `width`/`height` the API reports. + +**From a local HTML file:** + +```bash +mkdir -p temp && cp "path/to/design.html" temp/source.html +``` + +**From a URL:** + +```bash +bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html" +``` + +Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. + +**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above. -1. Run `list_tools` → find Stitch MCP prefix -2. Call `[prefix]:get_screen` with numeric `projectId` and `screenId` -3. Download HTML: `bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html"` -4. Check `screenshot.downloadUrl` — verify layout matches expectations +> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all. ## Step 2: Project structure diff --git a/skills/stitch-react-components/scripts/fetch-stitch.sh b/skills/stitch-react-components/scripts/fetch-stitch.sh index ccc6cfe..e0e7993 100644 --- a/skills/stitch-react-components/scripts/fetch-stitch.sh +++ b/skills/stitch-react-components/scripts/fetch-stitch.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # fetch-stitch.sh # Reliably downloads Stitch HTML from Google Cloud Storage URLs. -# GCS URLs require redirect handling and security handshakes that AI fetch tools fail on. +# GCS URLs require redirect handling and specific security handshakes that +# AI fetch tools often fail on. This script handles both. # # Usage: # bash scripts/fetch-stitch.sh "" "" @@ -14,8 +15,16 @@ set -euo pipefail URL="${1:?Usage: fetch-stitch.sh }" OUTPUT="${2:?Usage: fetch-stitch.sh }" +# Create output directory if it doesn't exist mkdir -p "$(dirname "$OUTPUT")" +# Use curl with: +# -L : follow redirects (GCS uses multiple redirect hops) +# -A : set User-Agent to avoid bot blocking +# --compressed : handle gzip responses +# --retry 3 : retry on transient failures +# --retry-delay 1 : wait 1s between retries +# --max-time 30 : don't hang forever curl -L \ -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \ --compressed \ @@ -27,6 +36,7 @@ curl -L \ --output "$OUTPUT" \ "$URL" +# Verify the download succeeded and is not empty if [ ! -s "$OUTPUT" ]; then echo "Error: Downloaded file is empty. URL may be expired or invalid." >&2 exit 1 diff --git a/skills/stitch-react-native-components/SKILL.md b/skills/stitch-react-native-components/SKILL.md index ff10feb..572ad54 100644 --- a/skills/stitch-react-native-components/SKILL.md +++ b/skills/stitch-react-native-components/SKILL.md @@ -1,6 +1,6 @@ --- name: stitch-react-native-components -description: Converts Stitch mobile designs into React Native / Expo components — TypeScript, StyleSheet, Expo Router, dark mode via useColorScheme, and proper touch targets. Cross-platform iOS and Android. +description: Converts a Stitch mobile screen, a local HTML file, or a URL into React Native / Expo components — TypeScript, StyleSheet, Expo Router, dark mode via useColorScheme, and proper touch targets. Cross-platform iOS and Android. Only the Stitch route needs an API key. allowed-tools: - "stitch*:*" - "Bash" @@ -23,18 +23,53 @@ Use this skill when: ## Prerequisites -- Stitch design generated with `deviceType: MOBILE` (desktop designs don't translate well to RN) +A mobile-layout source, read as structural and visual reference only — nothing here ships, RN components get written from scratch. Any one of these works: + +- A **Stitch screen** — needs Stitch MCP access and a screen generated with `deviceType: MOBILE` +- A **local HTML file** of a mobile layout — no Stitch account required +- A **URL** rendering a mobile layout — no Stitch account required + +Desktop layouts don't translate well to RN, regardless of which route you took — verify the source is narrow and vertical before converting. + +Also: - Target project uses **Expo** (SDK 50+) — not bare React Native - `expo-router` for file-based navigation -## Step 1: Retrieve the design +## Step 1: Resolve the source + +Everything downstream reads one file: `temp/source.html`. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from. + +**From a Stitch screen:** Only call this skill for **MOBILE** Stitch designs. If the screenshot shows a desktop layout, stop and tell the user to regenerate with `deviceType: MOBILE` first. -1. `list_tools` → find Stitch prefix -2. `[prefix]:get_screen` → fetch design JSON -3. Download HTML: `bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html"` -4. Check `screenshot.downloadUrl` — verify it's a mobile layout (narrow, vertical) +1. **Namespace discovery** — `list_tools` to find the Stitch MCP prefix +2. **Fetch metadata** — `[prefix]:get_screen` for the design JSON +3. **Download HTML** — GCS URLs need the reliable downloader: + ```bash + bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" + ``` +4. **Visual audit** — check `screenshot.downloadUrl` before converting. Append `=s0` to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the `width`/`height` the API reports. Confirm it's a mobile layout (narrow, vertical). + +**From a local HTML file:** + +```bash +mkdir -p temp && cp "path/to/design.html" temp/source.html +``` + +Open it and confirm it's a mobile layout before converting. + +**From a URL:** + +```bash +bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html" +``` + +Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. Confirm the page is a mobile layout before converting. + +**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above. + +> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all. ## Step 2: Project structure diff --git a/skills/stitch-svelte-components/SKILL.md b/skills/stitch-svelte-components/SKILL.md index b2a32ea..34fe4e2 100644 --- a/skills/stitch-svelte-components/SKILL.md +++ b/skills/stitch-svelte-components/SKILL.md @@ -1,6 +1,6 @@ --- name: stitch-svelte-components -description: Converts Stitch designs into Svelte 5 / SvelteKit components using the runes API — scoped CSS with custom properties, built-in transitions, TypeScript, dark mode, and accessible markup. +description: Converts a Stitch screen, a local HTML file, or a URL into Svelte 5 / SvelteKit components using the runes API — scoped CSS with custom properties, built-in transitions, TypeScript, dark mode, and accessible markup. Only the Stitch route needs an API key. allowed-tools: - "stitch*:*" - "Bash" @@ -23,19 +23,46 @@ Use this skill when: ## Prerequisites -- Access to the Stitch MCP server -- A Stitch project with at least one generated screen +An HTML source. Any one of these works: + +- A **Stitch screen** — needs Stitch MCP access and a generated screen +- A **local HTML file** — no Stitch account required +- A **URL** — no Stitch account required + +Also: - Target project uses Svelte 5 (runes enabled) — check `package.json` for `"svelte": "^5"` -## Step 1: Retrieve the Stitch design +## Step 1: Resolve the source + +Everything downstream reads one file: `temp/source.html`. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from. + +**From a Stitch screen:** -1. **Namespace discovery** — Run `list_tools` to find the Stitch MCP prefix. Use it for all subsequent calls. -2. **Fetch screen metadata** — Call `[prefix]:get_screen` to retrieve design JSON. -3. **Download HTML** — Use the reliable downloader: +1. **Namespace discovery** — `list_tools` to find the Stitch MCP prefix +2. **Fetch metadata** — `[prefix]:get_screen` for the design JSON +3. **Download HTML** — GCS URLs need the reliable downloader: ```bash bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" ``` -4. **Visual reference** — Check `screenshot.downloadUrl` before writing code. +4. **Visual audit** — check `screenshot.downloadUrl` before rewriting. Append `=s0` to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the `width`/`height` the API reports. + +**From a local HTML file:** + +```bash +mkdir -p temp && cp "path/to/design.html" temp/source.html +``` + +**From a URL:** + +```bash +bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html" +``` + +Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. + +**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above. + +> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all. ## Step 2: SvelteKit file conventions diff --git a/skills/stitch-svelte-components/scripts/fetch-stitch.sh b/skills/stitch-svelte-components/scripts/fetch-stitch.sh index ee42ea9..e0e7993 100644 --- a/skills/stitch-svelte-components/scripts/fetch-stitch.sh +++ b/skills/stitch-svelte-components/scripts/fetch-stitch.sh @@ -15,8 +15,16 @@ set -euo pipefail URL="${1:?Usage: fetch-stitch.sh }" OUTPUT="${2:?Usage: fetch-stitch.sh }" +# Create output directory if it doesn't exist mkdir -p "$(dirname "$OUTPUT")" +# Use curl with: +# -L : follow redirects (GCS uses multiple redirect hops) +# -A : set User-Agent to avoid bot blocking +# --compressed : handle gzip responses +# --retry 3 : retry on transient failures +# --retry-delay 1 : wait 1s between retries +# --max-time 30 : don't hang forever curl -L \ -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" \ --compressed \ @@ -28,6 +36,7 @@ curl -L \ --output "$OUTPUT" \ "$URL" +# Verify the download succeeded and is not empty if [ ! -s "$OUTPUT" ]; then echo "Error: Downloaded file is empty. URL may be expired or invalid." >&2 exit 1 diff --git a/skills/stitch-swiftui-components/SKILL.md b/skills/stitch-swiftui-components/SKILL.md index 4ef8cbc..01141de 100644 --- a/skills/stitch-swiftui-components/SKILL.md +++ b/skills/stitch-swiftui-components/SKILL.md @@ -1,6 +1,6 @@ --- name: stitch-swiftui-components -description: Converts Stitch mobile designs into SwiftUI views for native iOS apps — VStack/HStack/ZStack layout mapping, Color asset tokens with dark mode, NavigationStack/TabView routing, and Xcode project structure. +description: Converts a Stitch mobile screen, a local HTML file, or a URL into SwiftUI views for native iOS apps — VStack/HStack/ZStack layout mapping, Color asset tokens with dark mode, NavigationStack/TabView routing, and Xcode project structure. Only the Stitch route needs an API key. allowed-tools: - "stitch*:*" - "Bash" @@ -23,18 +23,53 @@ Use this skill when: ## Prerequisites -- Stitch design with `deviceType: MOBILE` +A mobile-layout source, read as structural and visual reference only — nothing here ships, SwiftUI views get written from scratch. Any one of these works: + +- A **Stitch screen** — needs Stitch MCP access and a screen generated with `deviceType: MOBILE` +- A **local HTML file** of a mobile layout — no Stitch account required +- A **URL** rendering a mobile layout — no Stitch account required + +Desktop layouts don't map well to SwiftUI without significant rethinking, regardless of which route you took. + +Also: - Xcode 15+ on macOS - Swift 5.9+ -## Step 1: Retrieve the design +## Step 1: Resolve the source + +Everything downstream reads one file: `temp/source.html`. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from. + +**From a Stitch screen:** + +Only call this skill for **MOBILE** Stitch designs. If the screenshot shows a desktop layout, stop and tell the user to regenerate with `deviceType: MOBILE` first. + +1. **Namespace discovery** — `list_tools` to find the Stitch MCP prefix +2. **Fetch metadata** — `[prefix]:get_screen` for the design JSON +3. **Download HTML** — GCS URLs need the reliable downloader: + ```bash + bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" + ``` +4. **Visual audit** — check `screenshot.downloadUrl` before converting. Append `=s0` to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the `width`/`height` the API reports. Confirm it's a mobile layout. + +**From a local HTML file:** + +```bash +mkdir -p temp && cp "path/to/design.html" temp/source.html +``` + +Open it and confirm it's a mobile layout before converting. + +**From a URL:** + +```bash +bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html" +``` + +Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. Confirm the page is a mobile layout before converting. -1. `list_tools` → find Stitch MCP prefix -2. `[prefix]:get_screen` → fetch metadata -3. Download HTML: `bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html"` -4. Check `screenshot.downloadUrl` — confirm mobile layout before converting +**From a screenshot:** there's no direct route. Run `stitch-mcp-upload-screens-from-images` to turn the image into a Stitch screen first, then take the Stitch path above. -Only convert **MOBILE** designs. Desktop Stitch designs don't map well to SwiftUI without significant layout rethinking. +> Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all. ## Step 2: Xcode project structure