{"id":"433d812d-5205-444b-ac5e-cc2d2eb71661","entityType":"agent","slug":"clawhub-cargo-ai-cargo-cdk","name":"cargo-cdk","canonicalUrl":"https://www.xpersona.co/agent/clawhub-cargo-ai-cargo-cdk","canonicalPath":"/agent/clawhub-cargo-ai-cargo-cdk","generatedAt":"2026-10-10T17:35:26.950Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T15:02:39.701Z","emptyReason":null},"description":"Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project. Skill: cargo-cdk Owner: cargo-ai Summary: Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project. Tags: latest:2.0.0 Version history: v2.0.0 | 2026-09-14T06:26:10.576Z | auto - Renamed the skill from cargo-cdk to cargo-project. - All guides, recipes, and reference documentation have been removed. - The skill now serves as a","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.4K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s178dcd9wkfn0a2fqrygmt3jzn87j9e1:cargo-cdk","sourceUrl":"https://clawhub.ai/cargo-ai/cargo-cdk","homepage":"https://clawhub.ai/cargo-ai/skills/cargo-cdk","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/cargo-ai/cargo-cdk","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/cargo-ai/skills/cargo-cdk","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":63,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project. Skill: ca"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T15:02:39.701Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T15:02:39.701Z","emptyReason":null},"stars":null,"forks":null,"downloads":1371,"packageName":null,"latestVersion":"2.0.0","tractionLabel":"1.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T15:02:39.701Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T15:02:39.701Z","lastCrawledAt":"2026-10-10T15:02:39.701Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T15:02:39.701Z","lastVerifiedAt":null,"highlights":[{"version":"2.0.0","createdAt":"2026-09-14T06:26:10.576Z","changelog":"- Renamed the skill from cargo-cdk to cargo-project. - All guides, recipes, and reference documentation have been removed. - The skill now serves as a redirect pointer to cargo-project and will be removed in a future release. - Users are advised to load cargo-project instead; all functionality and documentation have moved there.","fileCount":4,"zipByteSize":2122},{"version":"1.2.4","createdAt":"2026-09-10T18:17:19.304Z","changelog":"cargo-cdk 1.2.4 - Documentation expanded across guides, recipes, and reference sections for improved clarity and navigation. - Outdated and redundant documentation file (skill-card.md) removed. - SKILL.md updated to reference current supported commands and documentation structure. - Minor adjustments and clarifications to lifecycle, routing decisions, and bootstrap instructions.","fileCount":17,"zipByteSize":37345},{"version":"1.2.3","createdAt":"2026-08-24T04:48:28.655Z","changelog":"- Added a references/cookbooks.md file listing available Cargo CDK cookbooks and examples. - Expanded the SKILL.md description and triggers to mention cookbook support and provide a menu location. - Updated documentation to direct users to references/cookbooks.md for starting from a cookbook solution. - Removed the deprecated skill-card.md file. - Minor documentation improvements and clarifications throughout.","fileCount":17,"zipByteSize":35850},{"version":"1.2.2","createdAt":"2026-08-15T01:07:27.273Z","changelog":"- Streamlined and clarified skill description and triggers; updated for greater discoverability. - Added a new \"Bootstrap\" section with explicit, step-by-step CLI and login instructions. - Removed duplicate and outdated documentation, including the separate skill-card.md file. - Updated guidance on when to use the CDK versus an imperative skill, emphasizing routing and best practices. - Improved explanations and pointers for lifecycle commands, code review practices, and documentation navigation.","fileCount":16,"zipByteSize":32517},{"version":"1.2.1","createdAt":"2026-08-11T21:43:18.709Z","changelog":"cargo-cdk 1.2.1 - Updated sign-in instructions for the CLI: now includes `cargo-ai login --email` (no browser required) and clarifies authentication options. - Removed the skill-card.md file. - Improved compatibility notes to specify no browser required for email login. - Incremented version to 1.2.1.","fileCount":16,"zipByteSize":31675},{"version":"1.2.0","createdAt":"2026-08-09T22:58:33.772Z","changelog":"cargo-cdk 1.2.0 - Expanded documentation on critical rules: `cargo.state.json` is now also the only handle for deployed alerts (in addition to plays and agents). - Improved and updated references and guides for authoring, deployment lifecycle, and typed configuration. - Removed `skill-card.md` file. - Minor clarifications and rewording throughout documentation to improve accuracy and guidance.","fileCount":16,"zipByteSize":31538},{"version":"1.1.0","createdAt":"2026-08-08T21:20:48.926Z","changelog":"- Introduced version 1.1.0. - Added a new metadata file: `skill-metadata.json`. - Removed the file: `skill-card.md`. - Updated documentation in `SKILL.md` and `guides/authoring-resources.md` for improved clarity and versioning. - Minor improvements to documentation hierarchy and versioning information.","fileCount":16,"zipByteSize":30017},{"version":"1.0.0","createdAt":"2026-07-09T01:42:15.941Z","changelog":"Initial release of cargo-cdk: declarative \"workspace-as-code\" for Cargo - Introduces a TypeScript-based CDK to define and deploy entire Cargo workspaces, modeling every resource (connectors, models, tools, agents, servers, files, and more) from code. - Enables reproducible, version-controlled, and environment-portable deployments with `cargo-ai cdk` (`init`, `types`, `plan`, `deploy`, etc.), similar to Pulumi/AWS CDK for cloud infra. - Provides comprehensive guides, recipes, and reference docs linking users to key authoring, deployment, typing, and troubleshooting workflows. - Clarifies when to use the declarative CDK skill vs. imperative capability skills for one-off commands. - Emphasizes correct state handling, git best practices, secrets management, and recovery steps.","fileCount":15,"zipByteSize":28226}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s178dcd9wkfn0a2fqrygmt3jzn87j9e1:cargo-cdk","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T17:35:26.944Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-cargo-ai-cargo-cdk/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T15:02:39.701Z","emptyReason":null},"readme":"Skill: cargo-cdk\n\nOwner: cargo-ai\n\nSummary: Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project.\n\nTags: latest:2.0.0\n\nVersion history:\n\nv2.0.0 | 2026-09-14T06:26:10.576Z | auto\n\n- Renamed the skill from cargo-cdk to cargo-project.\n- All guides, recipes, and reference documentation have been removed.\n- The skill now serves as a redirect pointer to cargo-project and will be removed in a future release.\n- Users are advised to load cargo-project instead; all functionality and documentation have moved there.\n\nv1.2.4 | 2026-09-10T18:17:19.304Z | auto\n\ncargo-cdk 1.2.4\n\n- Documentation expanded across guides, recipes, and reference sections for improved clarity and navigation.\n- Outdated and redundant documentation file (skill-card.md) removed.\n- SKILL.md updated to reference current supported commands and documentation structure.\n- Minor adjustments and clarifications to lifecycle, routing decisions, and bootstrap instructions.\n\nv1.2.3 | 2026-08-24T04:48:28.655Z | auto\n\n- Added a references/cookbooks.md file listing available Cargo CDK cookbooks and examples.\n- Expanded the SKILL.md description and triggers to mention cookbook support and provide a menu location.\n- Updated documentation to direct users to references/cookbooks.md for starting from a cookbook solution.\n- Removed the deprecated skill-card.md file.\n- Minor documentation improvements and clarifications throughout.\n\nv1.2.2 | 2026-08-15T01:07:27.273Z | auto\n\n- Streamlined and clarified skill description and triggers; updated for greater discoverability.\n- Added a new \"Bootstrap\" section with explicit, step-by-step CLI and login instructions.\n- Removed duplicate and outdated documentation, including the separate skill-card.md file.\n- Updated guidance on when to use the CDK versus an imperative skill, emphasizing routing and best practices.\n- Improved explanations and pointers for lifecycle commands, code review practices, and documentation navigation.\n\nv1.2.1 | 2026-08-11T21:43:18.709Z | auto\n\ncargo-cdk 1.2.1\n\n- Updated sign-in instructions for the CLI: now includes `cargo-ai login --email` (no browser required) and clarifies authentication options.\n- Removed the skill-card.md file.\n- Improved compatibility notes to specify no browser required for email login.\n- Incremented version to 1.2.1.\n\nv1.2.0 | 2026-08-09T22:58:33.772Z | auto\n\ncargo-cdk 1.2.0\n\n- Expanded documentation on critical rules: `cargo.state.json` is now also the only handle for deployed alerts (in addition to plays and agents).\n- Improved and updated references and guides for authoring, deployment lifecycle, and typed configuration.\n- Removed `skill-card.md` file.\n- Minor clarifications and rewording throughout documentation to improve accuracy and guidance.\n\nv1.1.0 | 2026-08-08T21:20:48.926Z | auto\n\n- Introduced version 1.1.0.\n- Added a new metadata file: `skill-metadata.json`.\n- Removed the file: `skill-card.md`.\n- Updated documentation in `SKILL.md` and `guides/authoring-resources.md` for improved clarity and versioning.\n- Minor improvements to documentation hierarchy and versioning information.\n\nv1.0.0 | 2026-07-09T01:42:15.941Z | auto\n\nInitial release of cargo-cdk: declarative \"workspace-as-code\" for Cargo\n\n- Introduces a TypeScript-based CDK to define and deploy entire Cargo workspaces, modeling every resource (connectors, models, tools, agents, servers, files, and more) from code.\n- Enables reproducible, version-controlled, and environment-portable deployments with `cargo-ai cdk` (`init`, `types`, `plan`, `deploy`, etc.), similar to Pulumi/AWS CDK for cloud infra.\n- Provides comprehensive guides, recipes, and reference docs linking users to key authoring, deployment, typing, and troubleshooting workflows.\n- Clarifies when to use the declarative CDK skill vs. imperative capability skills for one-off commands.\n- Emphasizes correct state handling, git best practices, secrets management, and recovery steps.\n\nArchive index:\n\nArchive v2.0.0: 4 files, 2122 bytes\n\nFiles: skill-card.md (1647b), skill-metadata.json (425b), SKILL.md (686b), _meta.json (128b)\n\nFile v2.0.0:SKILL.md\n\n---\nname: cargo-cdk\ndescription: \"Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project.\"\nversion: \"2.0.0\"\ncompatibility: Requires @cargo-ai/cli (npm).\nhomepage: https://github.com/getcargohq/cargo-skills\nmetadata:\n  author: getcargo\n  redirect: cargo-project\n---\n\n# cargo-cdk is now cargo-project\n\nLoad [`cargo-project`](../cargo-project/SKILL.md) instead. It is this skill under its new name, following the CLI: `cargo-ai cdk` is now `cargo-ai project`, and `cdk` still works as an alias.\n\nThis directory holds no instructions. It is a redirect, and will be removed in a later release.\n\nFile v2.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7by8t6yt9yghbxtxz6hv0bts87k6bq\",\n  \"slug\": \"cargo-cdk\",\n  \"version\": \"2.0.0\",\n  \"publishedAt\": 1789367170576\n}\n\nFile v2.0.0:skill-card.md\n\n## Description:\n\ncargo-cdk is a compatibility redirect that points existing installs to the renamed cargo-project skill.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[cargo-ai](https://clawhub.ai/user/cargo-ai)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this compatibility entry to redirect legacy cargo-cdk installs to the cargo-project skill after the rename.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: This entry does not provide cargo-project behavior itself; relying on it without review can hide changed functionality or requirements.\n\nMitigation: Review the cargo-project skill and its @cargo-ai/cli requirements before deployment.\n\nRisk: The redirect entry is scheduled for future removal.\n\nMitigation: Update workflows and references to load cargo-project directly.\n\n## Reference(s):\n\n- [Cargo skills homepage](https://github.com/getcargohq/cargo-skills)\n- [cargo-cdk ClawHub release page](https://clawhub.ai/cargo-ai/skills/cargo-cdk)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, configuration]\n\n**Output Format:** [Markdown text]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Redirect-only entry; no executable code in the reviewed artifact.]\n\n## Skill Version(s):\n\n2.0.0 (source: frontmatter, skill-metadata.json, server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v2.0.0:skill-metadata.json\n\n{\n  \"$comment\": \"Generated by .github/scripts/skills-metadata.mjs — do not hand-edit. Regenerate with: node .github/scripts/skills-metadata.mjs --write .\",\n  \"name\": \"cargo-cdk\",\n  \"version\": \"2.0.0\",\n  \"documents\": [\n    {\n      \"path\": \"SKILL.md\",\n      \"kind\": \"entrypoint\",\n      \"title\": \"cargo-cdk is now cargo-project\"\n    }\n  ],\n  \"contentHash\": \"ad9701a71bd37558bd7ee80fff01428241f40a31b21598f547c5be5560965a92\"\n}\n\nArchive v1.2.4: 17 files, 37345 bytes\n\nFiles: guides/authoring-resources.md (10897b), guides/deploy-and-state.md (4952b), guides/typed-config.md (2811b), recipes/add-connector-and-model.md (2247b), recipes/build-an-agent.md (2971b), recipes/deploy-from-ci.md (2476b), recipes/migrate-existing-workspace.md (2532b), recipes/scaffold-a-workspace.md (2734b), references/commands.md (3376b), references/cookbooks.md (5083b), references/examples/full-workspace.md (4418b), references/resources.md (7155b), references/troubleshooting.md (3775b), skill-card.md (2873b), skill-metadata.json (2220b), SKILL.md (18139b), _meta.json (128b)\n\nFile v1.2.4:SKILL.md\n\n---\nname: cargo-cdk\ndescription: \"Manage a whole Cargo workspace as code — declare connectors, models, plays, tools, agents, MCP servers, segments, context, folders, files, workers, and apps in TypeScript, then reconcile them with `cargo-ai cdk` (init → types → plan → deploy), the way you would run Pulumi or the AWS CDK. Triggers: \\\"as code\\\", \\\"in git\\\", \\\"version-controlled\\\", \\\"reproducible\\\", \\\"Terraform for Cargo\\\", \\\"set up a whole workspace\\\", \\\"staging and production\\\", \\\"deploy from CI\\\", \\\"review this in a PR\\\", \\\"cargo.state.json\\\", \\\"scaffold from a template\\\", \\\"is there a cookbook for this\\\", \\\"start from a cookbook\\\". Skills with a CDK example (TAM building, account scoring, contact sourcing, routing, AI SDR, rep cockpit) live in gtm-skills; menu in references/cookbooks.md. Skip when: it is a one-off operation, a read, or an ad-hoc query — use the matching capability skill.\"\nversion: \"1.2.4\"\ncompatibility: Requires @cargo-ai/cli (npm). Sign in or create an account with `cargo-ai login --email` (emailed code, no browser), `--oauth`, or an API token\nhomepage: https://github.com/getcargohq/cargo-skills\nmetadata:\n  author: getcargo\n  openclaw:\n    requires:\n      bins:\n        - cargo-ai\n    install:\n      - kind: node\n        package: \"@cargo-ai/cli@latest\"\n        bins:\n          - cargo-ai\n    homepage: https://github.com/getcargohq/cargo-skills\n---\n\n# Cargo CDK — declarative workspace-as-code\n\nUse this skill to define a Cargo workspace in TypeScript (`define*` builders from\n`@cargo-ai/cdk`) and reconcile it to live infrastructure with `cargo-ai cdk deploy`.\nIt is the **declarative** counterpart to the imperative capability skills: instead\nof running one CLI command per resource, you write the whole graph once and deploy\nit repeatably, with a committed `cargo.state.json` linking your code to what Cargo\ncreated.\n\n## Bootstrap\n\nAlready signed in (`cargo-ai whoami` returns a workspace)? Skip to the next section.\n\n```bash\nnpm install -g @cargo-ai/cli            # no global install? prefix every command with `npx @cargo-ai/cli`\ncargo-ai login --email you@company.com  # emailed code, no browser; creates the account on first use\n                                        # alternatives: --oauth (browser) · --token <api-token> (CI)\ncargo-ai whoami                         # confirm the active workspace before any write\ncargo-ai cdk --help                     # `unknown command` = CLI too old; reinstall @cargo-ai/cli@latest\n```\n\nTwo CDK-specific extras: the project needs **`@cargo-ai/cdk` as a dependency** for the `define*` builders you import (`cargo-ai cdk init` scaffolds a `package.json` with it — then `npm install`), and the `cargo-ai cdk` domain ships with the CLI itself.\n\nEvery command prints JSON to stdout; failures exit non-zero with `{\"errorMessage\": \"...\"}`. Anything that creates a run or a batch is async — pass `--wait-until-finished` or poll the matching `get`. When the full skill bundle is installed, [`../cargo/references/prerequisites.md`](../cargo/references/prerequisites.md) adds the CLI version pin, token scopes, and the admin-only surface.\n\n## 1) What this skill governs\n\n- **Authoring** every Cargo resource with a `define*` builder that returns a\n  **handle**; wiring resources by passing handles to each other (the dependency\n  graph is your variable graph).\n- **Deploying** the graph: `plan` (offline diff) → `deploy` (create/update, write\n  state) → `destroy` (tear down). Plus drift (`refresh`), adoption (`import`), and\n  recovery (`rollback`).\n- **Typing** the config against your workspace's real integration schemas\n  (`cargo-ai cdk types`).\n\nThe CDK spans **every** resource kind — so it overlaps every imperative capability\nskill (`cargo-connection`, `cargo-storage`, `cargo-ai`, `cargo-orchestration`,\n`cargo-content`, `cargo-hosting`, …). Which to reach for is the first decision:\n\n## 2) CDK or the CLI? — the routing decision\n\n> **Declarative (this skill) vs imperative (a capability skill).**\n\nUse the **CDK** when the user is **managing resources as an artifact**:\n\n- \"Set up / stand up / bootstrap a whole workspace (as code / from a template).\"\n- \"Make this reproducible / version-controlled / in git / repeatable across\n  environments (dev → prod).\"\n- \"Deploy these connectors + models + agents together\" (a multi-resource graph\n  wired by dependency).\n- Anything that should be re-runnable and diffable, where losing the definition\n  would be a problem.\n\nUse the matching **capability skill** (imperative `cargo-ai <domain>`) when the\nuser is doing a **one-off operation** or **exploring**:\n\n- \"Create one connector\", \"add a column to this model\", \"list connectors\",\n  \"run this workflow\", \"query storage\", \"read this agent's memory.\"\n- Any read, ad-hoc query, or single mutation that doesn't need to live in code.\n\nWhen unsure, ask whether the result should be committed and re-deployable. If yes\n→ CDK. If it's a quick action or a read → the capability skill (see the\n[`cargo` router](../cargo/SKILL.md) to pick the right domain).\n\n## 3) The lifecycle\n\n```\ncargo-ai cdk init <dir>     scaffold a project from a template (blank | full)\n        │\ncargo-ai cdk types          generate per-workspace types for typed config (optional)\n        │\n   (author define* files)   importing a .ts file IS registration — no manifest\n        │\ncargo-ai cdk plan           offline: compile the graph, diff against cargo.state.json\n        │\ncargo-ai cdk deploy         create/update resources in dependency order, write state\n        │\ncargo-ai cdk destroy        tear down resources recorded in state\n```\n\n> **`cdk plan` says what resources change; it doesn't show what a play does.**\n> For a `definePlay` / `defineTool` graph past three nodes, present a Mermaid\n> flowchart of the node graph alongside the plan — routing, fallbacks, and which\n> nodes bill on every scheduled run are what the reviewer is approving. Generate it\n> from the deployed release after the first deploy, or from the node array while\n> authoring:\n> [`../cargo-orchestration/references/node-diagram.md`](../cargo-orchestration/references/node-diagram.md).\n\nSide branches: `cargo-ai cdk refresh` (read-only drift report) · `deploy --refresh`\n(re-apply code over out-of-band edits) · `deploy --prune` (delete resources removed\nfrom code) · `cargo-ai cdk import <id> <uuid>` (bind an existing live resource into\nstate) · `cargo-ai cdk rollback` (restore the pre-deploy state snapshot).\n\n## 4) Documentation hierarchy\n\n- **Level 1** — `SKILL.md` (this file): the decision model, lifecycle, critical\n  rules, and routing.\n- **Level 2** — Guides:\n  [`guides/authoring-resources.md`](guides/authoring-resources.md),\n  [`guides/deploy-and-state.md`](guides/deploy-and-state.md),\n  [`guides/typed-config.md`](guides/typed-config.md).\n- **Level 2.5** — Recipes: [`recipes/*.md`](recipes/) — step-by-step playbooks to\n  follow as your execution plan.\n- **References** — [`references/resources.md`](references/resources.md) (the full\n  builder catalog), [`references/commands.md`](references/commands.md) (every\n  `cargo-ai cdk` subcommand + flags),\n  [`references/troubleshooting.md`](references/troubleshooting.md), and\n  [`references/examples/full-workspace.md`](references/examples/full-workspace.md).\n\n## 5) Read behavior — match the task to a doc and READ IT\n\n| When the task involves… | Read this first | What it gives you |\n|---|---|---|\n| Writing `define*` files, wiring resources, `secret()`/`env()`, `defineWorkflow` bodies (tool/play logic) | [`guides/authoring-resources.md`](guides/authoring-resources.md) | The builder catalog, the handle/ref model, secrets, and how workflow bodies compile. |\n| `plan` / `deploy` / `destroy`, the state file, drift, adopting existing resources, CI | [`guides/deploy-and-state.md`](guides/deploy-and-state.md) | The deploy lifecycle, `cargo.state.json` semantics, drift/import/rollback, async builds. |\n| Typed config, `cargo-ai cdk types`, tsconfig wiring, `integrations.*` in workflow bodies | [`guides/typed-config.md`](guides/typed-config.md) | What `cdk types` generates and how to wire it into your project. |\n| A field/spec/output for a specific builder | [`references/resources.md`](references/resources.md) | Every builder → spec fields → which ref each takes → outputs. |\n| Exact command flags | [`references/commands.md`](references/commands.md) | Every `cargo-ai cdk` subcommand and its flags. |\n| A deploy error / footgun | [`references/troubleshooting.md`](references/troubleshooting.md) | The known failure modes and fixes. |\n| A known GTM outcome, before authoring one | [`references/cookbooks.md`](references/cookbooks.md) | The cookbook menu: gtm-skills that carry a worked CDK example, and the adaptations each supports. |\n\n### Cookbooks — check the menu before authoring a known outcome from scratch\n\n[`getcargohq/gtm-skills`](https://github.com/getcargohq/gtm-skills) holds, beside its\none-off skills, **cookbooks**: skills that carry worked CDK resources, the same job as a deployed\npipeline that keeps producing the result (TAM building, account scoring, contact\nsourcing, routing engine, AI SDR, rep cockpit, …). Every folder is self-contained: its\nown models, connectors and folders, no shared foundation, no requires graph.\n\n**The menu is local: [`references/cookbooks.md`](references/cookbooks.md).** Read it\nbefore authoring a common GTM outcome from scratch. It is generated from gtm-skills'\n`catalog.json`, so it cannot drift.\n\n**A cookbook is a worked example, not a template to fill in.** Each one declares in its `SKILL.md` what may be reshaped, what must hold or it stops\nworking, and what has to be answered either way, and it carries its own procedure.\n`cdk add` is the copy step in that procedure:\n\n```sh\ncargo-ai cdk add cookbook/tam-building               # inside a CDK project\ncargo-ai cdk init my-project --cookbook tam-building # no project yet: both at once\n```\n\nThat writes the resources to `infra/tam-building/` and the procedure to\n`.claude/skills/tam-building/`, skipping any file it would overwrite. **Then start the\nskill at its Adapt section** — its opening steps are written for someone who found the\nfolder on GitHub and still has to place it, so following them from the top scaffolds a\nsecond project and copies the folder in again.\n\nWhat is left after the copy is the part only you can do: reconcile it with what is\nalready declared, adapt the copied files **in place** to the project's real shape (do not\nregenerate them from the skill's prose — the safety lives in the TypeScript), plan and\nstop, deploy on a yes, walk its `Done when`.\n\n**If you are mid-task and the skill is not in this session**, `npx skills add\ngetcargohq/gtm-skills/<slug>` fetches the procedure alone and you can read\n`.agents/skills/<slug>/SKILL.md` directly; no reload needed. To read one without\ninstalling, `npx skills use getcargohq/gtm-skills@<slug>` prints it. Neither brings the\nCDK resources — for those you still want `cdk add`.\n\n**Routing rule: one-off versus standing.** A user who wants the list today wants\n`cargo-gtm` (or gtm-skills' one-off `build-tam-list`); a user who wants a pipeline\nthat keeps producing it wants `tam-building`. The same words describe both (\"build\nour TAM\"), so listen for whether the result is meant to keep arriving. A cookbook\nmatches → install it and follow it. No match → author from the recipes below.\n\n**Never `cargo-ai cdk init --force` into a directory that is not empty.** It replaces\nthe project's `package.json` and reverts adapted code, while `cargo.state.json`\nsurvives, so the next `plan` diffs a live workspace against code nobody wrote. Copy the\nskill folder in as a sibling instead.\n\nCaveat: the examples typecheck, but they are not yet deploy-verified against a live\nworkspace, and every one is `to-be-approved`. Treat each skill's `Done when` as the\nacceptance test, and always review `cargo-ai cdk plan` before deploying.\n\n### Recipes — follow step-by-step when one matches\n\n| Recipe | Use when… |\n|---|---|\n| [`recipes/scaffold-a-workspace.md`](recipes/scaffold-a-workspace.md) | Standing up a new workspace from scratch (`init` → types → plan → deploy). |\n| [`recipes/add-connector-and-model.md`](recipes/add-connector-and-model.md) | Adding a data source + a model sourced from it, wired by handle. |\n| [`recipes/build-an-agent.md`](recipes/build-an-agent.md) | Composing a model + tool + agent (with `uses` / `models` / `tools`) and deploying. |\n| [`recipes/migrate-existing-workspace.md`](recipes/migrate-existing-workspace.md) | Bringing an already-live workspace under CDK management via `cdk import`. |\n| [`recipes/deploy-from-ci.md`](recipes/deploy-from-ci.md) | Deploying non-interactively from CI (token auth + committed state). |\n\n## 6) Critical rules\n\n- **Commit `cargo.state.json`.** It is the link from your code to the resources\n  Cargo created — and the **only** handle on a deployed **play**, **agent**, or\n  **alert** (they have no slug). Lose it and those resources orphan; recover a link\n  with `cargo-ai cdk import`. It records only `{hash, uuid, outputs}` — never secret\n  values. Git-ignore the working files (`cdk init` scaffolds this):\n  ```gitignore\n  .cargo-ai/\n  cargo.state.lock\n  cargo.state.bak.json\n  cargo.state.audit.jsonl\n  ```\n- **Secrets:** wire credentials with `secret(\"ENV_VAR\")` (often\n  `secret(\"HUBSPOT_API_KEY\")`). The value is read from the environment **at deploy\n  time**, kept out of the content hash and out of state, so rotating a token\n  doesn't read as drift. Export the env var before deploying — a missing one fails\n  the deploy with an unresolved `${ENV_VAR}` placeholder.\n- **Wire by handle, never by `.uuid`.** Pass a `define*` handle directly\n  (`dataset: hubspot`, `tools: [enrich]`), or `xxRef(\"uuid\")` for a resource you\n  didn't define in code (`connectorRef`, `modelRef`, `folderRef`, `toolRef`,\n  `agentRef`, …). Where a reference needs per-call options, wrap it as\n  `{ ref, …options }` (e.g. `models: [{ ref: contacts, readOnly: true }]`).\n- **Run `cargo-ai cdk types` after workspace integrations change** — it\n  regenerates `.cargo-ai/` so `defineConnector`/`defineModel` config (and\n  `integrations.*` in workflow bodies) type-check against the real schemas. Typing\n  is a bonus, never a gate: deploy works without it.\n- **Run `cdk` commands from the project root.** `npx`/`cargo-ai` resolve from the\n  nearest `package.json`; run elsewhere and `.cargo-ai/` and `cargo.state.json`\n  land in the wrong directory. Use `--dir <path>` to be explicit.\n- **`--yes` in CI.** `deploy` and `destroy` prompt for confirmation; non-interactive\n  runs must pass `--yes`.\n- **A `definePlay`/`defineTool` graph with paid nodes gets a sample run before it\n  goes wide.** Deploying is not running, but the first thing that runs a deployed\n  play is usually a batch over the whole segment — and a scheduled play re-bills\n  every node on every run. Before enrolling everything (or enabling a schedule),\n  run the deployed workflow on **10–20 records** — `cargo-ai orchestration batch\n  create --data '{\"kind\":\"filter\",\"modelUuid\":\"…\",\"filter\":…,\"limit\":15}'`, or\n  `batch create --file ./plays/x.ts` to test-run the module without deploying —\n  then ask the user to approve the full enrollment with the **record count** and\n  **credit estimate**. Read the provider's playbook\n  (`../cargo-gtm/provider-playbooks/<slug>.md`, esp. its *Recurring use* section)\n  and the gate in\n  [`../cargo-gtm/references/cost-discipline.md`](../cargo-gtm/references/cost-discipline.md).\n- **A `defineAlert` whose actions call paid nodes re-bills on every breach.** An\n  alert's `actions` fire as real runs, so a badly-sized `threshold` on a tight\n  `schedule` can breach — and bill — every tick. Size the threshold with\n  `cargo-ai observability alert preview` before deploying, prefer cheap notification\n  actions (an agent that posts, a connector notification) over anything that fans\n  out, and apply the same cost gate above when an action calls a credits-based\n  provider. Scope/threshold and firing semantics:\n  [`../cargo-observability/SKILL.md`](../cargo-observability/SKILL.md).\n- **`defineMailbox` bills monthly, and `defineDomain` rewrites a DNS zone.** A\n  mailbox is 100–160 credits *per month* for as long as it exists (`cargo-ai\n  mailboxManagement pricing get` for live figures), so a `+ create mailbox:…` line\n  in the plan is a recurring charge the user approves, not a one-off. Its `domain`,\n  `username` and `type` are **create-only** — changing any of them is destroy +\n  recreate, i.e. a brand-new inbox back at the bottom of a 45-day warm-up ramp. The\n  deploy polls `refreshStatus` for up to 5 minutes waiting for `active`. On\n  `defineDomain`, `dnsRecords` is the **whole zone, not a patch**: declaring it\n  replaces every live record (including the ones the registrar wrote at purchase),\n  and omitting it leaves the zone untouched. Use `adopt: true` for a domain or\n  mailbox bought in the UI. Ramp, suppression and sending:\n  [`../cargo-mailbox-management/SKILL.md`](../cargo-mailbox-management/SKILL.md).\n- **Route CDK-managed resources into a clearly-labelled folder.** Set `folder:` on\n  each builder so everything CDK owns lands in a dedicated folder whose name signals\n  \"owned by code — don't hand-edit\" to anyone in the UI (manual UI edits read back as\n  drift on the next `plan`). Folders are per-kind, so give each kind its own but share\n  one short, recognizable prefix — recommended: **`🔒 CDK`** (e.g. `🔒 CDK Models`,\n  `🔒 CDK Agents`). Keep names short (long labels truncate in the folder tree); the\n  lock emoji is the \"don't touch\" cue. See\n  [`guides/authoring-resources.md`](guides/authoring-resources.md).\n\n## Help\n\n- `cargo-ai cdk --help` and `cargo-ai cdk <subcommand> --help` for the live flag\n  surface.\n- When a documented command/flag/response doesn't match what you observe, file a\n  report: `cargo-ai workspaceManagement report create` (see\n  [`../cargo-workspace-management/SKILL.md`](../cargo-workspace-management/SKILL.md)).\n\nFile v1.2.4:_meta.json\n\n{\n  \"ownerId\": \"kn7by8t6yt9yghbxtxz6hv0bts87k6bq\",\n  \"slug\": \"cargo-cdk\",\n  \"version\": \"1.2.4\",\n  \"publishedAt\": 1789064239304\n}\n\nFile v1.2.4:references/commands.md\n\n# Command reference — `cargo-ai cdk`\n\nAll subcommands accept `--dir <path>` (the project root, default `.`) and `--json`\n(machine-readable output). Run from the project root so `.cargo-ai/` and\n`cargo.state.json` land in the right place. Confirm the surface live with\n`cargo-ai cdk <subcommand> --help`.\n\n| Command | What it does |\n|---|---|\n| `cargo-ai cdk init <directory>` | Scaffold a GTM repo from `getcargohq/cargo-manifest`, with the CDK project in `infra/`. `--name <name>`, `--cookbook <slug>` (install a cookbook into the new project), `--force` (write into a non-empty directory). There is no template flag: the scaffold never varies, and what varies is the cookbook layered on top. |\n| `cargo-ai cdk add cookbook/<slug>` | Copy a worked example into this project — `infra/<slug>/` plus its procedure under the skills directories. `--overwrite` (replace existing files; default skips them), `--yes`. Omit the address to choose interactively. |\n| `cargo-ai cdk add connector/<integration>` | Authorize a connector in the browser and write its `defineConnector`. `--connector-uuid <uuid>` adopts one already created there. |\n| `cargo-ai cdk cookbook list\\|search\\|view` | Browse the cookbooks `add` installs — `view <slug>` shows what one deploys, what it will ask you for, and its declared adaptations. |\n| `cargo-ai cdk types` | Generate per-workspace types into `.cargo-ai/` for typed config. |\n| `cargo-ai cdk plan` | Offline: compile the graph and diff against `cargo.state.json`. No API calls. |\n| `cargo-ai cdk deploy` | Create/update resources in dependency order; write state. Prompts unless `--yes`. |\n| `cargo-ai cdk refresh` | Read-only: report resources that drifted from code (changed/deleted out of band). |\n| `cargo-ai cdk import <id> <uuid>` | Bind an existing live resource (`kind:slug`) to a uuid in state. |\n| `cargo-ai cdk rollback` | Restore `cargo.state.json` from the pre-deploy snapshot. |\n| `cargo-ai cdk destroy` | Tear down resources recorded in state. `--target <id>` for one, `--all` for everything. |\n\n## Common flags\n\n- `--dir <path>` — project root (default `.`).\n- `--yes` — skip the confirmation prompt (**required in CI / non-interactive**).\n- `--json` — machine-readable output.\n- `--force` — steal a stale `cargo.state.lock`.\n\n## `deploy` modifiers\n\n- `cargo-ai cdk deploy --prune` — also **delete** resources that are in state but\n  removed from code (reverse dependency order; adopted resources are released, not\n  deleted).\n- `cargo-ai cdk deploy --refresh` — re-read live resources and re-apply your code\n  over any out-of-band changes.\n\n## `destroy` targets\n\n- `cargo-ai cdk destroy --target <kind:slug>` — remove one resource (refused if\n  other state resources still depend on it).\n- `cargo-ai cdk destroy --all` — remove everything in state, dependents first.\n\n## Examples\n\n```bash\ncargo-ai cdk init acme                        # scaffold\ncargo-ai cdk add cookbook/tam-building --dir acme  # layer a worked example on\ncargo-ai cdk types --dir acme                 # type config\ncargo-ai cdk plan --dir acme                  # preview\ncargo-ai cdk deploy --dir acme --yes          # apply (non-interactive)\ncargo-ai cdk refresh --dir acme               # drift report\ncargo-ai cdk import agent:sdr <uuid> --dir acme  # adopt a live agent\ncargo-ai cdk destroy --dir acme --all --yes   # tear down\n```\n\nFile v1.2.4:references/cookbooks.md\n\n<!-- Generated by .github/scripts/sync-cookbooks.ts from gtm-skills' catalog.json. Do not edit by hand. -->\n\n# Cookbooks: worked CDK examples, before you author one from scratch\n\nSkills in [`getcargohq/gtm-skills`](https://github.com/getcargohq/gtm-skills) that are cookbooks: worked CDK resources, the same\njobs as the one-off skills there, as a deployed pipeline that keeps producing the result.\n\n**Every folder is self-contained** (its own models, connectors and folders; no shared\nfoundation, no requires graph). `cdk add` copies one into the project; the agent then\nreconciles it with what is already declared (an existing accounts model, an existing CRM\nconnector), adapts it in place, plans, deploys on a yes, and walks its `Done when`. The\ncode is a worked example, not a template to fill in — and not something to regenerate\nfrom the skill's prose.\n\n```sh\ncargo-ai cdk add cookbook/<slug>              # inside a CDK project: this is the copy step\ncargo-ai cdk init <dir> --cookbook <slug>     # no project yet: scaffold and install together\nnpx skills add getcargohq/gtm-skills/<slug>   # the procedure on its own, without the CDK resources\n```\n\nAfter either `cdk` command the files are in `infra/<slug>/` and `.claude/skills/<slug>/`.\nStart the skill at its Adapt section: its earlier steps assume you found the folder in\ngtm-skills and still have to place it.\n\n## With a skill\n\n| Skill | Deploys | State |\n| --- | --- | --- |\n| `account-scoring` | Keep every account scored and tiered against your written ICP by a deployed agent that re-scores as accounts arrive and as the ICP changes, writing the rationale back to the CRM. | to-be-approved |\n| `crm-enrichment` | Keep CRM accounts filled and refresh them when they go stale: a deployed play that fills approved blank firmographics from LinkedIn and re-enrolls a record after six months. | to-be-approved |\n| `tam-building` | Stand up your account universe as a deployed pipeline: a Sales Navigator company search split past the 1,000 extraction cap, resolved to real domains, deduped into a shared accounts model. | to-be-approved |\n\n## When one does not fit as written\n\nDeclared adaptations, not forks. Reach for one before concluding a skill is the wrong start.\n\n**`account-scoring`**\n\n- `deterministic-scoring` — You need fixed cost and exact reproducibility, or an LLM judgement is not acceptable to your team. Costs: The criteria move out of the ICP markdown and into code, so they stop being reviewable by non-engineers, and you lose the rationale entirely.\n- `skip-crm-roundtrip` — You want the score on the model directly and do not need it visible in the CRM. Costs: Reps lose the score and rationale where they actually work. The native's input is untyped, so confirm the field shape on the first run.\n- `no-crm-at-all` — You have no CRM, or you do not want to hand this skill a CRM credential. Costs: Every other CRM-dependent skill you install later brings a CRM connector of its own; reuse one.\n\n**`crm-enrichment`**\n\n- `crm` — The consumer uses Salesforce or Attio instead of HubSpot. Costs: Live generated types must be rechecked; a guessed flag writes or no-ops silently.\n- `selected_fields` — The approved contract differs from the starting recommendation. Costs: Each added field expands mapping, type-review, and the \"already filled\" filter.\n- `eligibility` — Only a governed subset should be enriched. Costs: Narrower scope reduces coverage and paid calls.\n- `approved_refresh_behavior` — Populated fields must be refreshed after explicit approval. Costs: Refresh can overwrite CRM-authoritative values if the preview and the write disagree.\n\n**`tam-building`**\n\n- `non-linkedin-source` — You do not want to source from LinkedIn at all, or Sales Nav does not cover your market. Costs: You lose the Sales Nav facet taxonomy that makes the split tactic mechanical, and the splitting has to be redesigned around the new source's own limits.\n- `land-without-promoting` — You want to see and filter the raw market before paying to enrich it. Costs: Nothing reaches `accounts`, so no downstream skill (scoring, contact sourcing, signals) has anything to work with until you promote.\n- `sample-first` — The market search is large and you want to see the cost curve before committing. Costs: Your TAM is deliberately incomplete until you widen it, so do not score or report on coverage from a sample.\n\n## Routing\n\n**One-off versus standing is the whole test.** A user who wants a list today wants a one-off\nskill (or `cargo-gtm`, when this pack is installed); a user who wants a pipeline that keeps\nproducing it wants one of these. The same words describe both, so listen for whether the\nresult is meant to keep arriving.\n\n**Never `cargo-ai cdk init --force` into a directory that is not empty.** It replaces the\nproject's `package.json` and reverts adapted code while `cargo.state.json` survives, so the\nnext plan diffs a live workspace against code nobody wrote. Run `cdk add cookbook/<slug>`\nin the project that is already there; it skips every file it would otherwise overwrite.\n\nFile v1.2.4:references/examples/full-workspace.md\n\n# Example: a full GTM workspace end-to-end\n\nThis walks a complete, runnable Cargo workspace defined in code that exercises\nevery resource type and wires them by **handle**. It is a reading example, not\nsomething a command scaffolds: `cargo-ai cdk init` produces one repo shape, and a\nworked pipeline comes from `cargo-ai cdk add cookbook/<slug>`.\n\n## The graph\n\n```\nhubspot (connector) ──dataset──▶ contacts (model) ──model──────────┬─▶ onboarding (play)\n                                                                    ├─▶ sdr (agent)\nopenai (connector) ──connector──▶ enricher (agent) ──subAgent──▶ sdr│\n                    └────────connector──────────────────▶ sdr ─────┘\nenrich (tool, backed by a workflow) ─┐\nsdr (agent) ─────────────────────────┼─▶ crm (mcpServer)\ncontacts (model) ────────────────────┘\nplaybook (file)   webhook (worker)   dashboard (app)   context (repo)\n```\n\n## Project layout\n\n```\nmy-workspace/\n  package.json            # depends on @cargo-ai/cdk + zod\n  tsconfig.json           # include: [\"**/*.ts\", \".cargo-ai/**/*.d.ts\"]\n  .gitignore              # .cargo-ai/, cargo.state.lock, cargo.state.bak.json, cargo.state.audit.jsonl\n  connectors/hubspot.ts   # defineConnector + secret()\n  connectors/openai.ts    # defineConnector adopt: true\n  folders/crm.ts          # defineFolder (per-kind)\n  models/contacts.ts      # defineModel dataset: hubspot\n  tools/enrich.ts         # defineWorkflow + defineTool\n  agents/enricher.ts      # defineAgent (sub-agent)\n  agents/sdr.ts           # defineAgent (model + tool + sub-agent + trigger + evaluator)\n  plays/onboarding.ts     # definePlay + defineWorkflow\n  mcp/crm.ts              # defineMcpServer\n  context/context.ts      # defineContext dir: \"context\" (+ context/*.md)\n  files/playbook.ts       # defineFile (+ playbook.md)\n  workers/webhook.ts      # defineWorker (+ webhook/ built bundle)\n  apps/dashboard.ts       # defineApp (+ dashboard/ Vite app)\n```\n\nImporting a `.ts` file **is** registration — there is no manifest. The loader\nimports every `.ts` under the project (skipping the worker/app bundle sub-dirs,\nwhich have their own `package.json`), and each `define*` registers as a side\neffect.\n\n## A wired slice\n\n```ts\n// connectors/hubspot.ts\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\n\n// models/contacts.ts\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot,                       // handle → connector deployed first, dataset injected\n  extractSlug: \"fetchRecords\",\n  config: { objectType: \"contacts\", columnSelectionMode: \"all\" },\n  folder: modelsFolder,\n  schedule: { type: \"cron\", cron: \"0 * * * *\" },\n});\n\n// agents/sdr.ts\nexport const sdr = defineAgent(\"sdr\", {\n  connector: openai,\n  languageModel: \"gpt-4o\",\n  systemPrompt: \"You qualify inbound leads and route hot ones to Slack.\",\n  models: [{ ref: contacts, readOnly: true }],\n  tools: [enrich],\n  subAgents: [{ ref: enricher, waitUntilFinished: true }],\n  folder: agentsFolder,\n});\n```\n\n## Deploy walkthrough\n\n```bash\ncd my-workspace && npm install\n\ncargo-ai login                 # authenticate + select the workspace\ncargo-ai cdk types             # type defineConnector/defineModel config against this workspace\nexport HUBSPOT_API_KEY=...      # matches secret(\"HUBSPOT_API_KEY\")\n\ncargo-ai cdk plan\n# → lists every resource as create / update / no-op, in dependency order:\n#   create connector:hubspot, create connector:open_ai (adopt), create folder:crm-models, …\n\ncargo-ai cdk deploy\n# → creates each in order, writing cargo.state.json after each resource.\n#   Workers/apps build server-side (slower). Live URLs appear as webhook.url / dashboard.url.\n\ngit add cargo.state.json && git commit -m \"Deploy full workspace\"\n```\n\nRe-run `cargo-ai cdk deploy` after editing a file — only the changed resource is\napplied. Tear it all down with `cargo-ai cdk destroy --all`.\n\nSecrets referenced with `secret(\"HUBSPOT_API_KEY\")` resolve from the environment at\ndeploy time and stay out of the content hash — only `{hash, uuid, outputs}` land in\n`cargo.state.json`, never secret values.\n\nFile v1.2.4:references/resources.md\n\n# Resource reference\n\nEvery builder is imported from `@cargo-ai/cdk`, takes `(slug, spec)` (except\n`defineContext`, which takes only a spec — it's a workspace singleton), and returns\na **handle** carrying deferred output tokens (`uuid`, and for connectors\n`datasetUuid`; for workers/apps `url`). Wire resources by passing a handle where a\nreference is expected; use `xxRef(\"uuid\")` for a resource not defined in code.\n\nThe tables below list the **commonly used** spec fields — the TypeScript types on\neach builder are the source of truth for the complete set. Fields that take a\n**ref** accept a handle or an `xxRef` (and `{ ref, …options }` when they carry\nper-call options).\n\n## Builders\n\n| Builder | Purpose | Key spec fields | Ref fields | Outputs |\n|---|---|---|---|---|\n| `defineConnector(slug, spec)` | Data source or LLM provider | `integration`, `config` (typed per integration), `adopt?`, `rateLimit?`, `cacheTtlMilliseconds?` | — | `uuid`, `datasetUuid` (data connectors) |\n| `defineModel(slug, spec)` | Table sourced from a connector's dataset | `dataset`, `extractSlug`, `config`, `schedule?`, `folder?` | `dataset` (connector/dataset), `folder` | `uuid` |\n| `defineTool(slug, spec)` | Tool backed by a workflow | `workflow`, `description?`, `emojiSlug?`, `triggers?`, `folder?` | `folder` | `uuid` |\n| `definePlay(slug, spec)` | Per-row automation over a model | `model`, `workflow`, `changeKinds`, `runCreationRule`, `schedule`, `folder?` | `model`, `folder` | `uuid` |\n| `defineAgent(slug, spec)` | AI agent | `connector`, `languageModel`, `systemPrompt`, `models?`, `tools?`, `subAgents?`, `connectorActions?`, `capabilities?`, `maxSteps?`, `triggers?`, `evaluator?`, `color?`, `folder?` | `connector`, `models`, `tools`, `subAgents`, `folder` | `uuid` |\n| `defineMcpServer(slug, spec)` | MCP endpoint bundling resources | `description?`, `tools?`, `agents?`, `models?`, `folder?` | `tools`, `agents`, `models`, `folder` | `uuid` |\n| `defineFolder(slug, spec)` | Per-kind folder | `kind`, `name`, `parent?` | `parent` | `uuid` |\n| `defineFile(slug, spec)` | Content file from a local path | `path`, `name`, `folder?` | `folder` | `uuid` |\n| `defineContext(spec)` | Workspace context repo (singleton) | `dir?`, `files?` | — | `uuid` |\n| `defineSegment(slug, spec)` | Saved view over a model | `model` (immutable), `filter` (required) | `model` | `uuid` |\n| `defineCapacity(slug, spec)` | Revenue-org capacity | `model`, `color?`, `description?`, member capacity fields | `model`, members | `uuid` |\n| `defineTerritory(slug, spec)` | Revenue-org territory | `model`, `members`, `color?`, `description?`, `fallbackMember?` | `model`, `members` | `uuid` |\n| `defineWorker(slug, spec)` | Hosted worker (built bundle) | `path`, `description?`, `folder?` | `folder` | `uuid`, `url` |\n| `defineApp(slug, spec)` | Hosted Vite SPA | `path`, `description?`, `folder?` | `folder` | `uuid`, `url` |\n| `defineDomain(name, spec)` | Sending domain + its DNS zone | `adopt?`, `dnsRecords?` (**replaces the whole zone**) | — | `uuid` |\n| `defineMailbox(slug, spec)` | Sending inbox on a domain (**monthly credit charge**) | `domain`, `type` (`google`/`shared`/`private` — no `outlook`), `username?` (defaults to slug), `firstName`, `lastName`, `signature?`, `folder?`, `adopt?` | `domain`, `folder` | `uuid` |\n| `defineAlert(slug, spec)` | Scheduled threshold alert (observability) | `schedule`, `scope`, `threshold`, `actions`, `name?`, `description?`, `enabled?`, `folder?` | scope: `workflow`/`connector`/`tool`/`agent`/`model`; each action's `ref`; `folder` | `uuid` |\n\n`defineWorkflow(slug, { input, output, uses? }, build)` is re-exported from\n`@cargo-ai/cdk` for `defineTool`/`definePlay` bodies — see\n[`../guides/authoring-resources.md`](../guides/authoring-resources.md).\n\n## Ref helpers\n\nFrom `@cargo-ai/cdk`: `connectorRef`, `datasetRef`, `modelRef`, `folderRef`,\n`playRef`, `memberRef`. From the workflow SDK (re-exported): `toolRef`, `agentRef`.\nEach takes a uuid string and returns a kind-branded handle:\n\n```ts\nimport { defineModel, connectorRef, folderRef } from \"@cargo-ai/cdk\";\n\nexport const leads = defineModel(\"leads\", {\n  dataset: connectorRef(\"6f0c…\"),   // existing connector, by uuid\n  extractSlug: \"fetchRecords\",\n  folder: folderRef(\"a1b2…\"),\n});\n```\n\n## Notes on specific fields\n\n- **`defineConnector` `config`** is a per-integration shape — a discriminated union\n  for auth (e.g. HubSpot `method: \"privateApp\" | \"oauth\"`). `secret()` is accepted\n  only on credential/encryption fields. Run `cargo-ai cdk types` to type it (see\n  [`../guides/typed-config.md`](../guides/typed-config.md)).\n- **`adopt: true`** on `defineConnector` links an existing authenticated connector\n  by slug instead of creating one — for OAuth/key connectors you can't declare.\n- **`defineModel` `dataset`** takes the **connector** handle (its dataset uuid is\n  injected) or a `datasetRef`/`connectorRef`.\n- **`schedule`** shapes: `{ type: \"cron\", cron: \"0 * * * *\" }` or\n  `{ type: \"watch\" }` (plays react to row changes).\n- **`definePlay` `changeKinds`**: `[\"added\", \"updated\", …]`; `runCreationRule`:\n  e.g. `\"always\"`.\n- **`defineFile` `path`** and **`defineWorker`/`defineApp` `path`** point at local\n  files/dirs, typically via `new URL(\"./x\", import.meta.url).pathname`. File content\n  is hashed at define time, so edits show as drift. Worker `path` must be a **built**\n  bundle dir (`index.js` + `manifest.json` + `package.json` + `package-lock.json`).\n- **`defineAlert` `scope` + `threshold`** are a **matched pair** — TS narrows the\n  threshold menu by `scope.kind`: `spans`/`runs`/`records` take the telemetry metrics\n  (`errorRate`, `duration`+`aggregation`, `credits`+`aggregation`, `count`), `model`\n  takes `recordsCount`/`recordsShare`/`freshness`/`syncDuration`, and\n  `orchestrationQuery`/`storageQuery` take `{ operator, value }` (the query computes\n  the value, so no metric). The scope wires the watched resource **by handle**\n  (`workflow:` a `definePlay`/`defineTool` handle or `workflowRef`, plus `connector`/\n  `tool`/`agent`/`model`), so the reconciler deploys the producer first and injects\n  its uuid.\n- **`defineAlert` `actions`** fire as runs on breach. Each is a `{ ref, config }`\n  wrapper (`config` required — an alert fires unattended, so a missing input is a type\n  error, not a silent `{}`). Prefer the typed helpers `alertConnectorAction({ ref:\n  slack.actions.postMessage, config })` / `alertToolAction({ ref: enrich, config })` —\n  `config` is checked against the action/tool input schema (connector schemas need\n  `cargo-ai cdk types` to have run) — or a bare `{ ref: agent, config, release?,\n  waitUntilFinished? }`. Every `config` leaf accepts a `{{ … }}` template\n  (`{{event.value}}`, `{{alert.name}}`, `{{alert.url}}`, …) interpolated against the\n  firing context. Like a play, an alert has **no author-set wire slug** — its identity\n  on redeploy is the state uuid, so committing `cargo.state.json` is what keeps it\n  addressable. Scope/threshold matrix, metric units, and firing semantics:\n  [`../../cargo-observability/SKILL.md`](../../cargo-observability/SKILL.md).\n\nFile v1.2.4:references/troubleshooting.md\n\n# Troubleshooting\n\n## `✗ Deploy failed: connector:<slug>: Invalid configuration`\n\nThe connector's `config` doesn't match the integration's schema. Most often the\ncredential wasn't wrapped in `secret()` — a data connector's credential field\nexpects an encryption envelope, and `secret(\"ENV_VAR\")` produces it. Fix:\n\n```ts\nconfig: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") }, // not a bare string\n```\n\nRun `cargo-ai cdk types` so the config type-checks against the real schema at\nauthor time and surfaces the required shape (see\n[`../guides/typed-config.md`](../guides/typed-config.md)). The deploy error now also\nsurfaces the API's structured detail (which field, the reason) — read past the\nterse \"Invalid configuration\" summary.\n\n## `unresolved placeholder \"${NAME}\"`\n\nA `secret(\"NAME\")` or `env(\"NAME\")` had no matching environment variable at deploy.\nThe CDK refuses to send a literal `${NAME}` to the API. Export it first:\n\n```bash\nexport NAME=...\ncargo-ai cdk deploy\n```\n\n## Deploy refuses: workspace mismatch\n\n`cargo.state.json` records the workspace it was deployed to; `deploy`/`destroy`\nrefuse when that ≠ the currently selected workspace (a guard against reconciling a\ndev definition into prod). Select the right workspace at `login`, or use a separate\nstate file per environment.\n\n## `.cargo-ai/` or `cargo.state.json` landed in the wrong directory\n\n`npx`/`cargo-ai` resolve from the **nearest `package.json`**, not your shell's cwd.\nRun `cdk` commands from the project root, or pass `--dir <project-root>` explicitly.\n\n## `integrations.<slug>` is `any` / not callable, or `config` isn't type-checked\n\nTypes aren't generated or aren't wired in. Run `cargo-ai cdk types`, ensure\n`tsconfig.json` `include` has the explicit glob `\".cargo-ai/**/*.d.ts\"` (a bare\n`.cargo-ai` dot-dir is ignored by TypeScript), and `import \"./.cargo-ai/cargo-register.js\";`\nat the top of workflow modules that use `integrations.*`. Re-run `cdk types` after\nchanging workspace integrations.\n\n## `could not parse the workflow body`\n\nA `defineWorkflow` body must be a supported JS subset — it's **parsed, not\nexecuted**. Remove `await`, `throw`, `try/catch`, closures over outer variables,\nand destructuring; compile workflow files with a modern target (ES2022+) and don't\ninstrument them with coverage tools (they rewrite the function source). Use\n`js(({ nodes }) => …)` for logic outside the supported subset.\n\n## Deploy is slow / seems to hang on a worker or app\n\nWorkers and apps **build server-side** — the reconciler uploads the bundle, waits\nfor the build, and promotes. This is expected to take longer than other resources.\nEnsure the worker bundle dir has a built `index.js` (+ `manifest.json`,\n`package.json`, `package-lock.json`) before deploying.\n\n## A play or agent got orphaned (state lost)\n\nPlays and agents have no slug, so `cargo.state.json` is the only link to them.\n**Commit the state file.** If it's lost, find the live uuid via the matching\ncapability skill and rebind: `cargo-ai cdk import agent:<slug> <uuid>`. Never\ndelete `cargo.state.json` to \"start clean\" — you'll orphan every play/agent it\ntracked.\n\n## `plan` shows `create` for a resource that already exists\n\nIts `kind:slug` id didn't match state. Either the slug in the `define*` changed, or\nyou migrated a workspace without importing — bind it: `cargo-ai cdk import <kind:slug> <uuid>`\n(see [`../recipes/migrate-existing-workspace.md`](../recipes/migrate-existing-workspace.md)).\n\n## Still stuck\n\nFile a report so the Cargo team sees it:\n`cargo-ai workspaceManagement report create --title \"<summary>\" --description \"<commands tried, errorMessage, expected vs actual>\"`\n— see [`../../cargo-workspace-management/SKILL.md`](../../cargo-workspace-management/SKILL.md).\n\nFile v1.2.4:guides/authoring-resources.md\n\n# Authoring resources\n\nEvery Cargo resource has a `define*` builder imported from `@cargo-ai/cdk`. Each\nreturns a **handle**; you wire resources together by passing one handle into\nanother builder. **Importing a `.ts` file is registration** — each `define*` call\nregisters itself as a side effect, so there is no manifest to maintain. The loader\nimports every `.ts` under the project directory (skipping worker/app bundle\nsub-directories, which have their own `package.json`).\n\nFor the exact spec fields and outputs of each builder, see\n[`../references/resources.md`](../references/resources.md).\n\n## The handle / ref model (the one thing to internalize)\n\nPass the **handle** a builder returned — never `handle.uuid`:\n\n```ts\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot, // ← the connector handle, not hubspot.datasetUuid\n});\n```\n\nThe CDK reads the dependency (connector → model), deploys the connector first, and\ninjects its real dataset uuid at deploy time. Your variable graph *is* the\ndependency graph.\n\nFor a resource you did **not** define in code (an existing connector, folder,\netc.), use a `xxRef(\"uuid\")` helper — it produces the same handle shape from a\nliteral uuid:\n\n```ts\nimport { defineModel, connectorRef } from \"@cargo-ai/cdk\";\n\nexport const leads = defineModel(\"leads\", {\n  dataset: connectorRef(\"6f0c…\"), // an already-authenticated connector, by uuid\n});\n```\n\nRef helpers: `connectorRef`, `datasetRef`, `modelRef`, `folderRef`, `playRef`,\n`memberRef` (from `@cargo-ai/cdk`) and `toolRef`, `agentRef` (re-exported from the\nworkflow SDK). Each is branded by kind, so a model can't be passed where a\nconnector is expected.\n\n**Per-call options:** where a reference takes options, wrap it as\n`{ ref, …options }`:\n\n```ts\nmodels: [{ ref: contacts, readOnly: true }],   // handle + options\nsubAgents: [{ ref: enricher, waitUntilFinished: true }],\ntools: [enrich],                               // bare handle when no options\n```\n\n## Secrets — `secret()` + `env()`\n\nWire credentials with `secret(\"ENV_VAR\")`. The value is read from the environment\n**at deploy time**, kept out of the content hash and out of `cargo.state.json`, so\nrotating the token never reads as drift:\n\n```ts\nimport { defineConnector, secret } from \"@cargo-ai/cdk\";\n\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\n```\n\n`secret()` is only accepted where a credential/encryption field is expected. Use\n`env(\"NAME\")` for non-secret config values that come from the environment. Export\nthe variables before deploying — a missing one fails deploy with an unresolved\n`${NAME}` placeholder rather than sending a literal to the API.\n\n## The builder catalog\n\nData & schema:\n\n```ts\n// Connector — a data source or LLM provider. Creating a data connector\n// auto-creates a dataset that models source from. OAuth connectors that can't be\n// declared in code use `adopt: true` to link the existing authenticated instance.\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\nexport const openai = defineConnector(\"open_ai\", { integration: \"openAi\", adopt: true });\n\n// Model — a table sourced from a connector's dataset by an extractor.\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot,                 // connector handle → its dataset is injected\n  extractSlug: \"fetchRecords\",\n  config: { objectType: \"contacts\", columnSelectionMode: \"all\" },\n  folder: modelsFolder,\n  schedule: { type: \"cron\", cron: \"0 * * * *\" },\n});\n```\n\nAutomation:\n\n```ts\n// Tool — backed by a workflow. defineWorkflow compiles the logic; defineTool\n// creates the tool and deploys that workflow as its release.\nconst enrichFlow = defineWorkflow(\n  \"enrich-contact\",\n  { input: z.object({ email: z.string() }), output: z.object({ company: z.string() }), uses: { enricher } },\n  ({ input, uses }) => ({ company: uses.enricher({ prompt: `Company for ${input.email}?` }) }),\n);\nexport const enrich = defineTool(\"enrich\", { workflow: enrichFlow, emojiSlug: \"mag\" });\n\n// Play — runs a per-row workflow as a data model's rows change.\nexport const onboarding = definePlay(\"onboarding\", {\n  model: contacts,\n  workflow: onboardRow,\n  changeKinds: [\"added\", \"updated\"],\n  runCreationRule: \"always\",\n  schedule: { type: \"watch\" },\n});\n\n// Agent — references models, tools, sub-agents, connector actions, and the LLM\n// connector, each by handle.\nexport const sdr = defineAgent(\"sdr\", {\n  connector: openai,\n  languageModel: \"gpt-4o\",\n  systemPrompt: \"Qualify inbound leads.\",\n  models: [{ ref: contacts, readOnly: true }],\n  tools: [enrich],\n  subAgents: [{ ref: enricher, waitUntilFinished: true }],\n  connectorActions: [{ integration: \"hunter\", actionSlug: \"emailFinder\" }],\n  folder: agentsFolder,\n});\n\n// MCP server — bundles tools, agents, and models behind one MCP endpoint.\nexport const crm = defineMcpServer(\"crm\", { tools: [enrich], agents: [sdr], models: [{ ref: contacts }] });\n```\n\nOrganization & knowledge:\n\n```ts\n// Folder — per-kind (a \"model\" folder and an \"agent\" folder are separate).\nexport const modelsFolder = defineFolder(\"crm-models\", { kind: \"model\", name: \"CRM\" });\n\n// RECOMMENDED: route every CDK-managed resource into a dedicated, clearly\n// labelled folder (via each builder's `folder:`), so a human in the UI sees at a\n// glance that these resources are owned by code and shouldn't be hand-edited —\n// manual UI changes read back as drift on the next `plan`. Because folders are\n// per-kind, give each kind its own but share ONE short, recognizable prefix, e.g.\n// `🔒 CDK` (or `🔒 CDK Models`, `🔒 CDK Agents`). Keep names short — long labels\n// truncate in the folder tree; the lock emoji is the \"don't touch\" cue.\nexport const cdkModels = defineFolder(\"cdk-models\", { kind: \"model\", name: \"🔒 CDK Models\" });\nexport const cdkAgents = defineFolder(\"cdk-agents\", { kind: \"agent\", name: \"🔒 CDK Agents\" });\n\n// File — content uploaded from a local path (hashed at define time, so edits show as drift).\nexport const playbook = defineFile(\"playbook\", {\n  path: new URL(\"./playbook.md\", import.meta.url).pathname,\n  name: \"SDR Playbook\",\n});\n\n// Context — the workspace's git-backed GTM knowledge base as code. Singleton;\n// additive (files added in the UI are left in place).\nexport const context = defineContext({ dir: \"context\" });\n```\n\nRevenue org & segmentation:\n\n```ts\n// Segment — a saved view over a model (filter is required; model is immutable).\nexport const hotLeads = defineSegment(\"hot-leads\", { model: contacts, filter: { /* … */ } });\n\n// Capacity / Territory — revenue-org planning over members and a model.\nexport const capacity = defineCapacity(\"ae-capacity\", { model: contacts, /* … */ });\nexport const territory = defineTerritory(\"west\", { model: contacts, members: [memberRef(\"…\")] });\n```\n\nHosting (async builds — see [`deploy-and-state.md`](deploy-and-state.md)):\n\n```ts\n// Worker — the hosted worker slot. `path` points at a BUILT bundle dir\n// (index.js + manifest.json + package.json + package-lock.json). Author the\n// runtime code with createWorker from @cargo-ai/worker-sdk and build to index.js.\nexport const webhook = defineWorker(\"webhook\", {\n  path: new URL(\"./webhook\", import.meta.url).pathname,\n  description: \"Receives inbound lead webhooks.\",\n});\n\n// App — a hosted Vite SPA. `path` points at the app package root.\nexport const dashboard = defineApp(\"dashboard\", {\n  path: new URL(\"./dashboard\", import.meta.url).pathname,\n});\n```\n\nObservability:\n\n```ts\n// Alert — a scheduled threshold check; fires actions as runs on breach. The\n// scope wires the watched resource by handle, and scope + threshold are a\n// matched pair (TS narrows the metric menu to the scope's kind).\nexport const syncErrors = defineAlert(\"crm-sync-errors\", {\n  schedule: { type: \"cron\", cron: \"*/30 * * * *\" },\n  scope: { kind: \"runs\", workflow: onboarding },   // the definePlay handle\n  threshold: { metric: \"errorRate\", operator: \"gte\", value: 10 },\n  actions: [\n    // Bare { ref, config } for an agent; config is templated against the firing\n    // context. Typed connector/tool actions use the alertConnectorAction /\n    // alertToolAction helpers (config checked against the action's input schema).\n    { ref: sdr, config: { message: \"CRM sync error rate at {{event.value}}% — {{alert.url}}\" } },\n  ],\n});\n```\n\n`defineAlert` is the declarative front for the observability domain — the full\nscope/threshold matrix, metric units, and firing semantics live in\n[`../../cargo-observability/SKILL.md`](../../cargo-observability/SKILL.md).\n\nThe full `full` template wires all of the above together end-to-end — see\n[`../references/examples/full-workspace.md`](../references/examples/full-workspace.md).\n\n## Workflow bodies (`defineWorkflow`) — parsed, not executed\n\n`defineTool` and `definePlay` take a `workflow:` built with `defineWorkflow`. The\nbody callback is **parsed, not executed** — the SDK reads the function's source\nand lowers it into the engine's node graph. So the body must be a supported JS\nsubset (no `await`, `throw`, `try/catch`, closures, or destructuring).\n\n```ts\ndefineWorkflow(\n  \"onboard-contact\",\n  {\n    input: z.object({ email: z.string() }),\n    output: z.object({ welcomed: z.boolean(), message: z.string() }),\n    uses: { enrich }, // reference tools/agents by handle here (or toolRef/agentRef)\n  },\n  ({ input, uses, ai, integrations, native }) => {\n    const enriched = uses.enrich({ email: input.email }); // typed to the tool's I/O\n    const message = ai(`Welcome ${input.email} at ${enriched.company}.`);\n    return { welcomed: true, message };\n  },\n);\n```\n\n- **`uses.<key>(input)`** calls a referenced tool/agent; it's typed to that\n  resource's input and returns a `Ref` you can dot-access (`enriched.company`).\n- **`integrations.<slug>.<action>({…})`** calls a connector action. The\n  `integrations` registry is **empty until you run `cargo-ai cdk types`** (see\n  [`typed-config.md`](typed-config.md)); `native.*` works without a sync.\n- Control flow lowers idiomatically: `if/else` → branch, `else if` → switch,\n  `for (const x of xs)` → group. `ai(\"…\")` inline-completes; `js(({nodes}) => …)`\n  is the escape hatch for logic outside the supported subset — it runs as a\n  script node, so `require()` is limited to `axios`, `cheerio`, `crypto-js`,\n  `date-fns`, `jsonschema`, `lodash`, `url`, `uuid`, and `zod`. Flow helpers:\n  `balance`, `split`, `humanReview`, `memory`.\n\nFor the full workflow-authoring surface (per-call retry/fallback, the supported-JS\ntable, toolchain requirements), that lives in the `@cargo-ai/workflow-sdk` docs —\n`defineWorkflow` is re-exported from `@cargo-ai/cdk`, so you import it from the one\npackage.\n\nFile v1.2.4:guides/deploy-and-state.md\n\n# Deploy & state\n\nThe deploy engine compiles your `define*` graph, diffs it against\n`cargo.state.json`, and reconciles the difference to live Cargo infrastructure in\ndependency order — persisting state after **each** resource so a mid-deploy crash\nleaves a recoverable file.\n\nFor every flag, see [`../references/commands.md`](../references/commands.md).\n\n## plan → deploy → destroy\n\n```bash\n# Offline: compile the graph and diff against cargo.state.json. No API calls.\ncargo-ai cdk plan --dir my-workspace\n\n# Create/update resources in dependency order; write cargo.state.json.\ncargo-ai cdk deploy --dir my-workspace          # prompts for confirmation\ncargo-ai cdk deploy --dir my-workspace --yes    # non-interactive (CI)\n\n# Tear down.\ncargo-ai cdk destroy --dir my-workspace --target model:contacts   # one resource\ncargo-ai cdk destroy --dir my-workspace --all                     # everything in state\n```\n\nRe-running `deploy` only changes what changed — an unchanged workspace is a no-op.\n`deploy` is idempotent: for each resource it updates by uuid if state has one,\notherwise adopts a slug-addressable match (connector/model) that already exists,\notherwise creates.\n\n## `cargo.state.json` — commit it\n\n`deploy` writes `cargo.state.json`: the link from your code to the resources Cargo\ncreated. It records only `{hash, uuid, outputs}` per resource — **never secret\nvalues**.\n\n**Commit it.** It is the *only* handle on a deployed **play** or **agent**, which\nhave no slug (unlike connectors and models, which self-heal by slug). Losing state\norphans those resources. If it happens, re-establish a link with `import` (below).\n\nGit-ignore the generated types and the CDK's working files (but **not**\n`cargo.state.json`). `cargo-ai cdk init` scaffolds this:\n\n```gitignore\n.cargo-ai/\ncargo.state.lock\ncargo.state.bak.json\ncargo.state.audit.jsonl\n```\n\nThe `cargo.state.lock` prevents two deploys racing; `--force` steals a stale lock.\n\n**Workspace guard:** state records the workspace it was deployed to; the CDK\nrefuses to `deploy`/`destroy` when the state's workspace ≠ the currently selected\nworkspace, so you can't accidentally reconcile a dev definition into prod. Select\nthe right workspace at `login` (or with the workspace flag) before deploying.\n\n## Prune — deleting resources removed from code\n\n`deploy` does **not** delete a resource just because you removed it from code —\nthat would make a typo destructive. To also remove resources that are in state but\nno longer in code:\n\n```bash\ncargo-ai cdk deploy --dir my-workspace --prune\n```\n\nPrune deletes in reverse dependency order (dependents before their dependencies).\nAdopted resources (linked via `adopt: true` or `import`) are **released** from\nstate, not deleted.\n\n## Drift — `refresh` and `deploy --refresh`\n\nA resource can change outside the CDK (someone edits an agent in the Cargo UI).\nThe CDK captures a fingerprint of each resource at deploy and compares on refresh:\n\n```bash\ncargo-ai cdk refresh --dir my-workspace          # read-only: report what drifted\ncargo-ai cdk deploy  --dir my-workspace --refresh # re-read live, re-apply your code over drift\n```\n\n`refresh` reports resources changed or deleted out-of-band; `deploy --refresh`\nmakes your code the source of truth again.\n\n## Adopting existing resources — `import`\n\nTo bring an already-live resource under CDK management, bind it into state by\nmapping its **code id** to its **live uuid**:\n\n```bash\ncargo-ai cdk import model:contacts 6f0c8e2a-… --dir my-workspace\n```\n\nThe code id is `kind:slug` (e.g. `connector:hubspot`, `model:contacts`,\n`agent:sdr`). After import, `deploy` updates that resource instead of creating a\nduplicate. Slug-addressable kinds (connector, model) can also self-adopt on deploy\nby matching slug; uuid-only kinds (play, agent, capacity, territory, segment) need\n`import` to recover a lost link. See\n[`../recipes/migrate-existing-workspace.md`](../recipes/migrate-existing-workspace.md).\n\n## Recovery — `rollback`\n\n`deploy` snapshots the pre-deploy state to `cargo.state.bak.json`. If a deploy went\nwrong, restore the snapshot:\n\n```bash\ncargo-ai cdk rollback --dir my-workspace\n```\n\nThis restores the state file — it does not undo live API changes already made;\nfollow with a corrected `deploy`.\n\n## Async resources — workers & apps\n\nMost resources create synchronously. **Workers and apps build server-side**: on\ndeploy the reconciler uploads the bundle, waits for the build, and promotes it —\nso a deploy touching a worker/app takes longer. Author worker runtime code with\n`createWorker` (`@cargo-ai/worker-sdk`) and build to `index.js` before deploying;\nthe CDK validates the bundle files (`index.js`, `manifest.json`, `package.json`,\n`package-lock.json`) exist at define time. The live URL is exposed on the handle\n(`webhook.url`, `dashboard.url`). For imperative one-off hosting operations, see\n[`../../cargo-hosting/SKILL.md`](../../cargo-hosting/SKILL.md).\n\nFile v1.2.4:guides/typed-config.md\n\n# Typed config — `cargo-ai cdk types`\n\n`defineConnector`/`defineModel` config and the `integrations.*` registry in\nworkflow bodies are typed against **your workspace's real integration schemas**.\nThose types aren't bundled (they're workspace-specific) — you generate them:\n\n```bash\ncargo-ai cdk types --dir my-workspace\n```\n\nTyping is a **bonus, never a gate**: an integration you haven't synced (or a\ncustom one) falls back to a loose `Record<string, unknown>`, so `deploy` works\nwithout ever running `cdk types`.\n\n## What it generates\n\nEverything lands in `.cargo-ai/` (git-ignored):\n\n- **`.cargo-ai/cargo-types.d.ts`** — `declare module` augmentations:\n  - types `@cargo-ai/cdk`'s `defineConnector`/`defineModel` `config` against your\n    connector and extractor schemas. E.g. HubSpot's config becomes a discriminated\n    union — the editor completes `method` and requires the matching credential,\n    and `secret()` is accepted wherever a credential is expected.\n  - adds your workspace's integration slugs to the `Integrations` interface, so\n    `integrations.<slug>.<action>({ … })` in a workflow body typechecks against the\n    real action schema.\n- **`.cargo-ai/cargo-register.ts`** — eager `registerIntegration` /\n  `registerNative` calls so those slugs are **callable at runtime** in workflow\n  bodies.\n\nRe-run `cargo-ai cdk types` whenever your workspace's integrations change (added a\nconnector, changed an extractor).\n\n## Wiring it into your project\n\n`cdk init` sets this up; for a hand-rolled project, two steps:\n\n1. **Add the glob to `tsconfig.json` `include`.** A bare `.cargo-ai` (a dot-dir) is\n   ignored by TypeScript — you must use an explicit glob:\n\n   ```jsonc\n   // tsconfig.json\n   \"include\": [\"**/*.ts\", \".cargo-ai/**/*.d.ts\"]\n   ```\n\n2. **Import the runtime registrations** at the top of workflow modules that use\n   `integrations.*`:\n\n   ```ts\n   import \"./.cargo-ai/cargo-register.js\";\n   ```\n\n   (`native.*` needs no registration — the platform's native actions are identical\n   in every workspace, so their types ship with the SDK. Tools and agents are not a\n   registry either — reference them by handle through `defineWorkflow`'s `uses`.)\n\n## Symptoms that mean \"run `cdk types`\"\n\n- `config` on a `defineConnector` isn't autocompleting / isn't rejecting a wrong\n  credential shape → types not generated (or `.cargo-ai/**/*.d.ts` not in\n  `include`).\n- `integrations.myConnector` is `any` / not callable at runtime → missing the\n  `cargo-register` import, or types are stale after an integration change.\n- A connector `deploy` fails with `Invalid configuration` → often the credential\n  wasn't wrapped in `secret()`; generating types surfaces the required shape at\n  author time. See [`../references/troubleshooting.md`](../references/troubleshooting.md).\n\nFile v1.2.4:recipes/add-connector-and-model.md\n\n# Recipe: add a connector and a model sourced from it\n\n**Use when** the user wants a new data source plus a model built from it, managed\nas code. The key move is wiring the model to the connector **by handle** — the CDK\ndeploys the connector first and injects its dataset uuid.\n\n## 1. Define the connector\n\nCreating a data connector auto-creates a **dataset** that models source from. Put\nthe credential behind `secret()`.\n\n```ts\n// connectors/hubspot.ts\nimport { defineConnector, secret } from \"@cargo-ai/cdk\";\n\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\n```\n\nFor an OAuth/key connector you authenticated in the UI and can't declare in code,\nuse `adopt: true` so the reconciler links the existing instance instead of creating\none:\n\n```ts\nexport const openai = defineConnector(\"open_ai\", { integration: \"openAi\", adopt: true });\n```\n\n## 2. Define the model, wired to the connector\n\nPass the **connector handle** as `dataset` — not `hubspot.datasetUuid`:\n\n```ts\n// models/contacts.ts\nimport { defineModel } from \"@cargo-ai/cdk\";\nimport { hubspot } from \"../connectors/hubspot\";\n\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot,                 // ← handle: model depends on connector\n  extractSlug: \"fetchRecords\",\n  config: { objectType: \"contacts\", columnSelectionMode: \"all\" },\n  schedule: { type: \"cron\", cron: \"0 * * * *\" },  // refresh hourly\n});\n```\n\nIf the connector already exists (not defined in code), reference it by uuid:\n`dataset: connectorRef(\"<connector-uuid>\")` — or `datasetRef(\"<dataset-uuid>\")` to\npoint at a specific dataset.\n\n## 3. Type the config (optional but recommended)\n\n```bash\ncargo-ai cdk types    # now `config` on both builders type-checks against HubSpot's schema\n```\n\n## 4. Deploy\n\n```bash\nexport HUBSPOT_API_KEY=...\ncargo-ai cdk plan       # shows: create connector:hubspot, create model:contacts\ncargo-ai cdk deploy\ngit add cargo.state.json && git commit -m \"Add HubSpot connector + contacts model\"\n```\n\nThe plan orders the connector before the model automatically because the model's\n`dataset` handle depends on it. Re-deploying after a config edit updates in place.\n\nFile v1.2.4:recipes/build-an-agent.md\n\n# Recipe: build an agent (model + tool + agent)\n\n**Use when** the user wants an AI agent with a data model, a tool, and an LLM\nconnector — all as code. Everything wires by handle, so the CDK deploys in\ndependency order.\n\n## 1. The LLM connector\n\nAn agent needs a language-model provider connector. Adopt an existing one:\n\n```ts\n// connectors/openai.ts\nimport { defineConnector } from \"@cargo-ai/cdk\";\nexport const openai = defineConnector(\"open_ai\", { integration: \"openAi\", adopt: true });\n```\n\n## 2. A tool, backed by a workflow\n\n`defineWorkflow` compiles the logic (parsed, not executed); `defineTool` deploys it\nas the tool's release. Reference other resources inside the body via `uses`.\n\n```ts\n// tools/enrich.ts\nimport { defineTool, defineWorkflow } from \"@cargo-ai/cdk\";\nimport { z } from \"zod\";\n\nconst enrichFlow = defineWorkflow(\n  \"enrich-contact\",\n  {\n    input: z.object({ email: z.string() }),\n    output: z.object({ company: z.string(), enriched: z.boolean() }),\n  },\n  ({ input, integrations }) => {\n    const found = integrations.hunter.companyEnrichment({ domain: input.email });\n    return { company: found.name, enriched: true };\n  },\n);\n\nexport const enrich = defineTool(\"enrich\", {\n  workflow: enrichFlow,\n  description: \"Enrich a contact with firmographic data.\",\n  emojiSlug: \"mag\",\n});\n```\n\n> `integrations.*` is typed and callable only after `cargo-ai cdk types` (it reads\n> your workspace's integrations). `native.*` works without it. See\n> [`../guides/typed-config.md`](../guides/typed-config.md).\n\n## 3. The agent, referencing model + tool + connector\n\nPass each dependency as a handle — bare, or `{ ref, …options }` when it needs\noptions:\n\n```ts\n// agents/sdr.ts\nimport { defineAgent } from \"@cargo-ai/cdk\";\nimport { openai } from \"../connectors/openai\";\nimport { contacts } from \"../models/contacts\";\nimport { enrich } from \"../tools/enrich\";\n\nexport const sdr = defineAgent(\"sdr\", {\n  connector: openai,\n  languageModel: \"gpt-4o\",\n  systemPrompt: \"You qualify inbound leads and enrich missing contact info.\",\n  maxSteps: 12,\n  capabilities: [\"webSearch\", \"memory\"],\n  models: [{ ref: contacts, readOnly: true }],\n  tools: [enrich],\n  triggers: [{ type: \"cron\", cron: \"0 9 * * *\", text: \"Daily qualification\" }],\n  evaluator: { rubric: \"Did it correctly qualify the lead?\", threshold: 0.8 },\n});\n```\n\nAdd a sub-agent with `subAgents: [{ ref: enricher, waitUntilFinished: true }]`, or a\nraw connector action with\n`connectorActions: [{ integration: \"hunter\", actionSlug: \"emailFinder\" }]`.\n\n## 4. Deploy\n\n```bash\ncargo-ai cdk types      # so integrations.* in the workflow body typecheck\ncargo-ai cdk plan       # orders: connector → tool (+ its workflow) → model → agent\ncargo-ai cdk deploy\ngit add cargo.state.json && git commit -m \"Add SDR agent\"\n```\n\nBecause `agent:sdr` has no slug, `cargo.state.json` is the **only** handle on it —\ncommit it, or the next deploy can't find it (recover with `cdk import agent:sdr <uuid>`).\n\nArchive v1.2.3: 17 files, 35850 bytes\n\nFiles: guides/authoring-resources.md (10740b), guides/deploy-and-state.md (4952b), guides/typed-config.md (2811b), recipes/add-connector-and-model.md (2247b), recipes/build-an-agent.md (2971b), recipes/deploy-from-ci.md (2476b), recipes/migrate-existing-workspace.md (2532b), recipes/scaffold-a-workspace.md (2636b), references/commands.md (2460b), references/cookbooks.md (3857b), references/examples/full-workspace.md (4312b), references/resources.md (7155b), references/troubleshooting.md (3775b), skill-card.md (2749b), skill-metadata.json (2220b), SKILL.md (17659b), _meta.json (128b)\n\nFile v1.2.3:SKILL.md\n\n---\nname: cargo-cdk\ndescription: \"Manage a whole Cargo workspace as code — declare connectors, models, plays, tools, agents, MCP servers, segments, context, folders, files, workers, and apps in TypeScript, then reconcile them with `cargo-ai cdk` (init → types → plan → deploy), the way you would run Pulumi or the AWS CDK. Triggers: \\\"as code\\\", \\\"in git\\\", \\\"version-controlled\\\", \\\"reproducible\\\", \\\"Terraform for Cargo\\\", \\\"set up a whole workspace\\\", \\\"staging and production\\\", \\\"deploy from CI\\\", \\\"review this in a PR\\\", \\\"cargo.state.json\\\", \\\"scaffold from a template\\\", \\\"is there a cookbook for this\\\", \\\"start from a cookbook\\\". Skills with a CDK example (TAM building, account scoring, contact sourcing, routing, AI SDR, rep cockpit) live in gtm-skills; menu in references/cookbooks.md. Skip when: it is a one-off operation, a read, or an ad-hoc query — use the matching capability skill.\"\nversion: \"1.2.3\"\ncompatibility: Requires @cargo-ai/cli (npm). Sign in or create an account with `cargo-ai login --email` (emailed code, no browser), `--oauth`, or an API token\nhomepage: https://github.com/getcargohq/cargo-skills\nmetadata:\n  author: getcargo\n  openclaw:\n    requires:\n      bins:\n        - cargo-ai\n    install:\n      - kind: node\n        package: \"@cargo-ai/cli@latest\"\n        bins:\n          - cargo-ai\n    homepage: https://github.com/getcargohq/cargo-skills\n---\n\n# Cargo CDK — declarative workspace-as-code\n\nUse this skill to define a Cargo workspace in TypeScript (`define*` builders from\n`@cargo-ai/cdk`) and reconcile it to live infrastructure with `cargo-ai cdk deploy`.\nIt is the **declarative** counterpart to the imperative capability skills: instead\nof running one CLI command per resource, you write the whole graph once and deploy\nit repeatably, with a committed `cargo.state.json` linking your code to what Cargo\ncreated.\n\n## Bootstrap\n\nAlready signed in (`cargo-ai whoami` returns a workspace)? Skip to the next section.\n\n```bash\nnpm install -g @cargo-ai/cli            # no global install? prefix every command with `npx @cargo-ai/cli`\ncargo-ai login --email you@company.com  # emailed code, no browser; creates the account on first use\n                                        # alternatives: --oauth (browser) · --token <api-token> (CI)\ncargo-ai whoami                         # confirm the active workspace before any write\ncargo-ai cdk --help                     # `unknown command` = CLI too old; reinstall @cargo-ai/cli@latest\n```\n\nTwo CDK-specific extras: the project needs **`@cargo-ai/cdk` as a dependency** for the `define*` builders you import (`cargo-ai cdk init` scaffolds a `package.json` with it — then `npm install`), and the `cargo-ai cdk` domain ships with the CLI itself.\n\nEvery command prints JSON to stdout; failures exit non-zero with `{\"errorMessage\": \"...\"}`. Anything that creates a run or a batch is async — pass `--wait-until-finished` or poll the matching `get`. When the full skill bundle is installed, [`../cargo/references/prerequisites.md`](../cargo/references/prerequisites.md) adds the CLI version pin, token scopes, and the admin-only surface.\n\n## 1) What this skill governs\n\n- **Authoring** every Cargo resource with a `define*` builder that returns a\n  **handle**; wiring resources by passing handles to each other (the dependency\n  graph is your variable graph).\n- **Deploying** the graph: `plan` (offline diff) → `deploy` (create/update, write\n  state) → `destroy` (tear down). Plus drift (`refresh`), adoption (`import`), and\n  recovery (`rollback`).\n- **Typing** the config against your workspace's real integration schemas\n  (`cargo-ai cdk types`).\n\nThe CDK spans **every** resource kind — so it overlaps every imperative capability\nskill (`cargo-connection`, `cargo-storage`, `cargo-ai`, `cargo-orchestration`,\n`cargo-content`, `cargo-hosting`, …). Which to reach for is the first decision:\n\n## 2) CDK or the CLI? — the routing decision\n\n> **Declarative (this skill) vs imperative (a capability skill).**\n\nUse the **CDK** when the user is **managing resources as an artifact**:\n\n- \"Set up / stand up / bootstrap a whole workspace (as code / from a template).\"\n- \"Make this reproducible / version-controlled / in git / repeatable across\n  environments (dev → prod).\"\n- \"Deploy these connectors + models + agents together\" (a multi-resource graph\n  wired by dependency).\n- Anything that should be re-runnable and diffable, where losing the definition\n  would be a problem.\n\nUse the matching **capability skill** (imperative `cargo-ai <domain>`) when the\nuser is doing a **one-off operation** or **exploring**:\n\n- \"Create one connector\", \"add a column to this model\", \"list connectors\",\n  \"run this workflow\", \"query storage\", \"read this agent's memory.\"\n- Any read, ad-hoc query, or single mutation that doesn't need to live in code.\n\nWhen unsure, ask whether the result should be committed and re-deployable. If yes\n→ CDK. If it's a quick action or a read → the capability skill (see the\n[`cargo` router](../cargo/SKILL.md) to pick the right domain).\n\n## 3) The lifecycle\n\n```\ncargo-ai cdk init <dir>     scaffold a project from a template (blank | full)\n        │\ncargo-ai cdk types          generate per-workspace types for typed config (optional)\n        │\n   (author define* files)   importing a .ts file IS registration — no manifest\n        │\ncargo-ai cdk plan           offline: compile the graph, diff against cargo.state.json\n        │\ncargo-ai cdk deploy         create/update resources in dependency order, write state\n        │\ncargo-ai cdk destroy        tear down resources recorded in state\n```\n\n> **`cdk plan` says what resources change; it doesn't show what a play does.**\n> For a `definePlay` / `defineTool` graph past three nodes, present a Mermaid\n> flowchart of the node graph alongside the plan — routing, fallbacks, and which\n> nodes bill on every scheduled run are what the reviewer is approving. Generate it\n> from the deployed release after the first deploy, or from the node array while\n> authoring:\n> [`../cargo-orchestration/references/node-diagram.md`](../cargo-orchestration/references/node-diagram.md).\n\nSide branches: `cargo-ai cdk refresh` (read-only drift report) · `deploy --refresh`\n(re-apply code over out-of-band edits) · `deploy --prune` (delete resources removed\nfrom code) · `cargo-ai cdk import <id> <uuid>` (bind an existing live resource into\nstate) · `cargo-ai cdk rollback` (restore the pre-deploy state snapshot).\n\n## 4) Documentation hierarchy\n\n- **Level 1** — `SKILL.md` (this file): the decision model, lifecycle, critical\n  rules, and routing.\n- **Level 2** — Guides:\n  [`guides/authoring-resources.md`](guides/authoring-resources.md),\n  [`guides/deploy-and-state.md`](guides/deploy-and-state.md),\n  [`guides/typed-config.md`](guides/typed-config.md).\n- **Level 2.5** — Recipes: [`recipes/*.md`](recipes/) — step-by-step playbooks to\n  follow as your execution plan.\n- **References** — [`references/resources.md`](references/resources.md) (the full\n  builder catalog), [`references/commands.md`](references/commands.md) (every\n  `cargo-ai cdk` subcommand + flags),\n  [`references/troubleshooting.md`](references/troubleshooting.md), and\n  [`references/examples/full-workspace.md`](references/examples/full-workspace.md).\n\n## 5) Read behavior — match the task to a doc and READ IT\n\n| When the task involves… | Read this first | What it gives you |\n|---|---|---|\n| Writing `define*` files, wiring resources, `secret()`/`env()`, `defineWorkflow` bodies (tool/play logic) | [`guides/authoring-resources.md`](guides/authoring-resources.md) | The builder catalog, the handle/ref model, secrets, and how workflow bodies compile. |\n| `plan` / `deploy` / `destroy`, the state file, drift, adopting existing resources, CI | [`guides/deploy-and-state.md`](guides/deploy-and-state.md) | The deploy lifecycle, `cargo.state.json` semantics, drift/import/rollback, async builds. |\n| Typed config, `cargo-ai cdk types`, tsconfig wiring, `integrations.*` in workflow bodies | [`guides/typed-config.md`](guides/typed-config.md) | What `cdk types` generates and how to wire it into your project. |\n| A field/spec/output for a specific builder | [`references/resources.md`](references/resources.md) | Every builder → spec fields → which ref each takes → outputs. |\n| Exact command flags | [`references/commands.md`](references/commands.md) | Every `cargo-ai cdk` subcommand and its flags. |\n| A deploy error / footgun | [`references/troubleshooting.md`](references/troubleshooting.md) | The known failure modes and fixes. |\n| A known GTM outcome, before authoring one | [`references/cookbooks.md`](references/cookbooks.md) | The cookbook menu: gtm-skills that carry a worked CDK example, and the adaptations each supports. |\n\n### Cookbooks — check the menu before authoring a known outcome from scratch\n\n[`getcargohq/gtm-skills`](https://github.com/getcargohq/gtm-skills) holds, beside its\none-off skills, **cookbooks**: skills that carry worked CDK resources, the same job as a deployed\npipeline that keeps producing the result (TAM building, account scoring, contact\nsourcing, routing engine, AI SDR, rep cockpit, …). Every folder is self-contained: its\nown models, connectors and folders, no shared foundation, no requires graph.\n\n**The menu is local: [`references/cookbooks.md`](references/cookbooks.md).** Read it\nbefore authoring a common GTM outcome from scratch. It is generated from gtm-skills'\n`catalog.json`, so it cannot drift.\n\n**A cookbook is a worked example, not a template to fill in.** Each one declares in its `SKILL.md` what may be reshaped, what must hold or it stops\nworking, and what has to be answered either way, and it carries its own procedure:\nlook at the repo, `cargo-ai cdk init --template blank` if there is no CDK project yet,\ncopy the folder in as a sibling and reconcile it with what is already declared, adapt,\nplan and stop, deploy on a yes, walk its `Done when`. There is no scaffolder or copy\ntool in the middle: **you place the code**, because you can see the project and a tool\ncannot.\n\n```sh\nnpx skills add getcargohq/gtm-skills/tam-building    # then: \"keep our TAM current\"\ncargo-ai cdk init my-project --template blank        # only if there is no CDK project yet\n```\n\n**If you are mid-task and the skill is not in this session**, run the `skills add`\nabove and read `.agents/skills/<slug>/SKILL.md` directly; no reload needed. To read\none without installing, `npx skills use getcargohq/gtm-skills@<slug>` prints it.\n\n**Routing rule: one-off versus standing.** A user who wants the list today wants\n`cargo-gtm` (or gtm-skills' one-off `build-tam-list`); a user who wants a pipeline\nthat keeps producing it wants `tam-building`. The same words describe both (\"build\nour TAM\"), so listen for whether the result is meant to keep arriving. A cookbook\nmatches → install it and follow it. No match → author from the recipes below.\n\n**Never `cargo-ai cdk init --force` into a directory that is not empty.** It replaces\nthe project's `package.json` and reverts adapted code, while `cargo.state.json`\nsurvives, so the next `plan` diffs a live workspace against code nobody wrote. Copy the\nskill folder in as a sibling instead.\n\nCaveat: the examples typecheck, but they are not yet deploy-verified against a live\nworkspace, and every one is `to-be-approved`. Treat each skill's `Done when` as the\nacceptance test, and always review `cargo-ai cdk plan` before deploying.\n\n### Recipes — follow step-by-step when one matches\n\n| Recipe | Use when… |\n|---|---|\n| [`recipes/scaffold-a-workspace.md`](recipes/scaffold-a-workspace.md) | Standing up a new workspace from scratch (`init --template full` → types → plan → deploy). |\n| [`recipes/add-connector-and-model.md`](recipes/add-connector-and-model.md) | Adding a data source + a model sourced from it, wired by handle. |\n| [`recipes/build-an-agent.md`](recipes/build-an-agent.md) | Composing a model + tool + agent (with `uses` / `models` / `tools`) and deploying. |\n| [`recipes/migrate-existing-workspace.md`](recipes/migrate-existing-workspace.md) | Bringing an already-live workspace under CDK management via `cdk import`. |\n| [`recipes/deploy-from-ci.md`](recipes/deploy-from-ci.md) | Deploying non-interactively from CI (token auth + committed state). |\n\n## 6) Critical rules\n\n- **Commit `cargo.state.json`.** It is the link from your code to the resources\n  Cargo created — and the **only** handle on a deployed **play**, **agent**, or\n  **alert** (they have no slug). Lose it and those resources orphan; recover a link\n  with `cargo-ai cdk import`. It records only `{hash, uuid, outputs}` — never secret\n  values. Git-ignore the working files (`cdk init` scaffolds this):\n  ```gitignore\n  .cargo-ai/\n  cargo.state.lock\n  cargo.state.bak.json\n  cargo.state.audit.jsonl\n  ```\n- **Secrets:** wire credentials with `secret(\"ENV_VAR\")` (often\n  `secret(\"HUBSPOT_API_KEY\")`). The value is read from the environment **at deploy\n  time**, kept out of the content hash and out of state, so rotating a token\n  doesn't read as drift. Export the env var before deploying — a missing one fails\n  the deploy with an unresolved `${ENV_VAR}` placeholder.\n- **Wire by handle, never by `.uuid`.** Pass a `define*` handle directly\n  (`dataset: hubspot`, `tools: [enrich]`), or `xxRef(\"uuid\")` for a resource you\n  didn't define in code (`connectorRef`, `modelRef`, `folderRef`, `toolRef`,\n  `agentRef`, …). Where a reference needs per-call options, wrap it as\n  `{ ref, …options }` (e.g. `models: [{ ref: contacts, readOnly: true }]`).\n- **Run `cargo-ai cdk types` after workspace integrations change** — it\n  regenerates `.cargo-ai/` so `defineConnector`/`defineModel` config (and\n  `integrations.*` in workflow bodies) type-check against the real schemas. Typing\n  is a bonus, never a gate: deploy works without it.\n- **Run `cdk` commands from the project root.** `npx`/`cargo-ai` resolve from the\n  nearest `package.json`; run elsewhere and `.cargo-ai/` and `cargo.state.json`\n  land in the wrong directory. Use `--dir <path>` to be explicit.\n- **`--yes` in CI.** `deploy` and `destroy` prompt for confirmation; non-interactive\n  runs must pass `--yes`.\n- **A `definePlay`/`defineTool` graph with paid nodes gets a sample run before it\n  goes wide.** Deploying is not running, but the first thing that runs a deployed\n  play is usually a batch over the whole segment — and a scheduled play re-bills\n  every node on every run. Before enrolling everything (or enabling a schedule),\n  run the deployed workflow on **10–20 records** — `cargo-ai orchestration batch\n  create --data '{\"kind\":\"filter\",\"modelUuid\":\"…\",\"filter\":…,\"limit\":15}'`, or\n  `batch create --file ./plays/x.ts` to test-run the module without deploying —\n  then ask the user to approve the full enrollment with the **record count** and\n  **credit estimate**. Read the provider's playbook\n  (`../cargo-gtm/provider-playbooks/<slug>.md`, esp. its *Recurring use* section)\n  and the gate in\n  [`../cargo-gtm/references/cost-discipline.md`](../cargo-gtm/references/cost-discipline.md).\n- **A `defineAlert` whose actions call paid nodes re-bills on every breach.** An\n  alert's `actions` fire as real runs, so a badly-sized `threshold` on a tight\n  `schedule` can breach — and bill — every tick. Size the threshold with\n  `cargo-ai observability alert preview` before deploying, prefer cheap notification\n  actions (an agent that posts, a connector notification) over anything that fans\n  out, and apply the same cost gate above when an action calls a credits-based\n  provider. Scope/threshold and firing semantics:\n  [`../cargo-observability/SKILL.md`](../cargo-observability/SKILL.md).\n- **`defineMailbox` bills monthly, and `defineDomain` rewrites a DNS zone.** A\n  mailbox is 100–160 credits *per month* for as long as it exists (`cargo-ai\n  mailboxManagement pricing get` for live figures), so a `+ create mailbox:…` line\n  in the plan is a recurring charge the user approves, not a one-off. Its `domain`,\n  `username` and `type` are **create-only** — changing any of them is destroy +\n  recreate, i.e. a brand-new inbox back at the bottom of a 45-day warm-up ramp. The\n  deploy polls `refreshStatus` for up to 5 minutes waiting for `active`. On\n  `defineDomain`, `dnsRecords` is the **whole zone, not a patch**: declaring it\n  replaces every live record (including the ones the registrar wrote at purchase),\n  and omitting it leaves the zone untouched. Use `adopt: true` for a domain or\n  mailbox bought in the UI. Ramp, suppression and sending:\n  [`../cargo-mailbox-management/SKILL.md`](../cargo-mailbox-management/SKILL.md).\n- **Route CDK-managed resources into a clearly-labelled folder.** Set `folder:` on\n  each builder so everything CDK owns lands in a dedicated folder whose name signals\n  \"owned by code — don't hand-edit\" to anyone in the UI (manual UI edits read back as\n  drift on the next `plan`). Folders are per-kind, so give each kind its own but share\n  one short, recognizable prefix — recommended: **`🔒 CDK`** (e.g. `🔒 CDK Models`,\n  `🔒 CDK Agents`). Keep names short (long labels truncate in the folder tree); the\n  lock emoji is the \"don't touch\" cue. See\n  [`guides/authoring-resources.md`](guides/authoring-resources.md).\n\n## Help\n\n- `cargo-ai cdk --help` and `cargo-ai cdk <subcommand> --help` for the live flag\n  surface.\n- When a documented command/flag/response doesn't match what you observe, file a\n  report: `cargo-ai workspaceManagement report create` (see\n  [`../cargo-workspace-management/SKILL.md`](../cargo-workspace-management/SKILL.md)).\n\nFile v1.2.3:_meta.json\n\n{\n  \"ownerId\": \"kn7by8t6yt9yghbxtxz6hv0bts87k6bq\",\n  \"slug\": \"cargo-cdk\",\n  \"version\": \"1.2.3\",\n  \"publishedAt\": 1787546908655\n}\n\nFile v1.2.3:references/commands.md\n\n# Command reference — `cargo-ai cdk`\n\nAll subcommands accept `--dir <path>` (the project root, default `.`) and `--json`\n(machine-readable output). Run from the project root so `.cargo-ai/` and\n`cargo.state.json` land in the right place. Confirm the surface live with\n`cargo-ai cdk <subcommand> --help`.\n\n| Command | What it does |\n|---|---|\n| `cargo-ai cdk init <directory>` | Scaffold a project from a template. `--template <blank\\|full>` (default `blank`), `--list-templates`. |\n| `cargo-ai cdk types` | Generate per-workspace types into `.cargo-ai/` for typed config. |\n| `cargo-ai cdk plan` | Offline: compile the graph and diff against `cargo.state.json`. No API calls. |\n| `cargo-ai cdk deploy` | Create/update resources in dependency order; write state. Prompts unless `--yes`. |\n| `cargo-ai cdk refresh` | Read-only: report resources that drifted from code (changed/deleted out of band). |\n| `cargo-ai cdk import <id> <uuid>` | Bind an existing live resource (`kind:slug`) to a uuid in state. |\n| `cargo-ai cdk rollback` | Restore `cargo.state.json` from the pre-deploy snapshot. |\n| `cargo-ai cdk destroy` | Tear down resources recorded in state. `--target <id>` for one, `--all` for everything. |\n\n## Common flags\n\n- `--dir <path>` — project root (default `.`).\n- `--yes` — skip the confirmation prompt (**required in CI / non-interactive**).\n- `--json` — machine-readable output.\n- `--force` — steal a stale `cargo.state.lock`.\n\n## `deploy` modifiers\n\n- `cargo-ai cdk deploy --prune` — also **delete** resources that are in state but\n  removed from code (reverse dependency order; adopted resources are released, not\n  deleted).\n- `cargo-ai cdk deploy --refresh` — re-read live resources and re-apply your code\n  over any out-of-band changes.\n\n## `destroy` targets\n\n- `cargo-ai cdk destroy --target <kind:slug>` — remove one resource (refused if\n  other state resources still depend on it).\n- `cargo-ai cdk destroy --all` — remove everything in state, dependents first.\n\n## Examples\n\n```bash\ncargo-ai cdk init acme --template full        # scaffold\ncargo-ai cdk types --dir acme                 # type config\ncargo-ai cdk plan --dir acme                  # preview\ncargo-ai cdk deploy --dir acme --yes          # apply (non-interactive)\ncargo-ai cdk refresh --dir acme               # drift report\ncargo-ai cdk import agent:sdr <uuid> --dir acme  # adopt a live agent\ncargo-ai cdk destroy --dir acme --all --yes   # tear down\n```\n\nFile v1.2.3:references/cookbooks.md\n\n<!-- Generated by .github/scripts/sync-cookbooks.ts from gtm-skills' catalog.json. Do not edit by hand. -->\n\n# Cookbooks: worked CDK examples, before you author one from scratch\n\nSkills in [`getcargohq/gtm-skills`](https://github.com/getcargohq/gtm-skills) that are cookbooks: worked CDK resources, the same\njobs as the one-off skills there, as a deployed pipeline that keeps producing the result.\n\n**Every folder is self-contained** (its own models, connectors and folders; no shared\nfoundation, no requires graph). The agent installing one copies it into the project as a\nsibling of what is there, reconciles it with what is already declared (an existing accounts\nmodel, an existing CRM connector), adapts it, plans, deploys on a yes, and walks its `Done\nwhen`. The code is a worked example, not a template to fill in.\n\n```sh\nnpx skills add getcargohq/gtm-skills/<slug>       # then say what you want; the skill carries its own procedure\ncargo-ai cdk init <dir> --template blank      # only if there is no CDK project yet: the shell comes from the CLI\n```\n\n## With a skill\n\n| Skill | Deploys | State |\n| --- | --- | --- |\n| `account-scoring` | Keep every account scored and tiered against your written ICP by a deployed agent that re-scores as accounts arrive and as the ICP changes, writing the rationale back to the CRM. | to-be-approved |\n| `tam-building` | Stand up your account universe as a deployed pipeline: a Sales Navigator company search split past the 1,000 extraction cap, resolved to real domains, deduped into a shared accounts model. | to-be-approved |\n\n## When one does not fit as written\n\nDeclared adaptations, not forks. Reach for one before concluding a skill is the wrong start.\n\n**`account-scoring`**\n\n- `deterministic-scoring` — You need fixed cost and exact reproducibility, or an LLM judgement is not acceptable to your team. Costs: The criteria move out of the ICP markdown and into code, so they stop being reviewable by non-engineers, and you lose the rationale entirely.\n- `skip-crm-roundtrip` — You want the score on the model directly and do not need it visible in the CRM. Costs: Reps lose the score and rationale where they actually work. The native's input is untyped, so confirm the field shape on the first run.\n- `no-crm-at-all` — You have no CRM, or you do not want to hand this skill a CRM credential. Costs: Every other CRM-dependent skill you install later brings a CRM connector of its own; reuse one.\n\n**`tam-building`**\n\n- `non-linkedin-source` — You do not want to source from LinkedIn at all, or Sales Nav does not cover your market. Costs: You lose the Sales Nav facet taxonomy that makes the split tactic mechanical, and the splitting has to be redesigned around the new source's own limits.\n- `land-without-promoting` — You want to see and filter the raw market before paying to enrich it. Costs: Nothing reaches `accounts`, so no downstream skill (scoring, contact sourcing, signals) has anything to work with until you promote.\n- `sample-first` — The market search is large and you want to see the cost curve before committing. Costs: Your TAM is deliberately incomplete until you widen it, so do not score or report on coverage from a sample.\n\n## Routing\n\n**One-off versus standing is the whole test.** A user who wants a list today wants a one-off\nskill (or `cargo-gtm`, when this pack is installed); a user who wants a pipeline that keeps\nproducing it wants one of these. The same words describe both, so listen for whether the\nresult is meant to keep arriving.\n\n**Never `cargo-ai cdk init --force` into a directory that is not empty.** It replaces the\nproject's `package.json` and reverts adapted code while `cargo.state.json` survives, so the\nnext plan diffs a live workspace against code nobody wrote. Copy the skill folder in as a\nsibling instead; that is what its own procedure says.\n\nFile v1.2.3:references/examples/full-workspace.md\n\n# Example: a full GTM workspace end-to-end\n\nThis walks the `full` template (`cargo-ai cdk init <dir> --template full`) — a\ncomplete, runnable Cargo workspace defined in code that exercises every resource\ntype and wires them by **handle**.\n\n## The graph\n\n```\nhubspot (connector) ──dataset──▶ contacts (model) ──model──────────┬─▶ onboarding (play)\n                                                                    ├─▶ sdr (agent)\nopenai (connector) ──connector──▶ enricher (agent) ──subAgent──▶ sdr│\n                    └────────connector──────────────────▶ sdr ─────┘\nenrich (tool, backed by a workflow) ─┐\nsdr (agent) ─────────────────────────┼─▶ crm (mcpServer)\ncontacts (model) ────────────────────┘\nplaybook (file)   webhook (worker)   dashboard (app)   context (repo)\n```\n\n## Project layout\n\n```\nmy-workspace/\n  package.json            # depends on @cargo-ai/cdk + zod\n  tsconfig.json           # include: [\"**/*.ts\", \".cargo-ai/**/*.d.ts\"]\n  .gitignore              # .cargo-ai/, cargo.state.lock, cargo.state.bak.json, cargo.state.audit.jsonl\n  connectors/hubspot.ts   # defineConnector + secret()\n  connectors/openai.ts    # defineConnector adopt: true\n  folders/crm.ts          # defineFolder (per-kind)\n  models/contacts.ts      # defineModel dataset: hubspot\n  tools/enrich.ts         # defineWorkflow + defineTool\n  agents/enricher.ts      # defineAgent (sub-agent)\n  agents/sdr.ts           # defineAgent (model + tool + sub-agent + trigger + evaluator)\n  plays/onboarding.ts     # definePlay + defineWorkflow\n  mcp/crm.ts              # defineMcpServer\n  context/context.ts      # defineContext dir: \"context\" (+ context/*.md)\n  files/playbook.ts       # defineFile (+ playbook.md)\n  workers/webhook.ts      # defineWorker (+ webhook/ built bundle)\n  apps/dashboard.ts       # defineApp (+ dashboard/ Vite app)\n```\n\nImporting a `.ts` file **is** registration — there is no manifest. The loader\nimports every `.ts` under the project (skipping the worker/app bundle sub-dirs,\nwhich have their own `package.json`), and each `define*` registers as a side\neffect.\n\n## A wired slice\n\n```ts\n// connectors/hubspot.ts\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\n\n// models/contacts.ts\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot,                       // handle → connector deployed first, dataset injected\n  extractSlug: \"fetchRecords\",\n  config: { objectType: \"contacts\", columnSelectionMode: \"all\" },\n  folder: modelsFolder,\n  schedule: { type: \"cron\", cron: \"0 * * * *\" },\n});\n\n// agents/sdr.ts\nexport const sdr = defineAgent(\"sdr\", {\n  connector: openai,\n  languageModel: \"gpt-4o\",\n  systemPrompt: \"You qualify inbound leads and route hot ones to Slack.\",\n  models: [{ ref: contacts, readOnly: true }],\n  tools: [enrich],\n  subAgents: [{ ref: enricher, waitUntilFinished: true }],\n  folder: agentsFolder,\n});\n```\n\n## Deploy walkthrough\n\n```bash\ncd my-workspace && npm install\n\ncargo-ai login                 # authenticate + select the workspace\ncargo-ai cdk types             # type defineConnector/defineModel config against this workspace\nexport HUBSPOT_API_KEY=...      # matches secret(\"HUBSPOT_API_KEY\")\n\ncargo-ai cdk plan\n# → lists every resource as create / update / no-op, in dependency order:\n#   create connector:hubspot, create connector:open_ai (adopt), create folder:crm-models, …\n\ncargo-ai cdk deploy\n# → creates each in order, writing cargo.state.json after each resource.\n#   Workers/apps build server-side (slower). Live URLs appear as webhook.url / dashboard.url.\n\ngit add cargo.state.json && git commit -m \"Deploy full workspace\"\n```\n\nRe-run `cargo-ai cdk deploy` after editing a file — only the changed resource is\napplied. Tear it all down with `cargo-ai cdk destroy --all`.\n\nSecrets referenced with `secret(\"HUBSPOT_API_KEY\")` resolve from the environment at\ndeploy time and stay out of the content hash — only `{hash, uuid, outputs}` land in\n`cargo.state.json`, never secret values.\n\nFile v1.2.3:references/resources.md\n\n# Resource reference\n\nEvery builder is imported from `@cargo-ai/cdk`, takes `(slug, spec)` (except\n`defineContext`, which takes only a spec — it's a workspace singleton), and returns\na **handle** carrying deferred output tokens (`uuid`, and for connectors\n`datasetUuid`; for workers/apps `url`). Wire resources by passing a handle where a\nreference is expected; use `xxRef(\"uuid\")` for a resource not defined in code.\n\nThe tables below list the **commonly used** spec fields — the TypeScript types on\neach builder are the source of truth for the complete set. Fields that take a\n**ref** accept a handle or an `xxRef` (and `{ ref, …options }` when they carry\nper-call options).\n\n## Builders\n\n| Builder | Purpose | Key spec fields | Ref fields | Outputs |\n|---|---|---|---|---|\n| `defineConnector(slug, spec)` | Data source or LLM provider | `integration`, `config` (typed per integration), `adopt?`, `rateLimit?`, `cacheTtlMilliseconds?` | — | `uuid`, `datasetUuid` (data connectors) |\n| `defineModel(slug, spec)` | Table sourced from a connector's dataset | `dataset`, `extractSlug`, `config`, `schedule?`, `folder?` | `dataset` (connector/dataset), `folder` | `uuid` |\n| `defineTool(slug, spec)` | Tool backed by a workflow | `workflow`, `description?`, `emojiSlug?`, `triggers?`, `folder?` | `folder` | `uuid` |\n| `definePlay(slug, spec)` | Per-row automation over a model | `model`, `workflow`, `changeKinds`, `runCreationRule`, `schedule`, `folder?` | `model`, `folder` | `uuid` |\n| `defineAgent(slug, spec)` | AI agent | `connector`, `languageModel`, `systemPrompt`, `models?`, `tools?`, `subAgents?`, `connectorActions?`, `capabilities?`, `maxSteps?`, `triggers?`, `evaluator?`, `color?`, `folder?` | `connector`, `models`, `tools`, `subAgents`, `folder` | `uuid` |\n| `defineMcpServer(slug, spec)` | MCP endpoint bundling resources | `description?`, `tools?`, `agents?`, `models?`, `folder?` | `tools`, `agents`, `models`, `folder` | `uuid` |\n| `defineFolder(slug, spec)` | Per-kind folder | `kind`, `name`, `parent?` | `parent` | `uuid` |\n| `defineFile(slug, spec)` | Content file from a local path | `path`, `name`, `folder?` | `folder` | `uuid` |\n| `defineContext(spec)` | Workspace context repo (singleton) | `dir?`, `files?` | — | `uuid` |\n| `defineSegment(slug, spec)` | Saved view over a model | `model` (immutable), `filter` (required) | `model` | `uuid` |\n| `defineCapacity(slug, spec)` | Revenue-org capacity | `model`, `color?`, `description?`, member capacity fields | `model`, members | `uuid` |\n| `defineTerritory(slug, spec)` | Revenue-org territory | `model`, `members`, `color?`, `description?`, `fallbackMember?` | `model`, `members` | `uuid` |\n| `defineWorker(slug, spec)` | Hosted worker (built bundle) | `path`, `description?`, `folder?` | `folder` | `uuid`, `url` |\n| `defineApp(slug, spec)` | Hosted Vite SPA | `path`, `description?`, `folder?` | `folder` | `uuid`, `url` |\n| `defineDomain(name, spec)` | Sending domain + its DNS zone | `adopt?`, `dnsRecords?` (**replaces the whole zone**) | — | `uuid` |\n| `defineMailbox(slug, spec)` | Sending inbox on a domain (**monthly credit charge**) | `domain`, `type` (`google`/`shared`/`private` — no `outlook`), `username?` (defaults to slug), `firstName`, `lastName`, `signature?`, `folder?`, `adopt?` | `domain`, `folder` | `uuid` |\n| `defineAlert(slug, spec)` | Scheduled threshold alert (observability) | `schedule`, `scope`, `threshold`, `actions`, `name?`, `description?`, `enabled?`, `folder?` | scope: `workflow`/`connector`/`tool`/`agent`/`model`; each action's `ref`; `folder` | `uuid` |\n\n`defineWorkflow(slug, { input, output, uses? }, build)` is re-exported from\n`@cargo-ai/cdk` for `defineTool`/`definePlay` bodies — see\n[`../guides/authoring-resources.md`](../guides/authoring-resources.md).\n\n## Ref helpers\n\nFrom `@cargo-ai/cdk`: `connectorRef`, `datasetRef`, `modelRef`, `folderRef`,\n`playRef`, `memberRef`. From the workflow SDK (re-exported): `toolRef`, `agentRef`.\nEach takes a uuid string and returns a kind-branded handle:\n\n```ts\nimport { defineModel, connectorRef, folderRef } from \"@cargo-ai/cdk\";\n\nexport const leads = defineModel(\"leads\", {\n  dataset: connectorRef(\"6f0c…\"),   // existing connector, by uuid\n  extractSlug: \"fetchRecords\",\n  folder: folderRef(\"a1b2…\"),\n});\n```\n\n## Notes on specific fields\n\n- **`defineConnector` `config`** is a per-integration shape — a discriminated union\n  for auth (e.g. HubSpot `method: \"privateApp\" | \"oauth\"`). `secret()` is accepted\n  only on credential/encryption fields. Run `cargo-ai cdk types` to type it (see\n  [`../guides/typed-config.md`](../guides/typed-config.md)).\n- **`adopt: true`** on `defineConnector` links an existing authenticated connector\n  by slug instead of creating one — for OAuth/key connectors you can't declare.\n- **`defineModel` `dataset`** takes the **connector** handle (its dataset uuid is\n  injected) or a `datasetRef`/`connectorRef`.\n- **`schedule`** shapes: `{ type: \"cron\", cron: \"0 * * * *\" }` or\n  `{ type: \"watch\" }` (plays react to row changes).\n- **`definePlay` `changeKinds`**: `[\"added\", \"updated\", …]`; `runCreationRule`:\n  e.g. `\"always\"`.\n- **`defineFile` `path`** and **`defineWorker`/`defineApp` `path`** point at local\n  files/dirs, typically via `new URL(\"./x\", import.meta.url).pathname`. File content\n  is hashed at define time, so edits show as drift. Worker `path` must be a **built**\n  bundle dir (`index.js` + `manifest.json` + `package.json` + `package-lock.json`).\n- **`defineAlert` `scope` + `threshold`** are a **matched pair** — TS narrows the\n  threshold menu by `scope.kind`: `spans`/`runs`/`records` take the telemetry metrics\n  (`errorRate`, `duration`+`aggregation`, `credits`+`aggregation`, `count`), `model`\n  takes `recordsCount`/`recordsShare`/`freshness`/`syncDuration`, and\n  `orchestrationQuery`/`storageQuery` take `{ operator, value }` (the query computes\n  the value, so no metric). The scope wires the watched resource **by handle**\n  (`workflow:` a `definePlay`/`defineTool` handle or `workflowRef`, plus `connector`/\n  `tool`/`agent`/`model`), so the reconciler deploys the producer first and injects\n  its uuid.\n- **`defineAlert` `actions`** fire as runs on breach. Each is a `{ ref, config }`\n  wrapper (`config` required — an alert fires unattended, so a missing input is a type\n  error, not a silent `{}`). Prefer the typed helpers `alertConnectorAction({ ref:\n  slack.actions.postMessage, config })` / `alertToolAction({ ref: enrich, config })` —\n  `config` is checked against the action/tool input schema (connector schemas need\n  `cargo-ai cdk types` to have run) — or a bare `{ ref: agent, config, release?,\n  waitUntilFinished? }`. Every `config` leaf accepts a `{{ … }}` template\n  (`{{event.value}}`, `{{alert.name}}`, `{{alert.url}}`, …) interpolated against the\n  firing context. Like a play, an alert has **no author-set wire slug** — its identity\n  on redeploy is the state uuid, so committing `cargo.state.json` is what keeps it\n  addressable. Scope/threshold matrix, metric units, and firing semantics:\n  [`../../cargo-observability/SKILL.md`](../../cargo-observability/SKILL.md).\n\nFile v1.2.3:references/troubleshooting.md\n\n# Troubleshooting\n\n## `✗ Deploy failed: connector:<slug>: Invalid configuration`\n\nThe connector's `config` doesn't match the integration's schema. Most often the\ncredential wasn't wrapped in `secret()` — a data connector's credential field\nexpects an encryption envelope, and `secret(\"ENV_VAR\")` produces it. Fix:\n\n```ts\nconfig: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") }, // not a bare string\n```\n\nRun `cargo-ai cdk types` so the config type-checks against the real schema at\nauthor time and surfaces the required shape (see\n[`../guides/typed-config.md`](../guides/typed-config.md)). The deploy error now also\nsurfaces the API's structured detail (which field, the reason) — read past the\nterse \"Invalid configuration\" summary.\n\n## `unresolved placeholder \"${NAME}\"`\n\nA `secret(\"NAME\")` or `env(\"NAME\")` had no matching environment variable at deploy.\nThe CDK refuses to send a literal `${NAME}` to the API. Export it first:\n\n```bash\nexport NAME=...\ncargo-ai cdk deploy\n```\n\n## Deploy refuses: workspace mismatch\n\n`cargo.state.json` records the workspace it was deployed to; `deploy`/`destroy`\nrefuse when that ≠ the currently selected workspace (a guard against reconciling a\ndev definition into prod). Select the right workspace at `login`, or use a separate\nstate file per environment.\n\n## `.cargo-ai/` or `cargo.state.json` landed in the wrong directory\n\n`npx`/`cargo-ai` resolve from the **nearest `package.json`**, not your shell's cwd.\nRun `cdk` commands from the project root, or pass `--dir <project-root>` explicitly.\n\n## `integrations.<slug>` is `any` / not callable, or `config` isn't type-checked\n\nTypes aren't generated or aren't wired in. Run `cargo-ai cdk types`, ensure\n`tsconfig.json` `include` has the explicit glob `\".cargo-ai/**/*.d.ts\"` (a bare\n`.cargo-ai` dot-dir is ignored by TypeScript), and `import \"./.cargo-ai/cargo-register.js\";`\nat the top of workflow modules that use `integrations.*`. Re-run `cdk types` after\nchanging workspace integrations.\n\n## `could not parse the workflow body`\n\nA `defineWorkflow` body must be a supported JS subset — it's **parsed, not\nexecuted**. Remove `await`, `throw`, `try/catch`, closures over outer variables,\nand destructuring; compile workflow files with a modern target (ES2022+) and don't\ninstrument them with coverage tools (they rewrite the function source). Use\n`js(({ nodes }) => …)` for logic outside the supported subset.\n\n## Deploy is slow / seems to hang on a worker or app\n\nWorkers and apps **build server-side** — the reconciler uploads the bundle, waits\nfor the build, and promotes. This is expected to take longer than other resources.\nEnsure the worker bundle dir has a built `index.js` (+ `manifest.json`,\n`package.json`, `package-lock.json`) before deploying.\n\n## A play or agent got orphaned (state lost)\n\nPlays and agents have no slug, so `cargo.state.json` is the only link to them.\n**Commit the state file.** If it's lost, find the live uuid via the matching\ncapability skill and rebind: `cargo-ai cdk import agent:<slug> <uuid>`. Never\ndelete `cargo.state.json` to \"start clean\" — you'll orphan every play/agent it\ntracked.\n\n## `plan` shows `create` for a resource that already exists\n\nIts `kind:slug` id didn't match state. Either the slug in the `define*` changed, or\nyou migrated a workspace without importing — bind it: `cargo-ai cdk import <kind:slug> <uuid>`\n(see [`../recipes/migrate-existing-workspace.md`](../recipes/migrate-existing-workspace.md)).\n\n## Still stuck\n\nFile a report so the Cargo team sees it:\n`cargo-ai workspaceManagement report create --title \"<summary>\" --description \"<commands tried, errorMessage, expected vs actual>\"`\n— see [`../../cargo-workspace-management/SKILL.md`](../../cargo-workspace-management/SKILL.md).\n\nFile v1.2.3:guides/authoring-resources.md\n\n# Authoring resources\n\nEvery Cargo resource has a `define*` builder imported from `@cargo-ai/cdk`. Each\nreturns a **handle**; you wire resources together by passing one handle into\nanother builder. **Importing a `.ts` file is registration** — each `define*` call\nregisters itself as a side effect, so there is no manifest to maintain. The loader\nimports every `.ts` under the project directory (skipping worker/app bundle\nsub-directories, which have their own `package.json`).\n\nFor the exact spec fields and outputs of each builder, see\n[`../references/resources.md`](../references/resources.md).\n\n## The handle / ref model (the one thing to internalize)\n\nPass the **handle** a builder returned — never `handle.uuid`:\n\n```ts\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot, // ← the connector handle, not hubspot.datasetUuid\n});\n```\n\nThe CDK reads the dependency (connector → model), deploys the connector first, and\ninjects its real dataset uuid at deploy time. Your variable graph *is* the\ndependency graph.\n\nFor a resource you did **not** define in code (an existing connector, folder,\netc.), use a `xxRef(\"uuid\")` helper — it produces the same handle shape from a\nliteral uuid:\n\n```ts\nimport { defineModel, connectorRef } from \"@cargo-ai/cdk\";\n\nexport const leads = defineModel(\"leads\", {\n  dataset: connectorRef(\"6f0c…\"), // an already-authenticated connector, by uuid\n});\n```\n\nRef helpers: `connectorRef`, `datasetRef`, `modelRef`, `folderRef`, `playRef`,\n`memberRef` (from `@cargo-ai/cdk`) and `toolRef`, `agentRef` (re-exported from the\nworkflow SDK). Each is branded by kind, so a model can't be passed where a\nconnector is expected.\n\n**Per-call options:** where a reference takes options, wrap it as\n`{ ref, …options }`:\n\n```ts\nmodels: [{ ref: contacts, readOnly: true }],   // handle + options\nsubAgents: [{ ref: enricher, waitUntilFinished: true }],\ntools: [enrich],                               // bare handle when no options\n```\n\n## Secrets — `secret()` + `env()`\n\nWire credentials with `secret(\"ENV_VAR\")`. The value is read from the environment\n**at deploy time**, kept out of the content hash and out of `cargo.state.json`, so\nrotating the token never reads as drift:\n\n```ts\nimport { defineConnector, secret } from \"@cargo-ai/cdk\";\n\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\n```\n\n`secret()` is only accepted where a credential/encryption field is expected. Use\n`env(\"NAME\")` for non-secret config values that come from the environment. Export\nthe variables before deploying — a missing one fails deploy with an unresolved\n`${NAME}` placeholder rather than sending a literal to the API.\n\n## The builder catalog\n\nData & schema:\n\n```ts\n// Connector — a data source or LLM provider. Creating a data connector\n// auto-creates a dataset that models source from. OAuth connectors that can't be\n// declared in code use `adopt: true` to link the existing authenticated instance.\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\nexport const openai = defineConnector(\"open_ai\", { integration: \"openAi\", adopt: true });\n\n// Model — a table sourced from a connector's dataset by an extractor.\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot,                 // connector handle → its dataset is injected\n  extractSlug: \"fetchRecords\",\n  config: { objectType: \"contacts\", columnSelectionMode: \"all\" },\n  folder: modelsFolder,\n  schedule: { type: \"cron\", cron: \"0 * * * *\" },\n});\n```\n\nAutomation:\n\n```ts\n// Tool — backed by a workflow. defineWorkflow compiles the logic; defineTool\n// creates the tool and deploys that workflow as its release.\nconst enrichFlow = defineWorkflow(\n  \"enrich-contact\",\n  { input: z.object({ email: z.string() }), output: z.object({ company: z.string() }), uses: { enricher } },\n  ({ input, uses }) => ({ company: uses.enricher({ prompt: `Company for ${input.email}?` }) }),\n);\nexport const enrich = defineTool(\"enrich\", { workflow: enrichFlow, emojiSlug: \"mag\" });\n\n// Play — runs a per-row workflow as a data model's rows change.\nexport const onboarding = definePlay(\"onboarding\", {\n  model: contacts,\n  workflow: onboardRow,\n  changeKinds: [\"added\", \"updated\"],\n  runCreationRule: \"always\",\n  schedule: { type: \"watch\" },\n});\n\n// Agent — references models, tools, sub-agents, connector actions, and the LLM\n// connector, each by handle.\nexport const sdr = defineAgent(\"sdr\", {\n  connector: openai,\n  languageModel: \"gpt-4o\",\n  systemPrompt: \"Qualify inbound leads.\",\n  models: [{ ref: contacts, readOnly: true }],\n  tools: [enrich],\n  subAgents: [{ ref: enricher, waitUntilFinished: true }],\n  connectorActions: [{ integration: \"hunter\", actionSlug: \"emailFinder\" }],\n  folder: agentsFolder,\n});\n\n// MCP server — bundles tools, agents, and models behind one MCP endpoint.\nexport const crm = defineMcpServer(\"crm\", { tools: [enrich], agents: [sdr], models: [{ ref: contacts }] });\n```\n\nOrganization & knowledge:\n\n```ts\n// Folder — per-kind (a \"model\" folder and an \"agent\" folder are separate).\nexport const modelsFolder = defineFolder(\"crm-models\", { kind: \"model\", name: \"CRM\" });\n\n// RECOMMENDED: route every CDK-managed resource into a dedicated, clearly\n// labelled folder (via each builder's `folder:`), so a human in the UI sees at a\n// glance that these resources are owned by code and shouldn't be hand-edited —\n// manual UI changes read back as drift on the next `plan`. Because folders are\n// per-kind, give each kind its own but share ONE short, recognizable prefix, e.g.\n// `🔒 CDK` (or `🔒 CDK Models`, `🔒 CDK Agents`). Keep names short — long labels\n// truncate in the folder tree; the lock emoji is the \"don't touch\" cue.\nexport const cdkModels = defineFolder(\"cdk-models\", { kind: \"model\", name: \"🔒 CDK Models\" });\nexport const cdkAgents = defineFolder(\"cdk-agents\", { kind: \"agent\", name: \"🔒 CDK Agents\" });\n\n// File — content uploaded from a local path (hashed at define time, so edits show as drift).\nexport const playbook = defineFile(\"playbook\", {\n  path: new URL(\"./playbook.md\", import.meta.url).pathname,\n  name: \"SDR Playbook\",\n});\n\n// Context — the workspace's git-backed GTM knowledge base as code. Singleton;\n// additive (files added in the UI are left in place).\nexport const context = defineContext({ dir: \"context\" });\n```\n\nRevenue org & segmentation:\n\n```ts\n// Segment — a saved view over a model (filter is required; model is immutable).\nexport const hotLeads = defineSegment(\"hot-leads\", { model: contacts, filter: { /* … */ } });\n\n// Capacity / Territory — revenue-org planning over members and a model.\nexport const capacity = defineCapacity(\"ae-capacity\", { model: contacts, /* … */ });\nexport const territory = defineTerritory(\"west\", { model: contacts, members: [memberRef(\"…\")] });\n```\n\nHosting (async builds — see [`deploy-and-state.md`](deploy-and-state.md)):\n\n```ts\n// Worker — the hosted worker slot. `path` points at a BUILT bundle dir\n// (index.js + manifest.json + package.json + package-lock.json). Author the\n// runtime code with createWorker from @cargo-ai/worker-sdk and build to index.js.\nexport const webhook = defineWorker(\"webhook\", {\n  path: new URL(\"./webhook\", import.meta.url).pathname,\n  description: \"Receives inbound lead webhooks.\",\n});\n\n// App — a hosted Vite SPA. `path` points at the app package root.\nexport const dashboard = defineApp(\"dashboard\", {\n  path: new URL(\"./dashboard\", import.meta.url).pathname,\n});\n```\n\nObservability:\n\n```ts\n// Alert — a scheduled threshold check; fires actions as runs on breach. The\n// scope wires the watched resource by handle, and scope + threshold are a\n// matched pair (TS narrows the metric menu to the scope's kind).\nexport const syncErrors = defineAlert(\"crm-sync-errors\", {\n  schedule: { type: \"cron\", cron: \"*/30 * * * *\" },\n  scope: { kind: \"runs\", workflow: onboarding },   // the definePlay handle\n  threshold: { metric: \"errorRate\", operator: \"gte\", value: 10 },\n  actions: [\n    // Bare { ref, config } for an agent; config is templated against the firing\n    // context. Typed connector/tool actions use the alertConnectorAction /\n    // alertToolAction helpers (config checked against the action's input schema).\n    { ref: sdr, config: { message: \"CRM sync error rate at {{event.value}}% — {{alert.url}}\" } },\n  ],\n});\n```\n\n`defineAlert` is the declarative front for the observability domain — the full\nscope/threshold matrix, metric units, and firing semantics live in\n[`../../cargo-observability/SKILL.md`](../../cargo-observability/SKILL.md).\n\nThe full `full` template wires all of the above together end-to-end — see\n[`../references/examples/full-workspace.md`](../references/examples/full-workspace.md).\n\n## Workflow bodies (`defineWorkflow`) — parsed, not executed\n\n`defineTool` and `definePlay` take a `workflow:` built with `defineWorkflow`. The\nbody callback is **parsed, not executed** — the SDK reads the function's source\nand lowers it into the engine's node graph. So the body must be a supported JS\nsubset (no `await`, `throw`, `try/catch`, closures, or destructuring).\n\n```ts\ndefineWorkflow(\n  \"onboard-contact\",\n  {\n    input: z.object({ email: z.string() }),\n    output: z.object({ welcomed: z.boolean(), message: z.string() }),\n    uses: { enrich }, // reference tools/agents by handle here (or toolRef/agentRef)\n  },\n  ({ input, uses, ai, integrations, native }) => {\n    const enriched = uses.enrich({ email: input.email }); // typed to the tool's I/O\n    const message = ai(`Welcome ${input.email} at ${enriched.company}.`);\n    return { welcomed: true, message };\n  },\n);\n```\n\n- **`uses.<key>(input)`** calls a referenced tool/agent; it's typed to that\n  resource's input and returns a `Ref` you can dot-access (`enriched.company`).\n- **`integrations.<slug>.<action>({…})`** calls a connector action. The\n  `integrations` registry is **empty until you run `cargo-ai cdk types`** (see\n  [`typed-config.md`](typed-config.md)); `native.*` works without a sync.\n- Control flow lowers idiomatically: `if/else` → branch, `else if` → switch,\n  `for (const x of xs)` → group. `ai(\"…\")` inline-completes; `js(({nodes}) => …)`\n  is the escape hatch for logic outside the supported subset. Flow helpers:\n  `balance`, `split`, `humanReview`, `memory`.\n\nFor the full workflow-authoring surface (per-call retry/fallback, the supported-JS\ntable, toolchain requirements), that lives in the `@cargo-ai/workflow-sdk` docs —\n`defineWorkflow` is re-exported from `@cargo-ai/cdk`, so you import it from the one\npackage.\n\nFile v1.2.3:guides/deploy-and-state.md\n\n# Deploy & state\n\nThe deploy engine compiles your `define*` graph, diffs it against\n`cargo.state.json`, and reconciles the difference to live Cargo infrastructure in\ndependency order — persisting state after **each** resource so a mid-deploy crash\nleaves a recoverable file.\n\nFor every flag, see [`../references/commands.md`](../references/commands.md).\n\n## plan → deploy → destroy\n\n```bash\n# Offline: compile the graph and diff against cargo.state.json. No API calls.\ncargo-ai cdk plan --dir my-workspace\n\n# Create/update resources in dependency order; write cargo.state.json.\ncargo-ai cdk deploy --dir my-workspace          # prompts for confirmation\ncargo-ai cdk deploy --dir my-workspace --yes    # non-interactive (CI)\n\n# Tear down.\ncargo-ai cdk destroy --dir my-workspace --target model:contacts   # one resource\ncargo-ai cdk destroy --dir my-workspace --all                     # everything in state\n```\n\nRe-running `deploy` only changes what changed — an unchanged workspace is a no-op.\n`deploy` is idempotent: for each resource it updates by uuid if state has one,\notherwise adopts a slug-addressable match (connector/model) that already exists,\notherwise creates.\n\n## `cargo.state.json` — commit it\n\n`deploy` writes `cargo.state.json`: the link from your code to the resources Cargo\ncreated. It records only `{hash, uuid, outputs}` per resource — **never secret\nvalues**.\n\n**Commit it.** It is the *only* handle on a deployed **play** or **agent**, which\nhave no slug (unlike connectors and models, which self-heal by slug). Losing state\norphans those resources. If it happens, re-establish a link with `import` (below).\n\nGit-ignore the generated types and the CDK's working files (but **not**\n`cargo.state.json`). `cargo-ai cdk init` scaffolds this:\n\n```gitignore\n.cargo-ai/\ncargo.state.lock\ncargo.state.bak.json\ncargo.state.audit.jsonl\n```\n\nThe `cargo.state.lock` prevents two deploys racing; `--force` steals a stale lock.\n\n**Workspace guard:** state records the workspace it was deployed to; the CDK\nrefuses to `deploy`/`destroy` when the state's workspace ≠ the currently selected\nworkspace, so you can't accidentally reconcile a dev definition into prod. Select\nthe right workspace at `login` (or with the workspace flag) before deploying.\n\n## Prune — deleting resources removed from code\n\n`deploy` does **not** delete a resource just because you removed it from code —\nthat would make a typo destructive. To also remove resources that are in state but\nno longer in code:\n\n```bash\ncargo-ai cdk deploy --dir my-workspace --prune\n```\n\nPrune deletes in reverse dependency order (dependents before their dependencies).\nAdopted resources (linked via `adopt: true` or `import`) are **released** from\nstate, not deleted.\n\n## Drift — `refresh` and `deploy --refresh`\n\nA resource can change outside the CDK (someone edits an agent in the Cargo UI).\nThe CDK captures a fingerprint of each resource at deploy and compares on refresh:\n\n```bash\ncargo-ai cdk refresh --dir my-workspace          # read-only: report what drifted\ncargo-ai cdk deploy  --dir my-workspace --refresh # re-read live, re-apply your code over drift\n```\n\n`refresh` reports resources changed or deleted out-of-band; `deploy --refresh`\nmakes your code the source of truth again.\n\n## Adopting existing resources — `import`\n\nTo bring an already-live resource under CDK management, bind it into state by\nmapping its **code id** to its **live uuid**:\n\n```bash\ncargo-ai cdk import model:contacts 6f0c8e2a-… --dir my-workspace\n```\n\nThe code id is `kind:slug` (e.g. `connector:hubspot`, `model:contacts`,\n`agent:sdr`). After import, `deploy` updates that resource instead of creating a\nduplicate. Slug-addressable kinds (connector, model) can also self-adopt on deploy\nby matching slug; uuid-only kinds (play, agent, capacity, territory, segment) need\n`import` to recover a lost link. See\n[`../recipes/migrate-existing-workspace.md`](../recipes/migrate-existing-workspace.md).\n\n## Recovery — `rollback`\n\n`deploy` snapshots the pre-deploy state to `cargo.state.bak.json`. If a deploy went\nwrong, restore the snapshot:\n\n```bash\ncargo-ai cdk rollback --dir my-workspace\n```\n\nThis restores the state file — it does not undo live API changes already made;\nfollow with a corrected `deploy`.\n\n## Async resources — workers & apps\n\nMost resources create synchronously. **Workers and apps build server-side**: on\ndeploy the reconciler uploads the bundle, waits for the build, and promotes it —\nso a deploy touching a worker/app takes longer. Author worker runtime code with\n`createWorker` (`@cargo-ai/worker-sdk`) and build to `index.js` before deploying;\nthe CDK validates the bundle files (`index.js`, `manifest.json`, `package.json`,\n`package-lock.json`) exist at define time. The live URL is exposed on the handle\n(`webhook.url`, `dashboard.url`). For imperative one-off hosting operations, see\n[`../../cargo-hosting/SKILL.md`](../../cargo-hosting/SKILL.md).\n\nFile v1.2.3:guides/typed-config.md\n\n# Typed config — `cargo-ai cdk types`\n\n`defineConnector`/`defineModel` config and the `integrations.*` registry in\nworkflow bodies are typed against **your workspace's real integration schemas**.\nThose types aren't bundled (they're workspace-specific) — you generate them:\n\n```bash\ncargo-ai cdk types --dir my-workspace\n```\n\nTyping is a **bonus, never a gate**: an integration you haven't synced (or a\ncustom one) falls back to a loose `Record<string, unknown>`, so `deploy` works\nwithout ever running `cdk types`.\n\n## What it generates\n\nEverything lands in `.cargo-ai/` (git-ignored):\n\n- **`.cargo-ai/cargo-types.d.ts`** — `declare module` augmentations:\n  - types `@cargo-ai/cdk`'s `defineConnector`/`defineModel` `config` against your\n    connector and extractor schemas. E.g. HubSpot's config becomes a discriminated\n    union — the editor completes `method` and requires the matching credential,\n    and `secret()` is accepted wherever a credential is expected.\n  - adds your workspace's integration slugs to the `Integrations` interface, so\n    `integrations.<slug>.<action>({ … })` in a workflow body typechecks against the\n    real action schema.\n- **`.cargo-ai/cargo-register.ts`** — eager `registerIntegration` /\n  `registerNative` calls so those slugs are **callable at runtime** in workflow\n  bodies.\n\nRe-run `cargo-ai cdk types` whenever your workspace's integrations change (added a\nconnector, changed an extractor).\n\n## Wiring it into your project\n\n`cdk init` sets this up; for a hand-rolled project, two steps:\n\n1. **Add the glob to `tsconfig.json` `include`.** A bare `.cargo-ai` (a dot-dir) is\n   ignored by TypeScript — you must use an explicit glob:\n\n   ```jsonc\n   // tsconfig.json\n   \"include\": [\"**/*.ts\", \".cargo-ai/**/*.d.ts\"]\n   ```\n\n2. **Import the runtime registrations** at the top of workflow modules that use\n   `integrations.*`:\n\n   ```ts\n   import \"./.cargo-ai/cargo-register.js\";\n   ```\n\n   (`native.*` needs no registration — the platform's native actions are identical\n   in every workspace, so their types ship with the SDK. Tools and agents are not a\n   registry either — reference them by handle through `defineWorkflow`'s `uses`.)\n\n## Symptoms that mean \"run `cdk types`\"\n\n- `config` on a `defineConnector` isn't autocompleting / isn't rejecting a wrong\n  credential shape → types not generated (or `.cargo-ai/**/*.d.ts` not in\n  `include`).\n- `integrations.myConnector` is `any` / not callable at runtime → missing the\n  `cargo-register` import, or types are stale after an integration change.\n- A connector `deploy` fails with `Invalid configuration` → often the credential\n  wasn't wrapped in `secret()`; generating types surfaces the required shape at\n  author time. See [`../references/troubleshooting.md`](../references/troubleshooting.md).\n\nFile v1.2.3:recipes/add-connector-and-model.md\n\n# Recipe: add a connector and a model sourced from it\n\n**Use when** the user wants a new data source plus a model built from it, managed\nas code. The key move is wiring the model to the connector **by handle** — the CDK\ndeploys the connector first and injects its dataset uuid.\n\n## 1. Define the connector\n\nCreating a data connector auto-creates a **dataset** that models source from. Put\nthe credential behind `secret()`.\n\n```ts\n// connectors/hubspot.ts\nimport { defineConnector, secret } from \"@cargo-ai/cdk\";\n\nexport const hubspot = defineConnector(\"hubspot\", {\n  integration: \"hubspot\",\n  config: { method: \"privateApp\", accessToken: secret(\"HUBSPOT_API_KEY\") },\n});\n```\n\nFor an OAuth/key connector you authenticated in the UI and can't declare in code,\nuse `adopt: true` so the reconciler links the existing instance instead of creating\none:\n\n```ts\nexport const openai = defineConnector(\"open_ai\", { integration: \"openAi\", adopt: true });\n```\n\n## 2. Define the model, wired to the connector\n\nPass the **connector handle** as `dataset` — not `hubspot.datasetUuid`:\n\n```ts\n// models/contacts.ts\nimport { defineModel } from \"@cargo-ai/cdk\";\nimport { hubspot } from \"../connectors/hubspot\";\n\nexport const contacts = defineModel(\"contacts\", {\n  dataset: hubspot,                 // ← handle: model depends on connector\n  extractSlug: \"fetchRecords\",\n  config: { objectType: \"contacts\", columnSelectionMode: \"all\" },\n  schedule: { type: \"cron\", cron: \"0 * * * *\" },  // refresh hourly\n});\n```\n\nIf the connector already exists (not defined in code), reference it by uuid:\n`dataset: connectorRef(\"<connector-uuid>\")` — or `datasetRef(\"<dataset-uuid>\")` to\npoint at a specific dataset.\n\n## 3. Type the config (optional but recommended)\n\n```bash\ncargo-ai cdk types    # now `config` on both builders type-checks against HubSpot's schema\n```\n\n## 4. Deploy\n\n```bash\nexport HUBSPOT_API_KEY=...\ncargo-ai cdk plan       # shows: create connector:hubspot, create model:contacts\ncargo-ai cdk deploy\ngit add cargo.state.json && git commit -m \"Add HubSpot connector + contacts model\"\n```\n\nThe plan orders the connector before the model automatically because the model's\n`dataset` handle depends on it. Re-deploying after a config edit updates in place.\n\nFile v1.2.3:recipes/build-an-agent.md\n\n# Recipe: build an agent (model + tool + agent)\n\n**Use when** the user wants an AI agent with a data model, a tool, and an LLM\nconnector — all as code. Everything wires by handle, so the CDK deploys in\ndependency order.\n\n## 1. The LLM connector\n\nAn agent needs a language-model provider connector. Adopt an existing one:\n\n```ts\n// connectors/openai.ts\nimport { defineConnector } from \"@cargo-ai/cdk\";\nexport const openai = defineConnector(\"open_ai\", { integration: \"openAi\", adopt: true });\n```\n\n## 2. A tool, backed by a workflow\n\n`defineWorkflow` compiles the logic (parsed, not executed); `defineTool` deploys it\nas the tool's release. Reference other resources inside the body via `uses`.\n\n```ts\n// tools/enrich.ts\nimport { defineTool, defineWorkflow } from \"@cargo-ai/cdk\";\nimport { z } from \"zod\";\n\nconst enrichFlow = defineWorkflow(\n  \"enrich-contact\",\n  {\n    input: z.object({ email: z.string() }),\n    output: z.object({ company: z.string(), enriched: z.boolean() }),\n  },\n  ({ input, integrations }) => {\n    const found = integrations.hunter.companyEnrichment({ domain: input.email });\n    return { company: found.name, enriched: true };\n  },\n);\n\nexport const enrich = defineTool(\"enrich\", {\n  workflow: enrichFlow,\n  description: \"Enrich a contact with firmographic data.\",\n  emojiSlug: \"mag\",\n});\n```\n\n> `integrations.*` is typed and callable only after `cargo-ai cdk types` (it reads\n> your workspace's integrations). `native.*` works without it. See\n> [`../guides/typed-config.md`](../guides/typed-config.md).\n\n## 3. The agent, referencing model + tool + connector\n\nPass each dependency as a handle — bare, or `{ ref, …options }` when it needs\noptions:\n\n```ts\n// agents/sdr.ts\nimport { defineAgent } from \"@cargo-ai/cdk\";\nimport { openai } from \"../connectors/openai\";\nimport { contacts } from \"../models/contacts\";\nimport { enrich } from \"../tools/enrich\";\n\nexport const sdr = defineAgent(\"sdr\", {\n  connector: openai,\n  languageModel: \"gpt-4o\",\n  systemPrompt: \"You qualify inbound leads and enrich missing contact info.\",\n  maxSteps: 12,\n  capabilities: [\"webSearch\", \"memory\"],\n  models: [{ ref: contacts, readOnly: true }],\n  tools: [enrich],\n  triggers: [{ type: \"cron\", cron: \"0 9 * * *\", text: \"Daily qualification\" }],\n  evaluator: { rubric: \"Did it correctly qualify the lead?\", threshold: 0.8 },\n});\n```\n\nAdd a sub-agent with `subAgents: [{ ref: enricher, waitUntilFinished: true }]`, or a\nraw connector action with\n`connectorActions: [{ integration: \"hunter\", actionSlug: \"emailFinder\" }]`.\n\n## 4. Deploy\n\n```bash\ncargo-ai cdk types      # so integrations.* in the workflow body typecheck\ncargo-ai cdk plan       # orders: connector → tool (+ its workflow) → model → agent\ncargo-ai cdk deploy\ngit add cargo.state.json && git commit -m \"Add SDR agent\"\n```\n\nBecause `agent:sdr` has no slug, `cargo.state.json` is the **only** handle on it —\ncommit it, or the next deploy can't find it (recover with `cdk import agent:sdr <uuid>`).\n\nArchive v1.2.2: 16 files, 32517 bytes\n\nFiles: guides/authoring-resources.md (10740b), guides/deploy-and-state.md (4952b), guides/typed-config.md (2811b), recipes/add-connector-and-model.md (2247b), recipes/build-an-agent.md (2971b), recipes/deploy-from-ci.md (2476b), recipes/migrate-existing-workspace.md (2532b), recipes/scaffold-a-workspace.md (2636b), references/commands.md (2460b), references/examples/full-workspace.md (4312b), references/resources.md (6745b), references/troubleshooting.md (3775b), skill-card.md (2486b), skill-metadata.json (2055b), SKILL.md (15037b), _meta.json (128b)\n\nFile v1.2.2:SKILL.md\n\n---\nname: cargo-cdk\ndescription: \"Manage a whole Cargo workspace as code — declare connectors, models, plays, tools, agents, MCP servers, segments, context, folders, files, workers, and apps in TypeScript, then reconcile them with `cargo-ai cdk` (init → types → plan → deploy), the way you would run Pulumi or the AWS CDK. Triggers: \\\"as code\\\", \\\"in git\\\", \\\"version-controlled\\\", \\\"reproducible\\\", \\\"Terraform for Cargo\\\", \\\"set up a whole workspace\\\", \\\"staging and production\\\", \\\"deploy from CI\\\", \\\"review this in a PR\\\", \\\"cargo.state.json\\\", \\\"scaffold from a template\\\". Scaffoldable outcome templates live in cargo-cookbooks. Skip when: it is a one-off operation, a read, or an ad-hoc query — use the matching capability skill.\"\nversion: \"1.2.2\"\ncompatibility: Requires @cargo-ai/cli (npm). Sign in or create an account with `cargo-ai login --email` (emailed code, no browser), `--oauth`, or an API token\nhomepage: https://github.com/getcargohq/cargo-skills\nmetadata:\n  author: getcargo\n  openclaw:\n    requires:\n      bins:\n        - cargo-ai\n    install:\n      - kind: node\n        package: \"@cargo-ai/cli@latest\"\n        bins:\n          - cargo-ai\n    homepage: https://github.com/getcargohq/cargo-skills\n---\n\n# Cargo CDK — declarative workspace-as-code\n\nUse this skill to define a Cargo workspace in TypeScript (`define*` builders from\n`@cargo-ai/cdk`) and reconcile it to live infrastructure with `cargo-ai cdk deploy`.\nIt is the **declarative** counterpart to the imperative capability skills: instead\nof running one CLI command per resource, you write the whole graph once and deploy\nit repeatably, with a committed `cargo.state.json` linking your code to what Cargo\ncreated.\n\n## Bootstrap\n\nAlready signed in (`cargo-ai whoami` returns a workspace)? Skip to the next section.\n\n```bash\nnpm install -g @cargo-ai/cli            # no global install? prefix every command with `npx @cargo-ai/cli`\ncargo-ai login --email you@company.com  # emailed code, no browser; creates the account on first use\n                                        # alternatives: --oauth (browser) · --token <api-token> (CI)\ncargo-ai whoami                         # confirm the active workspace before any write\ncargo-ai cdk --help                     # `unknown command` = CLI too old; reinstall @cargo-ai/cli@latest\n```\n\nTwo CDK-specific extras: the project needs **`@cargo-ai/cdk` as a dependency** for the `define*` builders you import (`cargo-ai cdk init` scaffolds a `package.json` with it — then `npm install`), and the `cargo-ai cdk` domain ships with the CLI itself.\n\nEvery command prints JSON to stdout; failures exit non-zero with `{\"errorMessage\": \"...\"}`. Anything that creates a run or a batch is async — pass `--wait-until-finished` or poll the matching `get`. When the full skill bundle is installed, [`../cargo/references/prerequisites.md`](../cargo/references/prerequisites.md) adds the CLI version pin, token scopes, and the admin-only surface.\n\n## 1) What this skill governs\n\n- **Authoring** every Cargo resource with a `define*` builder that returns a\n  **handle**; wiring resources by passing handles to each other (the dependency\n  graph is your variable graph).\n- **Deploying** the graph: `plan` (offline diff) → `deploy` (create/update, write\n  state) → `destroy` (tear down). Plus drift (`refresh`), adoption (`import`), and\n  recovery (`rollback`).\n- **Typing** the config against your workspace's real integration schemas\n  (`cargo-ai cdk types`).\n\nThe CDK spans **every** resource kind — so it overlaps every imperative capability\nskill (`cargo-connection`, `cargo-storage`, `cargo-ai`, `cargo-orchestration`,\n`cargo-content`, `cargo-hosting`, …). Which to reach for is the first decision:\n\n## 2) CDK or the CLI? — the routing decision\n\n> **Declarative (this skill) vs imperative (a capability skill).**\n\nUse the **CDK** when the user is **managing resources as an artifact**:\n\n- \"Set up / stand up / bootstrap a whole workspace (as code / from a template).\"\n- \"Make this reproducible / version-controlled / in git / repeatable across\n  environments (dev → prod).\"\n- \"Deploy these connectors + models + agents together\" (a multi-resource graph\n  wired by dependency).\n- Anything that should be re-runnable and diffable, where losing the definition\n  would be a problem.\n\nUse the matching **capability skill** (imperative `cargo-ai <domain>`) when the\nuser is doing a **one-off operation** or **exploring**:\n\n- \"Create one connector\", \"add a column to this model\", \"list connectors\",\n  \"run this workflow\", \"query storage\", \"read this agent's memory.\"\n- Any read, ad-hoc query, or single mutation that doesn't need to live in code.\n\nWhen unsure, ask whether the result should be committed and re-deployable. If yes\n→ CDK. If it's a quick action or a read → the capability skill (see the\n[`cargo` router](../cargo/SKILL.md) to pick the right domain).\n\n## 3) The lifecycle\n\n```\ncargo-ai cdk init <dir>     scaffold a project from a template (blank | full)\n        │\ncargo-ai cdk types          generate per-workspace types for typed config (optional)\n        │\n   (author define* files)   importing a .ts file IS registration — no manifest\n        │\ncargo-ai cdk plan           offline: compile the graph, diff against cargo.state.json\n        │\ncargo-ai cdk deploy         create/update resources in dependency order, write state\n        │\ncargo-ai cdk destroy        tear down resources recorded in state\n```\n\n> **`cdk plan` says what resources change; it doesn't show what a play does.**\n> For a `definePlay` / `defineTool` graph past three nodes, present a Mermaid\n> flowchart of the node graph alongside the plan — routing, fallbacks, and which\n> nodes bill on every scheduled run are what the reviewer is approving. Generate it\n> from the deployed release after the first deploy, or from the node array while\n> authoring:\n> [`../cargo-orchestration/references/node-diagram.md`](../cargo-orchestration/references/node-diagram.md).\n\nSide branches: `cargo-ai cdk refresh` (read-only drift report) · `deploy --refresh`\n(re-apply code over out-of-band edits) · `deploy --prune` (delete resources removed\nfrom code) · `cargo-ai cdk import <id> <uuid>` (bind an existing live resource into\nstate) · `cargo-ai cdk rollback` (restore the pre-deploy state snapshot).\n\n## 4) Documentation hierarchy\n\n- **Level 1** — `SKILL.md` (this file): the decision model, lifecycle, critical\n  rules, and routing.\n- **Level 2** — Guides:\n  [`guides/authoring-resources.md`](guides/authoring-resources.md),\n  [`guides/deploy-and-state.md`](guides/deploy-and-state.md),\n  [`guides/typed-config.md`](guides/typed-config.md).\n- **Level 2.5** — Recipes: [`recipes/*.md`](recipes/) — step-by-step playbooks to\n  follow as your execution plan.\n- **References** — [`references/resources.md`](references/resources.md) (the full\n  builder catalog), [`references/commands.md`](references/commands.md) (every\n  `cargo-ai cdk` subcommand + flags),\n  [`references/troubleshooting.md`](references/troubleshooting.md), and\n  [`references/examples/full-workspace.md`](references/examples/full-workspace.md).\n\n## 5) Read behavior — match the task to a doc and READ IT\n\n| When the task involves… | Read this first | What it gives you |\n|---|---|---|\n| Writing `define*` files, wiring resources, `secret()`/`env()`, `defineWorkflow` bodies (tool/play logic) | [`guides/authoring-resources.md`](guides/authoring-resources.md) | The builder catalog, the handle/ref model, secrets, and how workflow bodies compile. |\n| `plan` / `deploy` / `destroy`, the state file, drift, adopting existing resources, CI | [`guides/deploy-and-state.md`](guides/deploy-and-state.md) | The deploy lifecycle, `cargo.state.json` semantics, drift/import/rollback, async builds. |\n| Typed config, `cargo-ai cdk types`, tsconfig wiring, `integrations.*` in workflow bodies | [`guides/typed-config.md`](guides/typed-config.md) | What `cdk types` generates and how to wire it into your project. |\n| A field/spec/output for a specific builder | [`references/resources.md`](references/resources.md) | Every builder → spec fields → which ref each takes → outputs. |\n| Exact command flags | [`references/commands.md`](references/commands.md) | Every `cargo-ai cdk` subcommand and its flags. |\n| A deploy error / footgun | [`references/troubleshooting.md`](references/troubleshooting.md) | The known failure modes and fixes. |\n\n### Cookbooks — check the menu before authoring a known outcome from scratch\n\n[`getcargohq/cargo-cookbooks`](https://github.com/getcargohq/cargo-cookbooks) is a\nlibrary of ~20 composable cookbook folders of pre-written `define*` resources — one\nper GTM outcome (TAM building, list building, inbound qualification, contact\nsourcing, routing engine, account scoring, auto-enrichment, meeting prep, pipeline\nhealth, AI SDR, rep cockpit, …), all built on a shared `base-gtm` foundation\n(accounts/contacts models + core connectors). A cookbook scaffolds directly:\n\n```sh\ncargo-ai cdk init my-tam --from getcargohq/cargo-cookbooks/tam-building\n```\n\n`--from` pulls the cookbook plus its required siblings (`base-gtm`, transitively)\nwith the folder layout intact, so cross-folder imports resolve.\n\n**Routing rule:** when the user asks for a common GTM outcome as code, read the\ncookbook menu (the repo README's table) **first**. A cookbook matches → scaffold\nit, edit the `PLACEHOLDER`-marked values (API keys via env, channel IDs, persona\nfilters), then `plan` → `deploy`. No ma\n\nArchive v1.2.1: 16 files, 31675 bytes\n\nFiles: guides/authoring-resources.md (10740b), guides/deploy-and-state.md (4952b), guides/typed-config.md (2811b), recipes/add-connector-and-model.md (2247b), recipes/build-an-agent.md (2971b), recipes/deploy-from-ci.md (2476b), recipes/migrate-existing-workspace.md (2532b), recipes/scaffold-a-workspace.md (2636b), references/commands.md (2460b), references/examples/full-workspace.md (4312b), references/resources.md (6745b), references/troubleshooting.md (3775b), skill-card.md (3029b), skill-metadata.json (2055b), SKILL.md (12427b), _meta.json (128b)\n\nArchive v1.2.0: 16 files, 31538 bytes\n\nFiles: guides/authoring-resources.md (10740b), guides/deploy-and-state.md (4952b), guides/typed-config.md (2811b), recipes/add-connector-and-model.md (2247b), recipes/build-an-agent.md (2971b), recipes/deploy-from-ci.md (2476b), recipes/migrate-existing-workspace.md (2532b), recipes/scaffold-a-workspace.md (2636b), references/commands.md (2460b), references/examples/full-workspace.md (4312b), references/resources.md (6745b), references/troubleshooting.md (3775b), skill-card.md (2732b), skill-metadata.json (2055b), SKILL.md (12379b), _meta.json (128b)\n\nArchive v1.1.0: 16 files, 30017 bytes\n\nFiles: guides/authoring-resources.md (9653b), guides/deploy-and-state.md (4952b), guides/typed-config.md (2811b), recipes/add-connector-and-model.md (2247b), recipes/build-an-agent.md (2971b), recipes/deploy-from-ci.md (2476b), recipes/migrate-existing-workspace.md (2532b), recipes/scaffold-a-workspace.md (2636b), references/commands.md (2460b), references/examples/full-workspace.md (4312b), references/resources.md (4814b), references/troubleshooting.md (3775b), skill-card.md (2803b), skill-metadata.json (2055b), SKILL.md (11762b), _meta.json (128b)\n\nArchive v1.0.0: 15 files, 28226 bytes\n\nFiles: guides/authoring-resources.md (8893b), guides/deploy-and-state.md (4952b), guides/typed-config.md (2811b), recipes/add-connector-and-model.md (2247b), recipes/build-an-agent.md (2971b), recipes/deploy-from-ci.md (2476b), recipes/migrate-existing-workspace.md (2532b), recipes/scaffold-a-workspace.md (2636b), references/commands.md (2460b), references/examples/full-workspace.md (4312b), references/resources.md (4814b), references/troubleshooting.md (3775b), skill-card.md (2979b), SKILL.md (10227b), _meta.json (128b)","readmeExcerpt":"Skill: cargo-cdk Owner: cargo-ai Summary: Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project. Tags: latest:2.0.0 Version history: v2.0.0 | 2026-09-14T06:26:10.576Z | auto - Renamed the skill from cargo-cdk to cargo-project. - All guides, recipes, and reference documentation have been removed. - The skill now serves as a","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"npm install -g @cargo-ai/cli            # no global install? prefix every command with `npx @cargo-ai/cli`\ncargo-ai login --email you@company.com  # emailed code, no browser; creates the account on first use\n                                        # alternatives: --oauth (browser) · --token <api-token> (CI)\ncargo-ai whoami                         # confirm the active workspace before any write\ncargo-ai cdk --help                     # `unknown command` = CLI too old; reinstall @cargo-ai/cli@latest"},{"language":"text","snippet":"cargo-ai cdk init <dir>     scaffold a project from a template (blank | full)\n        │\ncargo-ai cdk types          generate per-workspace types for typed config (optional)\n        │\n   (author define* files)   importing a .ts file IS registration — no manifest\n        │\ncargo-ai cdk plan           offline: compile the graph, diff against cargo.state.json\n        │\ncargo-ai cdk deploy         create/update resources in dependency order, write state\n        │\ncargo-ai cdk destroy        tear down resources recorded in state"},{"language":"sh","snippet":"cargo-ai cdk add cookbook/tam-building               # inside a CDK project\ncargo-ai cdk init my-project --cookbook tam-building # no project yet: both at once"},{"language":"gitignore","snippet":".cargo-ai/\n  cargo.state.lock\n  cargo.state.bak.json\n  cargo.state.audit.jsonl"},{"language":"bash","snippet":"cargo-ai cdk init acme                        # scaffold\ncargo-ai cdk add cookbook/tam-building --dir acme  # layer a worked example on\ncargo-ai cdk types --dir acme                 # type config\ncargo-ai cdk plan --dir acme                  # preview\ncargo-ai cdk deploy --dir acme --yes          # apply (non-interactive)\ncargo-ai cdk refresh --dir acme               # drift report\ncargo-ai cdk import agent:sdr <uuid> --dir acme  # adopt a live agent\ncargo-ai cdk destroy --dir acme --all --yes   # tear down"},{"language":"sh","snippet":"cargo-ai cdk add cookbook/<slug>              # inside a CDK project: this is the copy step\ncargo-ai cdk init <dir> --cookbook <slug>     # no project yet: scaffold and install together\nnpx skills add getcargohq/gtm-skills/<slug>   # the procedure on its own, without the CDK resources"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: cargo-cdk\ndescription: \"Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project.\"\nversion: \"2.0.0\"\ncompatibility: Requires @cargo-ai/cli (npm).\nhomepage: https://github.com/getcargohq/cargo-skills\nmetadata:\n  author: getcargo\n  redirect: cargo-project\n---\n\n# cargo-cdk is now cargo-project\n\nLoad [`cargo-project`](../cargo-project/SKILL.md) instead. It is this skill under its new name, following the CLI: `cargo-ai cdk` is now `cargo-ai project`, and `cdk` still works as an alias.\n\nThis directory holds no instructions. It is a redirect, and will be removed in a later release."},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7by8t6yt9yghbxtxz6hv0bts87k6bq\",\n  \"slug\": \"cargo-cdk\",\n  \"version\": \"2.0.0\",\n  \"publishedAt\": 1789367170576\n}"},{"path":"skill-card.md","content":"## Description:\n\ncargo-cdk is a compatibility redirect that points existing installs to the renamed cargo-project skill.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[cargo-ai](https://clawhub.ai/user/cargo-ai)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agents use this compatibility entry to redirect legacy cargo-cdk installs to the cargo-project skill after the rename.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: This entry does not provide cargo-project behavior itself; relying on it without review can hide changed functionality or requirements.\n\nMitigation: Review the cargo-project skill and its @cargo-ai/cli requirements before deployment.\n\nRisk: The redirect entry is scheduled for future removal.\n\nMitigation: Update workflows and references to load cargo-project directly.\n\n## Reference(s):\n\n- [Cargo skills homepage](https://github.com/getcargohq/cargo-skills)\n- [cargo-cdk ClawHub release page](https://clawhub.ai/cargo-ai/skills/cargo-cdk)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, configuration]\n\n**Output Format:** [Markdown text]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Redirect-only entry; no executable code in the reviewed artifact.]\n\n## Skill Version(s):\n\n2.0.0 (source: frontmatter, skill-metadata.json, server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."},{"path":"skill-metadata.json","content":"{\n  \"$comment\": \"Generated by .github/scripts/skills-metadata.mjs — do not hand-edit. Regenerate with: node .github/scripts/skills-metadata.mjs --write .\",\n  \"name\": \"cargo-cdk\",\n  \"version\": \"2.0.0\",\n  \"documents\": [\n    {\n      \"path\": \"SKILL.md\",\n      \"kind\": \"entrypoint\",\n      \"title\": \"cargo-cdk is now cargo-project\"\n    }\n  ],\n  \"contentHash\": \"ad9701a71bd37558bd7ee80fff01428241f40a31b21598f547c5be5560965a92\"\n}"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project. Skill: cargo-cdk Owner: cargo-ai Summary: Renamed to cargo-project. This entry exists only so installs from before the rename are replaced by a pointer. Skip when: always — load cargo-project. Tags: latest:2.0.0 Version history: v2.0.0 | 2026-09-14T06:26:10.576Z | auto - Renamed the skill from cargo-cdk to cargo-project. - All guides, recipes, and reference documentation have been removed. - The skill now serves as a","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1204,"uniquenessScore":47,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T15:02:39.701Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T15:02:39.701Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T17:35:26.950Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}