Server CLI
For production deployments, strongly prefer gestaltd lock, then
gestaltd sync --locked during image build or release preparation, then
gestaltd serve --locked at runtime. The lockfile pins resolved provider
artifacts and verified hashes, and locked serve refuses to mutate deployment
state.
gestaltd manages server lifecycle and provider releases.
Server commands
| Command | Purpose |
|---|---|
gestaltd | Local-friendly startup. Generates a config if needed and serves. |
gestaltd serve --config PATH | Start the server. Repeat --config to layer overrides. |
gestaltd serve --config PATH --watch | Start from layered config and restart after debounced local config, source provider, or local release metadata changes. |
gestaltd serve --locked --config PATH | Start read-only from an existing lockfile and prepared artifacts. Repeat --config to layer overrides. |
gestaltd serve --artifacts-dir DIR | Directory for prepared provider artifacts. |
gestaltd serve --lockfile PATH | Override the lockfile location. PATH resolves like a normal CLI path. |
gestaltd lock --config PATH | Resolve published provider sources and write canonical lock metadata. Repeat --config to layer overrides. |
gestaltd lock --check --config PATH | Verify that the checked-in lockfile matches the current config without rewriting it. |
gestaltd sync --locked --config PATH | Materialize prepared provider artifacts from an existing lockfile. Local source UI preparation uses bounded parallelism by default. |
gestaltd sync --locked --check --config PATH | Verify that prepared artifacts exist and match the lockfile without rewriting them. |
gestaltd validate --config PATH | Validate config without serving. Repeat --config to layer overrides. |
gestaltd validate --lockfile PATH | Accept the same explicit lockfile path used by lock, sync, and serve without mutating it. |
gestaltd --version | Print the server version. |
Provider commands
| Command | Purpose |
|---|---|
gestaltd provider search [QUERY] | Search configured provider repositories. Pass --repo NAME to search one repository. |
gestaltd provider info PACKAGE | Show available versions and release metadata for one package. Pass --repo NAME to disambiguate. |
gestaltd provider add PACKAGE --config PATH | Add an indexed provider package to config and update the lockfile. Package sources are written by default. |
gestaltd provider add PACKAGE --kind KIND --name NAME | Choose the provider kind and config entry name explicitly. UI providers also require --set path=/mount. |
gestaltd provider add PACKAGE --version CONSTRAINT | Write a semver version constraint such as ^1.4.0, ~1.4.0, or an exact version. |
gestaltd provider add PACKAGE --exact-source | Write the resolved provider-release.yaml URL instead of a package source. |
gestaltd provider add PACKAGE --sync | Materialize prepared artifacts after locking. |
gestaltd provider list --config PATH | List configured providers and lock status. Pass --kind KIND to filter. |
gestaltd provider remove NAME --config PATH | Remove one provider entry and update the lockfile. Pass --kind KIND when the name is ambiguous. |
gestaltd provider upgrade --config PATH | Refresh lock state for all package sources without editing config version constraints. |
gestaltd provider upgrade NAME --version CONSTRAINT | Change one package source’s version constraint and update the lockfile. |
gestaltd provider repo add NAME URL | Add a provider repository to the user-level store. Pass --config PATH to write providerRepositories into project config instead. |
gestaltd provider repo list | List the default, user-level, and project provider repositories. |
gestaltd provider repo update | Fetch and cache provider repository indexes. |
gestaltd provider repo remove NAME | Remove a provider repository from the user-level store. Pass --config PATH to remove it from project config instead. |
gestaltd serve --path PATH | Run a local source app or UI bundle inside a synthesized Gestalt config. Serves /admin and any configured or inferred public UIs. |
gestaltd serve --path PATH --config PATH | Layer supporting providers, apps, and UI mounts on top of the synthesized local baseline. Repeat --config to merge left-to-right. |
gestaltd serve --remote URL --path PATH | Attach one local source app to an authenticated remote gestaltd session. The remote server matches by manifest source and keeps its configured auth, authorization, connections, app config, and host services. |
gestaltd serve --remote URL --config PATH | Attach every source-backed app in the layered config. Use repeated --config files when you need explicit local config overrides or multiple local apps. |
gestaltd provider attach list --remote URL | List your active remote provider-dev attachments on that server. |
gestaltd provider attach show --remote URL ATTACH_ID | Inspect one active remote provider-dev attachment. |
gestaltd provider attach detach --remote URL ATTACH_ID | Detach a stuck remote provider-dev attachment owned by your authenticated principal. |
gestaltd provider validate --path PATH | Validate a local source app or UI bundle inside the same synthesized Gestalt config used by gestaltd serve --path. |
gestaltd provider validate --config PATH | Validate the target provider together with selected supporting providers and null deletions from layered config overlays. |
gestaltd provider package --version VERSION | Build provider release archives from a source directory. Executable source providers use SDK-native source packages or build.command and default to the host platform; UI and declarative providers default to a generic archive. Pass --platform ... with os/arch targets or --platform all for multi-platform builds. |
gestaltd provider package --output DIR | Output directory for the release archives. Defaults to dist/. |
gestaltd provider release --dist-dir DIR | Finalize already-built release archives by validating them and writing checksums.txt and provider-release.yaml into the dist directory. |
For config-free local development, inferred UI mount paths use the manifest
source slug rather than the API-safe provider key. A source ending in
vm-style-guide mounts at /vm-style-guide, while the local integration key
may still be vm_style_guide. Explicit apps.<name>.ui.path values take
precedence for app-owned or sibling UI, and explicit
providers.ui.<name>.path values take precedence when developing a UI bundle
directly.
Provider package commands use the provider repository model described in
Provider packages. Mutating package commands accept one
--config path so the CLI edits the intended file instead of a merged runtime
view. provider add, provider remove, and provider upgrade NAME --version
update the lockfile by default. provider add and provider remove accept
--no-lock when you need to edit config only.
gestaltd sync --locked --parallelism N caps concurrent preparation for local
source.path UI bundles. The default is up to four workers, capped by
GOMAXPROCS; --parallelism 1 forces sequential preparation. Other provider
types and sync --locked --check remain sequential.
Config Watch Mode
Use gestaltd serve --watch for config-based local development when your
layered config points at local provider source paths or local
provider-release.yaml metadata. Watch mode starts normally, then restarts the
server after local file changes settle. If reload preparation fails, the current
server keeps running and the failure is logged.
For faster iteration on one configured plugin, combine --watch with
--app NAME so unrelated configured apps are not validated or prepared:
gestaltd serve \
--app support \
--config ./config.yaml \
--config ./local.yaml \
--watchWatch mode applies only to config-based serve. It cannot be combined with
--locked, --path, or --remote.
Examples
gestaltd
gestaltd lock --config ./config.yaml
gestaltd sync --locked --config ./config.yaml
gestaltd sync --locked --config ./config.yaml --parallelism 2
gestaltd serve --locked --config ./config.yaml
gestaltd validate --config ./config.yaml
gestaltd lock --config ./config.yaml --lockfile ./local/gestalt.lock.json
gestaltd sync --locked --config ./config.yaml --lockfile ./local/gestalt.lock.json
gestaltd serve --config ./config.yaml --lockfile ./local/gestalt.lock.json
gestaltd serve --config ./config.yaml --watch
gestaltd serve --app support --config ./config.yaml --config ./local.yaml --watch
gestaltd serve --locked --config ./config.yaml --lockfile ./local/gestalt.lock.json
gestaltd lock --config ./base.yaml --config ./overrides/prod.yaml
gestaltd sync --locked --config ./base.yaml --config ./overrides/prod.yaml
gestaltd serve --locked --config ./base.yaml --config ./overrides/prod.yaml
gestaltd provider search github
gestaltd provider info github.com/valon-technologies/gestalt-providers/app/github
gestaltd provider repo list
gestaltd provider repo add valon https://registry.gestaltd.ai/provider-index.yaml --config ./config.yaml
gestaltd provider repo update --config ./config.yaml
gestaltd provider add github.com/valon-technologies/gestalt-providers/app/github --config ./config.yaml --name github
gestaltd provider add github.com/valon-technologies/gestalt-providers/auth/oidc --config ./config.yaml --kind authentication --name oidc --version '^1.4.0'
gestaltd provider add github.com/acme/gestalt-providers/ui/console --config ./config.yaml --repo acme --kind ui --name console --set path=/console
gestaltd provider list --config ./config.yaml
gestaltd provider list --config ./config.yaml --kind app
gestaltd provider upgrade --config ./config.yaml
gestaltd provider upgrade github --config ./config.yaml --kind app --version '^1.5.0'
gestaltd provider remove github --config ./config.yaml --kind app
gestaltd provider validate --path ./apps/support
gestaltd provider validate --path ./ui/dashboard
gestaltd provider validate --path ./apps/support --config ./dev/support.yaml --config ./dev/local.yaml
gestaltd serve --path ./apps/support
gestaltd serve --path ./ui/dashboard
gestaltd serve --path ./apps/support --config ./dev/support.yaml --port 8080
gestaltd serve --remote https://gestalt.example.com --path ./apps/support
gestaltd serve --remote https://gestalt.example.com --path ./apps/support --name support
gestaltd serve --remote https://gestalt.example.com --remote-token <token-with-provider_dev.attach> --path ./apps/support
gestaltd serve --remote https://gestalt.example.com --config ./remote.yaml --config ./local-overrides.yaml
gestaltd provider attach list --remote https://gestalt.example.com
gestaltd provider attach show --remote https://gestalt.example.com att_123
gestaltd provider attach detach --remote https://gestalt.example.com att_123
gestaltd provider package --version 0.0.1-alpha.1
gestaltd provider package --version 0.0.1-alpha.1 --platform all
gestaltd provider package --version 0.0.1-alpha.1 --platform linux/amd64,linux/arm64
gestaltd provider release --dist-dir dist --version 0.0.1-alpha.1When repeated, --config files merge left-to-right. Maps deep-merge, later
scalar values win, lists replace inherited lists, and null deletes inherited
keys. By default, lockfiles and artifact paths stay rooted at the leftmost
config file. --lockfile overrides only the lockfile path. --artifacts-dir
keeps the same config-relative resolution used by sync and serve.
gestaltd serve --remote is environment-agnostic: the URL is just the remote
gestaltd instance to attach to. The local command only replaces source-backed
plugin implementations for the authenticated principal that created the session.
The remote server must opt in with server.dev.attachmentState; otherwise the
command fails before local code is attached. Use attachmentState: indexeddb on
shared or load-balanced servers so attachment metadata and queued provider calls
are stored in the configured host IndexedDB. Process-local remote attachment
state is not a supported server mode.
For the interactive happy path, gestaltd serve --remote creates a short-lived
attach approval request and opens the remote server in your browser. Approving
that page with your normal browser session creates an owner-scoped attachment
only when your resolved role is allowed by the app’s provider-dev attach
configuration. The terminal prints a verification code, and the browser approval
page requires that code before approval succeeds. --remote-token and
GESTALT_API_KEY are the non-interactive direct-attach path; those API tokens
must include permissions[].actions: ["provider_dev.attach"] for every attached
app. Stored CLI credentials from gestaltd auth login are not used for
direct attach; when no explicit token is provided, gestaltd serve --remote uses
browser approval.
With --remote URL --path PATH and no --config, the local command sends the
manifest source and the local implementation only; the remote server chooses
the configured app with the same manifest source and preserves that
remote plugin’s config. If multiple remote apps share the same source, or the
manifest has no source, pass --name to choose the configured remote app.
All non-local apps and remote host services continue to resolve through the
remote instance.
After browser approval or attach-token authentication, the remote creates an
attachment and the CLI uses the returned attachId plus a one-time dispatcher
secret for poll/complete traffic. The dispatcher secret is not shown by list/get
diagnostics and is not needed for owner cleanup detach. Remote attach requests
mark an attached provider with ui: true when the local dispatcher will serve
that provider’s mounted UI assets; diagnostic responses report the mounted
uiPath but never return local UI contents. Use
gestaltd provider attach list --remote URL,
gestaltd provider attach show --remote URL ATTACH_ID, and
gestaltd provider attach detach --remote URL ATTACH_ID to inspect or clean up
attachments owned by your authenticated principal. These diagnostic commands use
--remote-token, GESTALT_API_KEY, or a matching stored Gestalt CLI
credential, and they do not require provider_dev.attach because they cannot
create a new attachment.
API-token attach creation requires an explicit token action permission:
{
"name": "slack local dev",
"permissions": [
{
"app": "slack",
"actions": ["provider_dev.attach"]
}
]
}Normal provider scopes and operation permissions do not grant remote attach, and
provider_dev.attach does not grant normal invocation access. Subject-owned API
tokens are not accepted for remote attach v1.
When --config is present, source-backed app entries in the layered local
config are treated as explicit local overrides. Their app config is sent to
the remote session instead of inheriting the remote server’s config. Remote mode
allows missing local environment substitutions while loading config so unrelated
deploy-only env vars do not block attach.
Remote mode tunnels app RPC, catalog, post-connect, host-service calls, and
app-owned UI assets for mounted UIs that already exist on the remote server.
Raw GraphQL surfaces are not tunneled in v1.
For source-backed providers, gestaltd serve --path starts the manifest run
argv when one is declared. If run is omitted, it serves or starts the declared
entrypoint or SDK-native source package. Sequence-form build commands can
prepare dependencies before local startup; output-producing build.command
remains the packaging path for compiled artifacts.
See Configuration for the relationship between lock, sync --locked, serve --locked, and validate.