Skip to content

Migrate an early-alpha project to architecture v2 ​

Use this guide only for an Agent SDK project deployed on architecture v1 during the early alpha. Every other project already runs on v2.

Check whether your project needs migration ​

Your project needs migration if any of these is true:

  • package.json depends on @cursor/july.
  • A script or CI job runs the early-alpha CLI.
  • The agent sets architecture: "v1" or runtime: "grokbot".
  • The project has bot/storage.ts or agent/storage.ts.
  • An SCM channel credential is a literal value.
  • Code uses a /v1 continuation selector.
  • A reminder uses an anonymous run or until function.
  • A peer connection reads its URL from a *_MCP_URL secret.
  • agent-sdk deployment get <slug> doesn't print architecture: v2.

agent-sdk migrate checks the source for these signals and prints Nothing to migrate. when it finds none. It doesn't check scripts, CI jobs, or the hosted deployment.

To swap the early-alpha package, run:

bash
npm uninstall @cursor/july
npm install @grok/agent-sdk@latest

An existing agent/ folder still works.

Start the migration ​

Commit and push the source first. agent-sdk migrate starts a Cursor cloud agent on that pushed ref, and the agent opens a pull request without deploying.

bash
agent-sdk login
agent-sdk migrate --dir .

To migrate a pushed source outside your checkout, pass --repo, --ref, and --path. The CLI reference lists every flag.

You can also ask a coding agent in your checkout to follow the bundled bdk-migrate-v2 skill. If the project relies on a v1 capability that has no v2 path, the agent stops and names the blocker.

Review the pull request ​

Before you merge, check that the pull request:

  • Uses @grok/agent-sdk and agent-sdk, and removes architecture: "v1".
  • Moves durable state to ctx.host.kv or ctx.host.files, reads secrets inside the handler that needs them, and expects hosted routes to return 202.
  • Passes every SCM credential as { secretName: "NAME" }. agent-sdk validate warns about a literal or process.env getter while architecture: "v1" is set, and fails once you remove it.
  • Replaces each peer URL secret, such as BUILDER_MCP_URL, with defineConnection({ agent: "<slug>" }). Check each slug and any TODO the agent left.
  • Lists unsupported behavior, follow-ups, and the checks it ran or handed off.

Choose a cutover ​

CutoverWhat happensChoose it when
Same slugv2 copies the v1 secrets and replaces v1 once it starts. You can't undo it, and it deletes v1's hosted sessions, KV, files, and eval runs.A short outage and an empty v2 state are fine.
New slugv1 keeps serving while you test v2. Move senders to the new URL, then delete v1.You use Slack, webhooks, or hosted state.

With a new slug, point the trial at a test repository so the two deployments don't both act on the same events.

Deploy after merge ​

Deploy from the merged, pushed ref. Reuse every --cursor-events-repo value from v1, and move every --allow-domain value into hosting.egressDomains.

bash
agent-sdk deploy --dir . --slug <existing-or-new-slug>

Then follow the checklist that agent-sdk migrate printed:

  1. Deploy each agent folder separately by running agent-sdk deploy --dir <agent-folder> once for each one.
  2. For each Slack agent, run agent-sdk slack create --env prod --dir <agent-folder>. Then uninstall the old app and invite the new bot to its channels.
  3. For a peer connection, deploy both agents to the same team. Then delete each peer URL secret the pull request lists with agent-sdk secret delete <slug> NAME.
  4. For a new slug, add each secret with agent-sdk secret set <slug> NAME. It applies without a redeploy.

Finally, verify a hosted turn.