# Light Cloud · full documentation bundle > Light Cloud, Inc. builds two things, mirrored by the two halves of the website. The **Platform** is a managed way to ship web apps: push to a GitHub repository and every commit builds and deploys — static sites on a global CDN, containers on Cloud Run, managed PostgreSQL — with a preview environment per branch, automatic SSL on custom domains, observability in the console, and deploys you can trigger from Claude or GitHub Copilot. **Labs** is the company's open-source work, home to ICE, a visual editor for cloud infrastructure that deploys to your own cloud accounts. This bundle is organized like the site: the Platform first, then Labs / ICE in full — pitch, install, architecture, feature surface, security model, editions, roadmap, contributing, and links. The Platform is managed and hosted by Light Cloud; Labs is Apache 2.0 code you run yourself. They share a company and a philosophy, not a codebase. --- # Platform Push to Git and get a live URL. Light Cloud reads your repo, builds the commit, and rolls it out: static sites to a global CDN, containers to Cloud Run, with managed PostgreSQL provisioned alongside. Every branch gets a preview environment, custom domains get automatic SSL, and logs and metrics live in the same console you deploy from. You can deploy from Claude or GitHub Copilot instead of a dashboard. Billing is usage-based and hourly, and idle apps scale to zero. The platform runs on Google Cloud (Cloud Build for builds, Artifact Registry for images, Cloud Run for containers) with a Cloudflare CDN in front of static sites. Start on a 30-day free trial at https://console.light-cloud.com. ## Deployments Connect a GitHub repository and every push builds and deploys on its own — no manual build step, no separate CI to wire up. Light Cloud installs a GitHub App, then reads the repo to detect the framework, package manager, build command, and output directory; you can override any of them. A push to a connected branch triggers a build on Cloud Build, whose logs stream live, then static assets land on a global CDN and containers roll out on Cloud Run and you get a URL. A static build is uploaded to object storage and served from the CDN; a backend build becomes a container image on Cloud Run that scales with traffic — Light Cloud reads your repo to decide which path fits, and you can set it yourself. Every deploy keeps its commit, message, author, duration, status, and full build log, so you can see what shipped and redeploy any earlier commit to roll back. No Dockerfile in the repo? One is generated for your framework; bring your own and it wins. You can also push a local folder straight from the VS Code extension or the MCP server before a repo is set up. https://light-cloud.com/deployments ## Preview environments An application can have many environments, one per branch you connect — each with its own URL, build settings, and environment variables. Open a pull request and the preview builds automatically, so reviewers click a link instead of pulling the branch. Delete the branch and its environment is removed; stale previews do not pile up. The production environment is marked and protected, and branch activity never touches it. Container previews scale to zero when idle, so review apps cost nothing overnight, and a preview is built the same way production is, so what a reviewer sees is what ships. Auto-deploy on push and automatic cleanup are on by default and can be turned off per application. https://light-cloud.com/previews ## Databases Provision managed PostgreSQL on Cloud SQL from the same project you deploy from — a production Postgres instance with no servers to patch or back up by hand. Pick a tier, region, and storage size when you create it and change them as the app grows; turn on high availability for workloads that cannot take downtime. The admin password is encrypted at rest, and connection details are wired into your app as environment variables, so the backend reaches the database in the same project without extra setup. Most hosts stop at the frontend and leave the database to you; Light Cloud runs the whole app — a static site or container for the code and a managed Postgres instance for the data, provisioned and connected from the same console. https://light-cloud.com/databases ## Custom domains Point a domain at any app or environment. Add the domain, add the one DNS record Light Cloud gives you at your registrar (the only manual step), and an SSL certificate is provisioned automatically; traffic then reaches the right environment over HTTPS, encrypted end to end. Certificates are issued and renewed for you with nothing to install or rotate, DNS mapping from hostname to running service is handled, and you can attach a domain to production or give a staging environment its own hostname. https://light-cloud.com/domains ## Observability Watch a build stream live, then follow the running service — logs and metrics for every environment sit in the same console you shipped from, next to the environment they belong to. Build logs stream as the build runs and stay readable on the deploy record afterwards; runtime logs stream from the running service, filtered to the environment you are looking at; metrics show how a service is doing at a glance without setting up a monitoring stack first. Production and every preview keep their own logs and metrics, kept separate. There is no second dashboard and no switching tools to find out how a deploy is doing. https://light-cloud.com/observability ## Deploy with AI Ship from Claude or GitHub Copilot without leaving your chat or your editor. Add the Light Cloud MCP server to Claude, sign in once through your browser (credentials stored locally), and ask it to deploy: it can create apps, ship them, manage environments, list repositories and branches, and read environment logs from a conversation. Or install the VS Code extension and use @lightcloud in GitHub Copilot Chat, with slash commands covering the whole loop — /deploy, /redeploy, /status, /list, /plan (preview config before shipping), and /destroy — and a small project config file so follow-up commands need no arguments. Framework detection and .env parsing happen for you, and deploys come back with a live URL and a link to the console. https://light-cloud.com/deploy-with-ai ## Frameworks Light Cloud reads your repo and picks the right build. Static and frontend stacks — React (Vite, Create React App), Vue, Angular, Svelte and SvelteKit static, Next.js static export, and plain HTML/CSS/JS — go to the global CDN. Backends run as containers on Cloud Run: Next.js with server-side rendering, Node (Express, Fastify, NestJS, Koa), Python (FastAPI, Flask, Django), Go, Java (Spring Boot), Ruby, PHP, and .NET. Framework and runtime are detected from the files in the project, the package manager (npm, yarn, pnpm, pip, poetry) is matched to the right install and build steps, config files are parsed to find where the build output lands, and a Dockerfile in the repo is used as-is. Detection, not configuration. https://light-cloud.com/frameworks ## Pricing A 30-day free trial ($0, no card for the first two weeks, up to three resources, static sites and containers, one managed Postgres database, preview environments and custom domains), then usage-based hourly billing. You pay for what runs: compute per instance-hour (container apps default to zero minimum instances, so an idle app stops running and stops billing), managed Postgres for the tier and storage you provision, object storage for what you keep, bandwidth served (static sites go out over a CDN), and build minutes for the time builds take. No per-project fees; add team members at a flat $9 per user each month. Scale-to-zero is what makes many preview environments cheap — they cost nothing while they sit idle. https://light-cloud.com/pricing --- # Labs (open source): ICE Labs is Light Cloud's open-source side: the code you run yourself, deploying to your own cloud accounts, Apache 2.0 with no telemetry and no license keys. ICE is the flagship project; its blocks are the building units and its templates are ready-made compositions. The rest of this bundle documents ICE in full. ## ICE (Light Cloud Labs) > ICE (Integrated Cloud Environment) is an open-source visual editor for cloud infrastructure. Apache 2.0. Version 0.1.50. Tagline: "Visual Studio for Cloud." Drag provider-neutral concept blocks onto a canvas, connect them, and ICE compiles the canvas into real resources on GCP, AWS, or Azure. The graph engine is provider-agnostic; per-cloud deployers handle every SDK call. The desktop app is Electron-based, runs offline with an embedded gateway and a local SQLite database. An optional AI assistant (Anthropic Claude with a bring-your-own key, or any OpenAI-compatible endpoint such as Ollama / LM Studio / vLLM) edits the canvas in plain English using ghost-mode proposals that the user accepts or rejects. --- ## Why ICE exists Cloud infrastructure has the worst developer ergonomics in the stack: every team rebuilds the same shape (web service + database + queue + bucket + secrets) in Terraform or Pulumi, then duplicates it for staging, then again for a second cloud, then again as a CI/CD pipeline, then again as a cost dashboard. ICE makes the canvas the source of truth: one drag-and-drop document describes the architecture, plans the deploy, projects the cost, drives CI/CD, surfaces logs, and accepts AI edits. Provider-agnostic at the top, real cloud below. Apache 2.0, runs offline, no telemetry, no license keys: your canvas, your cloud, your data. --- ## Repository - Source: https://github.com/light-cloud-com/ice - Issues: https://github.com/light-cloud-com/ice/issues - Discussions: https://github.com/light-cloud-com/ice/discussions - Docs: https://github.com/light-cloud-com/ice/tree/main/docs - Docs landing: https://github.com/light-cloud-com/ice/blob/main/docs/README.md - Roadmap: https://github.com/light-cloud-com/ice/blob/main/ROADMAP.md - Contributing: https://github.com/light-cloud-com/ice/blob/main/CONTRIBUTING.md - Security: https://github.com/light-cloud-com/ice/blob/main/SECURITY.md - Support: https://github.com/light-cloud-com/ice/blob/main/SUPPORT.md - License: https://github.com/light-cloud-com/ice/blob/main/LICENSE The docs README groups pages by audience: - **For users**: [getting-started.md](https://github.com/light-cloud-com/ice/blob/main/docs/getting-started.md), [glossary.md](https://github.com/light-cloud-com/ice/blob/main/docs/glossary.md) - **For operators**: [architecture/README.md](https://github.com/light-cloud-com/ice/blob/main/docs/architecture/README.md), [architecture/database.md](https://github.com/light-cloud-com/ice/blob/main/docs/architecture/database.md), [architecture/desktop.md](https://github.com/light-cloud-com/ice/blob/main/docs/architecture/desktop.md), [architecture/ai-assistant.md](https://github.com/light-cloud-com/ice/blob/main/docs/architecture/ai-assistant.md) - **For contributors**: [testing.md](https://github.com/light-cloud-com/ice/blob/main/docs/testing.md), [architecture/core-engine.md](https://github.com/light-cloud-com/ice/blob/main/docs/architecture/core-engine.md), [architecture/frontend.md](https://github.com/light-cloud-com/ice/blob/main/docs/architecture/frontend.md), [architecture/services.md](https://github.com/light-cloud-com/ice/blob/main/docs/architecture/services.md), [reference/blocks.md](https://github.com/light-cloud-com/ice/blob/main/docs/reference/blocks.md), [reference/extending-providers.md](https://github.com/light-cloud-com/ice/blob/main/docs/reference/extending-providers.md) - **Per-provider readiness** is tracked in code: [`PROVIDER_READINESS`](https://github.com/light-cloud-com/ice/blob/main/packages/constants/src/providers.ts) Docs are hand-written and versioned with the code. When docs and code disagree, code wins. --- ## Repository layout ``` ice/ ├── apps/ │ ├── gateway/ Express composition of all services; routes, CORS, auth middleware │ └── desktop/ Electron main process, IPC, window management, auto-update ├── packages/ │ ├── core/ Graph engine, schemas, deploy planner, importers: no UI, no network │ ├── ui/ Shared React components (canvas, palette, panels, AI chat) │ ├── web/ Vite shell that boots the UI as a web app │ ├── blocks/ Cloud resource block definitions (concepts + provider-specific variants) │ ├── templates/ Pre-built infrastructure compositions (SaaS starter, RAG chatbot, …) │ ├── providers/aws/ AWS deployer implementation │ ├── providers/azure/ Azure deployer implementation │ ├── providers/gcp/ GCP deployer (20 service handlers) │ ├── db/ Prisma schema + client singleton │ ├── shared/ Auth middleware, crypto, Socket.IO helpers │ ├── constants/ Shared constants (incl. PROVIDER_READINESS) │ ├── ai/ AI provider abstraction (Anthropic + OpenAI-compatible) │ └── types/ Shared TypeScript interfaces: API contracts, DTOs, events └── services/ ├── canvas/ CanvasProject + environments CRUD ├── deploy/ Plan, apply, pipelines, GitHub webhooks, queue workers, drift ├── ai/ Claude integration, SSE streaming, diagnose-deploy ├── iam/ User/org/auth endpoints, onboarding, profile ├── credentials/ Encrypted cloud-provider credential storage └── engine/ Schema + resource metadata API ``` The dependency rule is strict: nothing in `packages/` depends on `services/` or `apps/`; services depend on packages; apps depend on everything. --- ## Install and first canvas ```bash git clone https://github.com/light-cloud-com/ice.git cd ice pnpm install pnpm schemas:build # one-time, 10–15 min, downloads ~600 MB into .schema-cache/ pnpm dev:all # web app at http://localhost:5173, gateway at 15173 # or: pnpm dev:desktop # Electron window with embedded gateway, fully offline ``` Prerequisites: Node 22+, pnpm 10+, Git. No Docker required for the default setup: dev mode uses an embedded SQLite file. Production-like dev (Postgres + Redis + BullMQ workers) requires Docker; a docker-compose setup is on the roadmap. There is no login screen in Community Edition: the gateway auto-seeds a single "desktop user" on first boot and every authenticated route resolves to it. Local secrets (session signing + at-rest credential encryption) are auto-generated per user and persisted at `~/Library/Application Support/ice/secrets.json` (macOS), `~/.config/ice/secrets.json` (Linux), or `%APPDATA%\ice\secrets.json` (Windows). Keep that file safe: it's the key to your DB-encrypted provider credentials. To narrow the schema build to just GCP + AWS + Azure (faster): ```bash pnpm schemas:build -- --providers hashicorp/google,hashicorp/aws,hashicorp/azurerm ``` First canvas walkthrough: 1. Open the palette (left side) and drag a Static Site block onto the surface. 2. Drag a Custom Domain block next to it. 3. Connect them by dragging from one block's edge to the other. 4. Select the Static Site block: the properties panel opens on the right. Fill in a GitHub repo (or leave blank). 5. Click Deploy. If GCP credentials are configured under Settings → Providers, the engine plans and applies real infrastructure. --- ## Configuration Community Edition needs zero env vars to run. Optional overrides via `.env`: | Variable | Purpose | |---|---| | `DATABASE_URL` | SQLite file path (dev) or PostgreSQL URL (prod). Default: local SQLite | | `JWT_SECRET` | Any random string (auto-generated on first boot if absent) | | `CREDENTIAL_ENCRYPTION_KEY` | Exactly 32 characters. AES-256-GCM key for provider credentials. Auto-generated per user if absent | | `ANTHROPIC_API_KEY` | Optional. Enables the AI assistant (Anthropic provider, preferred when set) | | `ICE_AI_URL` + `ICE_AI_MODEL` | Optional. Point at any OpenAI-compatible backend (Ollama, LM Studio, vLLM) | | `REDIS_URL` | Optional, prod only. Enables BullMQ background workers | | `FRONTEND_URL` | Used by the gateway's CORS allowlist | | `PORT` | Web app port (default 5173) | Cloud provider credentials (GCP / AWS / Azure) are entered **in-app** under Settings → Providers and live AES-256-GCM-encrypted in the workspace DB. Each provider has a `validate` endpoint that does a read-only API call to confirm the credential still works. --- # Architecture ## One-minute model ``` User → Web app (React + SVG Canvas) → Gateway (Express + Socket.IO) → 6 services ↓ canvas / deploy / ai iam / credentials / engine ↓ Prisma DB (SQLite or Postgres) BullMQ on Redis (prod only) Cloud SDK calls (GCP / AWS / Azure) Anthropic Claude (via SSE) ``` The web app is the only UI surface in development mode. The Electron desktop app re-uses the same web bundle with an embedded gateway inside the Electron main process: the renderer never imports Node; everything goes through HTTP to `localhost:15173`. ## The six services | Service | Purpose | | --------------- | ----------------------------------------------------------------------------- | | **canvas** | CanvasProject CRUD, environments, project members | | **deploy** | Plan, apply, pipelines, GitHub webhooks, queue workers, drift detection | | **ai** | Anthropic Claude integration, SSE streaming, deploy-failure diagnosis | | **iam** | Users, orgs, profile, onboarding flow | | **credentials** | Encrypted provider + GitHub credential storage | | **engine** | Schema + resource metadata API (what blocks exist, what properties they have) | In Community Edition, the gateway and all six services run in one process: no inter-service HTTP. The separation is a code-organization choice, not a deployment choice. The gateway adds Helmet, CORS, cookie-parser, rate limiting (200 req/min prod, 1000 req/min dev/test), and Socket.IO around them. ## Request flow ``` Web/Desktop → Gateway → Service router → Prisma → DB ↓ Helmet, CORS, rate limit, auth middleware ↓ Long-running work → Socket.IO event stream ``` The two interesting boundary crossings: 1. **`translate_card_to_graph`** (`packages/core/src/deploy/card-translator.ts`) converts the UI's "cards" (visual blocks with properties) into the core engine's provider-agnostic graph. This is where the visual representation and the deploy model actually meet. 2. **Per-handler apply** (`packages/providers//src/handlers/*` and `packages/core/src/deploy/providers//handlers/*`): one handler per cloud service. Each handler knows how to create, update, delete, and diff one resource type. ## Storage | Data | Where | | ---------------------------------------- | ------------------------------------------------- | | Canvas projects, environments, pipelines | Prisma DB (SQLite in dev, Postgres in prod) | | Cloud credentials | Prisma DB, encrypted at rest with AES-256-GCM | | Deploy event log | Prisma DB | | Job queue (prod) | Redis via BullMQ | | Session | Stateless JWT cookies | | File uploads | Local filesystem for dev; object storage for prod | Two SQLite databases play different roles: - **`.desktop-dev.db`**: *runtime state*. Canvases, environments, deployments, encrypted provider credentials, deploy event log, pipelines. `~1.5 MB` and grows. Gitignored. Moves to Postgres for production self-hosting and ICE Cloud (same Prisma schema). - **`packages/core/data/ice-schemas.db`**: *provider schema catalog*. Read-only. Generated by `pnpm schemas:build` from Terraform and Pulumi provider registries (~600 MB cached under `.schema-cache/`; first run takes 10–15 minutes). 36 MB committed. Powers the properties panel, autocomplete, and validation across tens of thousands of resource types. Stays SQLite even when the runtime DB is Postgres. --- # Product surface ## Canvas The canvas is a drag-and-drop editor with a properties panel on the right and a palette on the left. Blocks represent cloud resources; edges represent connections. The canvas validator runs continuously: unmet requirements show as badges, hard violations block the deploy. The renderer is a custom SVG implementation (chosen over React Flow for predictable pan/zoom math at 1000-node scale). ## 28 concept blocks across 8 categories The canvas palette is provider-neutral; each concept compiles to a per-cloud primitive at deploy time. **Compute** - Scalable Backend: Cloud Run (GCP), ECS Fargate (AWS), Container Apps (Azure) - Worker: Cloud Run / ECS Fargate / Container Apps - Serverless Function: Cloud Functions / Lambda / Functions - SSR Site: Cloud Run / ECS Fargate / App Service - Static Site: Cloud Storage + CDN / S3 + CloudFront / Storage Account + CDN **Data** - Postgres: Cloud SQL / RDS / Database for PostgreSQL - MySQL: Cloud SQL / RDS / Database for MySQL - MongoDB: Firestore / DocumentDB / Cosmos DB - Redis Cache: Memorystore / ElastiCache / Cache for Redis - Object Storage: Cloud Storage / S3 / Blob Storage - Vector DB: Vertex AI Vector Search / OpenSearch / AI Search **Messaging** - Message Queue: Pub/Sub / SQS / Service Bus - Event Stream: Pub/Sub / Kinesis / Event Hubs **AI** - LLM Gateway: Vertex AI endpoints / Bedrock / Azure OpenAI - Private AI Service: GKE / EKS / AKS - Vector DB: shared with Data category **Networking** - Public Traffic: Load Balancer / ALB + CloudFront / Front Door - Private Network: VPC / VPC / VNet - API Gateway: API Gateway / API Gateway / API Management - Custom Domain: Cloud DNS + LB / Route 53 / DNS Zone **Observability** - Observability: Cloud Logging / CloudWatch / Azure Monitor **Security** - Secret Store: Secret Manager / Secrets Manager / Key Vault - Env Config: Runtime Config / SSM Parameter Store / App Configuration **Integration** - GitHub Repo: Wire a repo to a service, auto-deploy on push - Email Service: SendGrid (partner) / SES / Communication Services - Scheduled Task: Cloud Scheduler / EventBridge / Logic Apps Each concept folder under `packages/blocks/src/common/concepts//` carries `index.ts` (definition), `blueprint.ts` (drop-to-canvas defaults + per-provider variants), and `info.ts` (long-form description). Provider-specific variants under `packages/blocks/src/{aws,azure,gcp}/` override the mapping when a concept compiles differently per cloud. Concepts advertise *requirements* enforced by `packages/core/src/validation/`: a Scalable Backend needs either a GitHub Repo or an Object Storage for code plus a Public Traffic upstream. Unmet hard requirements block the deploy; soft requirements warn. Authentication, analytics data warehouse, and search concepts are on the roadmap. ## 13 templates available today Pre-built canvas compositions, every block of which the user could drop individually: - **SaaS Starter**: static + backend + Postgres + auth + custom domain - **Full-Stack**: SSR + backend + Postgres + storage - **RAG Chatbot**: static + LLM + vector DB + backend - **Backend API**: backend + Postgres + observability - **Microservices**: multiple backends + event stream + shared DB - **Serverless API**: API gateway + functions + DB - **Event-Driven Serverless**: event stream + multiple functions - **Secure API**: backend behind private network + secrets - **AI / ML**: LLM + vector DB + model endpoints - **EU Compliance**: SaaS Starter, region-locked - **SaaS Multi-Tenant**: tenant-isolated - **SaaS Analytics Dashboard**: dashboard + data pipeline - **Budget Web App**: minimal cheapest full-stack shape Quick-Starts (single function, container + DB, worker + queue, static site) are on the next-up list. Templates live in `packages/templates/`. ## Provider matrix `PROVIDER_READINESS` in `packages/constants/src/providers.ts` is the truth source. - **GCP: stable.** 20+ handlers across compute (Cloud Run services + jobs, Cloud Functions, GKE), database (Cloud SQL PostgreSQL + MySQL, Firestore, Memorystore Redis), storage (Cloud Storage), messaging (Pub/Sub, Cloud Scheduler), AI/ML (Vertex AI endpoints + Vector Search + ML models), analytics (BigQuery, Discovery Engine), security (Secret Manager, Identity Platform), networking (API Gateway, Load Balancer, Domain Mapping), observability (Cloud Logging). Full create/update/destroy lifecycle with live progress streaming. Importer covers 45+ resource kinds via Cloud Asset Inventory plus service-specific APIs. - **AWS: experimental.** EC2 instance, S3 bucket, Lambda function ship end-to-end. Other categories surface "unsupported on AWS" in the plan modal. Importer not implemented. - **Azure: experimental.** Virtual Machine, Storage Account, Web App ship end-to-end. Other categories surface "unsupported on Azure". Importer not implemented. - **Kubernetes: design-only.** 13 blocks render on canvas; deployer not wired. - **Alibaba Cloud / Oracle Cloud / DigitalOcean / Tencent Cloud: design-only.** Block stubs only. Adding a provider is well-scoped contributor work: register in `packages/constants/src/providers.ts`, implement `ProviderDeployer` under `packages/core/src/deploy/providers/`, add an auth adapter, add provider-variants to the relevant concept blueprints, then wire tests and docs. `aws-deployer.ts` (~500 lines, 3 handlers) is the minimum-viable shape; `gcp-deployer.ts` is the reference. The full 7-step walkthrough lives at [`docs/reference/extending-providers.md`](https://github.com/light-cloud-com/ice/blob/main/docs/reference/extending-providers.md). --- # Core engine deep dive The core engine (`packages/core/`) is the provider-agnostic brain: everything about *how* infrastructure is modelled, validated, diffed, planned, applied, and imported, with no UI and no network dependencies. Everything else in ICE is either a consumer of core or a translator into it. The engine is usable standalone: the `ice` CLI in `packages/core/src/cli/` imports it and runs a deploy programmatically. ## Package layout ``` packages/core/src/ ├── index.ts Top-level re-export surface ├── types/ Shared types: Result, errors, IDs ├── schema/ SchemaProvider interface + SQLite implementation ├── schemas/ SQLite DBs (base + per-provider) and the loader ├── graph/ Parser, MutableGraph, algorithms, validator, classifier, inference ├── state/ Deploy state persistence (last-applied graph) ├── plan/ Plan computation: desired vs current, topological order ├── apply/ Execute a plan ├── diff/ Property-level diff helpers ├── compute/ Derived / aggregate / propagation rules for blocks ├── deploy/ Deploy engine: card translator, deploy service, provider index ├── providers/ Provider registry + mock provider for tests ├── resources/ High-level resources, blueprint factory, cloud provider registry ├── importers/ Terraform, Pulumi, GCP, AWS, Azure importers ├── validation/ Canvas-level validation (separate from graph validation) ├── export/ Terraform / Pulumi export from a graph ├── errors/ Domain-specific error types └── cli/ The `ice` CLI binary ``` ## Graph model A graph is nodes + edges with provider-neutral types and property bags. Key file: `packages/core/src/graph/mutable-graph.ts`. Algorithms (topological sort, cycle detection, path finding, execution layers) live in `packages/core/src/graph/algorithms.ts`. Three identifier spaces travel through the deploy stack and are NOT interchangeable: - **Canvas node id**: user-facing block id from `cards-slice.nodes[i].id`. The wire's `node_id` is always this. - **Graph node id**: engine-internal `${type}:${name}`, e.g. `gcp.sql.databaseInstance:ice-foo-prod-instance-abc123`. Lives only inside the scheduler and `MutableGraph`. - **Resource name**: the cloud-side identifier. Lives in handler code. `services/deploy/src/services/deploy.service.ts` is the translation seam. ## Plan and apply The deploy engine (`packages/core/src/deploy/`) is provider-agnostic at the top and per-cloud at the handler level. A typical apply cycle: 1. **Validate canvas**: cycles, references, type compatibility, connectivity, soft + hard requirements. 2. **`translate_card_to_graph`** converts UI cards into provider-neutral graph nodes, materializing each card's provider implementation based on the selected provider. 3. **Plan** diffs the graph against last-applied state and produces `CREATE / UPDATE / DELETE / NO_OP` per resource, plus a per-canvas monthly cost projection. 4. **Scheduler** (`packages/core/src/deploy/scheduler.ts`): a bounded worker pool over the per-node DAG. Pool size defaults to 6; per-handler caps reserve `gcp.sql.* = 1` and `gcp.redis.* = 1` so multi-instance fan-outs do not trip GCP create-rate quotas. Each node moves through `queued → applying → (succeeded | failed | skipped | cancelled-due-to-dep)`. 5. **Failure isolation**: failure isolates to descendants only; siblings and unrelated branches keep running, so a 12-resource canvas that loses one Cloud SQL still completes the rest and surfaces a partial-success rollup. 6. **Sub-step progress**: handlers report milestones via `ctx.on_step(name, { label, index, total })` so a Cloud SQL provision shows "Creating instance" → "Waiting for instance to become ready" rather than going dark for ten minutes. The build-helper extension pins every Cloud Build sub-state (Submitting / queued / running) to its outer step index, so the bar holds steady while labels refresh. 7. **State persistence**: new state is written back on success; partial failures persist state-so-far so the next plan resumes from the exact spot. The legacy `apply-engine.ts` and the per-resource percentage that reset between nodes are gone: see decisions entry "2026-04-28: Parallel deploy scheduler with per-node live status" for the alternatives considered (layer-batched `Promise.all` rejected because it waits for the slowest node in each layer; new socket room rejected because the existing `deploy:` is what the canvas hydration is shaped around). ## Live event wire contract The deploy service publishes one Socket.IO event name (`DEPLOY_EVENT_CHANNEL = 'deploy:event'`) carrying a discriminated `DeployEvent` union: types in `packages/types/src/deploy-events.ts`, emitter helpers in `packages/shared/src/socket/service.ts`. Five variants: | `event.type` | Fired when | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `node_status` | Per-node lifecycle transition. Carries `card_id`, `node_id`, `resource_name`, `resource_type`, `action`, optional `error`, optional `duration_ms` on terminal states. | | `node_progress` | Mid-apply milestone from a handler's `ctx.on_step`. Carries `step: { label, index, total }`. | | `log` | Free-text deploy log line, optionally `node_id`-scoped. | | `complete` | One-shot terminal for the whole deploy. Carries `outcome: 'success' \| 'partial' \| 'failure' \| 'cancelled'` and `totals`. The frontend computes its rollup from `nodesById` rather than relying on `totals` for live progress. | | `requirement_verified` | Post-deploy poller fires when a `BlockRequirementStatus` row flips. Carries the full unique key `(card_id, node_id, environment, requirement)` plus an optional `details` blob. | ## Schema catalog `packages/core/data/ice-schemas.db` is a read-only SQLite catalog (~36 MB committed) generated by `pnpm schemas:build` from the Terraform + Pulumi provider registries (~600 MB upstream schemas cached under `.schema-cache/`; first run takes 10–15 minutes, subsequent runs hit the cache). It powers the properties panel, autocomplete, and validation across tens of thousands of resource types. Stays SQLite even when the runtime DB is Postgres. Re-run any time you bump a provider version. ## Cost prediction Per-canvas monthly projection before apply. Each block contributes a line item from public pricing data plus its configured parameters (instance class, region, replicas, storage size, scaling profile). Variable costs (egress, per-request) are estimated against modelled traffic and surfaced separately. Free tiers and committed-use discounts are subtracted. Tied to the provider: a multi-cloud migration shows the projected bill on the target cloud before commit. Projected-vs-actual dashboards, drift alerts, cost-outlier suggestions, and per-environment budgets are on the roadmap. ## Import and export The GCP importer is the most mature: walks Cloud Asset Inventory plus service-specific APIs and produces a canvas representing what it found (45+ resource kinds). Terraform-state-JSON and Pulumi-checkpoint-JSON importers work today. AWS and Azure importers are partial. Docker Compose and a polished UI flow for all importers are on the roadmap. Importing is the read-only inverse of deploy and reuses the same graph model. Export goes the other way: `packages/core/src/export/` turns a graph back into Terraform HCL or Pulumi TypeScript, so a team that wants to drop ICE for plain IaC has a clean exit. AWS CDK and Kubernetes manifest exports are on the roadmap. ## Multi-cloud migration Switch the canvas provider; ICE remaps every block to the equivalent service on the new cloud, reprojects cost, and flags untranslatable details (region availability, IAM shape, network constructs) before apply. Data movement and DNS cut-over are explicitly out of scope. ## CI/CD Connect a GitHub repo to a canvas node. `services/deploy/src/routes/webhooks.ts` listens for push events on a watched branch, HMAC-verifies the payload against the repo's secret, and triggers a deploy on the configured environment. Pipelines are stored per-project; environments (production, staging, preview branches) each carry their own deploy state and credentials. Queue mode kicks in when `REDIS_URL` is set: long-running work is enqueued with BullMQ and picked up by workers; otherwise deploy runs synchronously in-process (the default in dev and on the desktop). --- # AI assistant Optional, off by default. Set `ANTHROPIC_API_KEY` (or `ICE_AI_URL` + `ICE_AI_MODEL` for an OpenAI-compatible backend) and the chat panel activates. Anthropic is picked first if both are set. - **Chat over the canvas.** The system prompt is built from a project-agnostic preamble, a serialized summary of the current canvas (blocks, edges, provider, environment, validation state), and a deployment-state summary (what's deployed where, what's drifted, what's pending). User turn follows; streaming via Server-Sent Events. - **Ghost mode proposals.** Two tool calls today: `add_block` and `connect_blocks`. The client renders them as dashed-outline reduced-opacity nodes/edges and waits for the user to accept or reject. Accepting converts them into real `cards-slice` state and triggers validation. More tool types (delete, rename, modify property, group) are coming. - **Deploy diagnosis.** On a failure, "Explain" forwards the error payload + relevant graph context to Claude for a plain-English diagnosis and a suggested fix. - **Cost.** A median turn (1 user message, ~30-block canvas, ~150-token reply) is roughly 4–8k input + 200–500 output tokens: fractions of a cent at Claude Sonnet 4.x rates. Deploy-diagnosis turns are larger (8–15k input tokens). Token usage is not billed back in Community Edition; you pay Anthropic directly. - **OpenAI-compat.** Point `ICE_AI_URL` at a local Ollama / LM Studio / vLLM (or any compatible endpoint). The streaming format translates automatically; SSE deltas land in the same `ChatChunk` type as Anthropic's. In production, `OpenAICompatProvider` throws at construction without a URL rather than silently falling back to localhost. - **No autonomous apply.** Every proposal goes through explicit user approval. The API key stays server-side; the browser never sees it. What is coming: live cloud queries (AI Read L3), multi-step tool use, full mutation surface (delete, rename, modify, group), proactive suggestions, per-provider prompt profiles, validated OpenAI-compat backend matrix. --- # Desktop app Cross-platform Electron, builds for macOS (ARM64 `.dmg` + `.zip` today; Intel a config flip away), Windows (NSIS `.exe` installer, x64), Linux (`.AppImage` x64+ARM64 and `.deb` x64). The main process dynamically imports `@ice/gateway`, which listens on `localhost:15173`. A `BrowserWindow` loads the same web bundle that `packages/web` produces; HTTP + WebSocket round-trips through the embedded gateway. All DB writes land in the local SQLite file under the platform's app-data directory (`~/Library/Application Support/ICE/ice.db` on macOS, `%APPDATA%/ICE/ice.db` on Windows, `~/.config/ICE/ice.db` on Linux). Delete that file to reset. Security model: `nodeIntegration: false`, `contextIsolation: true`, `sandbox: true` where possible. Preload exposes a typed, deliberate IPC surface. No `remote`, no unrestricted `ipcMain`. The renderer cannot import Node modules; everything goes through HTTP to the embedded gateway. v0.1 binaries are not yet code-signed: first-run on macOS uses the standard "right-click → Open" Gatekeeper path; Windows uses "More info → Run anyway". Apple Developer ID notarization, Windows EV code signing, and `electron-updater` against GitHub Releases are on the v0.2 plan. --- # Frontend React 18 + Vite. The canvas is a custom SVG renderer (chosen over React Flow for predictable pan/zoom math at 1000-node scale). Redux Toolkit with 17 slices: `account`, `ai`, `cards`, `debug`, `deploy`, `environments`, `ghost`, `graph`, `integrations`, `onboarding`, `pipeline`, `project-list`, `projects`, `selection`, `ui`, `validation`, `view`. Slice boundaries match feature folders under `packages/ui/src/features/`. Tailwind for layout, Radix UI for accessible primitives, custom `ice-*` design tokens. Internationalization is hand-rolled with two complete locales today (English and Mandarin). 300+ frontend component tests use a hand-rolled tree-walker pattern (TestRenderer + `vi.hoisted` mocks) for fast, pure tests; `jsdom` is also available. --- # Security model - **Cloud credentials** are AES-256-GCM ciphertext at rest in `ProviderCredential.encryptedData`; the key lives in `CREDENTIAL_ENCRYPTION_KEY` (must be exactly 32 characters; auto-generated per user on first boot if absent). - **GitHub webhook payloads** are HMAC-verified in `services/deploy/src/routes/webhooks.ts`. - **CORS** is restricted to `FRONTEND_URL`. - **Helmet.js** sets standard security headers. - **Rate limits** sit in front of every API route (200 req/min production, 1000 req/min dev/test). - **Desktop sandboxing**: `nodeIntegration: false`, `contextIsolation: true`, `sandbox: true` where possible. Renderer → main IPC is typed and deliberate. - **No telemetry**, **no license keys**, **secrets auto-generated** per user on first boot. Vulnerability reports go to [`SECURITY.md`](https://github.com/light-cloud-com/ice/blob/main/SECURITY.md). --- # Editions - **Community Edition**: this repo. Single user, Apache 2.0, no telemetry, no license keys. - **Team Edition**: planned. Self-hosted, multi-user with invites, OIDC SSO, RBAC (editor / viewer / owner), shared team/org template libraries, comments + mentions, real-time canvas presence + cursors with CRDT/OT locking, audit log. - **Cloud Edition**: planned. Managed by Light Cloud, usage-based billing, SLA, support, per-org token tracking for AI. Multi-user features (presence, comments, RBAC) ship in Team and Cloud only. --- # Tech stack - **Frontend**: React 18, Vite, Redux Toolkit (17 slices), Tailwind CSS, Radix UI, custom SVG canvas - **Backend**: Express, Prisma 6, PostgreSQL 16 / SQLite, Redis (prod only), BullMQ, Socket.IO - **AI**: Anthropic Claude (streaming SSE), OpenAI-compatible fallback for Ollama / LM Studio / vLLM - **Desktop**: Electron, electron-vite, embedded gateway, electron-builder, electron-updater - **Cloud SDKs**: Google Cloud (20 services), AWS SDK, Azure SDK - **Testing**: Vitest (unit + integration), Playwright (E2E), Playwright-driven GCP deployment-scenario dashboard at `:15200` - **Languages**: TypeScript everywhere - **Package manager**: pnpm 10 + workspaces, Node 22+ --- # Testing Four categories with separate `pnpm` scripts: - `pnpm test:unit`: Vitest, no DB or network. Lives next to source as `*.test.ts` / `*.test.tsx`. - `pnpm test:int`: Prisma SQLite. `*.int.test.ts`. - `pnpm test:e2e`: Playwright against a running gateway + web. CI uses Postgres + Redis service containers. - `pnpm test:gcp` + `pnpm test:scenarios`: real GCP, opt-in, contributor-only. Interactive dashboard at `http://localhost:15200`. `pnpm typecheck`, `pnpm lint:check`, and `pnpm format:check` round out the CI gates. --- # Internal agent workflow For non-trivial changes the maintainers run a four-agent loop: planner / implementer / critic / ux-tester. Persistent state lives in: - `state/decisions.md`: append-only architectural decisions - `state/progress.md`: orchestrator-only living document - `state/learnings.md`: append-only, kebab-anchored, dated by agent + unit Learnings cited 3+ times graduate to `/docs/*.md` and back-link from the original entry. Quarterly compaction archives older snapshots to `state/archive/learnings-YYYY-Qn.md`. This workflow is documented in [`docs/agents.md`](https://github.com/light-cloud-com/ice/blob/main/docs/agents.md) and informs how the codebase evolves. --- # Roadmap ## AI - Live telemetry context (AI Read L3): logs + metrics in prompt - Multi-step tool use (plan → read → propose → validate) - Full mutation surface: delete, rename, modify, group - Proactive suggestions: unused blocks, missing secrets, cost outliers - Per-provider prompt profiles - Validated OpenAI-compat backend matrix (Ollama, LM Studio, vLLM) ## Providers - AWS + Azure to GCP parity - Alibaba Cloud: design-only to deployable - Oracle Cloud Infrastructure - DigitalOcean: Droplets, App Platform, Managed DBs, Spaces - Tencent Cloud - Kubernetes (any): Helm + raw manifest outputs ## Blocks - Networking primitives: VPC, firewall, DNS, load balancer - Managed K8s: GKE, EKS, AKS - CI/CD: registries + build services - Workflow orchestration: Step Functions, Cloud Workflows, Logic Apps - More data: Aurora, Azure SQL, Spanner, time-series - Auth + Analytics concepts - Info panel: "compiles to" + code snippets in 6 languages ## Observability - Live logs in-canvas (Cloud Logging / CloudWatch / Azure Monitor) - Per-block metrics sparklines (rate / errors / latency) - Cost dashboards: projected vs actual, drift alerts - Alert configuration from the canvas - Real-time resource health polling ## Security - Secret rotation UI + expiring-cert warnings + audit log - Pre-deploy: dep-vuln scan, IAM over-permission, region compliance (EU, HIPAA) - Supply chain: SBOM, notarized macOS, EV-signed Windows, provenance - Per-canvas secrets: reference without leaking plaintext - Electron `safeStorage` for desktop credentials ## Import / Export / Migration - UI flow for existing GCP / AWS / Azure / Terraform / Pulumi importers - Docker Compose to canvas - Provider-to-provider migration plans - Export to Terraform HCL, Pulumi TS, AWS CDK, K8s manifests - Version migration: no canvas loss between releases ## Collaboration and teams - Real-time canvas editing: presence, cursors, locking (CRDT/OT) - Comments + mentions - RBAC UI: editor / viewer / owner, sharing links, audit log - Team Edition: self-hosted multi-user, invites, OIDC SSO - Shared team / org template libraries ## Templates - Missing patterns: serverless API, Jamstack, microservices, event-driven, batch, analytics - Quick-starts: single function, container+DB, worker+queue, static site - Per-env overrides in one template - Industry templates: e-commerce, mobile, IoT, media, multi-tenant SaaS ## Deploy - CI/CD workflow templates (Cloud Run, Vercel) - Full AWS + Azure Apply parity ## Frontend - Design system refresh: unified tokens, proportional sans-serif - Property help text rendering - Radix context menus: keyboard + a11y - Canvas search + export (SVG / PNG / PDF) ## Desktop - Auto-update via electron-updater - Signed + notarized builds (.dmg, .exe/.msi, .AppImage/.deb) - IPC + credential-storage tests ## Long tail - Marketplace: third-party blocks and templates - Policy as code: OPA / Rego hard gates - Project management: duplicate, archive, tags, filters - In-app learning: tutorial, contextual help, per-concept videos --- # Contributing Apache 2.0. Issues, feature requests, and PRs welcome. - Workflow: https://github.com/light-cloud-com/ice/blob/main/CONTRIBUTING.md - Code of conduct: https://github.com/light-cloud-com/ice/blob/main/CODE_OF_CONDUCT.md - Security disclosures: https://github.com/light-cloud-com/ice/blob/main/SECURITY.md A typical concept PR shape: 1. `packages/blocks/src/common/concepts//index.ts`: id, label, default properties, category 2. `packages/blocks/src/common/concepts//blueprint.ts`: drop-to-canvas initial state, per-provider variants 3. `packages/blocks/src/common/concepts//info.ts`: description 4. `packages/core/src/resources/high-level-resources.ts`: register the resource 5. `packages/providers//src/handlers/.ts`: per-provider handler 6. `packages/ui/src/features/canvas/components/nodes//`: custom node renderer (optional) 7. Tests Reference implementation: `packages/blocks/src/common/concepts/static-site/`. --- # Where to start reading the code - `packages/blocks/src/common/concepts/static-site/index.ts`: simplest concept - `packages/blocks/src/common/concepts/scalable-backend/index.ts`: a more complex one - `packages/core/src/graph/mutable-graph.ts`: graph model - `packages/core/src/deploy/scheduler.ts`: bounded worker pool, per-handler concurrency caps - `packages/core/src/deploy/card-translator.ts`: UI cards → provider-neutral graph - `packages/core/src/resources/high-level-resources.ts`: concept-to-cloud mapping - `packages/core/src/validation/`: canvas validation rules - `packages/templates/src/`: template compositions - `services/ai/src/services/ai.service.ts`: AI prompt building and streaming - `services/deploy/src/services/deploy.service.ts`: plan-and-apply orchestrator - `services/deploy/src/routes/webhooks.ts`: HMAC-verified GitHub webhook receiver - `apps/desktop/`: Electron shell --- # Product surface (light-cloud.com) The platform: - [Home](https://light-cloud.com/): Push to Git and get a live URL. Static sites, containers, and managed Postgres in one place - [Deployments](https://light-cloud.com/deployments): Every push builds and deploys. Build logs, deploy history, rollbacks - [Preview environments](https://light-cloud.com/previews): A URL per branch, built on push and cleaned up on delete - [Databases](https://light-cloud.com/databases): Managed PostgreSQL provisioned next to your app - [Custom domains](https://light-cloud.com/domains): Automatic SSL and DNS, per app or per environment - [Observability](https://light-cloud.com/observability): Logs and metrics for every environment, where you deploy - [Deploy with AI](https://light-cloud.com/deploy-with-ai): MCP server for Claude, VS Code extension for GitHub Copilot - [Frameworks](https://light-cloud.com/frameworks): Detected builds for static frontends and container backends - [Pricing](https://light-cloud.com/pricing): 30-day free trial, then usage-based hourly billing, scale to zero Labs (open source): - [Labs](https://light-cloud.com/labs): The open-source side of Light Cloud - [ICE](https://light-cloud.com/labs/ice): Visual editor for cloud infrastructure, Apache 2.0 - [Blocks](https://light-cloud.com/labs/blocks): 28-concept palette grouped by 8 categories, per-cloud mapping - [Templates](https://light-cloud.com/labs/templates): 13 templates shipped today plus Quick Starts - [Providers](https://light-cloud.com/labs/providers): GCP stable, AWS and Azure experimental, others in preview - [AI assistant](https://light-cloud.com/labs/ai): Claude edits the canvas, BYO Anthropic key - [Import infrastructure](https://light-cloud.com/labs/import): GCP, Terraform, Pulumi; AWS/Azure/Docker Compose on the roadmap - [Multi-cloud migration](https://light-cloud.com/labs/migration): Switch target, replan, reproject cost - [Cost prediction](https://light-cloud.com/labs/cost-prediction): Per-canvas monthly projection before apply Company: - [About](https://light-cloud.com/about): Light Cloud, Inc. - [Team](https://light-cloud.com/team): The people building Light Cloud - [Careers](https://light-cloud.com/careers): Open roles, remote-first - [Contact](https://light-cloud.com/contact): Get in touch - [Roadmap](https://light-cloud.com/roadmap): Forward direction across platform and Labs - [Community](https://light-cloud.com/community): GitHub, discussions, contributing --- # Key facts (ICE) - Version: 0.1.50 - License: Apache 2.0 - 28 concept blocks across 8 categories - GCP: 20 service handlers, 45+ importer kinds (stable) - AWS + Azure: experimental (compute / storage / managed DB primitives end-to-end) - 13 templates shipped today, Quick Starts coming - AI: Anthropic Claude API or any OpenAI-compatible endpoint (Ollama, LM Studio, vLLM) - Distribution: web app + Electron desktop (macOS ARM64 dmg/zip, Windows NSIS x64, Linux AppImage x64+ARM64 and .deb) - i18n: English, Mandarin - Credentials: AES-256-GCM at rest, validated read-only on save, never leave the machine - Realtime: Socket.IO `deploy:event` channel with 5-variant discriminated union - Schema catalog: 36 MB SQLite generated from Terraform + Pulumi registries, tens of thousands of resource types - No telemetry, no license keys, runs offline