Skip to content
chalupa
How it worksSecurityDocumentation
Open console
Menu
How it worksSecurityDocumentationOpen console
chalupa

Operational signal for ephemeral environments. Compute can be torn down while persistent data follows its own lifecycle.

Product

How it worksSecurityConsole

Learn

QuickstartConceptsAPI and schema

Built for ephemeral operations, not forgotten resources.

All displayed costs are estimates.

Documentation/Local CLI and operator UI
/

Start here

QuickstartLocal CLI and operator UISecrets with tvault

Operating model

Conceptschalupa.yml referenceLifecycleTunnels and securityData and seeds

Control plane

Control plane and agentPerformance telemetryPrivate log artifactsSuites and artifactsCosts and idle observation

Reference

Private operationsTroubleshootingAPI and schema
Browse documentation
/

Start here

QuickstartLocal CLI and operator UISecrets with tvault

Operating model

Conceptschalupa.yml referenceLifecycleTunnels and securityData and seeds

Control plane

Control plane and agentPerformance telemetryPrivate log artifactsSuites and artifactsCosts and idle observation

Reference

Private operationsTroubleshootingAPI and schema

Start here

Local CLI and operator UI

Install and use the offline-first Chalupa CLI without bypassing its Taskfile, confirmation, or secret boundaries.

Reviewed 2026-07-24

The Chalupa CLI is a local operator surface for the repository's existing workflow. It can inspect a configuration, read bounded local state, and delegate approved actions to public Taskfile commands. It does not implement a second Pulumi lifecycle.

Opening the interface does not contact DigitalOcean, read tvault, select a Pulumi stack, start Docker, or open SSH. An external process runs only after you explicitly request an action or refresh local status.

Run from a checkout

Install the locked dependencies, then invoke the CLI through Bun:

cd "$HOME/projects/chalupa"
bun install --frozen-lockfile
bun run chalupa -- doctor
bun run chalupa -- inspect

The extra -- separates Bun's arguments from Chalupa's arguments. This is the supported no-link workflow and always runs the source in the current checkout.

For a user-local chalupa command linked to the same checkout:

cd "$HOME/projects/chalupa"
bun link
chalupa --version

The link points at this checkout's declared binary. To update it, update the checkout and reinstall its locked dependencies:

cd "$HOME/projects/chalupa"
git pull --ff-only
bun install --frozen-lockfile
chalupa --version

Review local changes before pulling. bun link is optional; every example below also works as bun run chalupa -- <arguments>.

Check the workstation

Run the executable check before operating an environment:

chalupa doctor
chalupa doctor --json

doctor reports offlineReady separately from operatorReady. The offline inspection path is ready when the CLI itself is running. Full operation also requires Task, Pulumi, tvault, SSH, and nc to be discoverable on PATH. doctor does not execute those tools or query credentials, Docker, the network, local stacks, or a cloud provider. A missing operator requirement produces a non-zero exit while the report still identifies offline inspection as available.

Inspect safely first

With no config, inspect uses the repository's examples/demo-harbor fixture:

chalupa inspect
chalupa inspect --json

This is synthetic offline mode. It runs the same Compose inference as the Pulumi program and reports services, inferred roles, tunnel ports, named volumes, persistence, diagnostics, and the complete redacted remote Compose document. It does not run Task or any external process.

Redacted output is still operator information. Absolute paths, service names, topology, port numbers, images, and non-secret metadata can remain visible. Do not publish the output or treat it as a general data-loss-prevention scan.

Select a real configuration explicitly:

export DEMO_CONFIG="/absolute/path/to/project/chalupa.yml"
chalupa inspect --config "$DEMO_CONFIG"
chalupa tui --config "$DEMO_CONFIG"

Prefer --config in scripts and operator notes so the selected environment is visible at the call site.

Command reference

Command Behavior
chalupa Opens the operator UI when both input and output are interactive terminals. Prints help when invoked with no arguments outside a TTY.
chalupa doctor [--json] Reports separate offline and full-operator readiness without running external executables.
chalupa inspect [--config PATH] [--json] Builds a local inspection. Without a config, it uses the synthetic fixture.
chalupa status --config PATH [--json] Reads bounded compute and protected-data status from exact local Pulumi stacks.
chalupa tui [--config PATH] Opens the interactive operator UI. An explicit invocation fails outside a TTY.
chalupa run ACTION [--config PATH] Delegates one allowlisted public action to Task from the Chalupa repository root.

status reports what the local Pulumi backend knows about two exact stack names. Compute is absent, empty, or present. Protected data is not-configured, absent, present, or unknown; configured states include the expected size from chalupa.yml, while a present state also includes the bounded local volume name and ID. The expected size is not a live provider capacity reading.

The read path does not select a stack, load a provider credential, or query DigitalOcean. An unexpected data stack, invalid outputs, inconsistent config, or failed read becomes unknown instead of being treated as absent. Local state can still be stale; the provider console and invoice remain authoritative.

