A Next.js + Tailwind CSS workspace with a glassmorphic UI, an interactive canvas, and an AI chatbot sidebar. Built with TypeScript and the App Router.
- Glassmorphic UI: Clean, frosted-glass aesthetic using Tailwind.
- Interactive Canvas: Render and manage components with save/load.
- Saved Components: Persist, list, and reuse canvas items.
- AI Chat: Chatbot sidebar backed by an agent API route.
- Orchestration: Message bus and multi-agent coordination utilities.
- Framework: Next.js 15 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- AI SDKs:
ai,@ai-sdk/openai
dev: Start the Next.js dev serverbuild: Create a production buildstart: Run the production serverlint: Lint the project
npm installnpm run devThen open http://localhost:3000.
npm run build
npm startCopy .env.example to .env.local and set OPENAI_API_KEY.
OPENAI_API_KEY: required for AI routesBOARD_STORAGE_MODE=file|memory: optional- Local development defaults to
file - Hosted production defaults to
memory
- The app is deploy-safe on platforms like Vercel.
- Board state is ephemeral in hosted production unless you replace the in-memory store with persistent storage.
- Local development still persists the board to
.data/board.json. - The included GCP path targets Cloud Run because this project uses dynamic API routes and server-side OpenAI calls.
This repo now includes a Cloud Run deployment path for the landing page app.
- A standalone Next.js production server in a Docker container
- A Cloud Build pipeline defined in
cloudbuild.yaml - Shell scripts in
scripts/to bootstrap GCP resources and deploy - Runtime secret injection from Secret Manager for
OPENAI_API_KEY
gcloudCLI authenticated to your GCP account- Docker available locally if you want to test the image with
npm run docker:build - A GCP project with billing enabled
Set your project and optionally your OpenAI key in the shell:
export PROJECT_ID="your-gcp-project-id"
export REGION="europe-west1"
export REPOSITORY="ashley-os"
export OPENAI_API_KEY="your-rotated-openai-key"
npm run gcp:bootstrapThis enables the required APIs, creates the Artifact Registry repository if needed, and creates or updates the OPENAI_API_KEY secret.
export PROJECT_ID="your-gcp-project-id"
export REGION="europe-west1"
export SERVICE="ashley-os-landing"
export REPOSITORY="ashley-os"
npm run gcp:deployThe deployment pipeline will:
- Build the container image
- Push it to Artifact Registry
- Deploy the app to Cloud Run
- Set
NODE_ENV=production - Force
BOARD_STORAGE_MODE=memoryfor deploy-safe ephemeral storage - Mount
OPENAI_API_KEYfrom Secret Manager
npm run build
npm run docker:build- Cloud Run is stateless. Saved board data resets across revisions and instance restarts while
BOARD_STORAGE_MODE=memoryis used. - If you need persistent board data in production, move
lib/boardStore.tsto Firestore, Cloud SQL, or another durable store. - Do not deploy with the current
.env.localkey. Rotate it first and store the new value in Secret Manager.
app/
globals.css
layout.tsx
page.tsx
PreloadLibs.tsx
api/
agent/
route.ts
components/
Canvas.tsx
CanvasWithSavePanel.tsx
ChatbotSidebar.tsx
DynamicCanvasRenderer.tsx
SavedComponentsPanel.tsx
context/
CodeContext.tsx
SavedComponentContext.tsx
lib/
agents.ts
messageBus.ts
multiAgentOrchestrator.ts
useSavedComponents.ts
types/
babel-standalone.d.ts
- Canvas & Renderer:
Canvas.tsx,DynamicCanvasRenderer.tsxfor drawing and dynamic component rendering;CanvasWithSavePanel.tsxpairs the canvas with a save UI. - Saved Components:
SavedComponentsPanel.tsxanduseSavedComponents.tsmanage persistence and retrieval. - Chatbot:
ChatbotSidebar.tsxprovides the UI; the API lives inapp/api/agent/route.ts. - Orchestrator & Bus:
multiAgentOrchestrator.tsandmessageBus.tscoordinate agent workflows and events. - Contexts:
CodeContext.tsx,SavedComponentContext.tsxshare state across the app.
- Tailwind setup is defined in
tailwind.config.tsand global styles inapp/globals.css. - TypeScript config lives in
tsconfig.json; Next.js config innext.config.ts. - If you use the VS Code task, a background
devtask is available.
- Shared guidance lives in
lib/designLanguage.tsand is injected into coding agents. - Use the following classes for consistent visuals:
- Panels:
.panel-steel,.panel-steel-soft,.panel-frosted-glass - Buttons:
.button-steel - Inputs:
.input-steel - Layout:
w-full h-full,rounded-2xl/rounded-3xl, responsive spacing
- Panels:
- Theme awareness: the page sets
data-themetodayornight; global CSS adapts accordingly. - The canvas wraps generated components with
.panel-steel-softfor cohesion.
MIT