Examples
Browse copy-ready examples and generate a high-quality AI prompt that helps your coding agent produce a real flowlayer.jsonc for your project. Paste your repo paths, copy the prompt, send it to Claude, ChatGPT, or Copilot — and get a fully wired config back.
This page is the canonical Examples reference for FlowLayer. It covers:
- AI Prompt Builder — the full prompt template, grounding rules, and generation flow
- Assembled stack examples — minimal to complex, with every pattern explained
- All runtime patterns — 15 common situations with ready-to-copy JSONC
- Validation notes — what to check before running a new config
For short copy-ready fragments you can paste into an existing config, open Patterns.
How to use these examples
Section titled “How to use these examples”These examples are not aspirational — every snippet reflects patterns verified against real FlowLayer configs.
- Pick the scenario closest to your stack.
- Copy the JSONC block.
- Replace placeholder commands and ports with your actual values.
- Remove any service you don’t have.
- Run
flowlayer-serverwith your config.
When your stack is unfamiliar, use the AI Prompt Builder to let an agent read your repo and write the config from evidence.
AI Prompt Builder
Section titled “AI Prompt Builder”Concept
Section titled “Concept”The AI Prompt Builder turns your project roots into a grounded instruction for a coding agent. Instead of asking an LLM to guess your stack, the prompt instructs it to inspect your actual files before writing any config.
This prevents the most common errors:
- invented service names that don’t match the real stack
- fabricated ports not present in any source file
- missing
stopCmdon Docker-managed services - wrong
dependsOnorder that doesn’t reflect actual startup requirements
Generation flow
Section titled “Generation flow”flowlayer.jsonc with assumptions listedTested with Claude 3.5+, GPT-4o, and GitHub Copilot. For best results, give the agent read access to your file system.
Starter prompt template
Section titled “Starter prompt template”Copy and adapt this prompt. Replace the placeholder paths with your actual repo roots.
You are a senior software engineer. Your task is to generate a valid `flowlayer.jsonc`for the project below.
## Project Roots
- /workspace/api- /workspace/frontend- /workspace/worker
## Instructions
Inspect each project root directly before writing any config. Do not invent services,commands, or ports that are not evidenced by the files you find.
### What to look for
For each root:
**Entry points and commands**- `package.json` → `scripts.dev`, `scripts.start`, `main`- `Makefile` → `run`, `dev`, `start` targets- `go.mod` → module name; scan `cmd/` subdirectories for binaries- `Cargo.toml` → `[[bin]]` entries- `pyproject.toml` / `setup.py` → scripts, entry_points- `Procfile` → process definitions
**Infrastructure**- `docker-compose.yml` / `compose.yml` → services, ports, volumes- `Dockerfile` → EXPOSE, CMD, ENTRYPOINT
**Port evidence**- `.env.example` / `env.sample` → PORT=, ADDR=, HOST=- Source files → `listen(PORT)`, ":8080", `0.0.0.0:3000`- `docker-compose.yml` → `ports:` mappings
**Dependency evidence**- Env vars referencing other services: DATABASE_URL, REDIS_URL, API_URL- Network aliases in docker-compose- README startup order instructions
**Health endpoint evidence**- Source routes: `/health`, `/healthz`, `/ping`, `/ready`, `/status`
### Service rules
- Only add a service if you find real startup evidence in the project files- For Docker-managed services (postgres, redis, mysql, etc.): use `docker compose up <svc>` as `cmd` and `docker compose down <svc>` as `stopCmd`- Set `kind: "oneshot"` for migration scripts, seed steps, or one-time build steps- Set `cmd` to the exact command found in the project — do not guess or fabricate- Set `dependsOn` based on env var references and startup order evidence- Set `port` only when you have concrete evidence (env var, EXPOSE directive, listen call)- For HTTP services with a known health route, add `ready: { "type": "http", "url": "http://localhost:<port>/health" }`- For TCP-only services (databases, caches), add `ready: { "type": "tcp", "port": <port> }`- Omit `ready` if you cannot determine a reliable probe
### FlowLayer schema rules — strict, unknown fields cause a parse error
**Valid top-level fields only:** `session`, `logs`, `logView`, `services`
**`session` carries shared connection settings.** Include it when the runtime orconfig-mode client needs explicit values:- `bind` sets the server listening address (default: `127.0.0.1:6999`)- `token` sets the bearer token; if omitted, FlowLayer generates one at boot
`session.addr` is a client/TUI config field, not a server runtime field.
**Valid per-service fields only:**- `cmd` (required) — string or string array- `stopCmd` — only for Docker-managed processes- `kind` — `"daemon"` | `"oneshot"` (omit entirely for daemon, it is the default)- `port` — integer ≥ 0- `ready` — `{ "type": "http", "url": "..." }` or `{ "type": "tcp", "port": N }`- `dependsOn` — string array; every name must reference a service defined in this config- `env` — flat object of string:string pairs
Do not add any other fields. Typos in field names produce a parse error.
## Required output
### 1. flowlayer.jsonc
\`\`\`jsonc{ // "session": { // "bind": "127.0.0.1:6999", // "token": "flowlayer-dev-token" // }, "services": { // ... your inferred services here }}\`\`\`
### 2. Assumptions
For each decision, document:- Which file provided the evidence- Any port or command you could not confirm, and why- Services you considered but excluded, and why- Readiness probe rationale- What the developer should verify before runningAssembled stack examples
Section titled “Assembled stack examples”Minimal stack
Section titled “Minimal stack”A single native process — no database, no dependencies.
{ "services": { "api": { "cmd": "node dist/server.js", "port": 3000 } }}API + database + worker
Section titled “API + database + worker”The most common local dev shape: Docker infra, a one-shot migration gate, an HTTP service, and a background worker.
{ "session": { "bind": "127.0.0.1:6999", "token": "flowlayer-dev-token" }, "logView": { "maxEntries": 500, // explicit override for this stack "all": { "maxEntries": 800 } }, "services": { "postgres": { "cmd": ["docker", "compose", "up", "postgres"], "stopCmd": ["docker", "compose", "down", "postgres"], "port": 5432, "ready": { "type": "tcp", "port": 5432 } }, "migrate": { "cmd": ["pnpm", "--dir", "./services/users", "run", "db:migrate"], "kind": "oneshot", "dependsOn": ["postgres"] }, "users": { "cmd": ["pnpm", "--dir", "./services/users", "run", "start:dev"], "port": 3002, "dependsOn": ["migrate"], "ready": { "type": "http", "url": "http://127.0.0.1:3002/health" } }, "billing-worker": { "cmd": ["pnpm", "--dir", "./services/billing", "run", "start:worker"], "dependsOn": ["postgres", "users"], "env": { "QUEUE_NAME": "billing-jobs" } } }}Mixed native + Docker stack
Section titled “Mixed native + Docker stack”Run Docker infra alongside a native Go API. Use explicit stopCmd for Docker services; the native process gets a normal signal.
{ "services": { "redis": { // Start detached, stream logs so FlowLayer captures output "cmd": ["sh", "-c", "docker compose up redis -d && docker compose logs -f redis"], "stopCmd": "docker compose down redis", "port": 6379, "ready": { "type": "tcp", "port": 6379 } }, "api": { "cmd": ["go", "run", "./cmd/api"], "port": 8080, "dependsOn": ["redis"], "ready": { "type": "http", "url": "http://127.0.0.1:8080/healthz" } } }}Event stack (Kafka)
Section titled “Event stack (Kafka)”Bring up Kafka first, then start producers and consumers that wait on real infra readiness. Models a local event-driven stack with explicit boot ordering.
{ "services": { "kafka": { "cmd": "docker compose up kafka", "stopCmd": "docker compose down kafka", "ready": { "type": "tcp", "port": 9092 } }, "api": { "cmd": "pnpm --dir ./apps/api dev", "port": 3001, "dependsOn": ["kafka"], "env": { "KAFKA_BROKERS": "localhost:9092" } }, "worker": { "cmd": "go run ./cmd/worker", "dependsOn": ["kafka"], "env": { "KAFKA_BROKERS": "localhost:9092" } } }}Pattern reference
Section titled “Pattern reference”These are the individual building blocks. Each is copy-ready and production-verified.
TCP probe
Section titled “TCP probe”Wait for a TCP port to accept connections before starting dependents. Use for databases and any non-HTTP service.
{ "services": { "db": { "cmd": "docker compose up db", "stopCmd": "docker compose down db", "port": 5432, "ready": { "type": "tcp", "port": 5432 } } }}HTTP health probe
Section titled “HTTP health probe”Poll an HTTP endpoint until it returns a 2xx response. Use for API services that expose a health route.
{ "services": { "api": { "cmd": "node dist/server.js", "port": 3001, "ready": { "type": "http", "url": "http://localhost:3001/health" } } }}One-shot / migration
Section titled “One-shot / migration”Run a command once and exit — migrations, seed steps, or build tasks. Dependents wait for it to complete successfully before starting.
{ "services": { "db": { "cmd": "docker compose up db", "stopCmd": "docker compose down db", "ready": { "type": "tcp", "port": 5432 } }, "migrate": { "kind": "oneshot", "cmd": "npx prisma migrate deploy", "dependsOn": ["db"] } }}Dependency chain
Section titled “Dependency chain”Chain services so each waits for the previous. Here: database → migration → API.
{ "services": { "db": { "cmd": "docker compose up db", "stopCmd": "docker compose down db", "ready": { "type": "tcp", "port": 5432 } }, "migrate": { "kind": "oneshot", "cmd": "npx prisma migrate deploy", "dependsOn": ["db"] }, "api": { "cmd": "node dist/server.js", "port": 3001, "dependsOn": ["migrate"], "ready": { "type": "http", "url": "http://localhost:3001/health" } } }}Watch mode
Section titled “Watch mode”Long-running dev process with file watching.
--preserveWatchOutput keeps NestJS logs readable across recompiles.
{ "services": { "api": { "cmd": "npx nest start --watch --preserveWatchOutput", "port": 3000 } }}Worker process
Section titled “Worker process”Background queue worker that starts after its dependency. No readiness probe — workers don’t expose a port.
{ "services": { "worker": { "cmd": "python -m celery -A app.tasks worker --loglevel=info", "dependsOn": ["broker"] } }}Docker service with log streaming
Section titled “Docker service with log streaming”Manage a Docker service with cmd and stopCmd.
The live-logs form streams output so FlowLayer captures it.
{ "services": { "redis": { // Start detached, then stream logs so FlowLayer captures output "cmd": ["sh", "-c", "docker compose up redis -d && docker compose logs -f redis"], "stopCmd": "docker compose down redis", "port": 6379, "ready": { "type": "tcp", "port": 6379 } } }}Shell invocation
Section titled “Shell invocation”Use ["sh", "-c", "..."] for lightweight portability — cd, && chaining, no surprises.
Use ["bash", "-lc", "..."] when you need login-shell behavior: sourcing .nvm, version managers, or your full dev environment.
{ "services": { "api-sh": { // sh -c — portable "cmd": ["sh", "-c", "cd packages/api && pnpm dev"], "port": 3001 }, "frontend-nvm": { // bash -lc — login shell, sources .nvm "cmd": ["bash", "-lc", "source ~/.nvm/nvm.sh && nvm use 22 >/dev/null && pnpm dev"], "port": 5173 } }}Environment variables
Section titled “Environment variables”Inject service-specific variables with env.
Values are available to both cmd and stopCmd.
{ "services": { "web": { "cmd": "pnpm dev", "port": 5173, "env": { "VITE_API_URL": "http://localhost:3001", "FEATURE_BETA": "true" } }, "worker": { "cmd": "python -m worker", "env": { "DATABASE_URL": "postgresql://localhost:5432/mydb", "WORKER_CONCURRENCY": "4" } } }}Ephemeral job (Docker container)
Section titled “Ephemeral job (Docker container)”Run disposable tooling in a container before booting the app. A reproducible one-shot gate keeps local workflows clean and consistent.
{ "services": { "go-test": { "kind": "oneshot", "cmd": [ "docker", "run", "--rm", "-v", "./:/workspace", "-w", "/workspace", "golang:1.24", "go", "test", "./..." ] }, "api": { "cmd": "go run ./cmd/api", "dependsOn": ["go-test"], "port": 8080, "ready": { "type": "http", "url": "http://localhost:8080/healthz" } } }}Build steps (monorepo)
Section titled “Build steps (monorepo)”Build a shared package before starting dependent services.
Use kind: "oneshot" and dependsOn so services wait for the build to complete.
{ "services": { "build-shared": { "kind": "oneshot", "cmd": "pnpm --filter @myapp/shared build" }, "api": { "cmd": "pnpm --dir ./apps/api dev", "port": 3001, "dependsOn": ["build-shared"] }, "web": { "cmd": "pnpm --dir ./apps/web dev", "port": 5173, "dependsOn": ["build-shared"] } }}Monorepo service
Section titled “Monorepo service”Run a service from a subdirectory without a shell wrapper when your tooling supports --prefix or --dir.
Direct commands are more reliable than cd && ....
{ "services": { "web": { // npm supports --prefix — no shell wrapper needed "cmd": ["npm", "--prefix", "./apps/web", "run", "dev"], "port": 3000 }, "api": { // pnpm supports --dir "cmd": ["pnpm", "--dir", "./apps/api", "dev"], "port": 3001 } }}Python logs (unbuffered)
Section titled “Python logs (unbuffered)”Python buffers stdout by default — output won’t appear in FlowLayer until the buffer flushes.
Pass -u or set PYTHONUNBUFFERED=1 to stream logs in real time.
{ "services": { "worker-flag": { // Via flag "cmd": "python -u worker.py" }, "worker-env": { // Via env var "cmd": "python worker.py", "env": { "PYTHONUNBUFFERED": "1" } } }}Port wait (external dependency)
Section titled “Port wait (external dependency)”Wait for a dependency that lives outside FlowLayer — a shared database, a remote queue, or a service on another machine. A shell wrapper probes the TCP port in a loop, then hands off.
{ "services": { "api": { // Polls port 5432 until the external DB accepts connections, then starts "cmd": [ "sh", "-c", "until nc -z localhost 5432; do sleep 1; done && node dist/server.js" ], "port": 3001 } }}Validation notes
Section titled “Validation notes”Before running a freshly assembled config, confirm:
| Check | What to verify |
|---|---|
| Commands exist | Every cmd and stopCmd is a real executable or script |
| Dependency names match | Every name in dependsOn is a key in services |
| HTTP probes are real | Health route actually exists in the app code |
| TCP probes have evidence | Port comes from EXPOSE, env file, or listen call |
| Oneshots actually exit | Task is not a long-running process disguised as a step |
| stopCmd cleans up | Docker-managed resources are fully torn down |
| No unknown fields | Only the documented per-service keys — typos cause parse errors |
Common mistakes
Section titled “Common mistakes”{ "services": { "api": { // Wrong — "dir" is not a valid field, use shell wrapper or tool --dir flag "dir": "./apps/api", "cmd": "pnpm dev" } }}{ "services": { "api": { // Wrong — "restart" is not a valid field "cmd": "node server.js", "restart": "always" } }}See Configuration for the full field reference.
When to use Patterns instead
Section titled “When to use Patterns instead”Patterns is the right starting point when you need a single short snippet to paste into an existing config. It covers the same building blocks as this page but as minimal isolated fragments.
| Use Examples | Use Patterns |
|---|---|
| Building a full config from scratch | Grabbing one snippet to add to an existing config |
| Generating with an AI agent | Quickly looking up field syntax |
| Understanding how patterns combine | Copying a ready probe or stopCmd |
| Learning the assembly workflow | Verifying a single service shape |
Related pages
Section titled “Related pages”Short, isolated config fragments for every common situation — TCP probes, HTTP health, oneshot jobs, workers, Docker services.
Every field documented with types, defaults, and validation rules.
How to connect the terminal UI to a running FlowLayer server — direct mode and config mode.
Service fails to start, port conflicts, log gaps, and readiness probe debugging.