Actions and exact confirmations

Only these public actions are accepted by chalupa run. The Actions screen shows the same set plus the bounded local-status refresh:

Action Risk Exact phrase
preview offline none
validate offline none
data-up billable persistent data persist <environment>
up billable compute launch <environment>
agent-bootstrap changes the provisioned host bootstrap <environment>
tunnel read-only connection none
seed changes application data seed <environment>
teardown:register changes the local expiry registry register <environment>
down destroys disposable compute sink <environment>

<environment> is the exact name from chalupa.yml. Confirmation is case-sensitive and must match the whole phrase. A mismatch cancels the action before Task runs.

Before each typed confirmation, Chalupa prints a target summary with the redacted canonical config path, exact compute stack, region, and size. data-up also shows the exact <environment>-data stack and configured expected GiB. down shows the protected-data stack and states that it survives.

For example:

chalupa run up --config "$DEMO_CONFIG"

Every changing or long-running action requires an interactive terminal. preview and validate are the only actions available in synthetic mode and the only run actions accepted outside a TTY. status --json remains available to non-interactive consumers when they supply an explicit config.

Provider-bound sinking in the UI

The operator UI adds a stronger identity check to down. Press r immediately before selecting Sink compute. The UI accepts only a present compute status observed within the last two minutes with a valid provider ID. It shows that ID in the target summary and passes it to the Taskfile as a typed EXPECTED_PROVIDER_ID argument. The provider-scoped destroy task compares the current stack output with that value immediately before destruction and refuses a mismatch.

Direct chalupa run down intentionally does not refresh status and is not provider-ID-bound. Its target summary says that the binding is unavailable and that only the configured local stack identity is known. It still requires the exact sink <environment> phrase and uses the normal compute-only Taskfile path. Prefer the UI when a fresh local provider identity is available.

data-nuke is intentionally unavailable in the CLI and operator UI. Permanent data deletion remains an independent, explicitly confirmed Taskfile operation documented in Lifecycle. Never reproduce it with direct Pulumi commands.

Navigate the operator UI

The UI has five screens:

  1. Overview — environment identity, services, persistence, ports, diagnostics, and configured control-plane features.
  2. Preview — the complete redacted remote Compose document.
  3. Status — manually refreshed, independent compute and protected-data state from the local Pulumi backend.
  4. Actions — the fixed Taskfile allowlist and risk classification.
  5. Help — safety boundaries and keyboard reference.

Use these keys:

Key Effect
1–5 Open a screen directly.
Left, Right, or Tab Move between screens.
Up or Down Move through actions or scroll the current screen.
Enter Run the selected enabled action.
r Refresh status from the local Pulumi backend for an explicit config.
Escape Return to Overview.
q or Ctrl-C Exit.

The UI starts from local inspection only; it never refreshes status automatically. In synthetic mode it displays SYNTHETIC OFFLINE DEMO, disables status refresh, and disables every action except Preview and Validate.

For an explicit config, the Status screen presents compute and protected data separately. An unknown data state remains visible with its bounded reason; the UI never collapses it into absent. A fresh present compute status with a provider ID also enables provider-bound sinking for two minutes.

For confirmations and foreground Task output, the UI temporarily returns terminal ownership to the command. A tunnel keeps ownership until its Task or SSH process exits. After a completed Task, press Enter to return to the UI.

Recover from unknown state

If data-up, up, or down fails or is interrupted, do not immediately repeat it or assume that rollback succeeded. Resource state and billing may be unknown.

  1. Run chalupa status --config "$DEMO_CONFIG" to inspect bounded local compute and protected-data state.
  2. Run task status CONFIG="$DEMO_CONFIG" for the Taskfile's human view and diagnostics.
  3. Verify the exact resource in the DigitalOcean console and check billing.
  4. Re-run chalupa inspect --config "$DEMO_CONFIG" before choosing the next lifecycle action.

An absent local stack is not proof that the provider has no resource. A present protected-data state identifies bounded local outputs and the configured expected size, not live provider capacity or billing. Do not use data-nuke as recovery.

Taskfile and secret boundaries

The CLI passes a canonical config path to a fixed public Taskfile action. The Taskfile continues to own validation, the local Pulumi backend, tvault profiles, SSH, reporting, and separation of compute from persistent data. Do not call underscore-prefixed tasks or Pulumi lifecycle commands directly.

The CLI does not cache config history, persist secret values, or create a credential store. Tasks resolve their existing least-privilege tvault profiles only when the selected action needs them. The redacted preview and local Pulumi state can still contain private operational metadata; protect the workstation and state directory.

Continue with Quickstart, Lifecycle, Secrets with tvault, and Troubleshooting.

PreviousQuickstartNextSecrets with tvault

On this page

Run from a checkoutCheck the workstationInspect safely firstCommand referenceActions and exact confirmationsProvider-bound sinking in the UINavigate the operator UIRecover from unknown stateTaskfile and secret boundaries