Skip to main content

Greenfield Create

[MODE:GREENFIELD] Tier: greenfield. Not idempotent.

The single canonical entry point for creating a new app from scratch. Bundles repo/Prop creation + Template version + Playground + wait + symlink into one round-trip. Multi-repo templates are supported: each distinct dynamic source repo becomes its own private destination repo and Prop. Backed by the server POST /api/greenfields, which returns a request_id and runs GreenfieldCreateJob async; the SDK polls the returned status_url until done.

It can start from an existing template selector, inline template_body, or a GitHub repository config snapshot. Repository snapshot mode fetches fibe.yml, fibe.yaml, docker-compose.yml, or docker-compose.yaml through the Player's GitHub App installation, validates it as-is, creates new app-owned destination repo(s), and then launches normally.

When to use

  • Player asks to "create a new <type> app", "spin up a Tower for X", "scaffold a project".
  • Player provides a GitHub repository that contains a Fibe-compatible fibe.yml or Docker Compose file and wants a new app created from that snapshot.
  • After deciding template/git_provider/marquee in Greenfield mode (see system.md).

When NOT to use

  • Player is iterating on an existing app — use fibe_playgrounds_transform (Brownfield).
  • Just need a Playground from an existing Template — use fibe_templates_launch (no repo creation).
  • Player wants to change the stack of an already-deployed playground while preserving its id (e.g., "rebuild this playground with FastAPI + AngularJS instead") — use fibe_playgrounds_transform. That tool is the brownfield analog of this one and provisions Gitea-backed private Props on the fly the same way.

Inputs

FieldTypeRequiredNotes
namestringnoRepository/app name; inferred from repository_url basename when omitted
template_idnumbernoTemplate to base on; defaults to platform base template
versionstringnoTemplate version tag (e.g. v1); requires template_id
template_bodystringnoInline YAML; mutually exclusive with template_id/version
template_body_pathstringnoLocal FS path to YAML file (local MCP only)
repository_urlstringnoGitHub repo as owner/repo, owner/repo@ref, or https://github.com/owner/repo; mutually exclusive with template inputs
config_pathstringnoConfig file path inside the repo. If omitted, Fibe tries fibe.yml, fibe.yaml, docker-compose.yml, docker-compose.yaml
github_refstringnoBranch, tag, or commit for the config file. Only the config file revision; service refs stay in YAML
github_accountstringnoFriendly GitHub App installation owner alias when multiple installations exist
github_installation_idnumbernoExact GitHub App installation selector for automation or duplicate account names
git_providerenumnogitea (default) or github
privateboolnoCreate destination repo(s) as private
marquee_id_or_namestring/numbernoTarget Marquee. Falls back to FIBE_MARQUEE_ID env
variablesobjectnoTemplate variables, e.g. {"app_name":"Tower"}
service_subdomainsobjectnoPer exposed service subdomain overrides, e.g. {"app":"tower","admin":"tower-admin"}
wait_timeoutstringnoGo duration; default 10m

What it does (under the hood)

  1. Validates inputs; reads template_body_path or fetches repository config if provided.
  2. Resolves the target Marquee from marquee_id_or_name or env if missing.
  3. Calls the server Greenfield endpoint with normalized variables.
  4. Polls request status until terminal.
  5. On success: re-fetches the Playground (server may have promoted state since the request finished).
  6. Calls localplaygrounds.Link(target, "/app/playground") to symlink the playground's mounted volumes into the Agent container's working directory.

The server-side GreenfieldCreateJob does roughly:

  • Resolve dynamic source repos from the selected template or fetched repository snapshot.
  • Create a Git repo via the chosen provider for each distinct source repo.
  • Create one Prop per created repo.
  • Create an Import Template version owned by the App (or use the requested template).
  • Create a Playspec from the template version.
  • Create a Playground on the resolved Marquee and trigger rollout.

Output

{
"name": "demo",
"git_repo": { ... },
"prop": { ... },
"repos": [{ "repository_url": "...", "source_repo_url": "...", "service_names": ["app"] }],
"props": [{ "id": 17, "repository_url": "...", "service_names": ["app"] }],
"template": { ... },
"playspec": { ... },
"playground": { "id": 42, "name": "...", "status": "running", ... },
"service_urls": [{ "name": "app", "url": "https://..." }, { "name": "admin", "url": "https://..." }],
"link": { "linked": true, "path": "/app/playground" }
}

If wait_timeout elapses before running, the call returns whatever was reached and the playground will still be in creating/building. link is null on link failure (e.g., volumes not yet mounted).

Variables

The platform's base template uses {{var__app_name}} style placeholders compiled by FibeCore::compose.compile_template. Variables you don't pass keep template defaults; the platform also automatically injects $$root_domain (the Marquee's base domain).

Gotchas

  • template_body and template_id/version are mutually exclusive — error if both set.
  • repository_url is mutually exclusive with template_body, template_body_path, template_id, template_version_id, and version.
  • Repository snapshot mode does not auto-convert plain Compose or inject missing Fibe labels. The fetched file must already be a valid Fibe template/source.
  • GitHub App installation is required even for public repos. If no installation exists, run fibe github apps connect; if more than one exists, pass github_account or github_installation_id.
  • owner/repo@ref shorthand is accepted for repository_url; full GitHub URLs must use github_ref.
  • template_body_path only works when the MCP server has filesystem access — fails on remote/HTTP transports.
  • git_provider:"github" controls destination repo creation and requires the Player to have linked GitHub OAuth. GitHub App installation tokens are only for reading repository snapshot inputs, not for creating destination repos.
  • For multi-service templates, pass service_subdomains when the caller needs deterministic URLs. Overrides apply only to exposed services and are validated before repos are created.
  • A duplicate name collides with an existing Playground/Repo — the server returns VALIDATION_FAILED (handle and retry with a different name).
  • Greenfield is not idempotent. Re-calling produces a duplicate (or fails on naming collision). Use the request_id-based status endpoint to recover from network drops if the SDK call gets cut.
  • The Marquee must be running and chat_launchable for the Playground to deploy. Check fibe_resource_get(resource:"marquee", ...) if rollout stalls.
  • wait_timeout "0" is treated as "skip wait" — the call returns as soon as the Rails async job finishes its setup (status may still be creating).
  • fibe_templates_search — find a fitting template first.
  • fibe_templates_launch — Playground from an existing Template (no new repo).
  • fibe_playgrounds_transform — iterate after landing.
  • fibe_local_playgrounds_link — re-link if /app/playground symlinks went stale.