# Changelog

## 0.2.29 (2026-10-23)

### Breaking changes

- `@grok/agent-sdk/extensions/cursor-grokbot-agents` is removed. Remove that import. The package has no replacement.

### Behavior changes

- Rename commands and errors to agent-sdk

## 0.2.28 (2026-10-21)

### Breaking changes

- Semantic search is removed. Use Grep. Read [Migrate off semantic search](/docs/reference/agent-config.md#migrate-off-semantic-search).
- `CATCH_DELIVERY_ID_HEADER` left `@grok/agent-sdk/channels`. Remove that import. The npm package has no replacement.
- `attachRelayMcp` was not a published export. Remove that import. The npm package has no replacement.
- `CursorBackendClient` was not a published export. Remove that import. Clone a pull request with `@grok/agent-sdk/scm`.
- `postRelaySlackMessage` was not a published export. Remove that import. The npm package has no replacement.

### Behavior changes

- With deploy caps on, `agent-sdk deploy` stops at 20 deployments or 100 deploys in 24 hours. Read [Limits](/docs/reference/limits.md).
- `agent-sdk deploy` refuses `persistent: true`. A running persistent deployment keeps serving.
- A direct file-tool call respects `tools`. A path outside the workspace fails.
- With `local.sandbox` on, file tools refuse a path outside the session workspace.
- `@grok/agent-sdk` depends on `@modelcontextprotocol/sdk` 1.32.1.
- An MCP server that redirects to a different host or port fails.
- `agent-sdk init` and the templates depend on zod 4.

### New

- `claimIssue` is newly public on `@grok/agent-sdk/channels/issues`.
- `claimCheckpoint` is newly public on `@grok/agent-sdk/channels/change-monitors`.
- `@grok/agent-sdk/scm` is newly public.
- `agent-sdk sessions --prod` lists sessions on a Cursor-managed deployment.
- Set `botScopes` in `slack-manifest.json`, then run `agent-sdk slack create` again.
- Slack `post-file` accepts `alt_txt` and `initial_comment`.
- Send `X-BDK-Session-Key` to keep one hosted session for that key.
- A pull request on `<tenant>.ghe.com` keeps its own session.
- `agent-sdk logs --prod` prints process output and a `tool <name>` line. `agent-sdk session --prod --events` prints the events.

### Fixes

- A failed Slack file upload is reported on that thread.

## 0.2.27 (2026-10-16)

### Breaking changes

- Each `handle.agents` entry is `{ slug, url, info }`. It no longer has `project`. Read `info` instead.

### Behavior changes

- `@grok/agent-sdk` requires `@cursor/sdk` 1.0.38.
- In project info, a function `needsApproval` is `"dynamic"` instead of `true`.
- Project info has `schemaVersion: 1` and `architecture`. Diagnostic paths are relative to the project directory.
- `handle.project` is deprecated. Use `handle.agents`.
- `loadAgentProject`, `loadAgentProjects`, and `projectInfo` are deprecated. Use `loadProject`.
- `root` on `defineAgent` is deprecated. Use `fs`. Setting both is an error.

### New

- `loadProject(dir)` loads a project without serving it. Its `info` matches `GET /v1/info`. Pass `{ strict: true }` to fail on warnings.
- `serve` accepts a directory or a `Project` from `loadProject`.
- `defineAgent({ fs })` mounts your filesystem at `/`. Agent SDK mounts `/tmp` and `/agent/skills` over it.
- With `fs`, the agent's skills are read-only at `/agent/skills/<name>/SKILL.md`. Set `skills: false` to keep your own `/agent/skills`.
- Listing a directory includes the files of mounts nested under it.

### Fixes

- A local agent can use a model variant that needs Max Mode, such as Grok 4.7 with a 500k context window.
- A session that has been idle for 10 minutes releases its memory. Its next turn resumes the conversation.

## 0.2.26 (2026-10-16)

### Breaking changes

- `serve({ otel })` is removed. Delete `bot/otel.ts`, `agent/otel.ts`, and `bot/instrumentation.ts`. Set `OTEL_*` variables. Read [Migrating from serve({ otel })](/docs/guides/opentelemetry.md#migrating-from-serve-otel).

### Behavior changes

- `ctx.host.otel` is deprecated. It still runs for this release. The first call emits one deprecation warning. Set `OTEL_*` variables. Record with `metrics.getMeter` and `trace.getTracer` from `@opentelemetry/api`.
- A span started during a turn or a tool gets `cursor.conversation.id` from the active context when the span does not set it. A metric does not. Call `currentConversationId` from `@grok/agent-sdk/otel` and set the attribute yourself. See [OpenTelemetry](/docs/guides/opentelemetry.md#what-you-can-record).
- A turn waits for MCP OAuth only when a person can connect. That is a playground or HTTP chat turn, or a Slack message on a channel that shows Connect. `toolApprovals: true` shows Connect, and so does `buildToolApprovalEvents` in `events`. A schedule, a reminder, a webhook, an eval, or a Slack channel without Connect does not wait. A required connection fails with `Reconnect <connection>`. An optional connection is skipped.
- A turn never waits to authorize an `optional` connection, also in the playground.
- A turn that waits for MCP OAuth stops after 10 minutes with `Reconnect <connection>`. `interrupt()` also stops the wait.
- `agent-sdk deploy` rejects a source host other than GitHub, gitlab.com, or Origin.
- A new scaffold imports `zod/v4`. A zod 3 schema and a zod 4 schema both still parse.
- `agent-sdk deploy` with no terminal lists a connector that needs sign-in as pending.

### New

- `agent-sdk deploy` deploys a bot from a gitlab.com repository.
- When you omit `--cursor-events-repo`, a GitLab deploy watches that project. A nested group is part of the path.
- When that deploy cannot watch the project, the deploy still finishes. The CLI says the deployment is not watching the project.
- An agentic Slack reply can set `cards: { display: "plan" }`. Slack shows the `post-card` steps from that turn as one checklist.
- A `title` names that checklist. A title has at most 256 characters.
- With no `cards` option, Slack keeps one card for each step.
- `send()` returns a delivery id. Set `deliveryId` to choose it. `nudge.delivered` and `message.received` include that id.

### Fixes

- Public helper signatures use portable types. A webhook body is a `string` or a `Uint8Array`. An environment map is `Record<string, string | undefined>`.
- `HostFilesApi.read` takes a `HostFileTextEncoding`. A `Buffer` and `process.env` still type-check.
- OpenTelemetry ends each tool span when that tool finishes.
- With no OpenTelemetry endpoint, the process holds at most 2048 spans and 2048 log records.
- A follow-up after a redeploy resumes the same agent. A changed workspace path does not start a new conversation.
- In a Slack Connect channel, sender checks use the workspace where the app is installed.
- A `cursorAccount` GitHub GraphQL call includes the repository.
- A Slack bot with a lapsed MCP connection replies with a reconnect message.

## 0.2.25 (2026-10-14)

### New

- `agent-sdk validate --json` writes one JSON object. Each diagnostic has a code.

### Fixes

- OpenTelemetry metrics follow `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE`. The default stays delta.
- `ctx.host.github.getOctokit()` tries again after a failed lookup. A later call can succeed after a GitHub token becomes available.

## 0.2.24 (2026-10-13)

### Breaking changes

- Install `zod` in the project. The peer range is `^3.25.0` or `^4.0.0`. A new scaffold imports `zod/v3`.

### Behavior changes

- `setContinuationToken(null)` releases the continuation key. The next delivery starts a new session.
- Model fallback continues when a blocked model sends progress updates and no assistant text. Those updates are `user-message-appended`, `step-started`, and `step-completed`.
- Read a secret inside a handler, a tool, or a callback. A `process.env` read while the module is still loading returns an empty value on a Cursor-managed deploy.
- In the Agentic Approver template, a `paths` glob is relative to the policy directory.
- The package depends on `tsx` 4.23.15.

### New

- `hmacSignatureAuth` takes an optional `separator`. One header can then carry several HMAC signatures. PagerDuty uses a comma.
- `cursorCloudAgents` accepts `cloud.teamMcpServers`. The launch uses the team MCP servers you name.

### Fixes

- On Cursor-managed hosting, OpenTelemetry reads the endpoint, the headers, and the resource after secrets load. You can remove a workaround that reads `OTEL_EXPORTER_OTLP_HEADERS` again.

## 0.2.23 (2026-10-09)

### Behavior changes

- `agent-sdk migrate` rewrites a URL-secret MCP peer to `defineConnection({ agent })` in the migration pull request.
- `agent-sdk migrate` prints a checklist after the migration. It says when there is nothing to migrate.
- `agent-sdk slack create --prod` says the deployment redeploys by itself.
- `agent-sdk deploy` on a folder of several agents prints one command per agent. You run each command to deploy that agent.

### New

- A Slack app can opt in to the `chat:write.customize` scope. A post can then set its username and its icon. An app that leaves the scope off keeps its current scopes.
