# Migrate an early-alpha project to architecture v2

Use this guide only for Agent SDK projects deployed during the
early alpha. Projects that never deployed on architecture v1 already use v2
and need no migration.

## Check whether your project needs migration

Migrate when at least one of these signals is present:

- `package.json` depends on the legacy v1 package. Remove it, then install
  the package `agent-sdk init` writes:

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

- A script or CI job runs the legacy early-alpha CLI.

- `agent/agent.ts` sets `architecture: "v1"`.

- `agent-sdk deployment get <slug>` does not print `architecture: v2`.

Stop when none of these is true. An existing `agent/` project root can remain
in place; Agent SDK still loads it even though current examples use `bot/`.

`agent-sdk migrate` prints `Nothing to migrate.` and exits 0 only when `--dir` shows
no migration work. The check looks for an `@cursor/july` dependency,
`architecture: "v1"`, `bot/storage.ts` or `agent/storage.ts`,
`runtime: "grokbot"`, a literal SCM credential, a `/v1` continuation selector,
an anonymous reminder, and a `*_MCP_URL` peer connection. When any of those is
present, or a project file cannot be read, the command starts the agent. It
does not read the hosted deployment. Run `agent-sdk deployment get <slug>` when you still
need to see whether that copy is on v1.

## Start the migration

Commit and push the source you want to migrate. `agent-sdk migrate` reads that
pushed Git ref, starts a Cursor cloud agent with the bundled migration skill,
and waits for the agent to open a pull request. It does not deploy the project.

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

Inside a checkout, the command infers the repository, current ref, and project
path. Pass them when you need to target a different pushed source:

```bash
agent-sdk migrate \
  --dir ./bots/triage \
  --repo https://github.com/acme/agents \
  --ref migrate-triage-v2 \
  --path bots/triage
```

Use `--no-wait` to print the cloud agent URL and return while it works. Use
`--json` for machine-readable status. The
[CLI reference](/docs/reference/cli.md#migrate) covers every flag, output, and
exit status.

## Use the coding-agent skill directly

You can instead ask a coding agent working in the project checkout to follow
the bundled
[`bdk-migrate-v2` skill](/docs/package/skills/migrate-v2/SKILL.md). The skill owns the
code changes, capability checks, local verification, and deployment handoff.

> Follow the `bdk-migrate-v2` skill for this project. Open one pull request
> with the migration, but do not deploy it or change deployment secrets.

If the project depends on a v1 capability without a supported v2 path, the
skill tells the coding agent to stop and name the blocker instead of removing
the behavior.

## Review the pull request

Before merging, confirm the pull request:

- Uses `@grok/agent-sdk` and `agent-sdk`, and removes the v1 architecture opt-in.

- Moves durable state to `ctx.host.kv` or `ctx.host.files`, reads secrets
  inside the handler that needs them, and accounts for hosted HTTP routes
  returning `202`.

- Names SCM channel secrets instead of reading them: every
  `githubChannel({ credentials })` field and the GitLab or Bitbucket
  `webhookSecret` is `{ secretName: "NAME" }`. `agent-sdk validate` reports each
  field still written as a literal or `() => process.env.NAME` getter, as a
  warning while `architecture: "v1"` is set and as an error once it is
  removed. The [GitHub guide](/docs/guides/github.md#other-hosts) explains the named
  form.

- Rewrites each peer call that took its URL from a secret or environment
  variable, such as `BUILDER_MCP_URL`, to
  `defineConnection({ agent: "<slug>" })` under `bot/mcp-connections/`
  (or `agent/mcp-connections/` when the project root is `agent/`).
  Confirm the slug before you merge. The pull request lists each secret the
  rewrite left unused, and it leaves a TODO where it could not determine
  the slug.

- Calls out unsupported behavior and any follow-up needed for reminders,
  schedules, Slack, or MCP connections.

- Reports the validation, type checks, tests, and credential-dependent checks
  it ran or handed off.

The migration pull request should change source only. Deploy after it merges.

## Choose a cutover

| Cutover | What happens | Choose it when |
| --- | --- | --- |
| Same slug | The v2 deployment copies the v1 secrets and replaces v1 after it starts. The cutover cannot be undone, and it deletes v1's hosted sessions, KV, files, and eval runs. | A service interruption and an empty v2 state are acceptable. |
| New slug | The v1 deployment keeps serving while you configure and test v2. Move senders to the new URL, then delete the old deployment. | You use Slack, webhooks, or hosted state, or want a staged cutover. |

Prefer a new slug for Slack, webhooks, or data in `ctx.host.kv`. Point the trial
at a test repository so both deployments do not act on the same source-control
events. If the CLI reports that same-slug replacement is unavailable, use a
new slug.

## Deploy after merge

Deploy from the merged, pushed ref. Reuse every `--cursor-events-repo` value
from the v1 deployment, and move every `--allow-domain` value into
`hosting.egressDomains`. `agent-sdk deploy` has no `--allow-domain` flag.

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

When the folder contains more than one agent, deploy each agent folder
alone. Run `agent-sdk deploy --dir <agent folder>` one time for each agent. One
`agent-sdk deploy` on the parent folder prints those commands and does not deploy.
Do not use `agent-sdk deploy --all`. Repeat `agent-sdk slack create --env prod` for each
agent folder. The Slack app slug is the folder name.

When the pull request calls another agent with
`defineConnection({ agent: "<slug>" })`, deploy the caller and that peer
on `@grok/agent-sdk` 0.2.18 or newer. Both deployments must belong to the
same team, and the caller reaches the peer once the peer deployment is
running. The connection file is already in the merged source, so unset
each URL secret the pull request lists after both deploys:

```bash
agent-sdk secret delete <slug> NAME
```

`agent-sdk migrate` prints the steps that follow the first deploy: one deploy per
agent folder, `agent-sdk slack create --env prod --dir <agent-folder>` for each Slack
agent, `agent-sdk secret delete` for peer URL secrets the pull request lists, and
`agent-sdk secret list` / `agent-sdk secret set` when the slug is new. Slack setup
redeploys the deployment by itself. `agent-sdk secret set` takes effect on the
next request. Neither step needs another deploy.

After the deployment starts, follow that checklist for Slack, webhook callers,
peer connections, and secrets, then verify a hosted turn. The
[deployment guide](/docs/deployment.md) covers the managed hosting workflow.

## Related

- [CLI reference](/docs/reference/cli.md#migrate): migration flags, output, and
  exit status
- [`bdk-migrate-v2` skill](/docs/package/skills/migrate-v2/SKILL.md): the coding
  procedure and complete capability matrix
- [Peer agents](/docs/guides/agent-to-agent.md): how a deployed caller reaches another
  agent by slug
- [Deployment](/docs/deployment.md): deploy and verify the reviewed project
