@cursor/july 0.1.108 → 0.1.109
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 +2 -6
- package/README.md +3 -6
- package/dist/channels/bitbucket/api.d.ts +41 -0
- package/dist/channels/bitbucket/api.d.ts.map +1 -1
- package/dist/channels/bitbucket/api.js +260 -0
- package/dist/channels/bitbucket/binding.d.ts +4 -0
- package/dist/channels/bitbucket/binding.d.ts.map +1 -1
- package/dist/channels/bitbucket/binding.js +16 -0
- package/dist/channels/bitbucket/index.d.ts +1 -1
- package/dist/channels/bitbucket/index.d.ts.map +1 -1
- package/dist/channels/bitbucket/index.js +1 -1
- package/dist/channels/gitlab/api.d.ts +27 -0
- package/dist/channels/gitlab/api.d.ts.map +1 -1
- package/dist/channels/gitlab/api.js +88 -0
- package/dist/channels/gitlab/binding.d.ts +5 -0
- package/dist/channels/gitlab/binding.d.ts.map +1 -1
- package/dist/channels/gitlab/binding.js +10 -0
- package/dist/channels/gitlab/index.d.ts +1 -1
- package/dist/channels/gitlab/index.d.ts.map +1 -1
- package/dist/channels/gitlab/index.js +1 -1
- package/dist/channels/slack/dispatch.d.ts +10 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +20 -3
- package/dist/channels/slack/slack-channel.d.ts +12 -5
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +59 -8
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BASKM3M4.js → app.Cr-wVbnB.js} +1 -1
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.js → building-with-agents.md.D0KbSkJn.js} +2 -2
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.lean.js → building-with-agents.md.D0KbSkJn.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CFVQ4S17.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BOKxlYGP.js → VPLocalSearchBox.CVQERt56.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DbDZW-zb.js → theme.Dnsd3XOn.js} +2 -2
- package/dist/docs/assets/concepts.md.B4o63Gul.js +1 -0
- package/dist/docs/assets/evals.md.C7JLjoEP.js +211 -0
- package/dist/docs/assets/evals.md.C7JLjoEP.lean.js +1 -0
- package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.js +10 -0
- package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.lean.js +1 -0
- package/dist/docs/assets/{guides_github.md.BH33UEBJ.js → guides_github.md.TZaTZlfz.js} +13 -3
- package/dist/docs/assets/{guides_github.md.BH33UEBJ.lean.js → guides_github.md.TZaTZlfz.lean.js} +1 -1
- package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.js +14 -0
- package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.lean.js +1 -0
- package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.js → guides_webhooks.md.CJK484ex.js} +2 -2
- package/dist/docs/assets/{hillclimbing.md.CpTGTCle.js → hillclimbing.md.BOiVo1tf.js} +1 -1
- package/dist/docs/assets/index.md.DD9Q2XuJ.js +5 -0
- package/dist/docs/assets/{index.md.BjH1w2ZW.lean.js → index.md.DD9Q2XuJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.CAo-iK4j.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.lean.js → reference_channels.md.CAo-iK4j.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.Ca26u0Es.js → reference_cli.md.Deg7849l.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.CPWt00ds.js → reference_extensions.md.ZAVUyuEX.js} +2 -2
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.js → reference_hooks.md.BlM_bOg6.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.lean.js → reference_hooks.md.BlM_bOg6.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.oySXBO8o.js → reference_http-api.md.BwaCo-VO.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.js → reference_playground.md.DLnoaczX.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.lean.js → reference_playground.md.DLnoaczX.lean.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.js → reference_project-layout.md.BEU8MtQV.js} +3 -3
- package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.lean.js → reference_project-layout.md.BEU8MtQV.lean.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.CyXV1MUw.js +1 -0
- package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.js +35 -0
- package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.lean.js +1 -0
- package/dist/docs/assets/{skills_evals.md.BhovOvrl.js → skills_evals.md.DFxYPErF.js} +3 -3
- package/dist/docs/assets/skills_evals.md.DFxYPErF.lean.js +1 -0
- package/dist/docs/assets/{skills_framework-map.md.D-tFZhFS.js → skills_framework-map.md.BxLSOhSY.js} +1 -1
- package/dist/docs/assets/skills_index.md.DL7EHaQ-.js +1 -0
- package/dist/docs/assets/skills_index.md.DL7EHaQ-.lean.js +1 -0
- package/dist/docs/assets/{storage.md.BOHeqk2M.js → storage.md.BUrhJ-Zz.js} +4 -4
- package/dist/docs/assets/{storage.md.BOHeqk2M.lean.js → storage.md.BUrhJ-Zz.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +5 -5
- package/dist/docs/building-with-agents.md +3 -2
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/concepts.md +2 -4
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/evals.html +161 -35
- package/dist/docs/evals.md +612 -297
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/bitbucket.html +36 -0
- package/dist/docs/guides/bitbucket.md +84 -0
- package/dist/docs/guides/cloud-agents.html +4 -4
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +17 -7
- package/dist/docs/guides/github.md +31 -0
- package/dist/docs/guides/gitlab.html +40 -0
- package/dist/docs/guides/gitlab.md +92 -0
- package/dist/docs/guides/grokbot-agents.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/improve.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +4 -4
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +5 -5
- package/dist/docs/guides/webhooks.html +6 -6
- package/dist/docs/guides/webhooks.md +4 -2
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +6 -6
- package/dist/docs/hillclimbing.md +2 -2
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +10 -6
- package/dist/docs/llms-full.txt +1113 -778
- package/dist/docs/llms.txt +6 -5
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +6 -6
- package/dist/docs/reference/channels.md +16 -3
- package/dist/docs/reference/cli.html +6 -6
- package/dist/docs/reference/cli.md +6 -4
- package/dist/docs/reference/connections.html +4 -4
- package/dist/docs/reference/extensions.html +7 -7
- package/dist/docs/reference/extensions.md +0 -3
- package/dist/docs/reference/hooks.html +7 -7
- package/dist/docs/reference/hooks.md +9 -12
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +2 -3
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/playground.md +0 -4
- package/dist/docs/reference/project-layout.html +7 -7
- package/dist/docs/reference/project-layout.md +1 -8
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/result.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 +1 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +4 -4
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/skills/create-agent.html +4 -4
- package/dist/docs/skills/debug.html +4 -4
- package/dist/docs/skills/deploy.html +61 -0
- package/dist/docs/skills/deploy.md +161 -0
- package/dist/docs/skills/evals.html +8 -8
- package/dist/docs/skills/evals.md +44 -6
- package/dist/docs/skills/framework-map.html +5 -5
- package/dist/docs/skills/framework-map.md +1 -2
- package/dist/docs/skills/github.html +4 -4
- package/dist/docs/skills/hillclimb.html +4 -4
- package/dist/docs/skills/index.html +6 -6
- package/dist/docs/skills/index.md +1 -1
- package/dist/docs/skills/mcp-auth.html +4 -4
- package/dist/docs/skills/otel.html +4 -4
- package/dist/docs/skills/setup-slack.html +4 -4
- package/dist/docs/storage.html +8 -8
- package/dist/docs/storage.md +15 -24
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +4 -4
- package/dist/docs/templates/code-wiki.html +4 -4
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/grokbot-agents.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 +4 -4
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/extensions.d.ts +2 -3
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +2 -5
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/internal/authored-alias-hooks.d.ts +5 -0
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
- package/dist/internal/authored-alias-hooks.js +17 -0
- package/dist/internal/authored-loaders.d.ts +4 -0
- package/dist/internal/authored-loaders.d.ts.map +1 -1
- package/dist/internal/authored-loaders.js +21 -2
- package/dist/internal/cli-ax.d.ts +1 -2
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +1 -2
- package/dist/internal/continuation-channel.d.ts.map +1 -1
- package/dist/internal/continuation-channel.js +2 -2
- package/dist/internal/continuation-identity.js +8 -3
- package/dist/internal/discovery/agent.d.ts +1 -1
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/discovery/agent.js +0 -5
- package/dist/internal/discovery/extension-overlay.d.ts +1 -2
- package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
- package/dist/internal/discovery/extension-overlay.js +0 -14
- package/dist/internal/discovery/extensions.d.ts +1 -2
- package/dist/internal/discovery/extensions.d.ts.map +1 -1
- package/dist/internal/discovery/extensions.js +4 -22
- package/dist/internal/discovery/info.d.ts.map +1 -1
- package/dist/internal/discovery/info.js +42 -24
- package/dist/internal/discovery/modules.js +0 -1
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +0 -16
- package/dist/internal/eval-runner.js +0 -1
- package/dist/internal/framework-file-storage.d.ts +4 -5
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +4 -5
- package/dist/internal/framework-storage-selection.d.ts +2 -2
- package/dist/internal/framework-storage-selection.js +2 -2
- package/dist/internal/init-scaffold.d.ts.map +1 -1
- package/dist/internal/init-scaffold.js +1 -2
- package/dist/internal/install-cursor-skills.d.ts +5 -2
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +25 -5
- package/dist/internal/run-client.d.ts +1 -1
- package/dist/internal/sdk-runner.js +1 -1
- package/dist/internal/server.js +0 -14
- package/dist/internal/session-engine.d.ts +5 -35
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +17 -162
- package/dist/internal/storage-coordinator.d.ts +5 -19
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +3 -62
- package/dist/internal/storage-roles.d.ts +4 -9
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/storage-roles.js +2 -2
- package/dist/playground/assets/index-Bhxzrcf6.css +1 -0
- package/dist/playground/assets/index-CqLX5uF3.js +67 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted-v2.d.ts +4 -5
- package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted-v2.js +4 -5
- package/dist/storage-backends/cursor-hosted.d.ts +1 -2
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +0 -30
- package/dist/storage-backends/file-kv.d.ts +9 -12
- package/dist/storage-backends/file-kv.d.ts.map +1 -1
- package/dist/storage-backends/file-kv.js +11 -47
- package/dist/storage-protocol.d.ts +3 -11
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +3 -11
- package/dist/storage.d.ts +8 -36
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +8 -44
- package/dist/types.d.ts +20 -57
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +10 -6
- package/docs/building-with-agents.md +3 -2
- package/docs/concepts.md +2 -4
- package/docs/evals.md +613 -298
- package/docs/guides/bitbucket.md +89 -0
- package/docs/guides/github.md +31 -0
- package/docs/guides/gitlab.md +97 -0
- package/docs/guides/webhooks.md +4 -2
- package/docs/hillclimbing.md +2 -2
- package/docs/reference/channels.md +16 -3
- package/docs/reference/cli.md +6 -4
- package/docs/reference/extensions.md +0 -3
- package/docs/reference/hooks.md +9 -12
- package/docs/reference/http-api.md +2 -3
- package/docs/reference/playground.md +0 -4
- package/docs/reference/project-layout.md +1 -8
- package/docs/reference/sessions.md +1 -2
- package/docs/skills/index.md +2 -2
- package/docs/storage.md +15 -24
- package/package.json +1 -7
- package/skills/deploy/SKILL.md +169 -0
- package/skills/evals/SKILL.md +45 -8
- package/skills/framework-map/SKILL.md +1 -2
- package/src/channels/bitbucket/api.ts +341 -0
- package/src/channels/bitbucket/binding.ts +25 -0
- package/src/channels/bitbucket/index.ts +2 -0
- package/src/channels/gitlab/api.ts +123 -0
- package/src/channels/gitlab/binding.ts +12 -0
- package/src/channels/gitlab/index.ts +1 -0
- package/src/channels/slack/dispatch.ts +30 -0
- package/src/channels/slack/slack-channel.ts +69 -7
- package/src/extensions.ts +2 -6
- package/src/index.ts +0 -3
- package/src/internal/authored-alias-hooks.ts +32 -0
- package/src/internal/authored-loaders.ts +26 -2
- package/src/internal/cli-ax.ts +1 -2
- package/src/internal/continuation-channel.ts +2 -1
- package/src/internal/continuation-identity.ts +10 -2
- package/src/internal/discovery/agent.ts +1 -7
- package/src/internal/discovery/extension-overlay.ts +0 -18
- package/src/internal/discovery/extensions.ts +2 -26
- package/src/internal/discovery/info.ts +3 -13
- package/src/internal/discovery/modules.ts +0 -1
- package/src/internal/discovery/project.ts +0 -16
- package/src/internal/eval-runner.ts +0 -1
- package/src/internal/framework-file-storage.ts +4 -5
- package/src/internal/framework-storage-selection.ts +2 -2
- package/src/internal/init-scaffold.ts +1 -2
- package/src/internal/install-cursor-skills.ts +38 -5
- package/src/internal/run-client.ts +1 -1
- package/src/internal/sdk-runner.ts +1 -1
- package/src/internal/server.ts +0 -16
- package/src/internal/session-engine.ts +14 -202
- package/src/internal/storage-coordinator.ts +5 -76
- package/src/internal/storage-roles.ts +4 -9
- package/src/storage-backends/cursor-hosted-v2.ts +4 -7
- package/src/storage-backends/cursor-hosted.ts +0 -37
- package/src/storage-backends/file-kv.ts +10 -51
- package/src/storage-protocol.ts +3 -17
- package/src/storage.ts +10 -101
- package/src/types.ts +19 -56
- package/templates/demo/README.md +10 -6
- package/templates/demo/agent/channels/github.ts +2 -0
- package/templates/demo/agent/channels/queue.ts +6 -2
- package/templates/demo/agent/lib/repos.ts +5 -0
- package/templates/demo/init.json +25 -0
- package/dist/ab.d.ts +0 -209
- package/dist/ab.d.ts.map +0 -1
- package/dist/ab.js +0 -246
- package/dist/docs/ab.html +0 -80
- package/dist/docs/ab.md +0 -332
- package/dist/docs/assets/ab.md.mlVgqvSk.js +0 -54
- package/dist/docs/assets/ab.md.mlVgqvSk.lean.js +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BHZYsNVi.js +0 -1
- package/dist/docs/assets/concepts.md.DgEcZOfT.js +0 -1
- package/dist/docs/assets/evals.md.C1ekS3k2.js +0 -85
- package/dist/docs/assets/evals.md.C1ekS3k2.lean.js +0 -1
- package/dist/docs/assets/index.md.BjH1w2ZW.js +0 -5
- package/dist/docs/assets/reference_sessions.md.CueyOHSL.js +0 -1
- package/dist/docs/assets/skills_ab.md.CsFNatVx.js +0 -26
- package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +0 -1
- package/dist/docs/assets/skills_evals.md.BhovOvrl.lean.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +0 -1
- package/dist/docs/skills/ab.html +0 -52
- package/dist/docs/skills/ab.md +0 -50
- package/dist/internal/ab-collector.d.ts +0 -44
- package/dist/internal/ab-collector.d.ts.map +0 -1
- package/dist/internal/ab-collector.js +0 -142
- package/dist/internal/ab-fold.d.ts +0 -36
- package/dist/internal/ab-fold.d.ts.map +0 -1
- package/dist/internal/ab-fold.js +0 -175
- package/dist/internal/ab-snapshot.d.ts +0 -68
- package/dist/internal/ab-snapshot.d.ts.map +0 -1
- package/dist/internal/ab-snapshot.js +0 -208
- package/dist/internal/discovery/ab.d.ts +0 -9
- package/dist/internal/discovery/ab.d.ts.map +0 -1
- package/dist/internal/discovery/ab.js +0 -113
- package/dist/playground/assets/index-BMDqAeXu.js +0 -67
- package/dist/playground/assets/index-LUgJoWdL.css +0 -1
- package/docs/ab.md +0 -337
- package/skills/ab/SKILL.md +0 -58
- package/src/ab.ts +0 -430
- package/src/internal/ab-collector.ts +0 -200
- package/src/internal/ab-fold.ts +0 -232
- package/src/internal/ab-snapshot.ts +0 -331
- package/src/internal/discovery/ab.ts +0 -131
- /package/dist/docs/assets/{concepts.md.DgEcZOfT.lean.js → concepts.md.B4o63Gul.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.lean.js → guides_webhooks.md.CJK484ex.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.CpTGTCle.lean.js → hillclimbing.md.BOiVo1tf.lean.js} +0 -0
- /package/dist/docs/assets/{reference_cli.md.Ca26u0Es.lean.js → reference_cli.md.Deg7849l.lean.js} +0 -0
- /package/dist/docs/assets/{reference_extensions.md.CPWt00ds.lean.js → reference_extensions.md.ZAVUyuEX.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.oySXBO8o.lean.js → reference_http-api.md.BwaCo-VO.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.CueyOHSL.lean.js → reference_sessions.md.CyXV1MUw.lean.js} +0 -0
- /package/dist/docs/assets/{skills_framework-map.md.D-tFZhFS.lean.js → skills_framework-map.md.BxLSOhSY.lean.js} +0 -0
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import{_ as e,c as i,o as
|
|
1
|
+
import{_ as e,c as i,o as a,ag as t}from"./chunks/framework.BCISBCiQ.js";const c=JSON.parse('{"title":"GitHub","description":"Wake your agent from pull requests, CI, and comments by pulling Cursor SCM events, with fixtures and replay for local tests.","frontmatter":{"title":"GitHub","description":"Wake your agent from pull requests, CI, and comments by pulling Cursor SCM events, with fixtures and replay for local tests."},"headers":[],"relativePath":"guides/github.md","filePath":"guides/github.md"}'),n={name:"guides/github.md"};function h(l,s,o,p,r,d){return a(),i("div",null,[...s[0]||(s[0]=[t(`<h1 id="github-agents" tabindex="-1">GitHub agents <a class="header-anchor" href="#github-agents" aria-label="Permalink to "GitHub agents""></a></h1><p>Wake your agent from repository events without exposing a public webhook URL. Prefer <code>serve --cursor-events</code>: the host long-polls Cursor's SCM event stream for repos you've connected to Cursor. You still declare a <code>githubChannel</code> so hooks decide what each event does.</p><p>The companion skill for coding agents is <a href="./../skills/github.html"><code>skills/github/SKILL.md</code></a>.</p><h2 id="pull-events-from-cursor" tabindex="-1">Pull events from Cursor <a class="header-anchor" href="#pull-events-from-cursor" aria-label="Permalink to "Pull events from Cursor""></a></h2><p>Connect GitHub in Cursor for the repositories you care about (Settings or <a href="https://cursor.com/dashboard" target="_blank" rel="noreferrer">cursor.com/dashboard</a>). That gives your account access and lets Cursor receive the repo's webhooks. Sign the host in (<code>agent-sdk login</code>, <code>CURSOR_API_KEY</code>, or <code>CURSOR_SERVICE_ACCOUNT_KEY</code>), then opt the channel into the Cursor account connection:</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;"> githubChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cursorAccount: {</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> repos: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"owner/repo"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // permissions?: "read" | "pr-write" | "contents-write"</span></span>
|
|
5
5
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // default "pr-write" (comments / PR writes, no contents:write)</span></span>
|
|
6
6
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
7
7
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // hooks...</span></span>
|
|
8
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p><code>cursorAccount</code> starts the event relay and mints one short-lived GitHub credential scoped to those repositories. <code>ctx.github</code>, <code>ctx.host.github</code>, and child <code>gh</code> commands share it. The Agent SDK refreshes the credential before expiry. No GitHub App key, PAT, or separate <code>gh auth login</code> is needed on the host.</p><p>Choose <code>permissions</code> by what the agent needs:</p><table tabindex="0"><thead><tr><th><code>permissions</code></th><th>Use when</th></tr></thead><tbody><tr><td><code>"read"</code></td><td>Inspect PRs / issues / statuses only</td></tr><tr><td><code>"pr-write"</code> (default)</td><td>Comment, review, update PR/issue metadata</td></tr><tr><td><code>"contents-write"</code></td><td>Push code, or post merge-box checks</td></tr></tbody></table><p><code>contents-write</code> is an explicit opt-up. <code>progress.commitStatus</code> posts a GitHub check run (<code>checks:write</code>). Hosted <code>cursorAccount</code> mints that permission on <code>"contents-write"</code> tokens. Enabling <code>commitStatus</code> opts a <code>"pr-write"</code> channel up to that tier because it needs check-write permission. <code>"pr-write"</code> without <code>commitStatus</code> is enough for comments and banners. Prefer <code>"pr-write"</code> unless the agent must push or post a merge-box check.</p><p>Set <code>checks: true</code> when channel code posts its own Checks API runs through <code>ctx.github.createCheck</code>. The flag grants access. It does not post a check.</p><p>Selected repositories must share one GitHub owner (one App installation). Configuration that spans owners fails at startup / mint time.</p><p>To keep repository scope in deployment config instead, use <code>cursorAccount: true</code> and pass it at serve time:</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;"> --cursor-events</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --repo</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> owner/repo</span></span></code></pre></div><p>Repeat <code>--repo</code> for each repository. The stream and credential are resolved as the signed-in Cursor principal. <code>serve</code> refuses to start signed out.</p><p>The stream carries event metadata, not full webhook bodies, so your agent should re-read the PR or checks from GitHub instead of trusting a snapshot in the wake.</p><p>This is the preferred production path: no public URL, no repo admin webhook, and no inbound network for GitHub deliveries.</p><h2 id="
|
|
8
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p><code>cursorAccount</code> starts the event relay and mints one short-lived GitHub credential scoped to those repositories. <code>ctx.github</code>, <code>ctx.host.github</code>, and child <code>gh</code> commands share it. The Agent SDK refreshes the credential before expiry. No GitHub App key, PAT, or separate <code>gh auth login</code> is needed on the host.</p><p>Choose <code>permissions</code> by what the agent needs:</p><table tabindex="0"><thead><tr><th><code>permissions</code></th><th>Use when</th></tr></thead><tbody><tr><td><code>"read"</code></td><td>Inspect PRs / issues / statuses only</td></tr><tr><td><code>"pr-write"</code> (default)</td><td>Comment, review, update PR/issue metadata</td></tr><tr><td><code>"contents-write"</code></td><td>Push code, or post merge-box checks</td></tr></tbody></table><p><code>contents-write</code> is an explicit opt-up. <code>progress.commitStatus</code> posts a GitHub check run (<code>checks:write</code>). Hosted <code>cursorAccount</code> mints that permission on <code>"contents-write"</code> tokens. Enabling <code>commitStatus</code> opts a <code>"pr-write"</code> channel up to that tier because it needs check-write permission. <code>"pr-write"</code> without <code>commitStatus</code> is enough for comments and banners. Prefer <code>"pr-write"</code> unless the agent must push or post a merge-box check.</p><p>Set <code>checks: true</code> when channel code posts its own Checks API runs through <code>ctx.github.createCheck</code>. The flag grants access. It does not post a check.</p><p>Selected repositories must share one GitHub owner (one App installation). Configuration that spans owners fails at startup / mint time.</p><p>To keep repository scope in deployment config instead, use <code>cursorAccount: true</code> and pass it at serve time:</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;"> --cursor-events</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --repo</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> owner/repo</span></span></code></pre></div><p>Repeat <code>--repo</code> for each repository. The stream and credential are resolved as the signed-in Cursor principal. <code>serve</code> refuses to start signed out.</p><p>The stream carries event metadata, not full webhook bodies, so your agent should re-read the PR or checks from GitHub instead of trusting a snapshot in the wake.</p><p>This is the preferred production path: no public URL, no repo admin webhook, and no inbound network for GitHub deliveries.</p><h2 id="connect-github-enterprise-server" tabindex="-1">Connect GitHub Enterprise Server <a class="header-anchor" href="#connect-github-enterprise-server" aria-label="Permalink to "Connect GitHub Enterprise Server""></a></h2><p>GitHub Enterprise Server uses the same <code>githubChannel()</code> hooks and normalized events. Connect it through the direct webhook route. Set the REST API base and credentials for your server:</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;"> githubChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> api: {</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> apiBaseUrl: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"https://github.example.com/api/v3"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> credentials: {</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> token</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;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GITHUB_TOKEN</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> webhookSecret</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;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GITHUB_WEBHOOK_SECRET</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onPullRequest</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;">pr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pr.action </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "opened"</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { auth: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">defaultGitHubAuth</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(ctx) } </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>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Add a repository webhook for <code>https://<your-host>/<slug>/v1/channels/github</code>. Use the same webhook secret on the server and in <code>GITHUB_WEBHOOK_SECRET</code>. The channel verifies <code>X-Hub-Signature-256</code> before it parses the payload.</p><p>Cursor account event pull, <code>github replay</code>, and <code>github forward</code> target GitHub.com. Test Enterprise Server integrations by posting saved webhook fixtures to a local <code>--dev</code> server. Leave <code>GITHUB_WEBHOOK_SECRET</code> unset for this local test so the channel admits unsigned loopback deliveries. Use a real delivery from your server so the fixture matches its version.</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/github.ts</code> with <code>githubChannel()</code> from <code>@cursor/july/channels/github</code>. It mounts <code>POST /<slug>/v1/channels/github</code> and publishes the events it dispatches on. That event set comes from the hooks you declare, or you pin it with <code>webhookEvents</code>. Cursor event pull and local replay both use it.</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;"> { defaultGitHubAuth, githubChannel } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/channels/github"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
9
19
|
<span class="line"></span>
|
|
10
20
|
<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;"> githubChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
11
21
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> botName: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"my-agent"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// or GITHUB_APP_SLUG; used to ignore self-comments</span></span>
|
|
@@ -51,4 +61,4 @@ import{_ as e,c as i,o as t,ag as a}from"./chunks/framework.BCISBCiQ.js";const c
|
|
|
51
61
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
52
62
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onPullRequest</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;">pr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span></span>
|
|
53
63
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pr.action </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "opened"</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { auth: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">defaultGitHubAuth</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(ctx) } </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>
|
|
54
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Default stream events drive the lifecycle:</p><table tabindex="0"><thead><tr><th>Event</th><th>Check run</th><th>Banner</th></tr></thead><tbody><tr><td><code>turn.started</code></td><td><code>in_progress</code></td><td>create (or keep) the sticky comment</td></tr><tr><td><code>turn.completed</code></td><td><code>completed</code> / <code>success</code></td><td>PATCH the same comment</td></tr><tr><td><code>turn.failed</code> / <code>session.failed</code></td><td><code>completed</code> / <code>failure</code></td><td>PATCH the same comment</td></tr></tbody></table><p>Omit <code>commitStatus</code> / <code>banner</code>, or set them to <code>false</code>, to keep today's behavior. Reactions still default on; set <code>reactions: false</code> when the eyes emoji is noise. Descriptions are optional; defaults derive from <code>botName</code> or the check <code>context</code>.</p><p>To match dashboard automations, set <code>detailsUrl(sessionId)</code>, <code>summaryLinkText: "View agent"</code>, and <code>outputTitle: "context"</code> so the check title is the check name, the summary includes <code>[View agent](…)</code>, and Details opens the session.</p><p>A comment-only first wake has no head SHA, so the check waits for a PR or CI event. The banner still posts. A later turn on the same SHA creates a new check run; GitHub cannot reopen a completed run.</p><p>Override <code>events</code> when the mapping is custom. A handler can post commit status from <code>turn.started</code> / <code>action.result</code> / <code>turn.failed</code> and stay never-red; that pattern still wins when you replace a default handler key. Handlers you author replace the matching defaults (same as <code>progress.reactions</code> composition today).</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./webhooks.html">Webhooks and custom channels</a>: the HTTP mechanism under this pack</li><li><a href="./../evals.html">Evals</a>: turn replay snapshots into regression fixtures</li><li><a href="./../reference/hooks.html">Hooks</a>: observe-only; use channel <code>progress</code> for GitHub surfaces</li></ul>`,
|
|
64
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Default stream events drive the lifecycle:</p><table tabindex="0"><thead><tr><th>Event</th><th>Check run</th><th>Banner</th></tr></thead><tbody><tr><td><code>turn.started</code></td><td><code>in_progress</code></td><td>create (or keep) the sticky comment</td></tr><tr><td><code>turn.completed</code></td><td><code>completed</code> / <code>success</code></td><td>PATCH the same comment</td></tr><tr><td><code>turn.failed</code> / <code>session.failed</code></td><td><code>completed</code> / <code>failure</code></td><td>PATCH the same comment</td></tr></tbody></table><p>Omit <code>commitStatus</code> / <code>banner</code>, or set them to <code>false</code>, to keep today's behavior. Reactions still default on; set <code>reactions: false</code> when the eyes emoji is noise. Descriptions are optional; defaults derive from <code>botName</code> or the check <code>context</code>.</p><p>To match dashboard automations, set <code>detailsUrl(sessionId)</code>, <code>summaryLinkText: "View agent"</code>, and <code>outputTitle: "context"</code> so the check title is the check name, the summary includes <code>[View agent](…)</code>, and Details opens the session.</p><p>A comment-only first wake has no head SHA, so the check waits for a PR or CI event. The banner still posts. A later turn on the same SHA creates a new check run; GitHub cannot reopen a completed run.</p><p>Override <code>events</code> when the mapping is custom. A handler can post commit status from <code>turn.started</code> / <code>action.result</code> / <code>turn.failed</code> and stay never-red; that pattern still wins when you replace a default handler key. Handlers you author replace the matching defaults (same as <code>progress.reactions</code> composition today).</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./webhooks.html">Webhooks and custom channels</a>: the HTTP mechanism under this pack</li><li><a href="./../evals.html">Evals</a>: turn replay snapshots into regression fixtures</li><li><a href="./../reference/hooks.html">Hooks</a>: observe-only; use channel <code>progress</code> for GitHub surfaces</li></ul>`,57)])])}const u=e(n,[["render",h]]);export{c as __pageData,u as default};
|
package/dist/docs/assets/{guides_github.md.BH33UEBJ.lean.js → guides_github.md.TZaTZlfz.lean.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,c as i,o as
|
|
1
|
+
import{_ as e,c as i,o as a,ag as t}from"./chunks/framework.BCISBCiQ.js";const c=JSON.parse('{"title":"GitHub","description":"Wake your agent from pull requests, CI, and comments by pulling Cursor SCM events, with fixtures and replay for local tests.","frontmatter":{"title":"GitHub","description":"Wake your agent from pull requests, CI, and comments by pulling Cursor SCM events, with fixtures and replay for local tests."},"headers":[],"relativePath":"guides/github.md","filePath":"guides/github.md"}'),n={name:"guides/github.md"};function h(l,s,o,p,r,d){return a(),i("div",null,[...s[0]||(s[0]=[t("",57)])])}const u=e(n,[["render",h]]);export{c as __pageData,u as default};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import{_ as a,c as e,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const c=JSON.parse('{"title":"GitLab","description":"Wake your agent from GitLab merge requests, notes, pipelines, and pushes on GitLab.com or self-managed GitLab.","frontmatter":{"title":"GitLab","description":"Wake your agent from GitLab merge requests, notes, pipelines, and pushes on GitLab.com or self-managed GitLab."},"headers":[],"relativePath":"guides/gitlab.md","filePath":"guides/gitlab.md"}'),n={name:"guides/gitlab.md"};function l(h,s,p,o,r,d){return i(),e("div",null,[...s[0]||(s[0]=[t(`<h1 id="gitlab-agents" tabindex="-1">GitLab agents <a class="header-anchor" href="#gitlab-agents" aria-label="Permalink to "GitLab agents""></a></h1><p>Use <code>gitlabChannel()</code> for GitLab.com and self-managed GitLab. The channel verifies project hooks, normalizes their payloads, and gives each hook a project-bound <code>ctx.gitlab</code> API client.</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/gitlab.ts</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;"> { gitlabChannel } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/channels/gitlab"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
2
|
+
<span class="line"></span>
|
|
3
|
+
<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;"> gitlabChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({});</span></span></code></pre></div><p>Without <code>onMergeRequest</code>, new and reopened merge requests start turns. Updates start turns only when they include new commits. Notes, pushes, and pipelines are opt-in through <code>onNote</code>, <code>onPush</code>, and <code>onPipeline</code>. Use <code>onEvent</code> for other GitLab event types. Set <code>webhookEvents</code> when managed event delivery must subscribe to an event that only <code>onEvent</code> handles.</p><p>Filter note hooks by author before starting a turn. This prevents comments posted by the agent from triggering another turn.</p><p><code>ctx.gitlab</code> can call the project REST API and create commit statuses. See the <a href="./../reference/channels.html">Channels reference</a> for hook return values and session behavior.</p><h2 id="connect-gitlab" tabindex="-1">Connect GitLab <a class="header-anchor" href="#connect-gitlab" aria-label="Permalink to "Connect GitLab""></a></h2><p>On Cursor-managed hosting, use the signed-in Cursor account:</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;"> gitlabChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cursorAccount: {</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> projects: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"acme/platform"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>For direct webhooks, set a project hook secret and API token:</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:#24292E;--shiki-dark:#E1E4E8;">GITLAB_WEBHOOK_SECRET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">...</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">GITLAB_TOKEN</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">...</span></span></code></pre></div><p>Add a project webhook for <code>https://<your-host>/<slug>/v1/channels/gitlab</code>. Use the same value for the GitLab secret token and <code>GITLAB_WEBHOOK_SECRET</code>. The channel checks <code>X-Gitlab-Token</code> before it parses the payload.</p><p>Self-managed GitLab also needs its REST API base:</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;"> gitlabChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> apiBaseUrl: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"https://gitlab.example.com/api/v4"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> projects: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"acme/platform"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>You can set <code>GITLAB_API_BASE_URL</code> instead.</p><h2 id="test-locally" tabindex="-1">Test locally <a class="header-anchor" href="#test-locally" aria-label="Permalink to "Test locally""></a></h2><p>Start the agent, then replay a merge request you can read:</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;"> dev</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> gitlab</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> replay</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> https://gitlab.example.com/acme/platform/-/merge_requests/42</span></span></code></pre></div><p><code>GITLAB_TOKEN</code> needs API read access. Replay reads the merge request, creates GitLab-shaped payloads, and sends them through the same channel route. Use <code>--events '*'</code> to replay the supported events declared by the channel. Use <code>--dry-run --out fixtures/gitlab</code> to save fixtures.</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;"> gitlab</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> events</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> gitlab</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> forward</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --dir</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span></span></code></pre></div><p>GitLab has no local webhook relay. <code>forward</code> prints the project-hook and HTTPS tunnel setup for live deliveries.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./../reference/channels.html">Channels reference</a></li><li><a href="./webhooks.html">Webhooks and custom channels</a></li><li><a href="./../evals.html">Evals</a></li></ul>`,25)])])}const g=a(n,[["render",l]]);export{c as __pageData,g as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as a,c as e,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const c=JSON.parse('{"title":"GitLab","description":"Wake your agent from GitLab merge requests, notes, pipelines, and pushes on GitLab.com or self-managed GitLab.","frontmatter":{"title":"GitLab","description":"Wake your agent from GitLab merge requests, notes, pipelines, and pushes on GitLab.com or self-managed GitLab."},"headers":[],"relativePath":"guides/gitlab.md","filePath":"guides/gitlab.md"}'),n={name:"guides/gitlab.md"};function l(h,s,p,o,r,d){return i(),e("div",null,[...s[0]||(s[0]=[t("",25)])])}const g=a(n,[["render",l]]);export{c as __pageData,g as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as i,c as a,o as n,ag as h}from"./chunks/framework.BCISBCiQ.js";const o=JSON.parse('{"title":"Webhooks & custom channels","description":"Give the agent its own HTTP surface: validated routes, sessions keyed to your domain, and replies delivered back out.","frontmatter":{"title":"Webhooks & custom channels","description":"Give the agent its own HTTP surface: validated routes, sessions keyed to your domain, and replies delivered back out."},"headers":[],"relativePath":"guides/webhooks.md","filePath":"guides/webhooks.md"}'),t={name:"guides/webhooks.md"};function e(k,s,l,p,r,E){return n(),a("div",null,[...s[0]||(s[0]=[h(`<h1 id="webhooks-and-custom-channels" tabindex="-1">Webhooks and custom channels <a class="header-anchor" href="#webhooks-and-custom-channels" aria-label="Permalink to "Webhooks and custom channels""></a></h1><p>A custom channel gives the agent its own HTTP surface. You get routes with validated payloads, sessions keyed to something in your domain (a thread, a ticket, a PR), and replies delivered back to the caller. The <a href="./slack.html">Slack</a> and <a href="./github.html">GitHub</a> packs build on this mechanism. This page is the mechanism itself.</p><h2 id="what-you-already-have" tabindex="-1">What you already have <a class="header-anchor" href="#what-you-already-have" aria-label="Permalink to "What you already have""></a></h2><p>The built-in HTTP channel is always mounted (under <code>/<slug></code> in the default multi-agent layout). <code>POST /v1/session</code> starts a conversation, <code>POST /v1/session/:id</code> follows up, and <code>GET /v1/session/:id/stream</code> streams NDJSON events, plus sessions, approvals, and tool routes. See the <a href="./../reference/http-api.html">HTTP API reference</a>.</p><p>Write a custom channel when that shape doesn't fit: a webhook with its own payload contract, a surface that keys sessions by a domain id, or a flow that does host-side work before (or instead of) a model turn.</p><h2 id="define-a-channel" tabindex="-1">Define a channel <a class="header-anchor" href="#define-a-channel" aria-label="Permalink to "Define a channel""></a></h2><p>Author <code>agent/channels/<id>.ts</code> with <code>defineChannel</code>. The filename is the channel id, and routes mount under <code>/v1/channels/<id></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;"> { defineChannel, POST } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/channels"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
1
|
+
import{_ as i,c as a,o as n,ag as h}from"./chunks/framework.BCISBCiQ.js";const o=JSON.parse('{"title":"Webhooks & custom channels","description":"Give the agent its own HTTP surface: validated routes, sessions keyed to your domain, and replies delivered back out.","frontmatter":{"title":"Webhooks & custom channels","description":"Give the agent its own HTTP surface: validated routes, sessions keyed to your domain, and replies delivered back out."},"headers":[],"relativePath":"guides/webhooks.md","filePath":"guides/webhooks.md"}'),t={name:"guides/webhooks.md"};function e(k,s,l,p,r,E){return n(),a("div",null,[...s[0]||(s[0]=[h(`<h1 id="webhooks-and-custom-channels" tabindex="-1">Webhooks and custom channels <a class="header-anchor" href="#webhooks-and-custom-channels" aria-label="Permalink to "Webhooks and custom channels""></a></h1><p>A custom channel gives the agent its own HTTP surface. You get routes with validated payloads, sessions keyed to something in your domain (a thread, a ticket, a PR), and replies delivered back to the caller. The <a href="./slack.html">Slack</a> and <a href="./github.html">GitHub</a> packs build on this mechanism. The <a href="./gitlab.html">GitLab</a> and <a href="./bitbucket.html">Bitbucket</a> packs use it too. This page is the mechanism itself.</p><h2 id="what-you-already-have" tabindex="-1">What you already have <a class="header-anchor" href="#what-you-already-have" aria-label="Permalink to "What you already have""></a></h2><p>The built-in HTTP channel is always mounted (under <code>/<slug></code> in the default multi-agent layout). <code>POST /v1/session</code> starts a conversation, <code>POST /v1/session/:id</code> follows up, and <code>GET /v1/session/:id/stream</code> streams NDJSON events, plus sessions, approvals, and tool routes. See the <a href="./../reference/http-api.html">HTTP API reference</a>.</p><p>Write a custom channel when that shape doesn't fit: a webhook with its own payload contract, a surface that keys sessions by a domain id, or a flow that does host-side work before (or instead of) a model turn.</p><h2 id="define-a-channel" tabindex="-1">Define a channel <a class="header-anchor" href="#define-a-channel" aria-label="Permalink to "Define a channel""></a></h2><p>Author <code>agent/channels/<id>.ts</code> with <code>defineChannel</code>. The filename is the channel id, and routes mount under <code>/v1/channels/<id></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;"> { defineChannel, POST } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/channels"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { z } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "zod"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
3
3
|
<span class="line"></span>
|
|
4
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;"> defineChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -222,4 +222,4 @@ import{_ as i,c as a,o as n,ag as h}from"./chunks/framework.BCISBCiQ.js";const o
|
|
|
222
222
|
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .update(fs.readFileSync("fixtures/issue-create.json")).digest("hex"))'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
223
223
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -X</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POST</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> http://127.0.0.1:3000/</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"><</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">slu</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">g</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/v1/channels/linear/</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
224
224
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'content-type: application/json'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "linear-signature: </span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$SIG</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
225
|
-
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --data-binary</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @fixtures/issue-create.json</span></span></code></pre></div><h2 id="test-a-channel" tabindex="-1">Test a channel <a class="header-anchor" href="#test-a-channel" aria-label="Permalink to "Test a channel""></a></h2><p>Start with curl and saved payloads under <code>fixtures/</code>. The playground's <strong>Try</strong> modal covers manual probes. It remembers your last body per endpoint, has Copy curl, and opens the created session on a successful Try. For regression coverage, drive the same behavior through an eval, or keep channel logic deterministic in <code>agent/lib/</code> and unit-test it there. When something looks wrong, inspect the session event stream. The stream is the record of what happened.</p><p>For GitHub specifically, don't hand-roll fixtures. <code>agent-sdk github replay</code> synthesizes real-shaped, signed payloads from any PR you can read. See the <a href="./github.html">GitHub guide</a>.</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><p>Continue with these pages:</p><ul><li><a href="./../reference/channels.html">Channels reference</a>: the full authoring API</li><li><a href="./github.html">GitHub</a> and <a href="./slack.html">Slack</a>: the packaged channels</li><li><a href="./../reference/sessions.html">Sessions and streaming</a>: events your channel can subscribe to</li></ul>`,60)])])}const g=i(t,[["render",e]]);export{o as __pageData,g as default};
|
|
225
|
+
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --data-binary</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> @fixtures/issue-create.json</span></span></code></pre></div><h2 id="test-a-channel" tabindex="-1">Test a channel <a class="header-anchor" href="#test-a-channel" aria-label="Permalink to "Test a channel""></a></h2><p>Start with curl and saved payloads under <code>fixtures/</code>. The playground's <strong>Try</strong> modal covers manual probes. It remembers your last body per endpoint, has Copy curl, and opens the created session on a successful Try. For regression coverage, drive the same behavior through an eval, or keep channel logic deterministic in <code>agent/lib/</code> and unit-test it there. When something looks wrong, inspect the session event stream. The stream is the record of what happened.</p><p>For GitHub specifically, don't hand-roll fixtures. <code>agent-sdk github replay</code> synthesizes real-shaped, signed payloads from any PR you can read. See the <a href="./github.html">GitHub guide</a>.</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><p>Continue with these pages:</p><ul><li><a href="./../reference/channels.html">Channels reference</a>: the full authoring API</li><li><a href="./github.html">GitHub</a>, <a href="./gitlab.html">GitLab</a>, <a href="./bitbucket.html">Bitbucket</a>, and <a href="./slack.html">Slack</a>: the packaged channels</li><li><a href="./../reference/sessions.html">Sessions and streaming</a>: events your channel can subscribe to</li></ul>`,60)])])}const g=i(t,[["render",e]]);export{o as __pageData,g as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{_ as t,c as i,o as a,ag as l}from"./chunks/framework.BCISBCiQ.js";const m=JSON.parse('{"title":"Hillclimbing","description":"Improve an agent one measured round at a time, with the hillclimb skill running the loop with you.","frontmatter":{"title":"Hillclimbing","description":"Improve an agent one measured round at a time, with the hillclimb skill running the loop with you."},"headers":[],"relativePath":"hillclimbing.md","filePath":"hillclimbing.md"}'),o={name:"hillclimbing.md"};function n(r,e,s,h,d,c){return a(),i("div",null,[...e[0]||(e[0]=[l(`<h1 id="hillclimbing" tabindex="-1">Hillclimbing <a class="header-anchor" href="#hillclimbing" aria-label="Permalink to "Hillclimbing""></a></h1><p>Make an agent better on fixed inputs: measure, change one lever, remeasure, and lock every kept win with an eval.</p><h2 id="what-is-hillclimbing" tabindex="-1">What is hillclimbing? <a class="header-anchor" href="#what-is-hillclimbing" aria-label="Permalink to "What is hillclimbing?""></a></h2><p>Hillclimbing is a measured improvement loop. You pin a few fixtures, name the one dominant problem in the run, change one lever, and check the same fixtures again. Keep only what helps. Every kept change lands an <a href="./evals.html">eval</a> so the win stays put.</p><p>You don't have to run the loop alone. The package ships a coding-agent skill that drives it with you.</p><div class="language-mermaid vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">mermaid</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">flowchart LR</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> measure[Measure] --> change[Change one lever]</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> change --> remeasure[Remeasure]</span></span>
|
|
4
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> remeasure --> measure</span></span></code></pre></div><h2 id="how-do-i-hillclimb-an-agent-with-a-coding-agent" tabindex="-1">How do I hillclimb an agent with a coding agent? <a class="header-anchor" href="#how-do-i-hillclimb-an-agent-with-a-coding-agent" aria-label="Permalink to "How do I hillclimb an agent with a coding agent?""></a></h2><p>Have Cursor read <a href="./skills/hillclimb.html"><code>skills/hillclimb/SKILL.md</code></a>.</p><p>Tell it:</p><ol><li><strong>Which agent</strong> you're improving (path or slug)</li><li><strong>One to three fixtures</strong> you'll reuse every round: a PR URL, a saved webhook body, or a canonical chat prompt</li><li><strong>What "better" means</strong> this round: correct tool choice, fewer tools, lower latency, or output quality. Name the freeze line too: API shape, public output, and existing evals that must stay green</li></ol><p>The skill serves the agent, hits your fixtures, reads the session trajectory, proposes one change, remeasures, and checks with you before the next round.</p><p>Other skills cover the edges:</p><table tabindex="0"><thead><tr><th>When you need…</th><th>Skill</th></tr></thead><tbody><tr><td>The measured improvement loop</td><td><a href="./skills/hillclimb.html"><code>skills/hillclimb/SKILL.md</code></a></td></tr><tr><td>An eval that locks a kept win</td><td><a href="./skills/evals.html"><code>skills/evals/SKILL.md</code></a></td></tr><tr><td>Repeatable GitHub webhook inputs</td><td><a href="./skills/github.html"><code>skills/github/SKILL.md</code></a></td></tr><tr><td>A run that misbehaves</td><td><a href="./skills/debug.html"><code>skills/debug/SKILL.md</code></a></td></tr></tbody></table><p>See <a href="./building-with-agents.html">Building agents with agents</a> for every framework skill and a good first prompt.</p><h2 id="what-do-i-need-before-a-hillclimb-round" tabindex="-1">What do I need before a hillclimb round? <a class="header-anchor" href="#what-do-i-need-before-a-hillclimb-round" aria-label="Permalink to "What do I need before a hillclimb round?""></a></h2><p>Agree on four things before you edit:</p><ol><li><strong>The target agent</strong>: the project you're improving</li><li><strong>Fixtures</strong>: one to three fixed inputs you can compare across runs</li><li><strong>Success criteria</strong>: what better means this round</li><li><strong>The freeze line</strong>: what must not change</li></ol><p>Pin the input first. A moving fixture is noise. For GitHub agents, use <code>agent-sdk github replay</code> (see the <a href="./guides/github.html">GitHub guide</a>). For a single tool without a model turn, use <code>agent-sdk call</code>. For a chat turn, use <code>agent-sdk run --dir . --message "…"</code>.</p><h2 id="how-do-i-run-one-hillclimb-round" tabindex="-1">How do I run one hillclimb round? <a class="header-anchor" href="#how-do-i-run-one-hillclimb-round" aria-label="Permalink to "How do I run one hillclimb round?""></a></h2><p><strong>Measure.</strong> Hit the agent the way a user would: playground, channel HTTP, or Slack in <code>--dev</code>. Or ask the hillclimb skill to do it. <code>agent-sdk run</code> returns a JSON trajectory and writes a trace under the project state directory.</p><p><strong>Reflect.</strong> Score the trajectory, not impressions. Was the answer right? Did the model thrash (too many tools, fat evidence, grep loops)? Did it invent work the host should have prepared? Name the single dominant problem for this round in one sentence. Example: "Full-file dumps trigger grep loops."</p><p><strong>Change one lever.</strong> Prefer the smallest change that addresses that problem:</p><ol><li>Host prep: seed what the model needs so it doesn't hunt</li><li>Evidence shape: trim or reorder artifacts</li><li>Instructions and skills: tighten the procedure</li><li>Tool surface: remove or gate tools that invite wandering</li><li>Framework changes: only when the agent can't express the fix</li></ol><p><strong>Remeasure.</strong> Same fixtures. Diff tools, wall time, and quality side by side. Keep the change only if the target metric improves and the freeze line holds.</p><h2 id="how-do-i-lock-a-hillclimb-improvement-with-an-eval" tabindex="-1">How do I lock a hillclimb improvement with an eval? <a class="header-anchor" href="#how-do-i-lock-a-hillclimb-improvement-with-an-eval" aria-label="Permalink to "How do I lock a hillclimb improvement with an eval?""></a></h2><p>Every kept change needs an eval that would have failed before the change: a tool-choice gate,
|
|
4
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> remeasure --> measure</span></span></code></pre></div><h2 id="how-do-i-hillclimb-an-agent-with-a-coding-agent" tabindex="-1">How do I hillclimb an agent with a coding agent? <a class="header-anchor" href="#how-do-i-hillclimb-an-agent-with-a-coding-agent" aria-label="Permalink to "How do I hillclimb an agent with a coding agent?""></a></h2><p>Have Cursor read <a href="./skills/hillclimb.html"><code>skills/hillclimb/SKILL.md</code></a>.</p><p>Tell it:</p><ol><li><strong>Which agent</strong> you're improving (path or slug)</li><li><strong>One to three fixtures</strong> you'll reuse every round: a PR URL, a saved webhook body, or a canonical chat prompt</li><li><strong>What "better" means</strong> this round: correct tool choice, fewer tools, lower latency, or output quality. Name the freeze line too: API shape, public output, and existing evals that must stay green</li></ol><p>The skill serves the agent, hits your fixtures, reads the session trajectory, proposes one change, remeasures, and checks with you before the next round.</p><p>Other skills cover the edges:</p><table tabindex="0"><thead><tr><th>When you need…</th><th>Skill</th></tr></thead><tbody><tr><td>The measured improvement loop</td><td><a href="./skills/hillclimb.html"><code>skills/hillclimb/SKILL.md</code></a></td></tr><tr><td>An eval that locks a kept win</td><td><a href="./skills/evals.html"><code>skills/evals/SKILL.md</code></a></td></tr><tr><td>Repeatable GitHub webhook inputs</td><td><a href="./skills/github.html"><code>skills/github/SKILL.md</code></a></td></tr><tr><td>A run that misbehaves</td><td><a href="./skills/debug.html"><code>skills/debug/SKILL.md</code></a></td></tr></tbody></table><p>See <a href="./building-with-agents.html">Building agents with agents</a> for every framework skill and a good first prompt.</p><h2 id="what-do-i-need-before-a-hillclimb-round" tabindex="-1">What do I need before a hillclimb round? <a class="header-anchor" href="#what-do-i-need-before-a-hillclimb-round" aria-label="Permalink to "What do I need before a hillclimb round?""></a></h2><p>Agree on four things before you edit:</p><ol><li><strong>The target agent</strong>: the project you're improving</li><li><strong>Fixtures</strong>: one to three fixed inputs you can compare across runs</li><li><strong>Success criteria</strong>: what better means this round</li><li><strong>The freeze line</strong>: what must not change</li></ol><p>Pin the input first. A moving fixture is noise. For GitHub agents, use <code>agent-sdk github replay</code> (see the <a href="./guides/github.html">GitHub guide</a>). For a single tool without a model turn, use <code>agent-sdk call</code>. For a chat turn, use <code>agent-sdk run --dir . --message "…"</code>.</p><h2 id="how-do-i-run-one-hillclimb-round" tabindex="-1">How do I run one hillclimb round? <a class="header-anchor" href="#how-do-i-run-one-hillclimb-round" aria-label="Permalink to "How do I run one hillclimb round?""></a></h2><p><strong>Measure.</strong> Hit the agent the way a user would: playground, channel HTTP, or Slack in <code>--dev</code>. Or ask the hillclimb skill to do it. <code>agent-sdk run</code> returns a JSON trajectory and writes a trace under the project state directory.</p><p><strong>Reflect.</strong> Score the trajectory, not impressions. Was the answer right? Did the model thrash (too many tools, fat evidence, grep loops)? Did it invent work the host should have prepared? Name the single dominant problem for this round in one sentence. Example: "Full-file dumps trigger grep loops."</p><p><strong>Change one lever.</strong> Prefer the smallest change that addresses that problem:</p><ol><li>Host prep: seed what the model needs so it doesn't hunt</li><li>Evidence shape: trim or reorder artifacts</li><li>Instructions and skills: tighten the procedure</li><li>Tool surface: remove or gate tools that invite wandering</li><li>Framework changes: only when the agent can't express the fix</li></ol><p><strong>Remeasure.</strong> Same fixtures. Diff tools, wall time, and quality side by side. Keep the change only if the target metric improves and the freeze line holds.</p><h2 id="how-do-i-lock-a-hillclimb-improvement-with-an-eval" tabindex="-1">How do I lock a hillclimb improvement with an eval? <a class="header-anchor" href="#how-do-i-lock-a-hillclimb-improvement-with-an-eval" aria-label="Permalink to "How do I lock a hillclimb improvement with an eval?""></a></h2><p>Every kept change needs an eval that would have failed before the change: a tool-choice gate, a <code>maxToolCalls</code> bound, or an output-shape check. Run <code>agent-sdk eval --dir . --json</code> between rounds. Never weaken an existing gate to pass the round.</p><p>Details live in <a href="./evals.html#keep-improvements-with-regression-evals">Keep improvements with regression evals</a>. The evals skill will author the case with you.</p><h2 id="what-habits-help-hillclimbing-stay-reliable" tabindex="-1">What habits help hillclimbing stay reliable? <a class="header-anchor" href="#what-habits-help-hillclimbing-stay-reliable" aria-label="Permalink to "What habits help hillclimbing stay reliable?""></a></h2><ul><li>One problem per round. Don't bundle "trim evidence and rewrite instructions" unless you chose that on purpose.</li><li>Keep fixtures fixed until you deliberately need a harder case.</li><li>Separate host work from model tools when you blame latency. Moving deterministic prep onto the host is often the biggest win. In one PR reviewer, host-prepared evidence cut turns from about 8 minutes to about 1 minute.</li><li>Spot-check quality on at least one fixture against a known-good answer. Efficiency-only climbs quietly drop findings.</li><li>Treat <code>turn.failed</code> with <code>"turn interrupted"</code> as expected when a follow-up or stop preempted the turn.</li><li>Don't deploy, post to real surfaces, or weaken evals as part of a climb.</li></ul><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./evals.html">Evals</a></li><li><a href="./building-with-agents.html">Building agents with agents</a></li><li><a href="./guides/github.html">GitHub guide</a></li><li><a href="./troubleshooting.html">Fix common agent problems</a></li></ul>`,31)])])}const p=t(o,[["render",n]]);export{m as __pageData,p as default};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{_ as t,c as a,o as r,ag as s}from"./chunks/framework.BCISBCiQ.js";const g=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"}'),i={name:"index.md"};function n(o,e,l,h,d,c){return r(),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/grokbot-agents.html">Grok Bot agents</a>, <a href="./templates/code-wiki.html">Code wiki</a>, <a href="./templates/agents-md.html">Living AGENTS.md</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 or GitHub Enterprise Server</td><td><a href="./guides/github.html">GitHub guide</a></td></tr><tr><td>Wiring an agent to GitLab</td><td><a href="./guides/gitlab.html">GitLab guide</a></td></tr><tr><td>Wiring an agent to Bitbucket</td><td><a href="./guides/bitbucket.html">Bitbucket 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>Handing coding work to Cursor cloud agents</td><td><a href="./guides/cloud-agents.html">Cursor cloud agents</a></td></tr><tr><td>Talking to your Grok Bot agents</td><td><a href="./guides/grokbot-agents.html">Cursor Grok Bot agents</a></td></tr><tr><td>Letting an agent change its own source</td><td><a href="./guides/improve.html">Self-improvement</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>Gating agent behavior in CI</td><td><a href="./evals.html#run-evals-in-ci">Run evals in CI</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/grokbot-agents.html">Talk to your Grok Bot agents</a>: name the bots, then consult them from this agent's own conversation.</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/agents-md.html">Keep AGENTS.md current from last week's work</a>: pull rules out of merged PRs and Slack, then open a follow-up PR.</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, assert over the trajectory, and run them locally and in CI.</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/gitlab.html">GitLab</a>: trigger the agent from merge requests, notes, pipelines, and pushes.</li><li><a href="./guides/bitbucket.html">Bitbucket</a>: trigger the agent from pull requests, comments, and pushes.</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 persist them on hosted deployments (<code>--store</code>).</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-agents.html">Cursor cloud agents</a>: let the agent launch and steer cloud agents through the <code>cursor-cloud-agents</code> extension.</li><li><a href="./guides/grokbot-agents.html">Cursor Grok Bot agents</a>: let the agent talk to Grok Bot agents through the <code>cursor-grokbot-agents</code> extension.</li><li><a href="./guides/improve.html">Self-improvement</a>: let the agent change its own source through a one-off cloud agent and a pull request with the <code>improve</code> extension.</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> · <a href="./reference/extensions.html">Extensions</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/artifacts.html">Artifacts</a> · <a href="./reference/result.html">Turn result</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 p=t(i,[["render",n]]);export{g as __pageData,p as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as t,c as a,o as
|
|
1
|
+
import{_ as t,c as a,o as r,ag as s}from"./chunks/framework.BCISBCiQ.js";const g=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"}'),i={name:"index.md"};function n(o,e,l,h,d,c){return r(),a("div",null,[...e[0]||(e[0]=[s("",31)])])}const p=t(i,[["render",n]]);export{g as __pageData,p as default};
|
package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.CAo-iK4j.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as e,c as a,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const k=JSON.parse('{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies.","frontmatter":{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies."},"headers":[],"relativePath":"reference/channels.md","filePath":"reference/channels.md"}'),n={name:"reference/channels.md"};function o(h,s,l,r,d,c){return i(),a("div",null,[...s[0]||(s[0]=[t(`<h1 id="channels" tabindex="-1">Channels <a class="header-anchor" href="#channels" aria-label="Permalink to "Channels""></a></h1><p>A channel is the surface an agent lives on. The built-in HTTP session channel is always mounted. Custom channels declare their own routes under <code>/v1/channels/<id></code>. The Slack and GitHub packs are prebuilt channels with platform transports. This page is the authoring reference; for the walkthrough, see the <a href="./../guides/webhooks.html">Webhooks guide</a>.</p><h2 id="built-in-http-channel" tabindex="-1">Built-in HTTP channel <a class="header-anchor" href="#built-in-http-channel" aria-label="Permalink to "Built-in HTTP channel""></a></h2><p>It's always mounted, under <code>/<slug></code> in the default multi-agent layout: session create, follow-up, stream, stop, the sessions list, approvals, deterministic tool calls, health, and info. For the route-by-route contract, see the <a href="./http-api.html">HTTP API reference</a>.</p><p>Author <code>agent/channels/http.ts</code> only to override its defaults:</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;"> {</span></span>
|
|
1
|
+
import{_ as e,c as a,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const k=JSON.parse('{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies.","frontmatter":{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies."},"headers":[],"relativePath":"reference/channels.md","filePath":"reference/channels.md"}'),n={name:"reference/channels.md"};function o(h,s,l,r,d,c){return i(),a("div",null,[...s[0]||(s[0]=[t(`<h1 id="channels" tabindex="-1">Channels <a class="header-anchor" href="#channels" aria-label="Permalink to "Channels""></a></h1><p>A channel is the surface an agent lives on. The built-in HTTP session channel is always mounted. Custom channels declare their own routes under <code>/v1/channels/<id></code>. The Slack and GitHub packs are prebuilt channels with platform transports. GitLab and Bitbucket packs cover their hosted and self-managed products. This page is the authoring reference; for the walkthrough, see the <a href="./../guides/webhooks.html">Webhooks guide</a>.</p><h2 id="built-in-http-channel" tabindex="-1">Built-in HTTP channel <a class="header-anchor" href="#built-in-http-channel" aria-label="Permalink to "Built-in HTTP channel""></a></h2><p>It's always mounted, under <code>/<slug></code> in the default multi-agent layout: session create, follow-up, stream, stop, the sessions list, approvals, deterministic tool calls, health, and info. For the route-by-route contract, see the <a href="./http-api.html">HTTP API reference</a>.</p><p>Author <code>agent/channels/http.ts</code> only to override its defaults:</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;"> {</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> bearerAuth,</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> httpChannel,</span></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localDevStrict,</span></span>
|
|
@@ -50,4 +50,4 @@ import{_ as e,c as a,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const k
|
|
|
50
50
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
51
51
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
52
52
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // auth: [...], state: {...}, onStart(...), onStop(...)</span></span>
|
|
53
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This example assumes <code>agent/tools/inspect_pr.ts</code> exists. The handler calls it before the model turn, so every review starts with validated PR data. It also derives a stable conversation key from the PR URL and writes the tool result to <code>pr.json</code>. Instructions can ask the model to inspect a PR, but host code guarantees it.</p><h2 id="route-verbs-and-schemas" tabindex="-1">Route verbs and schemas <a class="header-anchor" href="#route-verbs-and-schemas" aria-label="Permalink to "Route verbs and schemas""></a></h2><p><code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>PATCH</code>, and <code>DELETE</code> helpers build routes. Their schemas are Zod, enforced at compile time:</p><table tabindex="0"><thead><tr><th>Verb</th><th>Required schema</th></tr></thead><tbody><tr><td><code>GET</code></td><td><code>querySchema</code></td></tr><tr><td><code>POST</code> / <code>PUT</code> / <code>PATCH</code></td><td><code>bodySchema</code> (optional <code>querySchema</code>)</td></tr><tr><td><code>DELETE</code></td><td>both optional</td></tr></tbody></table><p>Plain JSON Schema objects won't type-check; use <code>z.object({})</code> or <code>z.unknown()</code> for intentionally open surfaces. The host validates before the handler runs. Handlers receive typed <code>args.body</code> and <code>args.query</code>, and empty POST bodies are coerced to <code>{}</code> first. Declared schemas are projected on <code>GET /v1/info</code>, which powers the playground's <strong>Try</strong> buttons and composer <strong>slash commands</strong>.</p><h2 id="handler-arguments" tabindex="-1">Handler arguments <a class="header-anchor" href="#handler-arguments" aria-label="Permalink to "Handler arguments""></a></h2><p>Handlers receive the Fetch <code>Request</code> and an args object:</p><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>send(message, options?)</code></td><td>Run a model turn on this channel; returns the session handle (options below)</td></tr><tr><td><code>getSession(sessionId)</code></td><td>Look up an existing session on this channel</td></tr><tr><td><code>receive(channelDefinition, input)</code></td><td>Hand off to another channel (schedules use this)</td></tr><tr><td><code>callTool(name, input, options?)</code></td><td>Deterministic server-tool call (<a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>)</td></tr><tr><td><code>body</code>, <code>query</code>, <code>params</code></td><td>Validated payloads and <code>:param</code> path segments</td></tr><tr><td><code>auth</code></td><td>The <code>AuthContext</code> resolved by this route's auth chain</td></tr><tr><td><code>requestIp</code></td><td>The TCP peer address</td></tr><tr><td><code>host</code></td><td>Shared services: <code>host.mcp</code>, <code>host.github</code>, <code>host.slack</code>, <code>host.kv</code>, <code>host.files</code>, <code>host.reminders</code></td></tr><tr><td><code>waitUntil(promise)</code></td><td>Background work that outlives the response</td></tr><tr><td><code>sessionUrls(request, sessionId)</code></td><td>Absolute playground + trace URLs for a session on this mount</td></tr><tr><td><code>artifacts</code></td><td>Unbound <a href="./artifacts.html">artifacts</a> facade; pass <code>sessionId</code> in <code>tag</code> input to attribute one</td></tr></tbody></table><p><code>send</code> options: <code>continuationToken</code> (the conversation key), <code>admission</code> (<code>"preempt"</code> interrupts a busy session, the default; <code>"coalesce"</code> enqueues behind the running turn, the <a href="./sessions.html#what-happens-when-i-send-a-follow-up">Slack policy</a>), <code>workspaceFiles</code>, <code>workspaceDir</code>, <code>cloud</code> (attach cloud repos for this session), <code>auth</code> (defaults to the request principal), <code>state</code> (starting channel state for new sessions), <code>title</code> (session display title), and <code>purpose</code> (<code>"eval"</code> skips sticky A/B enrollment).</p><h2 id="events" tabindex="-1">Events <a class="header-anchor" href="#events" aria-label="Permalink to "Events""></a></h2><p>The <code>events</code> map subscribes the channel to stream events for the sessions it owns. Keys are event types from the <a href="./sessions.html#which-events-can-i-stream">event vocabulary</a>, or <code>"*"</code>. Handlers receive <code>(event, channel, ctx)</code>, where <code>channel.state</code> is the per-session adapter state, <code>ctx.session</code> is the session info, and <code>ctx.host</code> is the shared host services, bound to that session as in a <a href="./hooks.html#handler-context">hook</a>. This is where a channel delivers replies back to its surface.</p><h2 id="state-and-lifecycle" tabindex="-1">State and lifecycle <a class="header-anchor" href="#state-and-lifecycle" aria-label="Permalink to "State and lifecycle""></a></h2><p><code>state</code> declares the starting per-session adapter state (JSON), persisted on the session record. Routes and event handlers read and mutate it through <code>channel.state</code>. <code>onStart(args)</code> runs when the channel mounts. <code>onStop()</code> runs when the server stops.</p><p><code>onStart</code> receives the route helpers (<code>send</code>, <code>getSession</code>, <code>receive</code>, <code>callTool</code>, <code>host</code>, <code>waitUntil</code>, <code>artifacts</code>, <code>logger</code>) plus helpers for long-lived transports:</p><ul><li><code>emitAssistantMessage(sessionId, text)</code> appends an assistant message without a model turn, for host tasks that already produced the final text.</li><li><code>hasContinuationSession(token)</code> and <code>isContinuationBusy(token)</code> report whether a continuation token has a live session and whether a turn is in flight on it.</li><li><code>interruptContinuation(token)</code> stops the in-flight turn and clears coalesced follow-ups queued behind it.</li><li><code>resolveApproval(sessionId, callId, decision, auth, options?)</code> approves or denies a parked tool call, how Slack Block Kit buttons unblock a turn without the HTTP approvals route.</li></ul><h2 id="auth-policies" tabindex="-1">Auth policies <a class="header-anchor" href="#auth-policies" aria-label="Permalink to "Auth policies""></a></h2><p>Every route runs an auth-policy chain: the channel's <code>auth</code> array, or <code>[localDevStrict()]</code> when unset. A policy is a function <code>(request, info) => AuthContext | null</code> (async allowed); the first non-null wins, and a request no policy admits gets <code>401</code>.</p><table tabindex="0"><thead><tr><th>Policy</th><th>Admits</th></tr></thead><tbody><tr><td><code>localDevStrict()</code></td><td>Direct loopback callers with no proxy-forwarding headers (<code>X-Forwarded-For</code>, <code>X-Real-IP</code>, <code>Forwarded</code>, and <code>X-Forwarded-Host</code> are all rejected, so tunnels and same-host reverse proxies don't silently re-expose the route), plus a loopback <code>Host</code> header, which rejects DNS-rebinding callers that reach 127.0.0.1 with a remote hostname.</td></tr><tr><td><code>localDev()</code></td><td>Like <code>localDevStrict()</code> but without the <code>Host</code> check. An explicit, weaker opt-in.</td></tr><tr><td><code>loopbackOnly()</code></td><td>A loopback TCP peer, ignoring forwarding headers; for dev relays that legitimately carry them, like <code>gh webhook forward</code>.</td></tr><tr><td><code>bearerAuth(token)</code></td><td><code>Authorization: Bearer <token></code>, compared in constant time. Also accepts a verifier function mapping a presented token to an <code>AuthContext</code>.</td></tr><tr><td><code>allowAll()</code></td><td>Everyone, as an <code>anonymous</code> principal. Only for surfaces protected upstream (an HMAC-verified webhook) or intentionally public.</td></tr><tr><td><code>publicEndpoint()</code></td><td>Everyone on this custom channel. Managed hosting also serves the channel without an alias token. Use it only when the handler verifies the provider signature.</td></tr></tbody></table><p><code>publicEndpoint()</code> applies only to custom channel routes. It does not open the built-in session or tool API.</p><p>The resolved <code>AuthContext</code> (<code>{ authenticator, principalId, principalType, attributes? }</code>) becomes the request principal. Sessions bind to the principal that created them, and follow-up, stream, and list routes enforce ownership (<code>403</code> otherwise).</p><p>Server flags interact with authored auth: <code>--bearer-token</code> swaps the default <code>localDevStrict()</code> for <code>bearerAuth(...)</code> on channels that don't author their own chain, and <code>--allow-anonymous</code> swaps it for <code>allowAll()</code>. Authored <code>auth</code> arrays always win over both. A channel that declares <code>[localDevStrict()]</code> stays loopback-only even on an <code>--allow-anonymous</code> host.</p><h2 id="first-class-channels" tabindex="-1">First class channels <a class="header-anchor" href="#first-class-channels" aria-label="Permalink to "First class channels""></a></h2><p><strong>Slack</strong> (<code>@cursor/july/channels/slack</code>): Socket Mode transport, streaming replies, engagement rules, approval cards, and a default block on Slack Connect / guest / other-workspace senders. Author <code>agent/channels/slack.ts</code> with <code>slackChannel()</code>. Guide: <a href="./../guides/slack.html">Slack</a>.</p><p><strong>GitHub</strong> (<code>@cursor/july/channels/github</code>): webhook dispatch with signature verification, per-event hooks returning <code>{ auth }</code> (a model turn), <code>{ task }</code> (host work), or <code>null</code>, and CLI tooling for replay and live forwarding. Author <code>agent/channels/github.ts</code> with <code>githubChannel()</code>. Opt-in <code>progress.commitStatus</code> and <code>progress.banner</code> converge a merge-box check and sticky PR comment from default stream events. Guide: <a href="./../guides/github.html">GitHub</a>.</p><p><strong>Deployments</strong> (<code>@cursor/july/channels/deployments</code>): pull deploy events. Declare <code>events</code> and handle each one in <code>onEvent</code>. Each event carries <code>deploySourceUri</code> and <code>deployVersion</code>. Author <code>agent/channels/deployments.ts</code> with <code>deploymentsChannel()</code>.</p><p>On Cursor-managed hosting, omit <code>deploySourceUris</code>. The deployment's watched repositories bind the event scope automatically. Name sources to narrow the scope or to drive the self-hosted pull relay. Subscribe per deploy source with <code>deploySourceUris</code> and narrow with <code>environments</code> or <code>events</code>. Each entry must match <code>Deployment.deploy_source_uri</code> as your deployment writer records it. Matching is case-insensitive but otherwise literal. It uses the host credential. A restart resumes rather than dropping events. An empty <code>deploySourceUris</code> list mounts the channel but starts no pull, so an env-configured agent stays inert until its deploy sources are set.</p><p><strong>Change Monitors</strong> (<code>@cursor/july/channels/change-monitors</code>): Change Monitor Checkpoint events. The channel publishes Factory <code>checkpoint.created</code> for every Checkpoint create. The agent filters the result (for example to the <code>issues</code> arm). The payload contains the full Checkpoint resource. This channel is scoped to Change Monitors, not generic Factory Checkpoints. There is no repository filter or resource filter. Author <code>agent/channels/change-monitors.ts</code> with <code>changeMonitorsChannel()</code>. It uses the host credential.</p><p><strong>Issues</strong> (<code>@cursor/july/channels/issues</code>): Factory issue events. The channel publishes <code>issue.created</code> for every Issue create. The agent filters if it needs a subset. The payload contains the full Issue resource. There is no repository filter or resource filter. Author <code>agent/channels/issues.ts</code> with <code>issuesChannel()</code>. It uses the host credential.</p><p>For other platforms like Discord or Teams, use the authored <code>defineChannel</code> webhook form.</p><h2 id="continuation-semantics" tabindex="-1">Continuation semantics <a class="header-anchor" href="#continuation-semantics" aria-label="Permalink to "Continuation semantics""></a></h2><p>Channels own their continuation-token format. The built-in HTTP channel mints opaque rotating tokens, Slack uses <code>channelId:threadTs</code>, and PR automations use keys like <code>pr:owner/repo#N</code>. Same token, same durable session; one active continuation per session; the HTTP channel returns <code>409</code> for stale tokens. For the full session model, see <a href="./sessions.html">Sessions</a>.</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><p>Continue with these pages:</p><ul><li><a href="./../guides/webhooks.html">Webhooks guide</a>: the same API, walked through</li><li><a href="./http-api.html">HTTP API</a>: session, discovery, and channel routes</li><li><a href="./sessions.html">Sessions and streaming</a>: the events channels subscribe to</li></ul>`,43)])])}const E=e(n,[["render",o]]);export{k as __pageData,E as default};
|
|
53
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This example assumes <code>agent/tools/inspect_pr.ts</code> exists. The handler calls it before the model turn, so every review starts with validated PR data. It also derives a stable conversation key from the PR URL and writes the tool result to <code>pr.json</code>. Instructions can ask the model to inspect a PR, but host code guarantees it.</p><h2 id="route-verbs-and-schemas" tabindex="-1">Route verbs and schemas <a class="header-anchor" href="#route-verbs-and-schemas" aria-label="Permalink to "Route verbs and schemas""></a></h2><p><code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>PATCH</code>, and <code>DELETE</code> helpers build routes. Their schemas are Zod, enforced at compile time:</p><table tabindex="0"><thead><tr><th>Verb</th><th>Required schema</th></tr></thead><tbody><tr><td><code>GET</code></td><td><code>querySchema</code></td></tr><tr><td><code>POST</code> / <code>PUT</code> / <code>PATCH</code></td><td><code>bodySchema</code> (optional <code>querySchema</code>)</td></tr><tr><td><code>DELETE</code></td><td>both optional</td></tr></tbody></table><p>Plain JSON Schema objects won't type-check; use <code>z.object({})</code> or <code>z.unknown()</code> for intentionally open surfaces. The host validates before the handler runs. Handlers receive typed <code>args.body</code> and <code>args.query</code>, and empty POST bodies are coerced to <code>{}</code> first. Declared schemas are projected on <code>GET /v1/info</code>, which powers the playground's <strong>Try</strong> buttons and composer <strong>slash commands</strong>.</p><h2 id="handler-arguments" tabindex="-1">Handler arguments <a class="header-anchor" href="#handler-arguments" aria-label="Permalink to "Handler arguments""></a></h2><p>Handlers receive the Fetch <code>Request</code> and an args object:</p><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>send(message, options?)</code></td><td>Run a model turn on this channel; returns the session handle (options below)</td></tr><tr><td><code>getSession(sessionId)</code></td><td>Look up an existing session on this channel</td></tr><tr><td><code>receive(channelDefinition, input)</code></td><td>Hand off to another channel (schedules use this)</td></tr><tr><td><code>callTool(name, input, options?)</code></td><td>Deterministic server-tool call (<a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>)</td></tr><tr><td><code>body</code>, <code>query</code>, <code>params</code></td><td>Validated payloads and <code>:param</code> path segments</td></tr><tr><td><code>auth</code></td><td>The <code>AuthContext</code> resolved by this route's auth chain</td></tr><tr><td><code>requestIp</code></td><td>The TCP peer address</td></tr><tr><td><code>host</code></td><td>Shared services: <code>host.mcp</code>, <code>host.github</code>, <code>host.slack</code>, <code>host.kv</code>, <code>host.files</code>, <code>host.reminders</code></td></tr><tr><td><code>waitUntil(promise)</code></td><td>Background work that outlives the response</td></tr><tr><td><code>sessionUrls(request, sessionId)</code></td><td>Absolute playground + trace URLs for a session on this mount</td></tr><tr><td><code>artifacts</code></td><td>Unbound <a href="./artifacts.html">artifacts</a> facade; pass <code>sessionId</code> in <code>tag</code> input to attribute one</td></tr></tbody></table><p><code>send</code> options: <code>continuationToken</code> (the conversation key), <code>admission</code> (<code>"preempt"</code> interrupts a busy session, the default; <code>"coalesce"</code> enqueues behind the running turn, the <a href="./sessions.html#what-happens-when-i-send-a-follow-up">Slack policy</a>), <code>workspaceFiles</code>, <code>workspaceDir</code>, <code>cloud</code> (attach cloud repos for this session), <code>auth</code> (defaults to the request principal), <code>state</code> (starting channel state for new sessions), <code>title</code> (session display title), and <code>purpose</code> (<code>"eval"</code> marks the session as regression traffic).</p><h2 id="events" tabindex="-1">Events <a class="header-anchor" href="#events" aria-label="Permalink to "Events""></a></h2><p>The <code>events</code> map subscribes the channel to stream events for the sessions it owns. Keys are event types from the <a href="./sessions.html#which-events-can-i-stream">event vocabulary</a>, or <code>"*"</code>. Handlers receive <code>(event, channel, ctx)</code>, where <code>channel.state</code> is the per-session adapter state, <code>ctx.session</code> is the session info, and <code>ctx.host</code> is the shared host services, bound to that session as in a <a href="./hooks.html#handler-context">hook</a>. This is where a channel delivers replies back to its surface.</p><h2 id="state-and-lifecycle" tabindex="-1">State and lifecycle <a class="header-anchor" href="#state-and-lifecycle" aria-label="Permalink to "State and lifecycle""></a></h2><p><code>state</code> declares the starting per-session adapter state (JSON), persisted on the session record. Routes and event handlers read and mutate it through <code>channel.state</code>. <code>onStart(args)</code> runs when the channel mounts. <code>onStop()</code> runs when the server stops.</p><p><code>onStart</code> receives the route helpers (<code>send</code>, <code>getSession</code>, <code>receive</code>, <code>callTool</code>, <code>host</code>, <code>waitUntil</code>, <code>artifacts</code>, <code>logger</code>) plus helpers for long-lived transports:</p><ul><li><code>emitAssistantMessage(sessionId, text)</code> appends an assistant message without a model turn, for host tasks that already produced the final text.</li><li><code>hasContinuationSession(token)</code> and <code>isContinuationBusy(token)</code> report whether a continuation token has a live session and whether a turn is in flight on it.</li><li><code>interruptContinuation(token)</code> stops the in-flight turn and clears coalesced follow-ups queued behind it.</li><li><code>resolveApproval(sessionId, callId, decision, auth, options?)</code> approves or denies a parked tool call, how Slack Block Kit buttons unblock a turn without the HTTP approvals route.</li></ul><h2 id="auth-policies" tabindex="-1">Auth policies <a class="header-anchor" href="#auth-policies" aria-label="Permalink to "Auth policies""></a></h2><p>Every route runs an auth-policy chain: the channel's <code>auth</code> array, or <code>[localDevStrict()]</code> when unset. A policy is a function <code>(request, info) => AuthContext | null</code> (async allowed); the first non-null wins, and a request no policy admits gets <code>401</code>.</p><table tabindex="0"><thead><tr><th>Policy</th><th>Admits</th></tr></thead><tbody><tr><td><code>localDevStrict()</code></td><td>Direct loopback callers with no proxy-forwarding headers (<code>X-Forwarded-For</code>, <code>X-Real-IP</code>, <code>Forwarded</code>, and <code>X-Forwarded-Host</code> are all rejected, so tunnels and same-host reverse proxies don't silently re-expose the route), plus a loopback <code>Host</code> header, which rejects DNS-rebinding callers that reach 127.0.0.1 with a remote hostname.</td></tr><tr><td><code>localDev()</code></td><td>Like <code>localDevStrict()</code> but without the <code>Host</code> check. An explicit, weaker opt-in.</td></tr><tr><td><code>loopbackOnly()</code></td><td>A loopback TCP peer, ignoring forwarding headers; for dev relays that legitimately carry them, like <code>gh webhook forward</code>.</td></tr><tr><td><code>bearerAuth(token)</code></td><td><code>Authorization: Bearer <token></code>, compared in constant time. Also accepts a verifier function mapping a presented token to an <code>AuthContext</code>.</td></tr><tr><td><code>allowAll()</code></td><td>Everyone, as an <code>anonymous</code> principal. Only for surfaces protected upstream (an HMAC-verified webhook) or intentionally public.</td></tr><tr><td><code>publicEndpoint()</code></td><td>Everyone on this custom channel. Managed hosting also serves the channel without an alias token. Use it only when the handler verifies the provider signature.</td></tr></tbody></table><p><code>publicEndpoint()</code> applies only to custom channel routes. It does not open the built-in session or tool API.</p><p>The resolved <code>AuthContext</code> (<code>{ authenticator, principalId, principalType, attributes? }</code>) becomes the request principal. Sessions bind to the principal that created them, and follow-up, stream, and list routes enforce ownership (<code>403</code> otherwise).</p><p>Server flags interact with authored auth: <code>--bearer-token</code> swaps the default <code>localDevStrict()</code> for <code>bearerAuth(...)</code> on channels that don't author their own chain, and <code>--allow-anonymous</code> swaps it for <code>allowAll()</code>. Authored <code>auth</code> arrays always win over both. A channel that declares <code>[localDevStrict()]</code> stays loopback-only even on an <code>--allow-anonymous</code> host.</p><h2 id="first-class-channels" tabindex="-1">First class channels <a class="header-anchor" href="#first-class-channels" aria-label="Permalink to "First class channels""></a></h2><p><strong>Slack</strong> (<code>@cursor/july/channels/slack</code>): Socket Mode transport, streaming replies, engagement rules, approval cards, and a default block on Slack Connect / guest / other-workspace senders. Author <code>agent/channels/slack.ts</code> with <code>slackChannel()</code>. Guide: <a href="./../guides/slack.html">Slack</a>.</p><p><strong>GitHub</strong> (<code>@cursor/july/channels/github</code>): webhook dispatch with signature verification, per-event hooks returning <code>{ auth }</code> (a model turn), <code>{ task }</code> (host work), or <code>null</code>, and CLI tooling for replay and live forwarding. Author <code>agent/channels/github.ts</code> with <code>githubChannel()</code>. Opt-in <code>progress.commitStatus</code> and <code>progress.banner</code> converge a merge-box check and sticky PR comment from default stream events. Supports GitHub.com and GitHub Enterprise Server. Guide: <a href="./../guides/github.html">GitHub</a>.</p><p><strong>GitLab</strong> (<code>@cursor/july/channels/gitlab</code>): verified project hooks for merge requests, notes, pipelines, pushes, and custom event types. Supports GitLab.com and self-managed GitLab. Author <code>agent/channels/gitlab.ts</code> with <code>gitlabChannel()</code>. Guide: <a href="./../guides/gitlab.html">GitLab</a>.</p><p><strong>Bitbucket</strong> (<code>@cursor/july/channels/bitbucket</code>): verified repository hooks for pull requests, comments, pushes, and custom event types. Supports Bitbucket Cloud and Bitbucket Data Center through one normalized hook API. Author <code>agent/channels/bitbucket.ts</code> with <code>bitbucketChannel()</code>. Guide: <a href="./../guides/bitbucket.html">Bitbucket</a>.</p><p><strong>Deployments</strong> (<code>@cursor/july/channels/deployments</code>): pull deploy events. Declare <code>events</code> and handle each one in <code>onEvent</code>. Each event carries <code>deploySourceUri</code> and <code>deployVersion</code>. Author <code>agent/channels/deployments.ts</code> with <code>deploymentsChannel()</code>.</p><p>On Cursor-managed hosting, omit <code>deploySourceUris</code>. The deployment's watched repositories bind the event scope automatically. Name sources to narrow the scope or to drive the self-hosted pull relay. Subscribe per deploy source with <code>deploySourceUris</code> and narrow with <code>environments</code> or <code>events</code>. Each entry must match <code>Deployment.deploy_source_uri</code> as your deployment writer records it. Matching is case-insensitive but otherwise literal. It uses the host credential. A restart resumes rather than dropping events. An empty <code>deploySourceUris</code> list mounts the channel but starts no pull, so an env-configured agent stays inert until its deploy sources are set.</p><p><strong>Change Monitors</strong> (<code>@cursor/july/channels/change-monitors</code>): Change Monitor Checkpoint events. The channel publishes Factory <code>checkpoint.created</code> for every Checkpoint create. The agent filters the result (for example to the <code>issues</code> arm). The payload contains the full Checkpoint resource. This channel is scoped to Change Monitors, not generic Factory Checkpoints. There is no repository filter or resource filter. Author <code>agent/channels/change-monitors.ts</code> with <code>changeMonitorsChannel()</code>. It uses the host credential.</p><p><strong>Issues</strong> (<code>@cursor/july/channels/issues</code>): Factory issue events. The channel publishes <code>issue.created</code> for every Issue create. The agent filters if it needs a subset. The payload contains the full Issue resource. There is no repository filter or resource filter. Author <code>agent/channels/issues.ts</code> with <code>issuesChannel()</code>. It uses the host credential.</p><p>For other platforms like Discord or Teams, use the authored <code>defineChannel</code> webhook form.</p><h2 id="continuation-semantics" tabindex="-1">Continuation semantics <a class="header-anchor" href="#continuation-semantics" aria-label="Permalink to "Continuation semantics""></a></h2><p>Channels own their continuation-token format. The built-in HTTP channel mints opaque rotating tokens, Slack uses <code>channelId:threadTs</code>, and PR automations use keys like <code>pr:owner/repo#N</code>. Same token, same durable session; one active continuation per session; the HTTP channel returns <code>409</code> for stale tokens. For the full session model, see <a href="./sessions.html">Sessions</a>.</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><p>Continue with these pages:</p><ul><li><a href="./../guides/webhooks.html">Webhooks guide</a>: the same API, walked through</li><li><a href="./http-api.html">HTTP API</a>: session, discovery, and channel routes</li><li><a href="./sessions.html">Sessions and streaming</a>: the events channels subscribe to</li></ul>`,45)])])}const u=e(n,[["render",o]]);export{k as __pageData,u as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,c as a,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const k=JSON.parse('{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies.","frontmatter":{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies."},"headers":[],"relativePath":"reference/channels.md","filePath":"reference/channels.md"}'),n={name:"reference/channels.md"};function o(h,s,l,r,d,c){return i(),a("div",null,[...s[0]||(s[0]=[t("",
|
|
1
|
+
import{_ as e,c as a,o as i,ag as t}from"./chunks/framework.BCISBCiQ.js";const k=JSON.parse('{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies.","frontmatter":{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies."},"headers":[],"relativePath":"reference/channels.md","filePath":"reference/channels.md"}'),n={name:"reference/channels.md"};function o(h,s,l,r,d,c){return i(),a("div",null,[...s[0]||(s[0]=[t("",45)])])}const u=e(n,[["render",o]]);export{k as __pageData,u as default};
|
|
@@ -41,7 +41,7 @@ import{_ as i,c as e,o as a,ag as t}from"./chunks/framework.BCISBCiQ.js";const c
|
|
|
41
41
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prod</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --slug</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> pr-approver</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --team</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 123</span></span>
|
|
42
42
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># prints Eval ID immediately on --prod/--url; then:</span></span>
|
|
43
43
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> status</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> <</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">evalI</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prod</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --slug</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> pr-approver</span></span>
|
|
44
|
-
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> cancel</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> <</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">evalI</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prod</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --slug</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> pr-approver</span></span></code></pre></div><p><code>eval</code> runs <code>evals/**/*.eval.{ts,js}</code> on an ephemeral server or
|
|
44
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> eval</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> cancel</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> <</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">evalI</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">d</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">></span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --prod</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --slug</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> pr-approver</span></span></code></pre></div><p><code>eval</code> runs <code>evals/**/*.eval.{ts,js}</code> on an ephemeral server. With <code>--prod</code> or <code>--url</code>, the target server runs its own evals as a server-side batch. Select one or more exact case IDs, file ID prefixes, or tags. Omit selectors to run all cases. Repeated <code>--tag</code> flags use OR matching.</p><p>An eval run requires <code>evals/evals.config.{ts,js}</code> with <code>maxConcurrency</code> between 1 and 200. Timeout priority is the case's <code>timeoutMs</code>, the CLI's <code>--timeout-ms</code>, the config's <code>timeoutMs</code>, then 180 seconds.</p><table tabindex="0"><thead><tr><th>Flag</th><th>Meaning</th></tr></thead><tbody><tr><td><code>--list</code></td><td>Print discovered cases without running. <code>--list --json</code> prints them as an array.</td></tr><tr><td><code>--tag <tag></code></td><td>Run cases with this tag. Repeated flags use OR matching.</td></tr><tr><td><code>--json</code></td><td>Print <code>{ ok, passed, failed, scored, skipped, strict, results }</code>; see <a href="./../evals.html#run-evals-in-ci">Run evals in CI</a> for the result shape.</td></tr><tr><td><code>--verbose</code></td><td>Stream <code>t.log</code> lines and reply snippets.</td></tr><tr><td><code>--no-stream</code></td><td>Hide live progress on stderr.</td></tr><tr><td><code>--strict</code></td><td>Exit <code>1</code> when a scored case misses a soft threshold.</td></tr><tr><td><code>--max-concurrency <n></code></td><td>Override <code>maxConcurrency</code> from <code>evals.config.ts</code>.</td></tr><tr><td><code>--junit <path></code></td><td>Write JUnit XML for CI annotations.</td></tr><tr><td><code>--artifacts <dir></code></td><td>Write run artifacts here. The default is a timestamped directory under <code>evals/</code> in the project state directory (not affected by <code>--state-root</code>).</td></tr><tr><td><code>--no-artifacts</code></td><td>Skip run artifacts.</td></tr><tr><td><code>--skip-report</code></td><td>Ignore reporters from <code>evals.config.ts</code> and eval files.</td></tr><tr><td><code>--out <path></code></td><td>Also write the full results JSON to this path (also for <code>eval status <evalId></code>).</td></tr><tr><td><code>--no-wait</code></td><td>Return with the Eval ID as soon as a <code>--prod</code> or <code>--url</code> batch is accepted.</td></tr><tr><td><code>--timeout-ms <n></code></td><td>Per-case timeout override.</td></tr></tbody></table><p>Failed cases exit <code>1</code>. A scored case also exits <code>1</code> under <code>--strict</code>. No matching cases exit <code>2</code>. <code>eval status</code> exits <code>3</code> while the remote batch is still running.</p><h2 id="trajectory" tabindex="-1">trajectory <a class="header-anchor" href="#trajectory" aria-label="Permalink to "trajectory""></a></h2><p><code>trajectory</code> summarizes a saved event stream.</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:#032F62;--shiki-dark:#9ECBFF;"> /tmp/run.ndjson</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [--text]</span></span></code></pre></div><p><code>trajectory</code> converts a saved NDJSON stream into the trajectory JSON returned by <code>run</code>. <code>--text</code> prints the compact view. The command exits non-zero when the reconstructed trajectory failed.</p><h2 id="init" tabindex="-1">init <a class="header-anchor" href="#init" aria-label="Permalink to "init""></a></h2><p><code>init</code> scaffolds a new 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;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ./my-agent</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # scaffold package.json, tsconfig.json, agent/ + a demo tool</span></span>
|
|
45
45
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ./my-demo</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --template</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> demo</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # record a PR walkthrough</span></span>
|
|
46
46
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ./grokbot</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --template</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> grokbot-agents</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # talk to Grok Bot agents</span></span>
|
|
47
47
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">agent-sdk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> init</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ./code-wiki</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --template</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> code-wiki</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # keep wiki pages current after merge</span></span>
|