@cursor/july 0.1.96 → 0.1.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +3 -2
- package/dist/bin/agent-serve.js +13 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +16 -0
- package/dist/channels/origin/api.d.ts +15 -4
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +19 -3
- package/dist/channels/origin/binding.d.ts +11 -0
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +41 -25
- package/dist/channels/origin/index.d.ts +1 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +1 -0
- package/dist/channels/origin/origin-channel.d.ts +2 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +40 -4
- package/dist/channels/origin/reactions.d.ts +56 -0
- package/dist/channels/origin/reactions.d.ts.map +1 -0
- package/dist/channels/origin/reactions.js +67 -0
- package/dist/channels/origin/types.d.ts +11 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/approvals.d.ts +16 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -1
- package/dist/channels/slack/approvals.js +86 -0
- package/dist/channels/slack/cli-project.d.ts +19 -0
- package/dist/channels/slack/cli-project.d.ts.map +1 -0
- package/dist/channels/slack/cli-project.js +234 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +142 -63
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +1 -1
- package/dist/channels/slack/init.d.ts +3 -2
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +5 -5
- package/dist/channels/slack/interactive.d.ts +2 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +15 -4
- package/dist/channels/slack/live-delivery.d.ts +1 -1
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +4 -2
- package/dist/channels/slack/manifest.d.ts +1 -1
- package/dist/channels/slack/manifest.js +1 -1
- package/dist/channels/slack/progress-delivery.d.ts +28 -0
- package/dist/channels/slack/progress-delivery.d.ts.map +1 -0
- package/dist/channels/slack/progress-delivery.js +115 -0
- package/dist/channels/slack/setup.d.ts +1 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +10 -6
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +1 -0
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +91 -1
- package/dist/channels/slack/types.d.ts +9 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.jXleCmOc.js → app.BplEAZ3S.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.8LhyglIT.js → VPLocalSearchBox.CHXyv4wP.js} +1 -1
- package/dist/docs/assets/chunks/{theme.9ged-pr2.js → theme.BTcsZmjQ.js} +2 -2
- package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
- package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
- package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.js → reference_cli.md.DfoeyvL0.js} +9 -6
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.lean.js → reference_cli.md.DfoeyvL0.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
- package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.BEJx9XVj.js} +2 -2
- package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.CvAHsdSp.js} +10 -2
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.CvAHsdSp.lean.js} +1 -1
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/deployment.md +5 -4
- package/dist/docs/design/runtime-abstraction.md +1757 -0
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +8 -8
- package/dist/docs/guides/mcp-oauth.md +26 -8
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +17 -33
- package/dist/docs/guides/slack.md +92 -201
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +5 -3
- package/dist/docs/llms-full.txt +2065 -637
- package/dist/docs/llms.txt +3 -2
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/agent-config.md +2 -2
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +13 -10
- package/dist/docs/reference/cli.md +32 -16
- package/dist/docs/reference/connections.html +9 -8
- package/dist/docs/reference/connections.md +6 -3
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +7 -7
- package/dist/docs/reference/http-api.md +3 -1
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +5 -5
- package/dist/docs/reference/sessions.md +4 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +15 -7
- package/dist/docs/reference/tools.md +34 -2
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +28 -0
- package/dist/docs/templates/agents-md.md +105 -0
- package/dist/docs/templates/code-wiki.html +5 -5
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +5 -5
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/evals/run-facts.d.ts.map +1 -1
- package/dist/evals/run-facts.js +27 -0
- package/dist/files-backends/cursor-hosted.d.ts +3 -2
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +15 -9
- package/dist/internal/approval-gate.d.ts +12 -13
- package/dist/internal/approval-gate.d.ts.map +1 -1
- package/dist/internal/approval-gate.js +16 -21
- package/dist/internal/as-of.d.ts +19 -0
- package/dist/internal/as-of.d.ts.map +1 -0
- package/dist/internal/as-of.js +82 -0
- package/dist/internal/chat-client.js +10 -0
- package/dist/internal/cli-deploy.d.ts +6 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +149 -21
- package/dist/internal/cli-mcp-oauth.js +8 -18
- package/dist/internal/cli-slack-manual.d.ts +24 -2
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +251 -20
- package/dist/internal/cli-slack.d.ts +9 -2
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +29 -82
- package/dist/internal/cursor/account-mcp.d.ts +1 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +17 -0
- package/dist/internal/cursor-agent-template.d.ts +1 -1
- package/dist/internal/cursor-agent-template.d.ts.map +1 -1
- package/dist/internal/cursor-agent-template.js +1 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +5 -6
- package/dist/internal/deploy-client.d.ts +17 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +31 -10
- package/dist/internal/env-file.d.ts +19 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +90 -0
- package/dist/internal/framework-file-storage.d.ts +11 -17
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +17 -40
- package/dist/internal/framework-storage-selection.d.ts +13 -11
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +37 -26
- package/dist/internal/hosted-admission-adapter.d.ts +28 -0
- package/dist/internal/hosted-admission-adapter.d.ts.map +1 -0
- package/dist/internal/hosted-admission-adapter.js +7 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +13 -1
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +8 -1
- package/dist/internal/hosted-delivery.d.ts +21 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +101 -34
- package/dist/internal/hosted-execution-diag.d.ts +59 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
- package/dist/internal/hosted-execution-diag.js +187 -0
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +85 -2
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +2 -0
- package/dist/internal/logs-client.d.ts +5 -0
- package/dist/internal/logs-client.d.ts.map +1 -1
- package/dist/internal/logs-client.js +5 -0
- package/dist/internal/mcp-endpoint.js +2 -3
- package/dist/internal/mcp-host.d.ts +10 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +57 -8
- package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
- package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-on-demand.js +287 -0
- package/dist/internal/mcp-oauth-persist.d.ts +42 -0
- package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-persist.js +92 -0
- package/dist/internal/mcp-oauth.d.ts +1 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -1
- package/dist/internal/mcp-oauth.js +10 -2
- package/dist/internal/null-kv-storage.d.ts +48 -0
- package/dist/internal/null-kv-storage.d.ts.map +1 -0
- package/dist/internal/null-kv-storage.js +58 -0
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +22 -9
- package/dist/internal/server.d.ts +6 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +123 -33
- package/dist/internal/session-engine.d.ts +88 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +538 -46
- package/dist/internal/session-run-log.d.ts +120 -0
- package/dist/internal/session-run-log.d.ts.map +1 -0
- package/dist/internal/session-run-log.js +359 -0
- package/dist/internal/sessions-client.d.ts +9 -7
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +3 -1
- package/dist/internal/storage-coordinator.d.ts +13 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +37 -6
- package/dist/internal/storage-roles.d.ts +5 -0
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +10 -0
- package/dist/internal/tool-policy.d.ts +29 -9
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +24 -0
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +10 -0
- package/dist/internal/turn-outbox.d.ts +24 -0
- package/dist/internal/turn-outbox.d.ts.map +1 -0
- package/dist/internal/turn-outbox.js +80 -0
- package/dist/playground/assets/index-D7rGZNjy.css +1 -0
- package/dist/playground/assets/index-jzNbJENa.js +69 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +1 -1
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +12 -0
- package/dist/storage-protocol.d.ts +8 -0
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +8 -0
- package/dist/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/tools.d.ts +12 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/types.d.ts +88 -7
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +5 -3
- package/docs/deployment.md +5 -4
- package/docs/design/runtime-abstraction.md +1757 -0
- package/docs/guides/mcp-oauth.md +26 -8
- package/docs/guides/slack.md +93 -202
- package/docs/reference/agent-config.md +2 -2
- package/docs/reference/cli.md +32 -16
- package/docs/reference/connections.md +6 -3
- package/docs/reference/http-api.md +3 -1
- package/docs/reference/sessions.md +4 -2
- package/docs/reference/tools.md +34 -2
- package/docs/templates/agents-md.md +110 -0
- package/docs/troubleshooting.md +2 -2
- package/package.json +1 -1
- package/skills/create-agent/SKILL.md +2 -1
- package/skills/mcp-auth/SKILL.md +6 -3
- package/skills/setup-slack/SKILL.md +23 -13
- package/src/bin/agent-serve.ts +12 -1
- package/src/channels/github/github-channel.ts +17 -0
- package/src/channels/origin/api.ts +24 -5
- package/src/channels/origin/binding.ts +55 -26
- package/src/channels/origin/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +78 -10
- package/src/channels/origin/reactions.ts +82 -0
- package/src/channels/origin/types.ts +11 -0
- package/src/channels/slack/approvals.ts +105 -0
- package/src/channels/slack/cli-project.ts +267 -0
- package/src/channels/slack/defaults.ts +165 -74
- package/src/channels/slack/dispatch.ts +2 -0
- package/src/channels/slack/init.ts +10 -5
- package/src/channels/slack/interactive.ts +35 -9
- package/src/channels/slack/live-delivery.ts +5 -3
- package/src/channels/slack/manifest.ts +1 -1
- package/src/channels/slack/progress-delivery.ts +133 -0
- package/src/channels/slack/setup.ts +10 -6
- package/src/channels/slack/slack-channel.ts +1 -0
- package/src/channels/slack/tool-approval-events.ts +93 -0
- package/src/channels/slack/types.ts +9 -1
- package/src/evals/run-facts.ts +32 -0
- package/src/files-backends/cursor-hosted.ts +3 -2
- package/src/index.ts +4 -0
- package/src/internal/advertise-tools.ts +31 -10
- package/src/internal/approval-gate.ts +20 -29
- package/src/internal/as-of.ts +107 -0
- package/src/internal/chat-client.ts +19 -0
- package/src/internal/cli-deploy.ts +203 -13
- package/src/internal/cli-mcp-oauth.ts +7 -21
- package/src/internal/cli-slack-manual.ts +350 -18
- package/src/internal/cli-slack.ts +40 -84
- package/src/internal/cursor/account-mcp.ts +21 -0
- package/src/internal/cursor-agent-template.ts +1 -0
- package/src/internal/cursor-event-relay.ts +5 -6
- package/src/internal/deploy-client.ts +43 -0
- package/src/internal/env-file.ts +84 -0
- package/src/internal/framework-file-storage.ts +18 -46
- package/src/internal/framework-storage-selection.ts +41 -25
- package/src/internal/hosted-admission-adapter.ts +42 -0
- package/src/internal/hosted-delivery-protocol.ts +14 -2
- package/src/internal/hosted-delivery.ts +169 -44
- package/src/internal/hosted-execution-diag.ts +252 -0
- package/src/internal/http-channel.ts +107 -0
- package/src/internal/init-project.ts +2 -0
- package/src/internal/logs-client.ts +5 -0
- package/src/internal/mcp-endpoint.ts +13 -4
- package/src/internal/mcp-host.ts +77 -11
- package/src/internal/mcp-oauth-on-demand.ts +352 -0
- package/src/internal/mcp-oauth-persist.ts +127 -0
- package/src/internal/mcp-oauth.ts +17 -1
- package/src/internal/null-kv-storage.ts +74 -0
- package/src/internal/otel/collector.ts +30 -0
- package/src/internal/server.ts +159 -11
- package/src/internal/session-engine.ts +691 -57
- package/src/internal/session-run-log.ts +584 -0
- package/src/internal/sessions-client.ts +17 -8
- package/src/internal/storage-coordinator.ts +49 -9
- package/src/internal/storage-roles.ts +7 -0
- package/src/internal/stream-progress.ts +19 -0
- package/src/internal/tool-policy.ts +49 -9
- package/src/internal/trajectory.ts +10 -0
- package/src/internal/turn-outbox.ts +85 -0
- package/src/storage-backends/cursor-hosted.ts +13 -1
- package/src/storage-protocol.ts +10 -0
- package/src/storage.ts +12 -0
- package/src/tools.ts +12 -2
- package/src/types.ts +93 -8
- package/templates/agents-md/README.md +39 -0
- package/templates/agents-md/agent/agent.ts +8 -0
- package/templates/agents-md/agent/channels/github.ts +10 -0
- package/templates/agents-md/agent/channels/queue.ts +28 -0
- package/templates/agents-md/agent/channels/slack.ts +9 -0
- package/templates/agents-md/agent/instructions.md +39 -0
- package/templates/agents-md/agent/lib/collect.ts +439 -0
- package/templates/agents-md/agent/lib/config.ts +8 -0
- package/templates/agents-md/agent/lib/paths.ts +51 -0
- package/templates/agents-md/agent/schedules/weekly.ts +17 -0
- package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
- package/templates/agents-md/evals/agents.eval.ts +135 -0
- package/templates/agents-md/evals/evals.config.ts +5 -0
- package/templates/agents-md/init.json +38 -0
- package/templates/agents-md/package.json +18 -0
- package/templates/agents-md/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.js +0 -1
- package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
- package/dist/docs/assets/index.md.CI93Ltlb.js +0 -5
- package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
- package/dist/docs/design/agsh.md +0 -406
- package/dist/playground/assets/index-B1DDvBeC.css +0 -1
- package/dist/playground/assets/index-Cx9CclK_.js +0 -88
- package/docs/design/agsh.md +0 -406
- /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.CI93Ltlb.lean.js → index.md.CVeRUOeZ.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.BEJx9XVj.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import{_ as a,c as e,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const c=JSON.parse('{"title":"Slack","description":"Put the agent in Slack: a dedicated Socket Mode app via the dashboard wizard, or a manual manifest import.","frontmatter":{"title":"Slack","description":"Put the agent in Slack: a dedicated Socket Mode app via the dashboard wizard, or a manual manifest import."},"headers":[],"relativePath":"guides/slack.md","filePath":"guides/slack.md"}'),n={name:"guides/slack.md"};function h(l,s,o,p,d,r){return i(),e("div",null,[...s[0]||(s[0]=[t(`<h1 id="slack-agents" tabindex="-1">Slack agents <a class="header-anchor" href="#slack-agents" aria-label="Permalink to "Slack agents""></a></h1><p>The Slack channel puts your agent in Slack as its own Socket Mode bot. <code>agent-sdk slack create</code> opens the dashboard wizard and writes tokens to <code>.env.local</code>. To own the Slack app yourself, run <code>agent-sdk slack init --manual</code> and paste the manifests at <a href="https://api.slack.com/apps" target="_blank" rel="noreferrer">api.slack.com</a>. Socket Mode has no public Request URL. Replies stream in threads, with tool "thinking" steps, suggested prompts, and opt-in approval buttons.</p><p>The companion skill is <a href="./../../skills/setup-slack/SKILL.html"><code>skills/setup-slack/SKILL.md</code></a>.</p><h2 id="define-the-channel" tabindex="-1">Define the channel <a class="header-anchor" href="#define-the-channel" aria-label="Permalink to "Define the channel""></a></h2><p>Author <code>agent/channels/slack.ts</code> with <code>slackChannel()</code> from <code>@cursor/july/channels/slack</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { slackChannel } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/channels/slack"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
2
|
-
<span class="line"></span>
|
|
3
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Single agent: reads SLACK_BOT_TOKEN + SLACK_APP_TOKEN</span></span>
|
|
4
|
-
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> slackChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
|
|
5
|
-
<span class="line"></span>
|
|
6
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// Multi-agent serve: one Slack app (and token pair) per agent</span></span>
|
|
7
|
-
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> slackChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ envPrefix: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"WEATHER_AGENT"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
|
|
8
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// → WEATHER_AGENT_SLACK_BOT_TOKEN + WEATHER_AGENT_SLACK_APP_TOKEN</span></span></code></pre></div><p>By default the channel connects over Socket Mode (the app connects outward, so it works from behind any firewall) and responds only to <code>app_mention</code> events and direct messages. It also refuses Slack Connect users, guests, and senders from other workspaces. Threads bind to sessions with <code>continuationToken = channelId:threadTs</code>, so a thread is one durable conversation. Replies stream (<code>chat.startStream</code> / <code>appendStream</code> / <code>stopStream</code>) with a plain-message fallback, a rotating status shows while the agent works, and the pack sets thread titles and suggested prompts. When a Slack API is unavailable (<code>method_not_found</code>, <code>missing_scope</code>), the pack degrades to <code>postMessage</code> instead of failing.</p><p>Missing tokens leave the channel idle (<code>channel idle … missing credentials</code>) rather than failing <code>serve</code>. That's useful when you mount many agents and only some have Slack apps.</p><h2 id="control-who-can-message-the-agent" tabindex="-1">Control who can message the agent <a class="header-anchor" href="#control-who-can-message-the-agent" aria-label="Permalink to "Control who can message the agent""></a></h2><p>External senders are blocked by default. Slack Connect users, guests, and people whose home workspace is not the install team never reach the handler. Set <code>blockExternals: false</code> only when the agent should serve people outside your org:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> slackChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
9
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> policy: { blockExternals: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
10
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Sessions are thread-scoped by default, so anyone in the thread can continue. Restrict follow-ups to the person who started the session with <code>respondTo: "author"</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> slackChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
11
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> policy: { respondTo: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"author"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
12
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="set-it-up" tabindex="-1">Set it up <a class="header-anchor" href="#set-it-up" aria-label="Permalink to "Set it up""></a></h2><p>For a dedicated Socket Mode bot, run <code>agent-sdk slack create</code>. The CLI opens the signed-in Cursor dashboard wizard. Slack consent, bot name, and admin-approval wait happen there. Tokens are stored as deployment secrets and written to <code>.env.local</code>. They are never shown. Do not paste a manifest at <a href="https://api.slack.com/apps" target="_blank" rel="noreferrer">api.slack.com</a> unless you are on the <a href="#manual-setup">manual setup</a> path.</p><p>Bots that already have tokens in <code>.env.local</code> keep working. Skip the wizard unless you want a Cursor-managed app.</p><h3 id="provision-with-the-cli" tabindex="-1">Provision with the CLI <a class="header-anchor" href="#provision-with-the-cli" aria-label="Permalink to "Provision with the CLI""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> create</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # dev app (default)</span></span>
|
|
13
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> create</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prod</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # prod app</span></span></code></pre></div><p><code>slack create</code> needs a signed-in host (<code>agent-sdk login</code> or <code>CURSOR_API_KEY</code>). It scaffolds <code>agent/channels/slack.ts</code> when the file is missing, opens the dashboard wizard, and waits. Finish <strong>Add Slack to this agent</strong> in the browser as the same Cursor account. The CLI writes <code><PREFIX>_SLACK_BOT_TOKEN</code> and <code><PREFIX>_SLACK_APP_TOKEN</code> into <code><dir>/.env.local</code>, then runs <code>doctor</code>. Serve and smoke it as described <a href="#wire-the-env-and-verify">below</a>.</p><p>If Slack needs a workspace admin to approve the app, keep the CLI running. Managed install does not file the request. Open Slack's <strong>Request approval</strong> page (the CLI prints the link; the same URL is <strong>Send a reminder</strong> after you submit). After an admin approves, click <strong>Retry</strong> in the wizard.</p><p>Useful companions: <code>--name</code> / <code>--icon</code> / <code>--channel-posts</code> prefill the wizard. <code>--slack-team T0123ABCD</code> picks a workspace when several are connected. A second <code>slack create</code> for the same agent and env overwrites that Slack app. It keeps the Slack app id and replaces the manifest and tokens. <code>agent-sdk slack destroy</code> deletes the provisioned app. <code>agent-sdk slack icon <source></code> updates the icon later.</p><h3 id="provision-from-the-dashboard" tabindex="-1">Provision from the dashboard <a class="header-anchor" href="#provision-from-the-dashboard" aria-label="Permalink to "Provision from the dashboard""></a></h3><p>The same wizard is on <a href="https://cursor.com/dashboard" target="_blank" rel="noreferrer">Deployed Agents</a>. Open <strong>Integrations</strong> on an agent and click <strong>Add Slack to this agent</strong>, or follow the URL <code>slack create</code> printed.</p><p>A first-run agent that has no hosted engine yet shows <strong>Not deployed yet</strong>. Local <code>agent-sdk serve</code> works from <code>.env.local</code>. The next <strong>Deploy</strong> injects the stored secrets; there is no Slack-only Redeploy.</p><p>If Slack needs admin approval, the wizard waits. Click <strong>Request approval</strong> to file the request in Slack (that same page later sends a reminder). After an admin approves, click <strong>Retry</strong>.</p><p>The app row's menu covers later care: rename, set an icon, rotate tokens, remove the app, or disconnect the workspace.</p><h3 id="wire-the-env-and-verify" tabindex="-1">Wire the env and verify <a class="header-anchor" href="#wire-the-env-and-verify" aria-label="Permalink to "Wire the env and verify""></a></h3><p><code>agent-sdk slack create</code> already wrote the tokens to <code>.env.local</code>, so after provisioning skip straight to <code>doctor</code>. <code>serve</code> / <code>dev</code> / <code>slack doctor</code> load that file (real environment variables always win).</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> doctor</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prefix</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> MY_AGENT</span></span></code></pre></div><p>Proceed when <code>app_token</code>, <code>connections_open</code>, <code>bot_token</code>, and <code>auth_test</code> are all green. Then serve and smoke it:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> serve</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dev</span></span>
|
|
14
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># expect: [agent-sdk/slack] Socket Mode connected</span></span></code></pre></div><p>Invite the bot to a channel and @mention it (or DM it). Expect the Thinking… status, then a threaded streaming reply, with correlated server logs (<code>inbound kind=app_mention</code>, <code>session start</code>, <code>reply delivered via stream|postMessage</code>).</p><h3 id="manual-setup" tabindex="-1">Manual setup <a class="header-anchor" href="#manual-setup" aria-label="Permalink to "Manual setup""></a></h3><p><code>slack init --manual</code> is for a Slack app you own at api.slack.com. You paste the generated manifests and mint tokens yourself. Use this when you want an unmanaged app, or when the dashboard wizard is not an option.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --manual</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --name</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "My Agent"</span></span></code></pre></div><p>That writes <code>agent/channels/slack.ts</code>, Slack manifests under the project state directory, <code>env.example</code>, and <code>setup-status.json</code>. <code>--no-prefix</code> uses shared <code>SLACK_*</code> variables on a single-agent host. <code>--prefix CUSTOM</code> overrides the directory-derived prefix. <code>--channel-posts</code> subscribes the manifests to channel-post events.</p><p><code>slack manifest --env both</code> regenerates the JSON files without touching the channel file.</p><h4 id="create-the-apps" tabindex="-1">Create the apps <a class="header-anchor" href="#create-the-apps" aria-label="Permalink to "Create the apps""></a></h4><p>This phase needs someone with permission to create Slack apps.</p><ol><li>Open <a href="https://api.slack.com/apps" target="_blank" rel="noreferrer">api.slack.com/apps</a> → <strong>Create New App</strong> → <strong>From a manifest</strong>.</li><li>Paste <code>manifest.dev.json</code> and create the dev app.</li><li>Repeat with <code>manifest.prod.json</code>. Dev and prod are separate Slack apps with separate tokens.</li></ol><h4 id="install-and-mint-tokens" tabindex="-1">Install and mint tokens <a class="header-anchor" href="#install-and-mint-tokens" aria-label="Permalink to "Install and mint tokens""></a></h4><p>For each app: <strong>Install to Workspace</strong> and copy the Bot User OAuth Token (<code>xoxb-…</code>). Then under <strong>Basic Information → App-Level Tokens</strong> create a token with scope <code>connections:write</code> and copy it (<code>xapp-…</code>).</p><p>Put the pair in <code>.env.local</code> using the names from <code>env.example</code>, then run <code>slack doctor</code> and serve as <a href="#wire-the-env-and-verify">above</a>.</p><h2 id="choose-when-the-agent-engages" tabindex="-1">Choose when the agent engages <a class="header-anchor" href="#choose-when-the-agent-engages" aria-label="Permalink to "Choose when the agent engages""></a></h2><p>Mentions and DMs are on by default. Watching channels means dispatching on new posts without a mention. That's an explicit opt-in:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> slackChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
15
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> envPrefix: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"TRIAGE"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
16
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> engagement: {</span></span>
|
|
17
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // mentions / directMessages default to true</span></span>
|
|
18
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> channelPosts: {</span></span>
|
|
19
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> allow: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"#triage-alerts"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">], </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// use ["*"] for every joined channel</span></span>
|
|
20
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> posts: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"top-level"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// default: thread replies never dispatch</span></span>
|
|
21
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> debounceMs: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">15_000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// optional: let rapid edits settle</span></span>
|
|
22
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> includeBotPosts: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// default: bot-authored posts never dispatch</span></span>
|
|
23
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
24
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
25
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onChannelPost</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">ctx</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">message</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
26
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // same contract as onAppMention: return null to skip</span></span>
|
|
27
|
-
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> message.markdown.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">length</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 20</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {} </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> null</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
28
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
29
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Channel watching needs the <code>message.channels</code> / <code>message.groups</code> events on the Slack app. Pass <code>--channel-posts</code> on <code>slack create</code> or <code>slack init --manual</code>. The bot must also be a member of each watched channel.</p><p>Set <code>allow: ["*"]</code> to watch every channel the bot has joined.</p><p>Set <code>includeBotPosts: true</code> when the posts worth watching come from bots: alert feeds, webhook integrations, or other agents posting notes. The watching app's own posts stay dropped either way, matched by the <code>bot_id</code> and bot user id from <code>auth.test</code>, so an agent can never dispatch on its own replies. Use this for a bot-fed alerts channel.</p><h2 id="prepare-work-on-the-host" tabindex="-1">Prepare work on the host <a class="header-anchor" href="#prepare-work-on-the-host" aria-label="Permalink to "Prepare work on the host""></a></h2><p>Mention and DM handlers may return a prepared <code>message</code>, <code>workspaceFiles</code>, or <code>cloud</code> block. It's the same host-prep pattern as <a href="./webhooks.html#prepare-on-the-host-then-hand-off">custom channels</a>. PR agents use it: extract a PR URL from the mention text and run the same host path as the HTTP channel.</p><p>Slack file uploads are attached automatically. Images become vision input. Supported documents become workspace files for the turn.</p><h2 id="add-approval-buttons" tabindex="-1">Add approval buttons <a class="header-anchor" href="#add-approval-buttons" aria-label="Permalink to "Add approval buttons""></a></h2><p>Tools with <code>needsApproval</code> park until a person decides. Route that through Slack with one flag:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> slackChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
30
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> toolApprovals: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// posts Block Kit Approve/Deny cards + routes clicks</span></span>
|
|
31
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Approval cards need interactivity on the Slack app. Recreate with <code>slack create</code> if clicks do nothing. Composing events by hand: spread <code>buildToolApprovalEvents({ credentials })</code> into <code>events</code> and set <code>interactivity: true</code> on the channel so Socket Mode routes the clicks.</p><p>Cards show redacted, truncated arguments (Block Kit size limits); execution still uses the full validated input, so review sensitive tools in the playground when the arguments may exceed the card. Approvals exist for <code>execution: "server"</code> tools on the local runtime only, and parked calls do not survive a host restart. The full lifecycle is in <a href="./human-in-the-loop.html">Human-in-the-loop</a>.</p><h2 id="run-several-agents-on-one-host" tabindex="-1">Run several agents on one host <a class="header-anchor" href="#run-several-agents-on-one-host" aria-label="Permalink to "Run several agents on one host""></a></h2><p>One Slack app and token pair per agent. Never share a pair across agents in the same process. <code>envPrefix</code> keeps them apart (<code>WEATHER_AGENT_SLACK_*</code>, <code>TRIAGE_SLACK_*</code>, …), and agents without tokens mount with their Slack channel idle while everything else serves normally.</p><h2 id="keep-the-channel-healthy" tabindex="-1">Keep the channel healthy <a class="header-anchor" href="#keep-the-channel-healthy" aria-label="Permalink to "Keep the channel healthy""></a></h2><p>Two habits matter most.</p><ul><li>Don't <code>await</code> long work inside Slack dispatch handlers. The pack dispatches through <code>waitUntil</code> and streams as the turn progresses.</li><li>In <code>--dev</code> (loopback) or <code>--allow-anonymous</code> (trusted shared host), the playground can list and stream Slack sessions and resolve their parked approvals (the audit trail records the HTTP caller). Bearer-auth hosts stay strict: Slack approvals must come from Slack interactivity or a matching principal.</li></ul><h2 id="cli-reference" tabindex="-1">CLI reference <a class="header-anchor" href="#cli-reference" aria-label="Permalink to "CLI reference""></a></h2><p>The <code>slack</code> subcommands cover setup end to end.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> setup</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # printed setup guide</span></span>
|
|
32
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> create</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # dashboard wizard (dev app)</span></span>
|
|
33
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> create</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prod</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # prod app</span></span>
|
|
34
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> destroy</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # delete the provisioned app</span></span>
|
|
35
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> icon</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ./icon.png</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # set the provisioned app's icon</span></span>
|
|
36
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --manual</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # manifests to paste at api.slack.com</span></span>
|
|
37
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> manifest</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --env</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> both</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # regenerate those JSON files</span></span>
|
|
38
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> slack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> doctor</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prefix</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> MY_AGENT</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # token / connectivity checks</span></span></code></pre></div><h2 id="what-s-next" tabindex="-1">What's next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to "What's next""></a></h2><p>Continue with these pages:</p><ul><li><a href="./human-in-the-loop.html">Human-in-the-loop</a>: the approval lifecycle behind <code>toolApprovals</code></li><li><a href="./webhooks.html">Webhooks and custom channels</a>: the mechanism this pack is built on</li></ul>`,68)])])}const g=a(n,[["render",h]]);export{c as __pageData,g as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{_ as a,c as e,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const c=JSON.parse('{"title":"Slack","description":"Put the agent in Slack: a dedicated Socket Mode app via the dashboard wizard, or a manual manifest import.","frontmatter":{"title":"Slack","description":"Put the agent in Slack: a dedicated Socket Mode app via the dashboard wizard, or a manual manifest import."},"headers":[],"relativePath":"guides/slack.md","filePath":"guides/slack.md"}'),n={name:"guides/slack.md"};function h(l,s,o,p,d,r){return i(),e("div",null,[...s[0]||(s[0]=[t("",68)])])}const g=a(n,[["render",h]]);export{c as __pageData,g as default};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{_ as t,c as a,o as i,ag as s}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"Agent SDK documentation","description":"Build and run Cursor agents with tools, approvals, channels, and evals.","frontmatter":{"title":"Agent SDK documentation","description":"Build and run Cursor agents with tools, approvals, channels, and evals."},"headers":[],"relativePath":"index.md","filePath":"README.md"}'),r={name:"index.md"};function n(l,e,o,h,d,c){return i(),a("div",null,[...e[0]||(e[0]=[s(`<h1 id="agent-sdk-documentation" tabindex="-1">Agent SDK documentation <a class="header-anchor" href="#agent-sdk-documentation" aria-label="Permalink to "Agent SDK documentation""></a></h1><p>Use the Agent SDK to define Cursor agents in TypeScript and Markdown. See <a href="./reference/project-layout.html">Project layout</a> for the directory structure.</p><p>Use Node 22.13 or newer. Bun isn't supported.</p><p>Create a project:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @cursor/july</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ./my-agent</span></span>
|
|
2
|
-
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> my-agent</span></span>
|
|
3
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> dev</span></span></code></pre></div><p>If <code>agent-sdk</code> isn't on <code>PATH</code>, use <code>npx @cursor/july <command></code>.</p><p>Open the docs locally:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npx</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @cursor/july</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> docs</span></span></code></pre></div><h2 id="where-to-start" tabindex="-1">Where to start <a class="header-anchor" href="#where-to-start" aria-label="Permalink to "Where to start""></a></h2><table tabindex="0"><thead><tr><th>You are...</th><th>Start with</th></tr></thead><tbody><tr><td>New to the Agent SDK</td><td><a href="./quickstart.html">Quickstart</a> (PR reviewer), then <a href="./concepts.html">Concepts</a></td></tr><tr><td>Building a new agent with Cursor</td><td><a href="./scaffolding-agents.html">Scaffold an agent with Cursor</a></td></tr><tr><td>Turning a Cursor Automation into a project</td><td><a href="./guides/convert-automation.html">Convert a Cursor Automation</a></td></tr><tr><td>Wiring an agent to Slack</td><td><a href="./guides/slack.html">Slack guide</a></td></tr><tr><td>Starting from a packaged template</td><td><a href="./templates/demo.html">Demo</a>, <a href="./templates/code-wiki.html">Code wiki</a>, <a href="./templates/security-reviewer.html">Security reviewer</a>, <a href="./templates/security-help.html">Security help</a>, <a href="./templates/triage.html">Triage</a>, or <a href="./templates/agentic-owners.html">Agentic Owners</a></td></tr><tr><td>Wiring an agent to GitHub webhooks</td><td><a href="./guides/github.html">GitHub guide</a></td></tr><tr><td>Driving PRs from a cloud VM</td><td><a href="./templates/pr-autofixer.html">PR autofixer template</a></td></tr><tr><td>Driving an agent from Linear (or another tracker)</td><td><a href="./guides/webhooks.html#example-linear-as-the-control-plane">Webhooks guide: Linear example</a></td></tr><tr><td>Making an existing agent measurably better</td><td><a href="./evals.html">Evals</a>, then <a href="./hillclimbing.html">Hillclimbing</a></td></tr><tr><td>Comparing variants on live traffic</td><td><a href="./ab.html">Live A/B metrics</a></td></tr><tr><td>Deploying with Cursor or on your own infrastructure</td><td><a href="./deployment.html">Deployment</a></td></tr><tr><td>Debugging something that misbehaves</td><td><a href="./troubleshooting.html">Fix common agent problems</a></td></tr></tbody></table><h2 id="documentation" tabindex="-1">Documentation <a class="header-anchor" href="#documentation" aria-label="Permalink to "Documentation""></a></h2><p><strong>Core</strong></p><ul><li><a href="./quickstart.html">Quickstart</a>: build a PR reviewer that classifies changes by complexity and handles GitHub webhook events.</li><li><a href="./scaffolding-agents.html">Scaffold an agent with Cursor</a>: use the bundled skill for a guided build.</li><li><a href="./guides/convert-automation.html">Convert a Cursor Automation</a>: export a dashboard Automation into an Agent SDK project.</li><li><a href="./concepts.html">Concepts</a>: agent discovery, sessions, channels, runtimes, and observability.</li></ul><p><strong>Templates</strong></p><ul><li><a href="./templates/demo.html">Record a walkthrough from a collected PR</a>: host collects the PR, the model records, then comments.</li><li><a href="./templates/code-wiki.html">Keep a code wiki current after merge</a>: update in-repo <code>wiki/</code> pages when a pull request merges.</li><li><a href="./templates/security-reviewer.html">Security reviewer</a>: review pull requests for exploitable bugs and post one comment.</li><li><a href="./templates/security-help.html">Answer security questions in Slack</a>: answer from your skills, or take a first look at a pasted PR.</li><li><a href="./templates/triage.html">Triage Linear or Jira issues in place</a>: classify existing tickets and comment on them.</li><li><a href="./templates/agentic-owners.html">Review pull requests with owners policies</a>: request owners and approve changes allowed by repository policy.</li><li><a href="./templates/pr-autofixer.html">Fix pull requests on a Cursor cloud VM</a></li></ul><p><strong>Self-improving Agents</strong></p><ul><li><a href="./building-with-agents.html">Building agents with agents</a>: use a coding agent to scaffold, run, and iterate on your agent.</li><li><a href="./evals.html">Evals</a>: author <code>defineEval</code> cases, pick fixtures, and use evals as regression checks.</li><li><a href="./ab.html">Live A/B metrics</a>: assign sticky variants and compare cumulative metrics on live sessions.</li><li><a href="./storage.html">Storage</a>: point durable storage at a backend you own with <code>defineStorage</code>.</li><li><a href="./hillclimbing.html">Hillclimbing</a>: measure and improve an agent iteratively.</li></ul><p><strong>Guides</strong></p><ul><li><a href="./guides/webhooks.html">Webhooks and custom channels</a>: give the agent its own HTTP surface.</li><li><a href="./guides/github.html">GitHub</a>: trigger the agent from pull requests, CI, and comments.</li><li><a href="./guides/slack.html">Slack</a>: put the agent in Slack over Socket Mode.</li><li><a href="./guides/human-in-the-loop.html">Human-in-the-loop approvals</a>: park a tool call until a person signs off.</li><li><a href="./guides/mcp-oauth.html">Host MCP OAuth</a>: authorize <code>oauth: true</code> connections, store tokens locally, and <code>--store</code> them on hosted deployments.</li><li><a href="./guides/agent-to-agent.html">Agent-to-agent</a>: every agent is an MCP server; agents can delegate to each other.</li><li><a href="./guides/cloud-runtime.html">Cloud runtime</a>: run turns on Cursor cloud agents instead of the local harness.</li><li><a href="./guides/opentelemetry.html">OpenTelemetry</a>: push session, turn, and tool traces to an OTLP collector you run.</li></ul><p><strong>Operating</strong></p><ul><li><a href="./deployment.html">Deployment</a>: Cursor-managed hosting, self-hosting, auth, state, and operations.</li><li><a href="./troubleshooting.html">Fix common agent problems</a>: diagnose common failures by symptom.</li></ul><p><strong>Reference</strong></p><ul><li><a href="./reference/project-layout.html">Project layout</a>: the full folder structure.</li><li><a href="./reference/agent-config.html">Agent config</a> · <a href="./reference/instructions.html">Instructions</a> · <a href="./reference/tools.html">Tools</a> · <a href="./reference/prompt.html"><code>prompt</code></a> · <a href="./reference/skills.html">Skills</a> · <a href="./reference/connections.html">MCP connections</a> · <a href="./reference/subagents.html">Subagents</a></li><li><a href="./reference/channels.html">Channels</a> · <a href="./reference/schedules.html">Schedules and reminders</a> · <a href="./reference/hooks.html">Hooks</a> · <a href="./reference/sessions.html">Sessions and streaming</a> · <a href="./reference/playground.html">Playground</a></li><li><a href="./reference/cli.html">CLI</a> · <a href="./reference/http-api.html">HTTP API</a></li></ul><h2 id="run-the-cli" tabindex="-1">Run the CLI <a class="header-anchor" href="#run-the-cli" aria-label="Permalink to "Run the CLI""></a></h2><p>Docs use <code>agent-sdk <command></code>. If it isn't on <code>PATH</code>, use <code>npx @cursor/july <command></code>.</p><h2 id="credentials" tabindex="-1">Credentials <a class="header-anchor" href="#credentials" aria-label="Permalink to "Credentials""></a></h2><p>Sign in to Cursor or set <code>CURSOR_API_KEY</code>:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> login</span></span>
|
|
4
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># or: export CURSOR_API_KEY=key_...</span></span>
|
|
5
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> whoami</span></span></code></pre></div><p>Confirm <code>agent-sdk whoami</code> shows the expected account.</p><h2 id="related-documentation" tabindex="-1">Related documentation <a class="header-anchor" href="#related-documentation" aria-label="Permalink to "Related documentation""></a></h2><ul><li>Package reference: <a href="./../README.html"><code>README.md</code></a></li><li>Coding-agent workflows: <a href="./../skills/"><code>skills/</code></a></li></ul>`,31)])])}const m=t(r,[["render",n]]);export{p as __pageData,m as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{_ as t,c as s,o as a,ag as o}from"./chunks/framework.BCISBCiQ.js";const u=JSON.parse('{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives.","frontmatter":{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives."},"headers":[],"relativePath":"reference/sessions.md","filePath":"reference/sessions.md"}'),n={name:"reference/sessions.md"};function d(i,e,r,c,l,h){return a(),s("div",null,[...e[0]||(e[0]=[o('<h1 id="sessions-events-and-streaming" tabindex="-1">Sessions, events, and streaming <a class="header-anchor" href="#sessions-events-and-streaming" aria-label="Permalink to "Sessions, events, and streaming""></a></h1><p>A session keeps one conversation, its workspace, and an append-only record of every message and tool call.</p><h2 id="what-does-a-session-contain" tabindex="-1">What does a session contain? <a class="header-anchor" href="#what-does-a-session-contain" aria-label="Permalink to "What does a session contain?""></a></h2><p>Each session combines:</p><ul><li>A channel and authenticated caller</li><li>A conversation the caller can continue</li><li>A workspace for local turns</li><li>An NDJSON event stream</li><li>Runtime state needed to resume after a server restart</li></ul><p>Sessions belong to the principal that created them. Follow-up, stream, and list routes return <code>403</code> when another caller tries to access one.</p><h2 id="which-session-identifier-should-i-use" tabindex="-1">Which session identifier should I use? <a class="header-anchor" href="#which-session-identifier-should-i-use" aria-label="Permalink to "Which session identifier should I use?""></a></h2><p>Sessions have two identifiers because conversation routing and inspection are different jobs.</p><table tabindex="0"><thead><tr><th>Identifier</th><th>Use it for</th></tr></thead><tbody><tr><td><code>continuationToken</code></td><td>Continue a conversation through its channel</td></tr><tr><td><code>sessionId</code></td><td>Stream events, inspect state, resolve approvals, or run a session-bound tool call</td></tr></tbody></table><p>Channels decide what a continuation token looks like. Slack uses its thread identity. A PR channel can use a key such as <code>pr:owner/repo#1</code>. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up. Reusing a stale HTTP token returns <code>409</code>.</p><p>Use the continuation token to keep talking. Use the session ID to observe or manage the stored session.</p><h2 id="which-session-modes-are-available" tabindex="-1">Which session modes are available? <a class="header-anchor" href="#which-session-modes-are-available" aria-label="Permalink to "Which session modes are available?""></a></h2><table tabindex="0"><thead><tr><th>Mode</th><th>Created by</th><th>What happens after a turn</th></tr></thead><tbody><tr><td><code>chat</code></td><td>HTTP sessions, channel <code>send</code>, Slack, or MCP <code>ask</code></td><td>Waits in <code>session.waiting</code> and accepts follow-ups</td></tr><tr><td><code>task</code></td><td>Markdown schedules and fire-and-forget dispatch</td><td>Ends in <code>session.completed</code> or <code>session.failed</code></td></tr></tbody></table><p>Task sessions don't accept follow-ups. Trying one returns <code>409</code>.</p><h2 id="what-happens-when-i-send-a-follow-up" tabindex="-1">What happens when I send a follow-up? <a class="header-anchor" href="#what-happens-when-i-send-a-follow-up" aria-label="Permalink to "What happens when I send a follow-up?""></a></h2><p>A follow-up to an idle chat session starts another turn. Admission when the session is already busy depends on the channel:</p><table tabindex="0"><thead><tr><th>Path</th><th>Busy-session policy</th></tr></thead><tbody><tr><td>HTTP playground / <code>POST /v1/session/:id</code> / MCP <code>ask</code></td><td><strong>Preempt</strong> (default): interrupt the in-flight turn, wait for it to settle, then run the new message</td></tr><tr><td>Slack mentions / DMs / alert-watch</td><td><strong>Coalesce</strong>: leave the active turn running, enqueue the follow-up, and drain queued asks into one follow-up turn when the active turn finishes (no mid-turn tool/hook inject)</td></tr></tbody></table><p>Pass <code>admission: "coalesce"</code> on <code>send()</code> to opt into the Slack policy from other callers. Omit it (or pass <code>"preempt"</code>) to keep interrupt semantics.</p><p><code>POST /v1/session/:id/stop</code> interrupts a turn without sending a new message. Interrupted turns record <code>turn.failed</code> with <code>"turn interrupted"</code>. This means the turn was preempted. A whole-message Slack <code>stop</code> / <code>@agent stop</code> does the same for that thread and clears pending coalesced nudges.</p><p>Session-bound deterministic tool calls share the same execution lock. They return <code>409 session_busy</code> while a model turn is running.</p><h2 id="which-events-can-i-stream" tabindex="-1">Which events can I stream? <a class="header-anchor" href="#which-events-can-i-stream" aria-label="Permalink to "Which events can I stream?""></a></h2><p>Each NDJSON line uses this envelope: <code>{ type, index, sessionId, turnId?, at, data }</code>. The <code>index</code> increases within one session. The <code>at</code> field is an ISO-8601 timestamp.</p><table tabindex="0"><thead><tr><th>Phase</th><th>Events</th><th>What they tell you</th></tr></thead><tbody><tr><td>Session</td><td><code>session.started</code>, <a href="./../ab.html#assign-sticky-variants"><code>ab.assigned</code></a>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, A/B enrollment, readiness, and task completion</td></tr><tr><td>Agent</td><td><code>agent.bound</code></td><td>Cloud conversation URL</td></tr><tr><td>Input</td><td><code>message.received</code></td><td>A user message was accepted</td></tr><tr><td>Turn</td><td><code>turn.queued</code>, <code>turn.started</code>, <code>turn.completed</code>, <code>turn.failed</code></td><td>Queue position under a <a href="./agent-config.html#concurrency"><code>maxRunningTurns</code> cap</a>, then turn status, final result, and token usage</td></tr><tr><td>Steps</td><td><code>step.started</code>, <code>step.completed</code></td><td>Model step boundaries and duration</td></tr><tr><td>Reasoning</td><td><code>reasoning.appended</code>, <code>reasoning.completed</code></td><td>Streamed reasoning blocks</td></tr><tr><td>Reply</td><td><code>message.appended</code>, <code>message.completed</code></td><td>Text deltas and finalized assistant messages</td></tr><tr><td>Tools</td><td><code>actions.requested</code>, <code>action.result</code></td><td>Tool names, validated arguments, outputs, and errors</td></tr><tr><td>Approvals</td><td><code>action.approval_requested</code>, <code>action.approval_resolved</code></td><td>A parked tool call and the human decision</td></tr><tr><td>Subagents</td><td><code>subagent.called</code>, <code>subagent.completed</code></td><td>Delegated work</td></tr><tr><td>Artifacts</td><td><code>artifact.tagged</code></td><td>A durable <a href="./artifacts.html">artifact</a> was tagged for this session, by host code or <code>tag_artifact</code></td></tr></tbody></table><p>Pair <code>actions.requested</code> with <code>action.result</code> to reconstruct the tool trajectory. Read <code>turn.completed.data.usage</code> for input, output, and cache token counts.</p><h2 id="how-do-i-stream-or-replay-session-events" tabindex="-1">How do I stream or replay session events? <a class="header-anchor" href="#how-do-i-stream-or-replay-session-events" aria-label="Permalink to "How do I stream or replay session events?""></a></h2><p>One endpoint handles both live streaming and replay:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -N</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'http://127.0.0.1:3000/<slug>/v1/session/ses_…/stream?startIndex=0'</span></span></code></pre></div><p>Pass <code>startIndex</code> to continue after the last event you received. Omit it or pass <code>0</code> to replay the full session before following new events. <code>GET /v1/session/:id/events</code> returns a one-time dump without staying connected.</p><p>Event streams replay from disk after a server restart. Conversation state resumes from the Cursor SDK store.</p><h2 id="what-goes-into-a-local-session-workspace" tabindex="-1">What goes into a local session workspace? <a class="header-anchor" href="#what-goes-into-a-local-session-workspace" aria-label="Permalink to "What goes into a local session workspace?""></a></h2><p>The Agent SDK creates a workspace before the first local turn:</p><table tabindex="0"><thead><tr><th>Source path</th><th>Lands as</th></tr></thead><tbody><tr><td><code>instructions.*</code></td><td><code>AGENTS.md</code></td></tr><tr><td><code>skills/*</code></td><td><code>.cursor/skills/<name>/SKILL.md</code></td></tr><tr><td>agent tools (<code>execution: "agent"</code>)</td><td>scripts in the session workspace, with a catalog in <code>AGENTS.md</code></td></tr><tr><td><code>sandbox/workspace/**</code></td><td>copied in as seed files</td></tr><tr><td>per-send <code>workspaceFiles</code></td><td>written before the turn</td></tr></tbody></table><p>The local harness uses this workspace as its working directory. Parent directories can contribute <code>AGENTS.md</code> and <code>.cursor</code> settings. Set <code>local.cwd</code> when you need a clean parent directory. A channel can also provide a different working directory for one session, such as a PR worktree.</p><p>See <a href="./agent-config.html#local-cwd">Agent config: local cwd</a> for the inheritance rules.</p><h2 id="where-does-the-agent-sdk-store-session-data" tabindex="-1">Where does the Agent SDK store session data? <a class="header-anchor" href="#where-does-the-agent-sdk-store-session-data" aria-label="Permalink to "Where does the Agent SDK store session data?""></a></h2><p>Local state lives under <code>--state-root</code>. Slugged mounts store it under a subdirectory named for the slug.</p><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued. Cloud conversations remain on the Cursor backend.</p><p>Nested git checkouts already default <code>local.cwd</code> outside the enclosing repo. See <a href="./../concepts.html#what-files-can-a-local-session-access">local session workspaces</a>.</p><h2 id="how-do-i-inspect-a-saved-event-stream" tabindex="-1">How do I inspect a saved event stream? <a class="header-anchor" href="#how-do-i-inspect-a-saved-event-stream" aria-label="Permalink to "How do I inspect a saved event stream?""></a></h2><p>Use <code>trajectory</code> with a saved trace:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> trajectory</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --events</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> <</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">state-roo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">t</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/traces/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">sessionI</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.ndjson</span></span></code></pre></div><p>The command prints tool calls, the reply, and token usage in the same JSON shape as <code>run</code>. Use <strong>Open trace</strong> in the playground for a visual view.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./http-api.html">HTTP API</a></li><li><a href="./hooks.html">Hooks</a></li><li><a href="./../ab.html">Live A/B metrics</a></li><li><a href="./../concepts.html">How the Agent SDK works</a></li></ul>',44)])])}const g=t(n,[["render",d]]);export{u as __pageData,g as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{_ as t,c as o,o as a,ag as d}from"./chunks/framework.BCISBCiQ.js";const p=JSON.parse('{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail.","frontmatter":{"title":"Fix common agent problems","description":"Match what you see to a cause, then read a session trace when you need more detail."},"headers":[],"relativePath":"troubleshooting.md","filePath":"troubleshooting.md"}'),r={name:"troubleshooting.md"};function s(n,e,c,i,l,h){return a(),o("div",null,[...e[0]||(e[0]=[d('<h1 id="fix-common-agent-problems" tabindex="-1">Fix common agent problems <a class="header-anchor" href="#fix-common-agent-problems" aria-label="Permalink to "Fix common agent problems""></a></h1><p>Start with four checks, in order:</p><ol><li>Project discovery: <code>agent-sdk validate --dir .</code></li><li>Whether the serve process is running</li><li>What the playground or HTTP API shows</li><li>The session event stream (trace)</li></ol><p>Match your symptom below. Keep the commands as <code>agent-sdk</code>. If it is not on <code>PATH</code>, use <code>npx @cursor/july</code>.</p><h2 id="what-if-serve-or-the-playground-looks-wrong" tabindex="-1">What if serve or the playground looks wrong? <a class="header-anchor" href="#what-if-serve-or-the-playground-looks-wrong" aria-label="Permalink to "What if serve or the playground looks wrong?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>serve</code> won't start</td><td>Run <code>agent-sdk validate --dir .</code> and fix the reported errors.</td></tr><tr><td>Playground is blank or says there are no agents</td><td>The UI needs a running <code>serve</code> process. Building the playground assets alone is not enough.</td></tr><tr><td>The playground UI looks stale</td><td><code>serve --dev</code> prints a playground URL. Open that URL. Agent-file edits still need a restart (press Enter on the TTY).</td></tr><tr><td>Sessions exist but the playground list is empty</td><td>The list shows sessions for the authenticated caller. In <code>--dev</code> on loopback the list is wider. Otherwise open <code>/<slug>/playground?sessionId=ses_…</code>.</td></tr><tr><td>Port 3000 is already in use</td><td>For the default serve port, the CLI tries the next free port and prints a notice. Pass <code>--port</code> to pick one, or <code>--port 0</code> for any free port. Stop leftover playground or webhook-forwarder processes if you need the original port.</td></tr></tbody></table><h2 id="what-if-a-model-turn-goes-wrong" tabindex="-1">What if a model turn goes wrong? <a class="header-anchor" href="#what-if-a-model-turn-goes-wrong" aria-label="Permalink to "What if a model turn goes wrong?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>Built-in file reads and greps fail; the turn retries for a long time</td><td>Run under Node 22.13+ (or <code>tsx</code>), never Bun. Look for <code>NGHTTP2_FRAME_SIZE_ERROR</code> in logs.</td></tr><tr><td>The turn fails immediately with an API-key error</td><td>Sign in with <code>agent-sdk login</code>, or set <code>CURSOR_API_KEY</code>. Discovery, <code>info</code>, <code>call</code>, and serve bring-up work without a key; model turns need one.</td></tr><tr><td>Replies quote rules or <code>AGENTS.md</code> from outside your agent project</td><td>The session workspace inherited parent-folder config. Nested git checkouts default <code>local.cwd</code> to a per-project cache directory under <code>~/.cache</code>. Point <code>defineAgent({ local: { cwd } })</code> at a checkout only when the agent should inherit that tree, or set <code>--state-root</code> to a clean directory (for example under <code>/tmp</code>).</td></tr><tr><td>Yellow box shows Datadog/Linear tools, but the model lists <code>GetDynamicTools</code> / IDE <code>cursor</code> tools and never calls them</td><td>Attached MCP sits behind harness meta-tools, or the harness cwd is still inside another checkout. Set <code>advertiseTools: true</code> for named tools on local turns. Check <code>GET /v1/info</code> <code>local.cwd</code> and <code>connections[].advertiseTools</code>.</td></tr><tr><td>Server tools, skills, or workspace seed files never appear</td><td>Server tools and sandbox seeds apply on the local runtime (cloud server tools need <code>--public-url</code> / <code>--cloud-tools-url</code>). Skills reach cloud through the Agent Store when hosting or a personal <code>CURSOR_API_KEY</code> is available; otherwise only skills already in the cloud repo. <code>validate</code> warns when this combination is present.</td></tr><tr><td><code>validate</code> and <code>run</code> succeed, but typecheck fails in CI</td><td>The CLI runs TypeScript with type-stripping only. Keep tool <code>execute</code> return types as object literals or <code>type</code> aliases, not <code>interface</code> types.</td></tr><tr><td>Login works, but turns are rejected when using custom API hosts</td><td>Point login and model traffic at the same host (<code>CURSOR_API_BASE_URL</code> and <code>CURSOR_BACKEND_URL</code>). A key from one host is rejected by the other.</td></tr></tbody></table><h2 id="what-if-the-http-api-returns-an-error" tabindex="-1">What if the HTTP API returns an error? <a class="header-anchor" href="#what-if-the-http-api-returns-an-error" aria-label="Permalink to "What if the HTTP API returns an error?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>409</code> on a follow-up message</td><td>Refresh the <code>continuationToken</code> or confirm the session is a chat session. Task sessions do not accept follow-ups.</td></tr><tr><td><code>409 session_busy</code> on <code>call --session</code></td><td>Wait for the model turn to finish, or omit <code>--session</code> for a one-off call.</td></tr><tr><td><code>403</code> on stream or follow-up</td><td>Use the same auth identity that created the session. Off localhost, pass <code>--bearer-token</code> and send it on every request.</td></tr><tr><td>Works on localhost; blocked through a tunnel or LAN</td><td>Default auth allows only direct loopback callers. Share the host with <code>--bearer-token <secret></code> (or authored <code>bearerAuth</code>). Use <code>--allow-anonymous</code> only on a trusted private network.</td></tr><tr><td>A channel route fails to compile with a schema type error</td><td><code>GET</code> routes need a Zod <code>querySchema</code>. <code>POST</code> / <code>PUT</code> / <code>PATCH</code> need a Zod <code>bodySchema</code>. Use <code>z.object({})</code> or <code>z.unknown()</code> for open shapes.</td></tr></tbody></table><h2 id="what-if-github-webhooks-misbehave" tabindex="-1">What if GitHub webhooks misbehave? <a class="header-anchor" href="#what-if-github-webhooks-misbehave" aria-label="Permalink to "What if GitHub webhooks misbehave?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>github forward</code> returns 401 on every delivery, but the hook was created</td><td>Clear <code>GITHUB_TOKEN</code> and <code>GH_TOKEN</code> for that command. The forwarder uses your <code>gh</code> CLI login: <code>GITHUB_TOKEN= GH_TOKEN= agent-sdk github forward …</code></td></tr><tr><td><code>Hook already exists</code> when starting a forwarder</td><td>GitHub allows one forwarder per repo. Run a single <code>github forward --dir <parent></code> and stop stale forwarders.</td></tr><tr><td>Deliveries rejected outside <code>--dev</code></td><td>Set <code>GITHUB_WEBHOOK_SECRET</code> on the server and on the signer. Without a secret, the channel stays loopback-only.</td></tr><tr><td>You lack repo admin and can't forward</td><td>Use <code>agent-sdk github replay <pr-url></code>. It needs pull access only and posts signed test payloads.</td></tr></tbody></table><h2 id="what-if-slack-stays-quiet" tabindex="-1">What if Slack stays quiet? <a class="header-anchor" href="#what-if-slack-stays-quiet" aria-label="Permalink to "What if Slack stays quiet?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>Logs show <code>channel idle … missing credentials</code></td><td>Expected when tokens are missing. Run <code>agent-sdk slack create --dir <agent></code> to provision the app and write the tokens, or <code>agent-sdk slack init --manual --dir <agent></code> and paste the manifests at api.slack.com. Then set <code><PREFIX>_SLACK_BOT_TOKEN</code> and <code><PREFIX>_SLACK_APP_TOKEN</code> per agent and run <code>agent-sdk slack doctor --prefix <PREFIX></code>.</td></tr><tr><td><code>slack create</code> reports the app needs admin approval</td><td>Open Slack's <strong>Request approval</strong> page (the CLI prints the link; the same URL is <strong>Send a reminder</strong> after you submit). Managed install does not file the request. Keep the CLI running, then click <strong>Retry</strong> in the dashboard after an admin approves.</td></tr><tr><td>The bot ignores ordinary channel posts</td><td>Default engagement is mentions and DMs only. Enable <code>engagement.channelPosts</code> with an allowlist, and subscribe the app to <code>message.channels</code> / <code>message.groups</code>.</td></tr><tr><td>Approve / Deny buttons do nothing</td><td>Channels that post approval cards need <code>toolApprovals: true</code>. Recreate the app with <code>slack create</code> if interactivity is off.</td></tr></tbody></table><h2 id="what-if-host-mcp-oauth-fails" tabindex="-1">What if host MCP OAuth fails? <a class="header-anchor" href="#what-if-host-mcp-oauth-fails" aria-label="Permalink to "What if host MCP OAuth fails?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>must be defineConnection({ url, oauth: true })</code></td><td>The connection file needs <code>oauth: true</code>, or you passed the wrong connection name to <code>agent-sdk mcp oauth</code>.</td></tr><tr><td>Local auth works; hosted calls unauthorized</td><td>Run <code>agent-sdk mcp oauth <name> --store</code>, confirm names with <code>agent-sdk secrets list <slug></code>, then redeploy.</td></tr><tr><td>Model asks for <code>mcp_auth</code> or IDE MCP for a connector it already has</td><td>Attached MCP is behind meta-tools. Set <code>advertiseTools: true</code> for named tools on local turns, or call it from a host tool via <code>ctx.host.mcp</code>.</td></tr></tbody></table><p>See <a href="./guides/mcp-oauth.html">Host MCP OAuth</a> and <a href="./../skills/mcp-auth/SKILL.html"><code>skills/mcp-auth/SKILL.md</code></a>.</p><h2 id="what-if-a-secret-showed-up-in-a-terminal-transcript" tabindex="-1">What if a secret showed up in a terminal transcript? <a class="header-anchor" href="#what-if-a-secret-showed-up-in-a-terminal-transcript" aria-label="Permalink to "What if a secret showed up in a terminal transcript?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td><code>secrets set … NAME=VALUE</code> in an agent-captured terminal or shell history</td><td>Rotate the secret at the provider. Set it again with names only: <code>agent-sdk secrets set <slug> NAME</code> (hidden prompt) or pipe/redirect the value. <code>NAME=VALUE</code> requires <code>--from-argv</code> and still leaks into argv.</td></tr><tr><td>Alias token printed during first deploy or <code>rotate-token</code></td><td>Treat it as exposed if the transcript left your machine. Run <code>agent-sdk rotate-token <slug></code>, store the new token outside agent transcripts, and update callers.</td></tr><tr><td>Someone verified a secret with <code>echo</code> / <code>printenv</code></td><td>Rotate it. Confirm presence with <code>agent-sdk secrets list <slug></code> (names only), then redeploy and test the feature.</td></tr></tbody></table><h2 id="what-if-schedules-reminders-or-approvals-stall" tabindex="-1">What if schedules, reminders, or approvals stall? <a class="header-anchor" href="#what-if-schedules-reminders-or-approvals-stall" aria-label="Permalink to "What if schedules, reminders, or approvals stall?""></a></h2><table tabindex="0"><thead><tr><th>What you see</th><th>What to do</th></tr></thead><tbody><tr><td>A schedule or reminder never fires under <code>--dev</code></td><td>Dev mode does not auto-fire. Trigger with <code>POST /<slug>/v1/dev/schedules/<id></code> or <code>POST /<slug>/v1/dev/reminders/<id></code> (list reminders at <code>GET /v1/dev/reminders</code>).</td></tr><tr><td>A pending tool approval disappeared after restart</td><td>Parked approvals do not survive host restart. They resolve as interrupted. Run the turn again.</td></tr><tr><td>A reminder is disarmed after restart (<code>handler_lost_on_restart</code>)</td><td>Handler-form reminders live in memory. Re-arm them from the code that created them, or use prompt-form reminders.</td></tr></tbody></table><h2 id="how-do-i-read-a-session-trace" tabindex="-1">How do I read a session trace? <a class="header-anchor" href="#how-do-i-read-a-session-trace" aria-label="Permalink to "How do I read a session trace?""></a></h2><p>Look at <code>actions.requested</code> / <code>action.result</code> pairs for the tool trajectory. Count calls by tool name before blaming latency. Separate host-side work (channel <code>callTool</code>, preparation) from tools the model chose.</p><p><code>turn.failed</code> with <code>"turn interrupted"</code> means a follow-up or stop ended the turn on purpose.</p><p>If the model reads outside the session workspace, the prepared files don't match what the instructions expect. Fix the layout. See <a href="./hillclimbing.html">Hillclimbing</a>.</p><p><code>agent-sdk trajectory --events <file></code> summarizes any saved NDJSON stream. The playground <strong>Open trace</strong> control does the same visually.</p><h2 id="what-s-next" tabindex="-1">What's next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to "What's next""></a></h2><ul><li><a href="./concepts.html">Concepts</a>: the model behind these symptoms</li><li><a href="./hillclimbing.html">Hillclimbing</a>: when the agent runs but underperforms</li><li><a href="./deployment.html">Deployment</a>: auth and state on shared hosts</li></ul>',28)])])}const m=t(r,[["render",s]]);export{p as __pageData,m as default};
|