The CDK reconciles your code against the live workspace. All commands accept
--dir <path> (defaults to the current directory) and resolve cargo.state.json
relative to it.
Plan
Compiles your resources and diffs them against cargo.state.json — offline,
no API calls. Output marks each resource + create, ~ update, = noop, or
- delete (state-tracked but no longer in code).
Deploy
cargo-ai cdk deploy # create/update; prompts before applying
cargo-ai cdk deploy --yes # skip the prompt (required in CI / non-TTY)
cargo-ai cdk deploy --dry-run # show the plan, change nothing
deploy applies in dependency order and persists state after each resource,
so a crash mid-deploy leaves a recoverable cargo.state.json — just re-run.
Create
First deploy creates every resource and writes state.
No-op
Re-deploy with no code changes does nothing.
Update
Change one resource; only it updates.
Prune
By default deploy never deletes. To remove resources you deleted from code:
cargo-ai cdk deploy --prune
Without --prune, the plan still shows what would be pruned and reminds you.
Refresh on deploy
cargo-ai cdk deploy --refresh
Re-reads the live resources first and folds any out-of-band drift into the plan:
a resource edited in the UI re-applies (code wins). A resource deleted in the
UI is not silently recreated — the deploy stops and asks you to either re-run
with --recreate-deleted (to restore it) or remove it from your code (if the
deletion was intentional). See State & drift.
Import
Bind an existing live resource to a code resource — recover a lost state link, or
adopt pre-existing infra:
cargo-ai cdk import agent:sdr 1a2b3c4d-...
The CDK reconstructs the resource’s outputs and records it so the next deploy is
a no-op. Imported resources are treated as adopted: a later destroy
releases them (drops them from state) rather than deleting infra the CDK didn’t
create.
Destroy
cargo-ai cdk destroy --all # tear down everything in state
cargo-ai cdk destroy --target play:welcome # just one resource
Blanket teardown is opt-in: destroy refuses unless you pass --all or
--target <id> (so --yes alone can’t wipe a workspace). It deletes by uuid in
dependency-safe order (dependents first) and releases adopted resources
instead of deleting them. A --target that still has dependents — or that
isn’t in state — is rejected rather than silently skipped.
destroy and deploy --prune delete real Cargo resources. With --yes they
skip the prompt — double-check --dir and that cargo.state.json matches the
workspace you intend.
Locking & --force
A deploy/destroy/import holds a lock (cargo.state.lock) for the whole
read→plan→apply sequence so two concurrent runs can’t corrupt the state file. A
lock whose holder has died is reclaimed automatically; to override a lock you
believe is stale:
cargo-ai cdk deploy --force
Programmatic use
plan/apply are exported, so CI or the backend can reconcile the same way:
import { loadResources, apply, liveExecutors, liveReaders, readState, emptyState, writeState } from "@cargo-ai/cdk";
const nodes = await loadResources(root); // import the repo's resource files
const state = readState(root) ?? emptyState(workspaceUuid);
await apply({ nodes, state }, liveExecutors(api), (next) => writeState(root, next), liveReaders(api));