Cargo project — a Cargo workspace, declared in a repo
Use this skill to define a Cargo workspace in TypeScript (
builders from
) and reconcile it to live infrastructure with
.
It is the
declarative counterpart to the imperative capability skills: instead
of running one CLI command per resource, you write the whole graph once and deploy
it repeatably, with a
deploy state — held in your workspace, pointed at by a
committed
— linking your code to what Cargo created.
"Project" and "workspace" are two different things — keep them apart. A
workspace is the Cargo tenant you sign into: it holds the models, connectors,
agents, mailboxes and credits, and it is what
selects and
what
reports. A
project is the
repo that declares resources and
deploys them into a workspace: it is what
scaffolds, what
points from, and what
locates. One project deploys into
one workspace at a time — the workspace guard refuses a deploy when the state's
workspace isn't the selected one — and the same project reaches a dev and a prod
workspace through a different deploy state each. Say "project" for the repo, and
don't name a project directory
.
Bootstrap
Already signed in (
returns a workspace)? Skip to the next section.
bash
npm install -g @cargo-ai/cli # no global install? prefix every command with `npx @cargo-ai/cli`
cargo-ai login --email you@company.com # emailed code, no browser; creates the account on first use
# alternatives: --oauth (browser) · --token <api-token> (CI)
cargo-ai whoami # confirm the active workspace before any write
cargo-ai project --help # `unknown command` = CLI too old; reinstall @cargo-ai/cli@latest
Two CDK-specific extras: the project needs
as a dependency for the
builders you import (
scaffolds a
with it — then
), and the
domain ships with the CLI itself.
Every command prints JSON to stdout; failures exit non-zero with
. Anything that creates a run or a batch is async — pass
or poll the matching
. When the full skill bundle is installed,
../cargo/references/prerequisites.md
adds the CLI version pin, token scopes, and the admin-only surface.
1) What this skill governs
- Authoring every Cargo resource with a builder that returns a
handle; wiring resources by passing handles to each other (the dependency
graph is your variable graph).
- Deploying the graph: (offline diff) → (create/update, write
state) → (tear down). Plus drift (), adoption (), and
recovery ().
- Typing the config against your workspace's real integration schemas
().
The CDK spans
every resource kind — so it overlaps every imperative capability
skill (
,
,
,
,
,
, …). Which to reach for is the first decision:
2) CDK or the CLI? — the routing decision
Declarative (this skill) vs imperative (a capability skill).
Use the CDK when the user is managing resources as an artifact:
- "Set up / stand up / bootstrap a whole workspace (as code / from a template)."
- "Make this reproducible / version-controlled / in git / repeatable across
environments (dev → prod)."
- "Deploy these connectors + models + agents together" (a multi-resource graph
wired by dependency).
- Anything that should be re-runnable and diffable, where losing the definition
would be a problem.
Use the matching
capability skill (imperative
) when the
user is doing a
one-off operation or
exploring:
- "Create one connector", "add a column to this model", "list connectors",
"run this workflow", "query storage", "read this agent's memory."
- Any read, ad-hoc query, or single mutation that doesn't need to live in code.
When unsure, ask whether the result should be committed and re-deployable. If yes
→ CDK. If it's a quick action or a read → the capability skill (see the
router to pick the right domain).
3) The lifecycle
cargo-ai project init <dir> scaffold from getcargohq/cargo-manifest; resources in infra/
│
cargo-ai project types generate per-workspace types for typed config (optional)
│
(author define* files) importing a .ts file IS registration — no manifest
│
cargo-ai project plan offline: compile the graph, diff against the deploy state
│
cargo-ai project deploy create/update resources in dependency order, write state
│
cargo-ai project destroy tear down resources recorded in state
says what resources change; it doesn't show what a play does.
For a
/
graph past three nodes, present a Mermaid
flowchart of the node graph alongside the plan — routing, fallbacks, and which
nodes bill on every scheduled run are what the reviewer is approving. Generate it
from the deployed release after the first deploy, or from the node array while
authoring:
../cargo-orchestration/references/node-diagram.md
.
Side branches:
(validate the tree, no state, no API calls —
the CI/editor subset of
) ·
(what is here: every declared
resource, the file that declared it, whether it is deployed) ·
(read-only drift report) ·
(re-apply code over out-of-band edits) ·
(delete resources removed from code) ·
cargo-ai project import <id> <uuid>
(bind an existing live resource into state) ·
(generate
source from a live workspace and adopt it) ·
cargo-ai project rollback
(restore the
pre-deploy state snapshot) ·
(inspect and repoint the deploy state).
and answer different questions. answers
what will deploy do —
its unit is the change, and it exits non-zero so CI can gate on it.
answers
what
is here — its unit is the resource, and it never fails.
is
minus the diff:
it needs no state, so it is what an editor or a pre-commit hook runs. Running
with no arguments does
inside a project and
outside one.
4) Documentation hierarchy
- Level 1 — (this file): the decision model, lifecycle, critical
rules, and routing.
- Level 2 — Guides:
guides/authoring-resources.md
,
guides/deploy-and-state.md
,
.
- Level 2.5 — Recipes: — step-by-step playbooks to
follow as your execution plan.
- References — (the full
builder catalog), (every
subcommand + flags),
references/troubleshooting.md
, and
references/examples/full-workspace.md
.
5) Read behavior — match the task to a doc and READ IT
| When the task involves… | Read this first | What it gives you |
|---|
| Writing files, wiring resources, /, bodies (tool/play logic) | guides/authoring-resources.md
| The builder catalog, the handle/ref model, secrets, and how workflow bodies compile. |
| / / , the state file, drift, adopting existing resources, CI | guides/deploy-and-state.md
| The deploy lifecycle, semantics, drift/import/rollback, async builds. |
| Typed config, , tsconfig wiring, in workflow bodies | | What generates and how to wire it into your project. |
| A field/spec/output for a specific builder | | Every builder → spec fields → which ref each takes → outputs. |
| Exact command flags | | Every subcommand and its flags. |
| A deploy error / footgun | references/troubleshooting.md
| The known failure modes and fixes. |
| A known GTM outcome, before authoring one | | The cookbook menu: gtm-skills that carry a worked CDK example, and the adaptations each supports. |
Cookbooks — check the menu before authoring a known outcome from scratch
holds, beside its
one-off skills,
cookbooks: skills that carry worked CDK resources, the same job as a deployed
pipeline that keeps producing the result (TAM building, account scoring, contact
sourcing, routing engine, AI SDR, rep cockpit, …). Every folder is self-contained: its
own models, connectors and folders, no shared foundation, no requires graph.
The menu is local: . Read it
before authoring a common GTM outcome from scratch. It is generated from gtm-skills'
, so it cannot drift.
A cookbook is a worked example, not a template to fill in. Each one declares in its
what may be reshaped, what must hold or it stops
working, and what has to be answered either way, and it carries its own procedure.
is the copy step in that procedure:
sh
cargo-ai project add cookbook/tam-building # inside a CDK project
cargo-ai project init my-project --cookbook tam-building # no project yet: both at once
That writes the resources to
and the procedure to
.claude/skills/tam-building/
, skipping any file it would overwrite.
Then start the
skill at its Adapt section — its opening steps are written for someone who found the
folder on GitHub and still has to place it, so following them from the top scaffolds a
second project and copies the folder in again.
What is left after the copy is the part only you can do: reconcile it with what is
already declared, adapt the copied files
in place to the project's real shape (do not
regenerate them from the skill's prose — the safety lives in the TypeScript), plan and
stop, deploy on a yes, walk its
.
If you are mid-task and the skill is not in this session,
npx skills add getcargohq/gtm-skills/<slug>
fetches the procedure alone and you can read
.agents/skills/<slug>/SKILL.md
directly; no reload needed. To read one without
installing,
npx skills use getcargohq/gtm-skills@<slug>
prints it. Neither brings the
CDK resources — for those you still want
.
Routing rule: one-off versus standing. A user who wants the list today wants
(or gtm-skills' one-off
); a user who wants a pipeline
that keeps producing it wants
. The same words describe both ("build
our TAM"), so listen for whether the result is meant to keep arriving. A cookbook
matches → install it and follow it. No match → author from the recipes below.
Never cargo-ai project init --force
into a directory that is not empty. It replaces
the project's
and reverts adapted code, while
survives, so the next
diffs a live workspace against code nobody wrote. Copy the
skill folder in as a sibling instead.
Caveat: the examples typecheck, but they are not yet deploy-verified against a live
workspace, and every one is
. Treat each skill's
as the
acceptance test, and always review
before deploying.
Recipes — follow step-by-step when one matches
| Recipe | Use when… |
|---|
recipes/scaffold-a-project.md
| Standing up a new project from scratch ( → types → plan → deploy). |
recipes/add-connector-and-model.md
| Adding a data source + a model sourced from it, wired by handle. |
recipes/build-an-agent.md
| Composing a model + tool + agent (with / / ) and deploying. |
recipes/migrate-existing-workspace.md
| Bringing an already-live workspace under a project via . |
recipes/deploy-from-ci.md
| Deploying non-interactively from CI (token auth + committed state). |
6) Critical rules
-
Commit — it is a pointer now, not the state. The deploy
state lives in your
workspace; the repo commits only
.
creates the state and writes that
pointer, so it lands in the scaffold commit. Commit it: without the uuid a fresh
checkout can't find its state, and a deploy will
not quietly create a
replacement (that would orphan everything the old one tracks). The state records
only uuids, hashes and outputs — never secret values. It is still the
only
handle on a deployed
play,
agent, or
alert (they have no slug);
recover a lost link with
project state bind <uuid>
, or per-resource with
. Git-ignore the working files (
scaffolds
this):
gitignore
.cargo-ai/
cargo.state.lock
cargo.state.bak.json
cargo.state.cache.json
cargo.state.audit.jsonl
One state per repo, and at most 10 live states per workspace:
bash
cargo-ai project state list # every state here, and which one this project is on
cargo-ai project state create # create one for this project, write the pointer
cargo-ai project state bind <uuid> # repoint at an existing one
A project scaffolded before states moved to the workspace has the resource map
inline in
, and keeps deploying against that file for as
long as you leave it there — nothing migrates behind your back.
is
what moves it: the map goes onto a new state, the file becomes a pointer, and you
commit it. Don't migrate without telling the team, since a teammate who deploys
before pulling the new pointer is deploying from a state that no longer exists.
(Deleting a state —
— is in the CDK README but is
not in CLI
1.0.96; it lands in the next release.)
-
Three ways to get a value in, and they are not interchangeable.
- — read from your environment at deploy time, excluded
from the content hash and from state. Export the env var before deploying; a
missing one fails the deploy with an unresolved placeholder.
- — read from your environment at load time, and its value
enters the spec and therefore the content hash, so changing it shows as drift.
Use it for non-secret config you want tracked.
- — a pointer at a workspace env-var catalog entry.
Nothing is read locally and nothing can fail; the value stays server-side and is
re-read on every use, so rotating it in the workspace reaches the resource with
no redeploy. Manage the catalog with
cargo-ai workspaceManagement envVar
(see ../cargo-workspace-management/SKILL.md
).
and
are accepted at
secret-typed schema positions
only —
prints the union at exactly those positions. A
resource's own
block takes
or
and
rejects a pointer,
because a worker, app, agent or script already inherits the whole workspace
catalog; a pointer there could only restate a variable it can read anyway.
-
A rotated needs more than a plain deploy to land. Keeping the value
out of the content hash is what stops rotation reading as drift — and it is also
why
won't push the new value: nothing in the hash changed, so the
resource isn't re-applied. Roll it with
, or any other edit to
that resource.
has no such step; that is most of its appeal.
-
Wire by handle, never by . Pass a
handle directly
(
,
), or
for a resource you
didn't define in code (
,
,
,
,
, …). Where a reference needs per-call options, wrap it as
(e.g.
models: [{ ref: contacts, readOnly: true }]
).
-
Run after workspace integrations change — it
regenerates
so
/
config (and
in workflow bodies) type-check against the real schemas. Typing
is a bonus, never a gate: deploy works without it.
-
Any subdirectory of the repo is fine (CLI ≥ 1.0.83). Commands walk
up to
the package root where
is declared, then back
down to the
resource directory (
in a scaffolded repo), so
and
land in the right place from anywhere inside the project.
still overrides it. This is why resources live in
and not
at the root: the loader imports
every under the directory it is given, and
a repo root also holds
— whose files run on import. Pointing a command
at the root would execute them.
-
in CI. and
prompt for confirmation; non-interactive
runs must pass
.
-
A / graph with paid nodes gets a sample run before it
goes wide. Deploying is not running, but the first thing that runs a deployed
play is usually a batch over the whole segment — and a scheduled play re-bills
every node on every run. Before enrolling everything (or enabling a schedule),
run the deployed workflow on
10–20 records —
cargo-ai orchestration batch create --data '{"kind":"filter","modelUuid":"…","filter":…,"limit":15}'
, or
batch create --file ./plays/x.ts
to test-run the module without deploying —
then ask the user to approve the full enrollment with the
record count and
credit estimate. Read the provider's playbook
(
../cargo-gtm/provider-playbooks/<slug>.md
, esp. its
Recurring use section)
and the gate in
../cargo-gtm/references/cost-discipline.md
.
-
A whose actions call paid nodes re-bills on every breach. An
alert's
fire as real runs, so a badly-sized
on a tight
can breach — and bill — every tick. Size the threshold with
cargo-ai observability alert preview
before deploying, prefer cheap notification
actions (an agent that posts, a connector notification) over anything that fans
out, and apply the same cost gate above when an action calls a credits-based
provider. Scope/threshold and firing semantics:
../cargo-observability/SKILL.md
.
-
bills monthly, and rewrites a DNS zone. A
mailbox is 100–160 credits
per month for as long as it exists (
cargo-ai mailboxManagement pricing get
for live figures), so a
line
in the plan is a recurring charge the user approves, not a one-off. Its
,
and
are
create-only — changing any of them is destroy +
recreate, i.e. a brand-new inbox back at the bottom of a 45-day warm-up ramp. The
deploy polls
for up to 5 minutes waiting for
. On
,
is the
whole zone, not a patch: declaring it
replaces every live record (including the ones the registrar wrote at purchase),
and omitting it leaves the zone untouched.
,
and
are
additive and are the supported way to configure a zone
without replacing it, so reach for
only when you mean to own every
record. Use
for a domain or mailbox bought in the UI. Ramp,
suppression and sending:
../cargo-mailbox-management/SKILL.md
.
-
Route CDK-managed resources into a clearly-labelled folder. Set
on
each builder so everything CDK owns lands in a dedicated folder whose name signals
"owned by code — don't hand-edit" to anyone in the UI (manual UI edits read back as
drift on the next
). Folders are per-kind, so give each kind its own but share
one short, recognizable prefix — recommended:
(e.g.
,
). Keep names short (long labels truncate in the folder tree); the
lock emoji is the "don't touch" cue. See
guides/authoring-resources.md
.
Help
- and
cargo-ai project <subcommand> --help
for the live flag
surface.
- When a documented command/flag/response doesn't match what you observe, file a
report:
cargo-ai workspaceManagement report create
(see
../cargo-workspace-management/SKILL.md
).