diff --git a/.claude/pipeline.config.json b/.claude/pipeline.config.json index a3cc740..43f3d23 100644 --- a/.claude/pipeline.config.json +++ b/.claude/pipeline.config.json @@ -534,10 +534,10 @@ "directory": ".claude/pipeline-cache", "maxAgeDays": 7, "inputCategories": { - "source": ["src/**/*.{ts,tsx,js,jsx}", "components/**/*.{ts,tsx}"], + "source": ["src/**/*.{ts,tsx,js,jsx}", "src/**/*.astro", "components/**/*.{ts,tsx}"], "styles": ["src/**/*.css", "styles/**/*.css", "tailwind.config.*"], "tests": ["**/*.test.{ts,tsx,js,jsx}", "**/*.spec.{ts,tsx}"], - "config": ["package.json", "tsconfig.json", "vite.config.*", "next.config.*"], + "config": ["package.json", "tsconfig.json", "vite.config.*", "next.config.*", "astro.config.*"], "tokens": ["design-tokens.lock.json", "tailwind.config.*"], "figma": ["build-spec.json", "design-tokens.lock.json"] }, diff --git a/README.md b/README.md index 55e20b1..4a29f63 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ A Claude Code-integrated multi-framework app development framework with TypeScri git clone cd aurelius -# Initialize a new project (Next.js or Vite) -./scripts/setup-project.sh my-app --vite # or --next +# Initialize a new project (Next.js, Vite, Astro, SvelteKit, or Expo) +./scripts/setup-project.sh my-app --vite # or --next, --astro, --svelte, --expo # Install dependencies cd app && pnpm install @@ -79,6 +79,7 @@ project-root/ │ ├── shared/ # ESLint, Prettier, Tailwind, TS, Vitest │ ├── nextjs/ # Next.js config │ ├── vite/ # Vite config +│ ├── astro/ # Astro hybrid-islands starter (React + Tailwind) │ └── chrome-extension/ # Playwright E2E fixtures for extensions ├── docs/ # Documentation │ ├── figma-to-react/ # Figma pipeline guide @@ -258,6 +259,7 @@ Starter configuration files for new projects: | `templates/shared/` | ESLint, Prettier, Tailwind, TypeScript, Vitest configs | | `templates/nextjs/` | Next.js config | | `templates/vite/` | Vite config | +| `templates/astro/` | Astro hybrid-islands starter (React islands + Tailwind, file-based routing) | | `templates/chrome-extension/` | Playwright E2E fixtures for Chrome extensions | Full reference: `templates/README.md` diff --git a/docs/multi-framework/README.md b/docs/multi-framework/README.md index b55a1dc..2f012ea 100644 --- a/docs/multi-framework/README.md +++ b/docs/multi-framework/README.md @@ -68,6 +68,8 @@ The intake skills (`figma-intake`, `canva-intake`, `screenshot-intake`) also ask - **Converter agent:** `astro-converter` - **Renderer:** `astro` (`language`/`outputTarget` = `react`) +- **App type:** `web-app` — Astro produces standard web output (static HTML + optional SSR), so it uses the **`web-app`** app type in `pipeline.config.json`. App type describes the _kind_ of app (web-app / chrome-extension / pwa / react-native); the framework choice (Next.js / Vite / **Astro**) is the orthogonal `renderer`, owned by the renderer registry. `pipeline.config.json` recognizes Astro inputs via `astro.config.*` and `src/**/*.astro` in its cache categories. +- **Scaffold:** `./scripts/setup-project.sh --astro` copies `templates/astro/` (a complete starter) and installs it. - **Styling:** Tailwind CSS via `@astrojs/tailwind` - **Test library:** Vitest + @testing-library/react (islands) + Astro Container API (`.astro` statics) - **Template:** `templates/astro/` (`@astrojs/react` islands + `@astrojs/tailwind`) diff --git a/scripts/__tests__/setup-project.test.js b/scripts/__tests__/setup-project.test.js index 809997c..2fbe4d6 100644 --- a/scripts/__tests__/setup-project.test.js +++ b/scripts/__tests__/setup-project.test.js @@ -61,6 +61,13 @@ describe("setup-project.sh", () => { expect(r.stdout).toMatch(/template:\s+templates\/sveltekit/); }); + it("--astro alias maps to the astro renderer", () => { + const r = run(["my-app", "--astro", "--dry-run"]); + expect(r.exitCode).toBe(0); + expect(r.stdout).toMatch(/Renderer: astro/); + expect(r.stdout).toMatch(/template:\s+templates\/astro/); + }); + it("exits non-zero on an unknown renderer", () => { const r = run(["my-app", "--renderer", "does-not-exist", "--dry-run"]); expect(r.exitCode).not.toBe(0); diff --git a/scripts/setup-project.sh b/scripts/setup-project.sh index 522bb91..904be84 100644 --- a/scripts/setup-project.sh +++ b/scripts/setup-project.sh @@ -13,6 +13,7 @@ set -euo pipefail # ./scripts/setup-project.sh my-app --vue # Create Vue 3 app # ./scripts/setup-project.sh my-app --svelte # Alias for --renderer sveltekit # ./scripts/setup-project.sh my-app --expo # Alias for --renderer expo +# ./scripts/setup-project.sh my-app --astro # Alias for --renderer astro # # The --renderer flag is backed by the renderer registry # (scripts/renderer-registry.js). The legacy framework flags above are kept as @@ -32,7 +33,7 @@ usage() { local renderers renderers="$(list_renderers || echo "nextjs vite sveltekit expo astro")" echo "Usage: $0 [--renderer ] [--dry-run]" - echo " $0 [--next|--vite|--react|--vue|--svelte|--expo] [--dry-run]" + echo " $0 [--next|--vite|--react|--vue|--svelte|--expo|--astro] [--dry-run]" echo "" echo "Options:" echo " --renderer Create an app for a registry renderer (authoritative)" @@ -43,6 +44,7 @@ usage() { echo " --vue Create a Vue 3 app" echo " --svelte Alias for --renderer sveltekit" echo " --expo Alias for --renderer expo" + echo " --astro Alias for --renderer astro" echo " --dry-run Print the resolved plan and exit without creating anything" echo " -h, --help Show this message" } @@ -76,6 +78,7 @@ while [[ $i -lt ${#args[@]} ]]; do --vite) RENDERER="vite" ;; --expo) RENDERER="expo" ;; --svelte) RENDERER="sveltekit" ;; + --astro) RENDERER="astro" ;; --react) FRAMEWORK="react" ;; --vue) FRAMEWORK="vue" ;; --dry-run) DRY_RUN=1 ;; @@ -198,8 +201,15 @@ case "$FRAMEWORK" in pnpm create expo-app "$PROJECT_NAME" --template tabs ;; astro) - echo "Creating Astro app..." - pnpm create astro@latest "$PROJECT_NAME" -- --template basics --typescript strict --no-install --no-git + # Astro ships a complete hybrid-islands starter under templates/astro + # (full package.json + src), so scaffold from it directly — deterministic + # and offline, unlike `pnpm create astro` which downloads the basics template. + echo "Creating Astro app from templates/astro..." + mkdir -p "$PROJECT_NAME" + cp -R "$TEMPLATES_DIR/astro/." "$PROJECT_NAME/" + # Personalize the package name. + sed -i.bak "s/\"my-astro-app\"/\"$PROJECT_NAME\"/" "$PROJECT_NAME/package.json" \ + && rm -f "$PROJECT_NAME/package.json.bak" ;; esac @@ -233,8 +243,8 @@ case "$FRAMEWORK" in ADDITIONAL_DEPS+=(prettier vitest @testing-library/svelte jsdom @vitest/coverage-v8) ;; astro) - # Astro hybrid: React islands + Tailwind + container-based testing - ADDITIONAL_DEPS+=(@astrojs/react @astrojs/tailwind tailwindcss prettier vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom @vitest/coverage-v8) + # templates/astro already pins all runtime + test deps (React islands, + # Tailwind, vitest, testing-library, jsdom); nothing extra to add. ;; expo) ADDITIONAL_DEPS+=(prettier jest jest-expo @testing-library/react-native) diff --git a/templates/README.md b/templates/README.md index 150c194..4f2f834 100644 --- a/templates/README.md +++ b/templates/README.md @@ -11,6 +11,7 @@ templates/ ├── shared/ # Framework-agnostic configs (used by all project types) ├── nextjs/ # Next.js-specific configs ├── vite/ # Vite-specific configs +├── astro/ # Astro hybrid-islands starter (React islands + Tailwind) ├── vue/ # Vue 3 + Vite configs ├── sveltekit/ # SvelteKit configs ├── expo/ # Expo + React Native configs