Run an app and its servers
vyuh_blueprint_cli provides local process orchestration. A development profile selects the app and servers to start; the product's BlueprintRegistry still owns its executable targets and domain bindings.
In a product workspace
Configure the app alongside servers
The same profile supports servers and Flutter clients. A Flutter entry is automatically a client, so dev excludes it. Choose its device and build settings in the profile:
{
"version": 1,
"registry": ["dart", "bin/blueprint.dart"],
"default": ["app"],
"services": {
"api": { "target": "ops", "port": 9001 },
"app": {
"directory": "apps/app",
"dependsOn": ["api"],
"port": 53117,
"timeoutSeconds": 180,
"flutter": {
"device": "web-server",
"wasm": true,
"mode": "profile",
"entrypoint": "lib/main.dart",
"defines": { "API_BASE_URL": "${services.api.url}" }
}
}
}
}Use your registry's actual target and app path. blueprint dev starts the API only; blueprint app runs the default app interactively, blueprint serve api starts just the API, and blueprint stop stops every managed session for this profile. Add auth and workflow entries and their dependencies in the same way.
For macOS, use "flutter": { "device": "macos", "mode": "debug" } and remove the app's web-only port, host, url, and health fields. Other device IDs from flutter devices are accepted; Wasm is restricted to web devices. Web apps default to Wasm in profile mode; native apps default to debug mode. Set wasm: false and mode: "debug" for the usual Flutter web debug workflow. Modes are debug, profile, and release. Dart defines are strings and are compiled into the client, so they must not contain secrets.
flutter cannot be combined with command, target, or external. Raw command entries remain available for other app frameworks and custom launchers.
Diagnose setup
blueprint doctor uses [+] for passed checks, [-] for failures, and [!] for warnings or skipped checks. A missing profile is a warning, not a failure. Use blueprint doctor -v for executable paths and details, --json for automation, or blueprint --version to identify the installed CLI. These checks cover setup; runtime health is verified during startup when a health URL is configured.
Discover services
Run blueprint init to generate blueprint.dev.json, then blueprint doctor and blueprint dev. Initialization discovers server targets from the root bin/blueprint.dart targets --json, root or apps/*/bin/server.dart entrypoints, and Flutter apps in nested source packages. Registry discovery runs local project code; use trusted projects with dependencies already resolved. All discovered services become defaults. Registry ports start at 9000 and Flutter ports at 53117; review these and add required environment, health checks, and dependency ordering. An empty project gets an empty profile with guidance. Initialization creates the profile only and never overwrites an existing file. Use blueprint init --update to add new discoveries while preserving all existing service settings and names. New services are appended to default; existing default selections are preserved. Nothing is removed. Preview the complete proposed JSON with blueprint init --update --dry-run. Without --update, an existing profile is protected. Repeating an update without new discoveries does not rewrite the file. Conflicting names abort the update.
Discovery requires direct runtime dependencies in each package's pubspec:
| Kind | Qualification | Entrypoint |
|---|---|---|
| Server | vyuh_blueprint_server | bin/blueprint.dart with servable registry targets, otherwise bin/server.dart |
| App | Flutter SDK plus vyuh_blueprint_ui or vyuh_blueprint | lib/main.dart |
Dev dependencies, transitive dependencies, arbitrary Flutter packages, and Blueprint libraries without runnable entrypoints do not qualify. The scan is recursive under the profile directory and skips hidden/generated directories, node_modules, vendor, Pods, and symlinks. Names come from pubspec names; nested registry services append the target name. Generated discoveryId values let subsequent updates recognize entries even if you rename or customize them. Keep those IDs unchanged. Existing profiles without IDs are matched by directory and target or app/server kind; ambiguous setups should be configured manually.
Start or add an existing server
blueprint init --update --dry-run # inspect new discoveries
blueprint init --update # append them, preserve your configuration
blueprint targets # get the exact service names
blueprint doctor <service>
blueprint serve <service> # only this server
blueprint dev <service> # this service and its dependencies
blueprint dev # servers from defaults and dependencies
blueprint stop # all managed sessions for this profileThere is no universal blueprint server: each product supplies its server implementation and registry bindings. Discovery finds the runnable package; it does not provision its database or credentials. For a custom entrypoint, add a service manually and include its name in default or another service's dependsOn. For example:
"api": {
"directory": "apps/api_server",
"command": ["dart", "run", "bin/main.dart"],
"envFile": ".env.local",
"requiredEnv": ["DATABASE_URL"],
"port": 9001,
"health": "http://127.0.0.1:9001/health"
}The command must actually listen on the declared port; raw commands are not given port flags automatically. Updates leave manually added services intact. Use blueprint init --profile dev.json for a custom filename, and pass the same --profile dev.json to subsequent commands.
Without a profile, doctor checks Dart availability and explains that project checks were skipped. An explicitly selected missing profile or an invalid existing profile still fails. blueprint create remains the whole-project command for copying a trusted starter template.
Complete profile field reference
The file is strict JSON (no comments). Unknown fields are errors. Paths below are relative to the profile directory unless stated otherwise.
| Top-level field | Type | Meaning |
|---|---|---|
version | integer | Required; currently 1. |
default | string array | Required service names started by dev; must be nonempty when services exist. |
services | object | Required map of service names to entries; empty is allowed after initialization. |
registry | string array | Optional default registry command for target services. |
databases | object | Optional map of product names to { "command": [...], "install": [...] }: the product's Blueprint target command that blueprint db emit runs in the profile directory, and the ordered install globs (with optional provision globs) of its SQL. A product exists only when install is declared. See developer commands. |
Service names start with a lowercase letter and contain lowercase letters, digits, underscores, or hyphens. Each managed entry uses exactly one of command, target, or flutter.
| Service field | Type/default | Meaning |
|---|---|---|
description | string | Optional human-readable summary shown in the dev dashboard Info view. |
command | string array | Executable and separate arguments; no shell evaluation. |
target | string | Exact servable Blueprint registry target name. |
registry | string array | Override the top-level registry for this target; executed in the service directory. |
flutter | object | Flutter launch settings listed below; automatically a client. |
directory | string, . | Working directory. |
dependsOn | string array, [] | Service dependencies; started before this service. Cycles are rejected. |
envFile | string | Literal environment file relative to the profile root; shell values take precedence. |
requiredEnv | string array, [] | Environment variables which must be nonempty. |
host | string, 127.0.0.1 | Bind host for target/web app launch and port checks. |
port | integer, 1–65535 | Local port; required for Flutter web. |
url | HTTP(S) URL | Public URL; defaults to host and port when configured. |
health | HTTP(S) URL | Readiness probe; requires 2xx. Without one, only process startup is known. |
external | boolean, false | Check an already-running service; requires health and forbids launch settings. |
client | boolean, false | Mark a raw-command app; run it with app, excluded from dev. |
timeoutSeconds | integer, 60 | Readiness/target diagnostic timeout, 1–600. |
watch | string array, [] | Paths watched with dev --watch; restarting applies to the owned stack. |
discoveryId | string | Generated identity used by init --update; leave unchanged. |
HTTP URLs cannot contain credentials, queries, or fragments. Public URLs can be referenced in command arguments or Flutter defines as ${services.api.url}.
| Flutter field | Type/default | Meaning |
|---|---|---|
device | string, web-server | One Flutter device ID; all is not accepted. |
wasm | boolean | Defaults to true for web, false for native. Web devices only. |
mode | string | debug, profile, or release; defaults to profile for Wasm, otherwise debug. |
entrypoint | string, lib/main.dart | Dart entrypoint relative to the service directory. |
defines | string-to-string object | Public compile-time Dart defines. Never store secrets here. |
Create blueprint.dev.json beside the product's registry executable. For a product with an ops target and a Flutter app:
{
"version": 1,
"registry": ["dart", "bin/blueprint.dart"],
"default": ["app"],
"services": {
"api": {
"target": "ops",
"port": 9001,
"envFile": ".env.local",
"requiredEnv": ["DATABASE_URL"],
"health": "http://127.0.0.1:9001/health",
"watch": ["packages/domain", "apps/api"]
},
"app": {
"command": ["flutter", "run", "-d", "web-server", "--web-port", "53117", "--dart-define=API_BASE_URL=${services.api.url}"],
"directory": "apps/app",
"dependsOn": ["api"],
"port": 53117,
"health": "http://127.0.0.1:53117/",
"timeoutSeconds": 180,
"client": true
}
}
}Replace the target, paths, environment keys, and health routes with the product's actual configuration. The Flutter app must consume the named define. The profile does not generate an application or configure a database by itself.
blueprint dev # API only
blueprint app # Default app, in another terminal
blueprint app app # Named app, with interactive Flutter controls
blueprint restart api # Restart only API
blueprint restart # Restart all managed servers
blueprint dev api # API and its declared dependencies
blueprint serve api # Exactly this server, without dependencies
blueprint dev --watch # Restart the owned stack after source editsAdd additional named servers to services and use dependsOn for their startup order. Run serve auth, serve api, and serve workflow in separate terminals when managing servers individually. Those names must exist in your profile. Disjoint sessions can coexist; overlapping ownership is rejected.
Where Blueprint Auth fits
Blueprint Auth supplies shared authentication routes, a controller, and a server plugin using BlueprintAuthenticationProvider. The product can host those routes in its API or a separate executable. There is no standalone Blueprint identity server supplied by this CLI.
If auth is hosted by a local executable, declare it as a managed service and make the API depend on it. If an identity service is already running, use:
{
"external": true,
"health": "http://127.0.0.1:9000/health"
}External services are checked for readiness and never started or stopped. A profile entry does not introduce another credential or session authority.
Configuration rules
| Field | Meaning |
|---|---|
target | Existing registry target; launches through the shared serve runner |
command | Argument array for another process; mutually exclusive with target |
directory | Working directory relative to the profile; defaults to its directory |
dependsOn | Services to start first when using dev |
host, port | Local bind settings; target arguments are generated automatically |
url | Public base URL; defaults to HTTP using the configured host and port |
health | HTTP readiness URL requiring a 2xx response without redirects |
envFile, requiredEnv | Literal environment file and required variable names |
client | Omit this process with --no-client, while retaining server dependencies |
external | Check health only; no managed process |
watch | Source paths monitored when --watch is enabled |
timeoutSeconds | Startup/diagnostic timeout; defaults to 60, maximum 600 |
${services.api.url} resolves a public URL into a command argument. It does not evaluate shell expressions or interpolate secrets. Shell environment values override the environment file. Keep server secrets out of client profiles. Raw process commands must use the same port as their profile's port field.
Unknown fields, dependency cycles, missing services, and ambiguous commands are rejected. Paths are relative to the selected profile file. Use --profile path/to/another.json to choose a different configuration.
Diagnose and control
blueprint doctor api
blueprint doctor --json
blueprint status --json
blueprint logs api --follow
blueprint stop --session ID
blueprint stopdoctor checks configuration, executables, required environment keys, target declarations/bindings, local ports, and external HTTP readiness. Target checks require the registry's <target> doctor --json command. It does not prove database authentication or an authenticated business operation. A service with no health probe is reported as running, not ready.
Ctrl-C stops the current session. stop requests shutdown of all sessions rooted at the selected profile directory; --session ID selects one. Cleanup stops the owned process tree, including launcher children. It does not signal unrelated processes using cached PIDs. Supervision currently supports macOS and Linux.
Logs and session records are stored under .dart_tool/blueprint/sessions. Child processes are responsible for redacting their output. SIGKILL cannot run cleanup; unreachable session records are reported without killing old PIDs.
Watch mode restarts the owned stack in dependency order. It does not generate artifacts, apply migrations, or reset data. Continue using the product's explicit generation and migration workflow.
Reuse a tested starter
blueprint create inventory --template /path/to/trusted/starterThe template must contain a valid development profile. __app_name__ is replaced in text and paths. Existing destinations and symbolic links are rejected; caches, Git metadata, and environment files are omitted except environment examples. No template code is executed. Follow its runbook to resolve dependencies and configure providers before starting services.
A bundled authenticated full-stack starter remains a next step. Today, use a product-owned template whose auth, storage, and grants are already tested.
Interactive apps and server restarts
blueprint dev starts only servers, including dependencies of default apps. Run blueprint app <name> in another terminal; omit the name when exactly one app is listed in default. The app inherits terminal input and output, including Flutter hot reload (r) and hot restart (R). It stays independent of server sessions and is stopped from its own terminal.
blueprint restart <server> restarts only that server in its existing supervisor and waits for its configured readiness check. blueprint restart restarts all managed servers, stopping in reverse dependency order and starting in dependency order within each session. Use --session <id> to select a session. External services and interactive apps are excluded. Concurrent restarts are rejected.
Flutter web launches explicitly enable --cross-origin-isolation. The development server sends Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: credentialless, enabling SharedArrayBuffer and multithreaded Skwasm rendering. This applies to web-server, Chrome, and Edge; native app launches receive no web flags.