@cursor/july 0.1.1
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 +290 -0
- package/LICENSE.md +3 -0
- package/README.md +1233 -0
- package/dist/ab.d.ts +290 -0
- package/dist/ab.d.ts.map +1 -0
- package/dist/ab.js +386 -0
- package/dist/bin/agent-serve.d.ts +15 -0
- package/dist/bin/agent-serve.d.ts.map +1 -0
- package/dist/bin/agent-serve.js +754 -0
- package/dist/channels/github/api.d.ts +101 -0
- package/dist/channels/github/api.d.ts.map +1 -0
- package/dist/channels/github/api.js +229 -0
- package/dist/channels/github/auth.d.ts +67 -0
- package/dist/channels/github/auth.d.ts.map +1 -0
- package/dist/channels/github/auth.js +239 -0
- package/dist/channels/github/binding.d.ts +73 -0
- package/dist/channels/github/binding.d.ts.map +1 -0
- package/dist/channels/github/binding.js +114 -0
- package/dist/channels/github/defaults.d.ts +24 -0
- package/dist/channels/github/defaults.d.ts.map +1 -0
- package/dist/channels/github/defaults.js +100 -0
- package/dist/channels/github/events.d.ts +18 -0
- package/dist/channels/github/events.d.ts.map +1 -0
- package/dist/channels/github/events.js +59 -0
- package/dist/channels/github/forward.d.ts +137 -0
- package/dist/channels/github/forward.d.ts.map +1 -0
- package/dist/channels/github/forward.js +271 -0
- package/dist/channels/github/github-channel.d.ts +127 -0
- package/dist/channels/github/github-channel.d.ts.map +1 -0
- package/dist/channels/github/github-channel.js +1688 -0
- package/dist/channels/github/index.d.ts +52 -0
- package/dist/channels/github/index.d.ts.map +1 -0
- package/dist/channels/github/index.js +51 -0
- package/dist/channels/github/replay.d.ts +115 -0
- package/dist/channels/github/replay.d.ts.map +1 -0
- package/dist/channels/github/replay.js +282 -0
- package/dist/channels/github/state.d.ts +26 -0
- package/dist/channels/github/state.d.ts.map +1 -0
- package/dist/channels/github/state.js +50 -0
- package/dist/channels/github/types.d.ts +385 -0
- package/dist/channels/github/types.d.ts.map +1 -0
- package/dist/channels/github/types.js +1 -0
- package/dist/channels/slack/api.d.ts +117 -0
- package/dist/channels/slack/api.d.ts.map +1 -0
- package/dist/channels/slack/api.js +437 -0
- package/dist/channels/slack/approvals.d.ts +32 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -0
- package/dist/channels/slack/approvals.js +157 -0
- package/dist/channels/slack/assistant.d.ts +23 -0
- package/dist/channels/slack/assistant.d.ts.map +1 -0
- package/dist/channels/slack/assistant.js +67 -0
- package/dist/channels/slack/auth.d.ts +40 -0
- package/dist/channels/slack/auth.d.ts.map +1 -0
- package/dist/channels/slack/auth.js +71 -0
- package/dist/channels/slack/channel-watch.d.ts +46 -0
- package/dist/channels/slack/channel-watch.d.ts.map +1 -0
- package/dist/channels/slack/channel-watch.js +180 -0
- package/dist/channels/slack/constants.d.ts +17 -0
- package/dist/channels/slack/constants.d.ts.map +1 -0
- package/dist/channels/slack/constants.js +27 -0
- package/dist/channels/slack/credentials.d.ts +35 -0
- package/dist/channels/slack/credentials.d.ts.map +1 -0
- package/dist/channels/slack/credentials.js +88 -0
- package/dist/channels/slack/cursor-account.d.ts +76 -0
- package/dist/channels/slack/cursor-account.d.ts.map +1 -0
- package/dist/channels/slack/cursor-account.js +88 -0
- package/dist/channels/slack/defaults.d.ts +32 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -0
- package/dist/channels/slack/defaults.js +380 -0
- package/dist/channels/slack/dispatch.d.ts +43 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -0
- package/dist/channels/slack/dispatch.js +185 -0
- package/dist/channels/slack/doctor.d.ts +24 -0
- package/dist/channels/slack/doctor.d.ts.map +1 -0
- package/dist/channels/slack/doctor.js +115 -0
- package/dist/channels/slack/event-id-dedupe.d.ts +10 -0
- package/dist/channels/slack/event-id-dedupe.d.ts.map +1 -0
- package/dist/channels/slack/event-id-dedupe.js +23 -0
- package/dist/channels/slack/inbound.d.ts +41 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -0
- package/dist/channels/slack/inbound.js +166 -0
- package/dist/channels/slack/index.d.ts +45 -0
- package/dist/channels/slack/index.d.ts.map +1 -0
- package/dist/channels/slack/index.js +44 -0
- package/dist/channels/slack/init.d.ts +32 -0
- package/dist/channels/slack/init.d.ts.map +1 -0
- package/dist/channels/slack/init.js +82 -0
- package/dist/channels/slack/interactive.d.ts +19 -0
- package/dist/channels/slack/interactive.d.ts.map +1 -0
- package/dist/channels/slack/interactive.js +142 -0
- package/dist/channels/slack/links.d.ts +10 -0
- package/dist/channels/slack/links.d.ts.map +1 -0
- package/dist/channels/slack/links.js +19 -0
- package/dist/channels/slack/live-delivery.d.ts +75 -0
- package/dist/channels/slack/live-delivery.d.ts.map +1 -0
- package/dist/channels/slack/live-delivery.js +143 -0
- package/dist/channels/slack/log.d.ts +25 -0
- package/dist/channels/slack/log.d.ts.map +1 -0
- package/dist/channels/slack/log.js +47 -0
- package/dist/channels/slack/manifest.d.ts +57 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -0
- package/dist/channels/slack/manifest.js +110 -0
- package/dist/channels/slack/pr-ref.d.ts +18 -0
- package/dist/channels/slack/pr-ref.d.ts.map +1 -0
- package/dist/channels/slack/pr-ref.js +36 -0
- package/dist/channels/slack/setup.d.ts +14 -0
- package/dist/channels/slack/setup.d.ts.map +1 -0
- package/dist/channels/slack/setup.js +86 -0
- package/dist/channels/slack/slack-channel.d.ts +15 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -0
- package/dist/channels/slack/slack-channel.js +281 -0
- package/dist/channels/slack/socket-mode.d.ts +26 -0
- package/dist/channels/slack/socket-mode.d.ts.map +1 -0
- package/dist/channels/slack/socket-mode.js +116 -0
- package/dist/channels/slack/stream.d.ts +26 -0
- package/dist/channels/slack/stream.d.ts.map +1 -0
- package/dist/channels/slack/stream.js +39 -0
- package/dist/channels/slack/tool-approval-events.d.ts +33 -0
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -0
- package/dist/channels/slack/tool-approval-events.js +129 -0
- package/dist/channels/slack/types.d.ts +326 -0
- package/dist/channels/slack/types.d.ts.map +1 -0
- package/dist/channels/slack/types.js +4 -0
- package/dist/channels.d.ts +116 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +294 -0
- package/dist/connections.d.ts +75 -0
- package/dist/connections.d.ts.map +1 -0
- package/dist/connections.js +75 -0
- package/dist/docs/404.html +22 -0
- package/dist/docs/ab.html +87 -0
- package/dist/docs/assets/ab.md.COdXkces.js +63 -0
- package/dist/docs/assets/ab.md.COdXkces.lean.js +1 -0
- package/dist/docs/assets/app.DqfFEmJd.js +1 -0
- package/dist/docs/assets/building-with-agents.md.CJCtZCyi.js +13 -0
- package/dist/docs/assets/building-with-agents.md.CJCtZCyi.lean.js +1 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +1 -0
- package/dist/docs/assets/chunks/VPLocalSearchBox.BaLEdS15.js +9 -0
- package/dist/docs/assets/chunks/framework.CAZyNGu9.js +19 -0
- package/dist/docs/assets/chunks/theme.CZRvu_0q.js +2 -0
- package/dist/docs/assets/concepts.md.Cfb9b-k1.js +4 -0
- package/dist/docs/assets/concepts.md.Cfb9b-k1.lean.js +1 -0
- package/dist/docs/assets/deployment.md.Dx1TYNk5.js +14 -0
- package/dist/docs/assets/deployment.md.Dx1TYNk5.lean.js +1 -0
- package/dist/docs/assets/evals.md.DPZ_MAnI.js +85 -0
- package/dist/docs/assets/evals.md.DPZ_MAnI.lean.js +1 -0
- package/dist/docs/assets/guides_agent-to-agent.md.CrtrsySy.js +10 -0
- package/dist/docs/assets/guides_agent-to-agent.md.CrtrsySy.lean.js +1 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CYlNMTNp.js +9 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CYlNMTNp.lean.js +1 -0
- package/dist/docs/assets/guides_github.md.DwbKhCeS.js +20 -0
- package/dist/docs/assets/guides_github.md.DwbKhCeS.lean.js +1 -0
- package/dist/docs/assets/guides_human-in-the-loop.md.Dvuctx7s.js +28 -0
- package/dist/docs/assets/guides_human-in-the-loop.md.Dvuctx7s.lean.js +1 -0
- package/dist/docs/assets/guides_slack.md.bv41fHfW.js +37 -0
- package/dist/docs/assets/guides_slack.md.bv41fHfW.lean.js +1 -0
- package/dist/docs/assets/guides_webhooks.md.hFTik3lf.js +50 -0
- package/dist/docs/assets/guides_webhooks.md.hFTik3lf.lean.js +1 -0
- package/dist/docs/assets/hillclimbing.md.DHNast08.js +4 -0
- package/dist/docs/assets/hillclimbing.md.DHNast08.lean.js +1 -0
- package/dist/docs/assets/index.md.BPKcj5AI.js +20 -0
- package/dist/docs/assets/index.md.BPKcj5AI.lean.js +1 -0
- package/dist/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/dist/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/dist/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/dist/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/dist/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/dist/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/dist/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/dist/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/dist/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/dist/docs/assets/quickstart.md.tVPiGK_L.js +35 -0
- package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +1 -0
- package/dist/docs/assets/reference_agent-config.md.Bpd7HQwf.js +34 -0
- package/dist/docs/assets/reference_agent-config.md.Bpd7HQwf.lean.js +1 -0
- package/dist/docs/assets/reference_channels.md.D7JTR03W.js +53 -0
- package/dist/docs/assets/reference_channels.md.D7JTR03W.lean.js +1 -0
- package/dist/docs/assets/reference_cli.md.DA730zCu.js +33 -0
- package/dist/docs/assets/reference_cli.md.DA730zCu.lean.js +1 -0
- package/dist/docs/assets/reference_connections.md.C3vNH_DE.js +26 -0
- package/dist/docs/assets/reference_connections.md.C3vNH_DE.lean.js +1 -0
- package/dist/docs/assets/reference_hooks.md.BCEc3MyM.js +12 -0
- package/dist/docs/assets/reference_hooks.md.BCEc3MyM.lean.js +1 -0
- package/dist/docs/assets/reference_http-api.md.DBAahtdz.js +11 -0
- package/dist/docs/assets/reference_http-api.md.DBAahtdz.lean.js +1 -0
- package/dist/docs/assets/reference_instructions.md.BC05LEQ8.js +12 -0
- package/dist/docs/assets/reference_instructions.md.BC05LEQ8.lean.js +1 -0
- package/dist/docs/assets/reference_playground.md.CPZhfYaO.js +1 -0
- package/dist/docs/assets/reference_playground.md.CPZhfYaO.lean.js +1 -0
- package/dist/docs/assets/reference_project-layout.md.Bd_CKtNS.js +31 -0
- package/dist/docs/assets/reference_project-layout.md.Bd_CKtNS.lean.js +1 -0
- package/dist/docs/assets/reference_schedules.md.D7qijxLk.js +82 -0
- package/dist/docs/assets/reference_schedules.md.D7qijxLk.lean.js +1 -0
- package/dist/docs/assets/reference_sessions.md.DdjWabnN.js +8 -0
- package/dist/docs/assets/reference_sessions.md.DdjWabnN.lean.js +1 -0
- package/dist/docs/assets/reference_skills.md.VQnlBT3Q.js +15 -0
- package/dist/docs/assets/reference_skills.md.VQnlBT3Q.lean.js +1 -0
- package/dist/docs/assets/reference_subagents.md.CIRAVcPK.js +10 -0
- package/dist/docs/assets/reference_subagents.md.CIRAVcPK.lean.js +1 -0
- package/dist/docs/assets/reference_tools.md.DF5kwlt0.js +46 -0
- package/dist/docs/assets/reference_tools.md.DF5kwlt0.lean.js +1 -0
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +1 -0
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +1 -0
- package/dist/docs/assets/style.Bj-IXa5W.css +1 -0
- package/dist/docs/assets/troubleshooting.md.DkovjS7h.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DkovjS7h.lean.js +1 -0
- package/dist/docs/building-with-agents.html +37 -0
- package/dist/docs/concepts.html +28 -0
- package/dist/docs/deployment.html +38 -0
- package/dist/docs/evals.html +109 -0
- package/dist/docs/guides/agent-to-agent.html +34 -0
- package/dist/docs/guides/cloud-runtime.html +33 -0
- package/dist/docs/guides/github.html +44 -0
- package/dist/docs/guides/human-in-the-loop.html +52 -0
- package/dist/docs/guides/slack.html +61 -0
- package/dist/docs/guides/webhooks.html +74 -0
- package/dist/docs/hashmap.json +1 -0
- package/dist/docs/hillclimbing.html +28 -0
- package/dist/docs/index.html +44 -0
- package/dist/docs/quickstart.html +59 -0
- package/dist/docs/reference/agent-config.html +58 -0
- package/dist/docs/reference/channels.html +77 -0
- package/dist/docs/reference/cli.html +57 -0
- package/dist/docs/reference/connections.html +50 -0
- package/dist/docs/reference/hooks.html +36 -0
- package/dist/docs/reference/http-api.html +35 -0
- package/dist/docs/reference/instructions.html +36 -0
- package/dist/docs/reference/playground.html +25 -0
- package/dist/docs/reference/project-layout.html +55 -0
- package/dist/docs/reference/schedules.html +106 -0
- package/dist/docs/reference/sessions.html +32 -0
- package/dist/docs/reference/skills.html +39 -0
- package/dist/docs/reference/subagents.html +34 -0
- package/dist/docs/reference/tools.html +70 -0
- package/dist/docs/scaffolding-agents.html +25 -0
- package/dist/docs/troubleshooting.html +25 -0
- package/dist/docs/vp-icons.css +0 -0
- package/dist/evals.d.ts +312 -0
- package/dist/evals.d.ts.map +1 -0
- package/dist/evals.js +254 -0
- package/dist/hooks.d.ts +23 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +23 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +101 -0
- package/dist/internal/ab-collector.d.ts +42 -0
- package/dist/internal/ab-collector.d.ts.map +1 -0
- package/dist/internal/ab-collector.js +153 -0
- package/dist/internal/ab-fold.d.ts +36 -0
- package/dist/internal/ab-fold.d.ts.map +1 -0
- package/dist/internal/ab-fold.js +171 -0
- package/dist/internal/ab-snapshot.d.ts +70 -0
- package/dist/internal/ab-snapshot.d.ts.map +1 -0
- package/dist/internal/ab-snapshot.js +208 -0
- package/dist/internal/approval-gate.d.ts +34 -0
- package/dist/internal/approval-gate.d.ts.map +1 -0
- package/dist/internal/approval-gate.js +85 -0
- package/dist/internal/auth.d.ts +8 -0
- package/dist/internal/auth.d.ts.map +1 -0
- package/dist/internal/auth.js +27 -0
- package/dist/internal/authored-alias-hooks.d.ts +31 -0
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -0
- package/dist/internal/authored-alias-hooks.js +43 -0
- package/dist/internal/authored-loaders.d.ts +25 -0
- package/dist/internal/authored-loaders.d.ts.map +1 -0
- package/dist/internal/authored-loaders.js +129 -0
- package/dist/internal/bounded-int.d.ts +11 -0
- package/dist/internal/bounded-int.d.ts.map +1 -0
- package/dist/internal/bounded-int.js +13 -0
- package/dist/internal/brand.d.ts +6 -0
- package/dist/internal/brand.d.ts.map +1 -0
- package/dist/internal/brand.js +17 -0
- package/dist/internal/chat-client.d.ts +19 -0
- package/dist/internal/chat-client.d.ts.map +1 -0
- package/dist/internal/chat-client.js +327 -0
- package/dist/internal/cli-ax.d.ts +58 -0
- package/dist/internal/cli-ax.d.ts.map +1 -0
- package/dist/internal/cli-ax.js +345 -0
- package/dist/internal/cli-cursor.d.ts +20 -0
- package/dist/internal/cli-cursor.d.ts.map +1 -0
- package/dist/internal/cli-cursor.js +227 -0
- package/dist/internal/cli-github.d.ts +47 -0
- package/dist/internal/cli-github.d.ts.map +1 -0
- package/dist/internal/cli-github.js +644 -0
- package/dist/internal/cli-slack.d.ts +18 -0
- package/dist/internal/cli-slack.d.ts.map +1 -0
- package/dist/internal/cli-slack.js +144 -0
- package/dist/internal/cloud-merge.d.ts +23 -0
- package/dist/internal/cloud-merge.d.ts.map +1 -0
- package/dist/internal/cloud-merge.js +28 -0
- package/dist/internal/cron.d.ts +17 -0
- package/dist/internal/cron.d.ts.map +1 -0
- package/dist/internal/cron.js +60 -0
- package/dist/internal/cursor/account-mcp.d.ts +95 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -0
- package/dist/internal/cursor/account-mcp.js +342 -0
- package/dist/internal/cursor/backend-client.d.ts +118 -0
- package/dist/internal/cursor/backend-client.d.ts.map +1 -0
- package/dist/internal/cursor/backend-client.js +477 -0
- package/dist/internal/cursor/credentials.d.ts +112 -0
- package/dist/internal/cursor/credentials.d.ts.map +1 -0
- package/dist/internal/cursor/credentials.js +329 -0
- package/dist/internal/cursor-event-relay.d.ts +111 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -0
- package/dist/internal/cursor-event-relay.js +181 -0
- package/dist/internal/cursor-relay-core.d.ts +113 -0
- package/dist/internal/cursor-relay-core.d.ts.map +1 -0
- package/dist/internal/cursor-relay-core.js +364 -0
- package/dist/internal/cursor-slack-relay.d.ts +94 -0
- package/dist/internal/cursor-slack-relay.d.ts.map +1 -0
- package/dist/internal/cursor-slack-relay.js +171 -0
- package/dist/internal/describe-error.d.ts +3 -0
- package/dist/internal/describe-error.d.ts.map +1 -0
- package/dist/internal/describe-error.js +4 -0
- package/dist/internal/dev-mode.d.ts +13 -0
- package/dist/internal/dev-mode.d.ts.map +1 -0
- package/dist/internal/dev-mode.js +17 -0
- package/dist/internal/discovery.d.ts +55 -0
- package/dist/internal/discovery.d.ts.map +1 -0
- package/dist/internal/discovery.js +1427 -0
- package/dist/internal/distribution.d.ts +47 -0
- package/dist/internal/distribution.d.ts.map +1 -0
- package/dist/internal/distribution.js +82 -0
- package/dist/internal/docs-site.d.ts +28 -0
- package/dist/internal/docs-site.d.ts.map +1 -0
- package/dist/internal/docs-site.js +169 -0
- package/dist/internal/duration.d.ts +8 -0
- package/dist/internal/duration.d.ts.map +1 -0
- package/dist/internal/duration.js +35 -0
- package/dist/internal/eval-run-store.d.ts +81 -0
- package/dist/internal/eval-run-store.d.ts.map +1 -0
- package/dist/internal/eval-run-store.js +396 -0
- package/dist/internal/eval-runner.d.ts +76 -0
- package/dist/internal/eval-runner.d.ts.map +1 -0
- package/dist/internal/eval-runner.js +336 -0
- package/dist/internal/event-log.d.ts +51 -0
- package/dist/internal/event-log.d.ts.map +1 -0
- package/dist/internal/event-log.js +167 -0
- package/dist/internal/event-mapper.d.ts +46 -0
- package/dist/internal/event-mapper.d.ts.map +1 -0
- package/dist/internal/event-mapper.js +226 -0
- package/dist/internal/frontmatter.d.ts +12 -0
- package/dist/internal/frontmatter.d.ts.map +1 -0
- package/dist/internal/frontmatter.js +61 -0
- package/dist/internal/github-fanout.d.ts +32 -0
- package/dist/internal/github-fanout.d.ts.map +1 -0
- package/dist/internal/github-fanout.js +122 -0
- package/dist/internal/handleAgentServeTrigger.d.ts +59 -0
- package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -0
- package/dist/internal/handleAgentServeTrigger.js +115 -0
- package/dist/internal/host-platforms.d.ts +40 -0
- package/dist/internal/host-platforms.d.ts.map +1 -0
- package/dist/internal/host-platforms.js +113 -0
- package/dist/internal/http-channel.d.ts +54 -0
- package/dist/internal/http-channel.d.ts.map +1 -0
- package/dist/internal/http-channel.js +382 -0
- package/dist/internal/ids.d.ts +19 -0
- package/dist/internal/ids.d.ts.map +1 -0
- package/dist/internal/ids.js +34 -0
- package/dist/internal/init-project.d.ts +22 -0
- package/dist/internal/init-project.d.ts.map +1 -0
- package/dist/internal/init-project.js +125 -0
- package/dist/internal/json-dir-store.d.ts +32 -0
- package/dist/internal/json-dir-store.d.ts.map +1 -0
- package/dist/internal/json-dir-store.js +100 -0
- package/dist/internal/json-schema.d.ts +18 -0
- package/dist/internal/json-schema.d.ts.map +1 -0
- package/dist/internal/json-schema.js +53 -0
- package/dist/internal/log-ring.d.ts +23 -0
- package/dist/internal/log-ring.d.ts.map +1 -0
- package/dist/internal/log-ring.js +42 -0
- package/dist/internal/map-pool.d.ts +6 -0
- package/dist/internal/map-pool.d.ts.map +1 -0
- package/dist/internal/map-pool.js +41 -0
- package/dist/internal/mcp-endpoint.d.ts +59 -0
- package/dist/internal/mcp-endpoint.d.ts.map +1 -0
- package/dist/internal/mcp-endpoint.js +355 -0
- package/dist/internal/mcp-host.d.ts +28 -0
- package/dist/internal/mcp-host.d.ts.map +1 -0
- package/dist/internal/mcp-host.js +162 -0
- package/dist/internal/net.d.ts +5 -0
- package/dist/internal/net.d.ts.map +1 -0
- package/dist/internal/net.js +30 -0
- package/dist/internal/peer-connections.d.ts +44 -0
- package/dist/internal/peer-connections.d.ts.map +1 -0
- package/dist/internal/peer-connections.js +67 -0
- package/dist/internal/playground/static.d.ts +35 -0
- package/dist/internal/playground/static.d.ts.map +1 -0
- package/dist/internal/playground/static.js +162 -0
- package/dist/internal/playground/toolchain.d.ts +57 -0
- package/dist/internal/playground/toolchain.d.ts.map +1 -0
- package/dist/internal/playground/toolchain.js +226 -0
- package/dist/internal/reminder-runner.d.ts +62 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -0
- package/dist/internal/reminder-runner.js +582 -0
- package/dist/internal/reminder-schedule.d.ts +22 -0
- package/dist/internal/reminder-schedule.d.ts.map +1 -0
- package/dist/internal/reminder-schedule.js +82 -0
- package/dist/internal/reminder-store.d.ts +58 -0
- package/dist/internal/reminder-store.d.ts.map +1 -0
- package/dist/internal/reminder-store.js +106 -0
- package/dist/internal/resolved-connections.d.ts +41 -0
- package/dist/internal/resolved-connections.d.ts.map +1 -0
- package/dist/internal/resolved-connections.js +73 -0
- package/dist/internal/review-comments.d.ts +50 -0
- package/dist/internal/review-comments.d.ts.map +1 -0
- package/dist/internal/review-comments.js +194 -0
- package/dist/internal/router.d.ts +33 -0
- package/dist/internal/router.d.ts.map +1 -0
- package/dist/internal/router.js +93 -0
- package/dist/internal/run-client.d.ts +49 -0
- package/dist/internal/run-client.d.ts.map +1 -0
- package/dist/internal/run-client.js +208 -0
- package/dist/internal/schedule-runner.d.ts +31 -0
- package/dist/internal/schedule-runner.d.ts.map +1 -0
- package/dist/internal/schedule-runner.js +126 -0
- package/dist/internal/sdk-runner.d.ts +41 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -0
- package/dist/internal/sdk-runner.js +221 -0
- package/dist/internal/server.d.ts +25 -0
- package/dist/internal/server.d.ts.map +1 -0
- package/dist/internal/server.js +1374 -0
- package/dist/internal/session-engine.d.ts +287 -0
- package/dist/internal/session-engine.d.ts.map +1 -0
- package/dist/internal/session-engine.js +1377 -0
- package/dist/internal/session-store.d.ts +29 -0
- package/dist/internal/session-store.d.ts.map +1 -0
- package/dist/internal/session-store.js +140 -0
- package/dist/internal/session-urls.d.ts +10 -0
- package/dist/internal/session-urls.d.ts.map +1 -0
- package/dist/internal/session-urls.js +25 -0
- package/dist/internal/stream-progress.d.ts +14 -0
- package/dist/internal/stream-progress.d.ts.map +1 -0
- package/dist/internal/stream-progress.js +195 -0
- package/dist/internal/tool-result.d.ts +20 -0
- package/dist/internal/tool-result.d.ts.map +1 -0
- package/dist/internal/tool-result.js +45 -0
- package/dist/internal/trajectory.d.ts +56 -0
- package/dist/internal/trajectory.d.ts.map +1 -0
- package/dist/internal/trajectory.js +248 -0
- package/dist/internal/workspace.d.ts +42 -0
- package/dist/internal/workspace.d.ts.map +1 -0
- package/dist/internal/workspace.js +199 -0
- package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
- package/dist/playground/assets/index-1K-hG-7p.css +1 -0
- package/dist/playground/assets/index-FlWjhg3x.js +79 -0
- package/dist/playground/index.html +17 -0
- package/dist/reminders.d.ts +23 -0
- package/dist/reminders.d.ts.map +1 -0
- package/dist/reminders.js +22 -0
- package/dist/schedules.d.ts +23 -0
- package/dist/schedules.d.ts.map +1 -0
- package/dist/schedules.js +26 -0
- package/dist/skills.d.ts +22 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +22 -0
- package/dist/tools.d.ts +92 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +68 -0
- package/dist/types.d.ts +1609 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +80 -0
- package/docs/README.md +174 -0
- package/docs/ab.md +355 -0
- package/docs/building-with-agents.md +129 -0
- package/docs/concepts.md +177 -0
- package/docs/deployment.md +218 -0
- package/docs/evals.md +383 -0
- package/docs/guides/agent-to-agent.md +118 -0
- package/docs/guides/cloud-runtime.md +122 -0
- package/docs/guides/github.md +172 -0
- package/docs/guides/human-in-the-loop.md +131 -0
- package/docs/guides/slack.md +245 -0
- package/docs/guides/webhooks.md +201 -0
- package/docs/hillclimbing.md +93 -0
- package/docs/quickstart.md +183 -0
- package/docs/reference/agent-config.md +154 -0
- package/docs/reference/channels.md +206 -0
- package/docs/reference/cli.md +257 -0
- package/docs/reference/connections.md +137 -0
- package/docs/reference/hooks.md +74 -0
- package/docs/reference/http-api.md +219 -0
- package/docs/reference/instructions.md +77 -0
- package/docs/reference/playground.md +67 -0
- package/docs/reference/project-layout.md +119 -0
- package/docs/reference/schedules.md +220 -0
- package/docs/reference/sessions.md +165 -0
- package/docs/reference/skills.md +79 -0
- package/docs/reference/subagents.md +74 -0
- package/docs/reference/tools.md +203 -0
- package/docs/scaffolding-agents.md +113 -0
- package/docs/troubleshooting.md +95 -0
- package/package.json +185 -0
- package/skills/ab/SKILL.md +139 -0
- package/skills/create-agent/SKILL.md +219 -0
- package/skills/debug/SKILL.md +71 -0
- package/skills/evals/SKILL.md +217 -0
- package/skills/framework-map/SKILL.md +142 -0
- package/skills/github/SKILL.md +144 -0
- package/skills/hillclimb/SKILL.md +162 -0
- package/skills/setup-slack/SKILL.md +180 -0
- package/src/ab.ts +675 -0
- package/src/bin/agent-serve.ts +949 -0
- package/src/channels/github/api.ts +374 -0
- package/src/channels/github/auth.ts +275 -0
- package/src/channels/github/binding.ts +223 -0
- package/src/channels/github/defaults.ts +111 -0
- package/src/channels/github/events.ts +72 -0
- package/src/channels/github/forward.ts +381 -0
- package/src/channels/github/github-channel.ts +2270 -0
- package/src/channels/github/index.ts +52 -0
- package/src/channels/github/replay.ts +387 -0
- package/src/channels/github/state.ts +95 -0
- package/src/channels/github/types.ts +490 -0
- package/src/channels/slack/api.ts +580 -0
- package/src/channels/slack/approvals.ts +198 -0
- package/src/channels/slack/assistant.ts +76 -0
- package/src/channels/slack/auth.ts +112 -0
- package/src/channels/slack/channel-watch.ts +219 -0
- package/src/channels/slack/constants.ts +30 -0
- package/src/channels/slack/credentials.ts +90 -0
- package/src/channels/slack/cursor-account.ts +166 -0
- package/src/channels/slack/defaults.ts +450 -0
- package/src/channels/slack/dispatch.ts +293 -0
- package/src/channels/slack/doctor.ts +135 -0
- package/src/channels/slack/event-id-dedupe.ts +30 -0
- package/src/channels/slack/inbound.ts +219 -0
- package/src/channels/slack/index.ts +45 -0
- package/src/channels/slack/init.ts +133 -0
- package/src/channels/slack/interactive.ts +194 -0
- package/src/channels/slack/links.ts +23 -0
- package/src/channels/slack/live-delivery.ts +201 -0
- package/src/channels/slack/log.ts +83 -0
- package/src/channels/slack/manifest.ts +179 -0
- package/src/channels/slack/pr-ref.ts +50 -0
- package/src/channels/slack/setup.ts +97 -0
- package/src/channels/slack/slack-channel.ts +374 -0
- package/src/channels/slack/socket-mode.ts +154 -0
- package/src/channels/slack/stream.ts +63 -0
- package/src/channels/slack/tool-approval-events.ts +136 -0
- package/src/channels/slack/types.ts +349 -0
- package/src/channels.ts +385 -0
- package/src/connections.ts +89 -0
- package/src/evals.ts +501 -0
- package/src/hooks.ts +33 -0
- package/src/index.ts +184 -0
- package/src/internal/ab-collector.ts +210 -0
- package/src/internal/ab-fold.ts +228 -0
- package/src/internal/ab-snapshot.ts +335 -0
- package/src/internal/approval-gate.ts +115 -0
- package/src/internal/auth.ts +39 -0
- package/src/internal/authored-alias-hooks.ts +69 -0
- package/src/internal/authored-loaders.ts +138 -0
- package/src/internal/bounded-int.ts +27 -0
- package/src/internal/brand.ts +29 -0
- package/src/internal/chat-client.ts +407 -0
- package/src/internal/cli-ax.ts +474 -0
- package/src/internal/cli-cursor.ts +275 -0
- package/src/internal/cli-github.ts +849 -0
- package/src/internal/cli-slack.ts +175 -0
- package/src/internal/cloud-merge.ts +41 -0
- package/src/internal/cron.ts +78 -0
- package/src/internal/cursor/account-mcp.ts +472 -0
- package/src/internal/cursor/backend-client.ts +614 -0
- package/src/internal/cursor/credentials.ts +401 -0
- package/src/internal/cursor-event-relay.ts +281 -0
- package/src/internal/cursor-relay-core.ts +444 -0
- package/src/internal/cursor-slack-relay.ts +242 -0
- package/src/internal/describe-error.ts +4 -0
- package/src/internal/dev-mode.ts +20 -0
- package/src/internal/discovery.ts +1709 -0
- package/src/internal/distribution.ts +97 -0
- package/src/internal/docs-site.ts +191 -0
- package/src/internal/duration.ts +39 -0
- package/src/internal/eval-run-store.ts +519 -0
- package/src/internal/eval-runner.ts +522 -0
- package/src/internal/event-log.ts +175 -0
- package/src/internal/event-mapper.ts +272 -0
- package/src/internal/frontmatter.ts +77 -0
- package/src/internal/github-fanout.ts +159 -0
- package/src/internal/handleAgentServeTrigger.ts +156 -0
- package/src/internal/host-platforms.ts +144 -0
- package/src/internal/http-channel.ts +546 -0
- package/src/internal/ids.ts +44 -0
- package/src/internal/init-project.ts +165 -0
- package/src/internal/json-dir-store.ts +109 -0
- package/src/internal/json-schema.ts +69 -0
- package/src/internal/log-ring.ts +59 -0
- package/src/internal/map-pool.ts +32 -0
- package/src/internal/mcp-endpoint.ts +518 -0
- package/src/internal/mcp-host.ts +211 -0
- package/src/internal/net.ts +31 -0
- package/src/internal/peer-connections.ts +100 -0
- package/src/internal/playground/static.ts +189 -0
- package/src/internal/playground/toolchain.ts +277 -0
- package/src/internal/reminder-runner.ts +756 -0
- package/src/internal/reminder-schedule.ts +106 -0
- package/src/internal/reminder-store.ts +145 -0
- package/src/internal/resolved-connections.ts +145 -0
- package/src/internal/review-comments.ts +268 -0
- package/src/internal/router.ts +145 -0
- package/src/internal/run-client.ts +320 -0
- package/src/internal/schedule-runner.ts +161 -0
- package/src/internal/sdk-runner.ts +315 -0
- package/src/internal/server.ts +1737 -0
- package/src/internal/session-engine.ts +1810 -0
- package/src/internal/session-store.ts +147 -0
- package/src/internal/session-urls.ts +40 -0
- package/src/internal/stream-progress.ts +254 -0
- package/src/internal/tool-result.ts +54 -0
- package/src/internal/trajectory.ts +306 -0
- package/src/internal/workspace.ts +223 -0
- package/src/reminders.ts +35 -0
- package/src/schedules.ts +37 -0
- package/src/skills.ts +27 -0
- package/src/tools.ts +127 -0
- package/src/types.ts +1848 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,1848 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for @anysphere/agent-serve.
|
|
3
|
+
*
|
|
4
|
+
* The framework is filesystem-first: customers author an agent as files under
|
|
5
|
+
* an `agent/` directory (markdown for prose, TypeScript for typed behavior),
|
|
6
|
+
* and the framework discovers those files, compiles them into an
|
|
7
|
+
* {@link AgentProject}, and serves the agent over channels using the Cursor
|
|
8
|
+
* SDK as the execution harness.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { InteractionUpdate, SDKCustomTool } from "@cursor/sdk";
|
|
12
|
+
import type { z } from "zod";
|
|
13
|
+
import type { ABConfigFile } from "./ab.js";
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// JSON
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
20
|
+
export type JsonValue = JsonPrimitive | JsonValue[] | JsonObject;
|
|
21
|
+
export type JsonObject = { [key: string]: JsonValue };
|
|
22
|
+
|
|
23
|
+
/** A plain JSON Schema object (already-serialized tool input schema). */
|
|
24
|
+
export type JsonSchemaObject = Record<string, unknown>;
|
|
25
|
+
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Definition branding
|
|
28
|
+
// ============================================================================
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Discriminates the `define*` helper that produced a module's default export
|
|
32
|
+
* so discovery can validate that a file landed in the right authored slot.
|
|
33
|
+
*/
|
|
34
|
+
export type DefinitionKind =
|
|
35
|
+
| "agent"
|
|
36
|
+
| "instructions"
|
|
37
|
+
| "tool"
|
|
38
|
+
| "skill"
|
|
39
|
+
| "connection"
|
|
40
|
+
| "channel"
|
|
41
|
+
| "http-channel"
|
|
42
|
+
| "schedule"
|
|
43
|
+
| "reminder"
|
|
44
|
+
| "hook"
|
|
45
|
+
| "eval"
|
|
46
|
+
| "ab";
|
|
47
|
+
|
|
48
|
+
export interface BrandedDefinition<K extends DefinitionKind> {
|
|
49
|
+
readonly __agentServe: K;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Agent config (agent.ts)
|
|
54
|
+
// ============================================================================
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A Cursor model selection. Either a bare model id (`"gpt-5.2"`) or an id
|
|
58
|
+
* with model parameters, mirroring the Cursor SDK's `ModelSelection`.
|
|
59
|
+
*/
|
|
60
|
+
export type ModelSetting =
|
|
61
|
+
| string
|
|
62
|
+
| {
|
|
63
|
+
id: string;
|
|
64
|
+
params?: Array<{ id: string; value: string }>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Model used when the root agent omits `model` (local Cursor agents have no
|
|
69
|
+
* harness-level default of their own).
|
|
70
|
+
*/
|
|
71
|
+
export const DEFAULT_MODEL: ModelSetting = {
|
|
72
|
+
id: "grok-4.5",
|
|
73
|
+
params: [
|
|
74
|
+
{ id: "effort", value: "high" },
|
|
75
|
+
{ id: "fast", value: "true" },
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Where turns execute. `"local"` (default) uses the Cursor SDK local
|
|
81
|
+
* harness on this machine; `"cloud"` runs on Cursor cloud agents.
|
|
82
|
+
*/
|
|
83
|
+
export type AgentRuntime = "local" | "cloud";
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Cloud-only options forwarded to the Cursor SDK's `cloud` field on
|
|
87
|
+
* `Agent.create` / `Agent.resume`. Ignored when {@link AgentConfig.runtime}
|
|
88
|
+
* is `"local"` (the default).
|
|
89
|
+
*/
|
|
90
|
+
export interface AgentCloudOptions {
|
|
91
|
+
env?:
|
|
92
|
+
| { type: "cloud"; name?: string }
|
|
93
|
+
| { type: "pool"; name?: string }
|
|
94
|
+
| { type: "machine"; name?: string };
|
|
95
|
+
repos?: Array<{
|
|
96
|
+
url: string;
|
|
97
|
+
startingRef?: string;
|
|
98
|
+
prUrl?: string;
|
|
99
|
+
}>;
|
|
100
|
+
workOnCurrentBranch?: boolean;
|
|
101
|
+
autoCreatePR?: boolean;
|
|
102
|
+
skipReviewerRequest?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Per-session env vars injected into the cloud agent's shell.
|
|
105
|
+
* When set, the cloud API mints the SDK agent id (persisted as
|
|
106
|
+
* {@link SessionRecord.sdkAgentId}).
|
|
107
|
+
*/
|
|
108
|
+
envVars?: Record<string, string>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Safe `/v1/info` projection of {@link AgentCloudOptions}; secret values are omitted. */
|
|
112
|
+
export type AgentCloudPublicInfo = Omit<AgentCloudOptions, "envVars"> & {
|
|
113
|
+
envVarsConfigured?: boolean;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
function redactHttpUrlCredentials(url: string): string {
|
|
117
|
+
try {
|
|
118
|
+
const parsed = new URL(url);
|
|
119
|
+
if (parsed.username !== "" || parsed.password !== "") {
|
|
120
|
+
parsed.username = "";
|
|
121
|
+
parsed.password = "";
|
|
122
|
+
}
|
|
123
|
+
return parsed.toString();
|
|
124
|
+
} catch {
|
|
125
|
+
return url.replace(/^(https?:\/\/)[^@/]+@/i, "$1");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function toPublicCloudInfo(
|
|
130
|
+
cloud: AgentCloudOptions
|
|
131
|
+
): AgentCloudPublicInfo {
|
|
132
|
+
const { envVars, repos, ...rest } = cloud;
|
|
133
|
+
const hasEnvVars = envVars !== undefined && Object.keys(envVars).length > 0;
|
|
134
|
+
return {
|
|
135
|
+
...rest,
|
|
136
|
+
...(repos !== undefined
|
|
137
|
+
? {
|
|
138
|
+
repos: repos.map((repo) => ({
|
|
139
|
+
...repo,
|
|
140
|
+
url: redactHttpUrlCredentials(repo.url),
|
|
141
|
+
...(repo.prUrl !== undefined
|
|
142
|
+
? { prUrl: redactHttpUrlCredentials(repo.prUrl) }
|
|
143
|
+
: {}),
|
|
144
|
+
})),
|
|
145
|
+
}
|
|
146
|
+
: {}),
|
|
147
|
+
...(hasEnvVars ? { envVarsConfigured: true } : {}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Input to `defineAgent` (authored at `agent/agent.ts`). */
|
|
152
|
+
export interface AgentConfig {
|
|
153
|
+
/**
|
|
154
|
+
* Cursor model to run the agent on. Defaults to {@link DEFAULT_MODEL} on
|
|
155
|
+
* the root agent when omitted. Subagents omit it to inherit the parent's
|
|
156
|
+
* model.
|
|
157
|
+
*/
|
|
158
|
+
model?: ModelSetting;
|
|
159
|
+
/**
|
|
160
|
+
* What this agent is for. Required on subagents: the parent model reads it
|
|
161
|
+
* to decide when to delegate. Optional (documentation only) on the root.
|
|
162
|
+
*/
|
|
163
|
+
description?: string;
|
|
164
|
+
/** Display name override. Defaults to the package name / directory name. */
|
|
165
|
+
name?: string;
|
|
166
|
+
/**
|
|
167
|
+
* Inline instructions. Prefer `instructions.md` next to `agent.ts`; this
|
|
168
|
+
* exists for subagents and generated configs.
|
|
169
|
+
*/
|
|
170
|
+
instructions?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Execution runtime. Defaults to `"local"`. Use `"cloud"` to run turns
|
|
173
|
+
* on Cursor cloud agents (see {@link cloud}).
|
|
174
|
+
*/
|
|
175
|
+
runtime?: AgentRuntime;
|
|
176
|
+
/**
|
|
177
|
+
* Cloud agent defaults. Used when {@link runtime} is `"cloud"`, and as
|
|
178
|
+
* the base merged under per-session {@link SendMessageOptions.cloud}
|
|
179
|
+
* (so a local agent can still open cloud-attached sessions from a
|
|
180
|
+
* channel or tool handoff). In-process `agent/tools` are only available
|
|
181
|
+
* on local turns; cloud sessions should prefer MCP / workspace tools.
|
|
182
|
+
*/
|
|
183
|
+
cloud?: AgentCloudOptions;
|
|
184
|
+
/**
|
|
185
|
+
* Local harness defaults (ignored for cloud turns). Counterpart to
|
|
186
|
+
* {@link cloud}.
|
|
187
|
+
*/
|
|
188
|
+
local?: AgentLocalOptions;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Local runtime options on {@link AgentConfig.local}.
|
|
193
|
+
*/
|
|
194
|
+
export interface AgentLocalOptions {
|
|
195
|
+
/**
|
|
196
|
+
* Default local harness cwd parent. Absolute, or relative to the agent
|
|
197
|
+
* project root. Each session uses `<cwd>/<sessionId>` unless a per-send
|
|
198
|
+
* {@link SendMessageOptions.workspaceDir} overrides it. Prefer a path
|
|
199
|
+
* outside large monorepos so Cursor `project` settings do not inherit
|
|
200
|
+
* ambient `AGENTS.md` / `.cursor` rules.
|
|
201
|
+
*/
|
|
202
|
+
cwd?: string;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export type AgentConfigDefinition = AgentConfig & BrandedDefinition<"agent">;
|
|
206
|
+
|
|
207
|
+
/** Input to `defineInstructions` (authored at `agent/instructions.ts`). */
|
|
208
|
+
export interface InstructionsConfig {
|
|
209
|
+
markdown: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export type InstructionsDefinition = InstructionsConfig &
|
|
213
|
+
BrandedDefinition<"instructions">;
|
|
214
|
+
|
|
215
|
+
// ============================================================================
|
|
216
|
+
// Tools (agent/tools/*.ts)
|
|
217
|
+
// ============================================================================
|
|
218
|
+
|
|
219
|
+
export type ToolResultContent =
|
|
220
|
+
| { type: "text"; text: string }
|
|
221
|
+
| { type: "image"; data: string; mimeType?: string };
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* JSON-ish value a tool may return. Unlike {@link JsonValue} this permits
|
|
225
|
+
* `undefined` leaves (and thus optional object properties), because the
|
|
226
|
+
* result is JSON-serialized before it reaches the model and `undefined`
|
|
227
|
+
* fields are simply dropped — so authored tools can return objects shaped by
|
|
228
|
+
* optional fields without fighting the type system.
|
|
229
|
+
*/
|
|
230
|
+
export type ToolResultValue =
|
|
231
|
+
| string
|
|
232
|
+
| number
|
|
233
|
+
| boolean
|
|
234
|
+
| null
|
|
235
|
+
| undefined
|
|
236
|
+
| ToolResultValue[]
|
|
237
|
+
| readonly ToolResultValue[]
|
|
238
|
+
| { [key: string]: ToolResultValue };
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* What a tool's `execute` may return. Strings are passed to the model
|
|
242
|
+
* verbatim, JSON values are serialized, and the envelope form carries rich
|
|
243
|
+
* content and an error flag.
|
|
244
|
+
*/
|
|
245
|
+
export type ToolExecuteResult =
|
|
246
|
+
| ToolResultValue
|
|
247
|
+
| { content: ToolResultContent[]; isError?: boolean };
|
|
248
|
+
|
|
249
|
+
/** Repo-agnostic GitHub client on the agent-serve host. */
|
|
250
|
+
export interface HostGitHubClient {
|
|
251
|
+
getOctokit(): Promise<import("@octokit/rest").Octokit>;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Bot-token Slack Web API client on the agent-serve host. */
|
|
255
|
+
export interface HostSlackClient {
|
|
256
|
+
getClient(): Promise<import("@slack/web-api").WebClient>;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Host-side handle for calling an MCP connection from a server tool or channel handler. */
|
|
260
|
+
export interface HostMcpRegistry {
|
|
261
|
+
/** MCP connection names (filenames under `agent/mcp-connections/`). */
|
|
262
|
+
names(): string[];
|
|
263
|
+
listTools(connectionName: string): Promise<HostMcpToolInfo[]>;
|
|
264
|
+
callTool(
|
|
265
|
+
connectionName: string,
|
|
266
|
+
toolName: string,
|
|
267
|
+
args?: Record<string, unknown>
|
|
268
|
+
): Promise<HostMcpCallResult>;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface HostMcpToolInfo {
|
|
272
|
+
name: string;
|
|
273
|
+
description?: string;
|
|
274
|
+
inputSchema?: JsonObject;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export interface HostMcpCallResult {
|
|
278
|
+
content: Array<
|
|
279
|
+
| { type: "text"; text: string }
|
|
280
|
+
| { type: "image"; data: string; mimeType?: string }
|
|
281
|
+
| { type: string; [key: string]: unknown }
|
|
282
|
+
>;
|
|
283
|
+
isError?: boolean;
|
|
284
|
+
structuredContent?: JsonObject;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Shared host services available on every tool / channel / schedule surface.
|
|
289
|
+
* Channel packs attach this as `ctx.host` so handlers can tap GitHub, Slack,
|
|
290
|
+
* or MCP without the pack depending on another platform.
|
|
291
|
+
*/
|
|
292
|
+
export interface HostContext {
|
|
293
|
+
/**
|
|
294
|
+
* Authored MCP connections (`agent/mcp-connections/*`). Call a specific MCP
|
|
295
|
+
* tool deterministically without going through the agent loop.
|
|
296
|
+
*/
|
|
297
|
+
mcp: HostMcpRegistry;
|
|
298
|
+
/**
|
|
299
|
+
* Host GitHub client (PAT / env / `gh auth` / App). Prefer webhook
|
|
300
|
+
* `ctx.github` (installation-scoped) when handling a GitHub delivery.
|
|
301
|
+
*/
|
|
302
|
+
github: HostGitHubClient;
|
|
303
|
+
/** Host Slack Web API client (`SLACK_BOT_TOKEN` / channel envPrefix). */
|
|
304
|
+
slack: HostSlackClient;
|
|
305
|
+
/**
|
|
306
|
+
* Per-session reminders (create / list / cancel / dispatch). Present once
|
|
307
|
+
* the serve host has attached a {@link ReminderRunner}.
|
|
308
|
+
*/
|
|
309
|
+
reminders?: ReminderHostApi;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** Runtime context handed to a tool's `execute`. */
|
|
313
|
+
export interface ToolContext {
|
|
314
|
+
/** Correlates with `actions.requested` / `action.result` stream events. */
|
|
315
|
+
toolCallId?: string;
|
|
316
|
+
/** The session this tool call runs inside. */
|
|
317
|
+
session: SessionInfo;
|
|
318
|
+
/** Absolute path of the session's materialized workspace directory. */
|
|
319
|
+
workspaceDir: string;
|
|
320
|
+
/** Shared host services (MCP / GitHub / Slack). */
|
|
321
|
+
host: HostContext;
|
|
322
|
+
/**
|
|
323
|
+
* Start or resume a session on any channel (cross-channel handoff).
|
|
324
|
+
* Same semantics as a channel route's `send`, with an explicit channel id
|
|
325
|
+
* — e.g. a chat tool that opens a `drive` cloud session for a PR.
|
|
326
|
+
* `auth` defaults to this tool call's session principal (like HTTP
|
|
327
|
+
* channel `send`); pass explicitly to override.
|
|
328
|
+
*/
|
|
329
|
+
send(
|
|
330
|
+
channelId: string,
|
|
331
|
+
message: string,
|
|
332
|
+
options?: SendMessageOptions
|
|
333
|
+
): Promise<ChannelSession>;
|
|
334
|
+
/** Look up a session on a channel (e.g. refresh `sdkAgentId` after a turn). */
|
|
335
|
+
getSession(
|
|
336
|
+
channelId: string,
|
|
337
|
+
sessionId: string
|
|
338
|
+
): Promise<ChannelSession | null>;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Where a tool's body runs.
|
|
343
|
+
*
|
|
344
|
+
* - `"server"` (default): in-process on the agent-serve host via Cursor SDK
|
|
345
|
+
* custom tools. Only available when the agent {@link AgentConfig.runtime}
|
|
346
|
+
* is `"local"`.
|
|
347
|
+
* - `"agent"` — materialized into the session workspace as a shell
|
|
348
|
+
* script the Cursor agent invokes (local harness or cloud VM). Requires
|
|
349
|
+
* {@link ToolConfig.script}; `execute` is not used.
|
|
350
|
+
*/
|
|
351
|
+
export type ToolExecution = "server" | "agent";
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Whether a server tool call must pause for human approval before
|
|
355
|
+
* `execute` runs. Boolean always gates; a predicate decides per call from
|
|
356
|
+
* validated input only (no {@link ToolContext} — runs before the gate).
|
|
357
|
+
*/
|
|
358
|
+
export type ToolNeedsApproval<TInput> =
|
|
359
|
+
| boolean
|
|
360
|
+
| ((input: TInput) => boolean | Promise<boolean>);
|
|
361
|
+
|
|
362
|
+
export interface ToolConfig<TInput> {
|
|
363
|
+
description: string;
|
|
364
|
+
/**
|
|
365
|
+
* Where the tool body runs. Defaults to `"server"` (in-process on the
|
|
366
|
+
* agent-serve process). Use `"agent"` to materialize a workspace script
|
|
367
|
+
* the Cursor agent invokes instead.
|
|
368
|
+
*/
|
|
369
|
+
execution?: ToolExecution;
|
|
370
|
+
/**
|
|
371
|
+
* Zod schema (validated before `execute` runs) or a plain JSON Schema
|
|
372
|
+
* object (forwarded to the model as-is, unvalidated). Omit to accept any
|
|
373
|
+
* JSON object.
|
|
374
|
+
*/
|
|
375
|
+
inputSchema?: z.ZodType<TInput> | JsonSchemaObject;
|
|
376
|
+
/**
|
|
377
|
+
* When true (or when the predicate returns true), the host parks the
|
|
378
|
+
* in-flight tool call until a human approves or denies via
|
|
379
|
+
* `POST /v1/session/:sessionId/approvals/:callId`. Only supported for
|
|
380
|
+
* `execution: "server"` tools on the local runtime.
|
|
381
|
+
*/
|
|
382
|
+
needsApproval?: ToolNeedsApproval<TInput>;
|
|
383
|
+
/**
|
|
384
|
+
* In-process implementation. Required when {@link execution} is
|
|
385
|
+
* `"server"` (the default); ignored for `"agent"` tools.
|
|
386
|
+
*/
|
|
387
|
+
execute?: (
|
|
388
|
+
input: TInput,
|
|
389
|
+
ctx: ToolContext
|
|
390
|
+
) => ToolExecuteResult | Promise<ToolExecuteResult>;
|
|
391
|
+
/**
|
|
392
|
+
* Agent tools: shell script body written into the session workspace.
|
|
393
|
+
* Receives a JSON object on stdin and should print the result on
|
|
394
|
+
* stdout. Required when {@link execution} is `"agent"`.
|
|
395
|
+
*/
|
|
396
|
+
script?: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/** Discovered tool definition with erased input generics. */
|
|
400
|
+
export interface ToolDefinition extends BrandedDefinition<"tool"> {
|
|
401
|
+
readonly description: string;
|
|
402
|
+
readonly execution?: ToolExecution;
|
|
403
|
+
readonly inputSchema?: z.ZodTypeAny | JsonSchemaObject;
|
|
404
|
+
readonly needsApproval?: ToolNeedsApproval<never>;
|
|
405
|
+
readonly execute?: (
|
|
406
|
+
input: never,
|
|
407
|
+
ctx: ToolContext
|
|
408
|
+
) => ToolExecuteResult | Promise<ToolExecuteResult>;
|
|
409
|
+
readonly script?: string;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// ============================================================================
|
|
413
|
+
// Skills (agent/skills/*)
|
|
414
|
+
// ============================================================================
|
|
415
|
+
|
|
416
|
+
/** Input to `defineSkill` (authored at `agent/skills/<name>.ts`). */
|
|
417
|
+
export interface SkillConfig {
|
|
418
|
+
/** Routing hint advertised to the model in the skills catalog. */
|
|
419
|
+
description?: string;
|
|
420
|
+
/** The skill body (becomes `SKILL.md`). */
|
|
421
|
+
markdown: string;
|
|
422
|
+
/** Package-relative sibling files, e.g. `references/checklist.md`. */
|
|
423
|
+
files?: Record<string, string>;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
export type SkillDefinition = SkillConfig & BrandedDefinition<"skill">;
|
|
427
|
+
|
|
428
|
+
// ============================================================================
|
|
429
|
+
// MCP connections (agent/mcp-connections/*.ts)
|
|
430
|
+
// ============================================================================
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Transport for an MCP connection, mirroring the Cursor SDK's
|
|
434
|
+
* `McpServerConfig` shapes — plus two agent-serve variants that stay
|
|
435
|
+
* symbolic until the server starts:
|
|
436
|
+
*
|
|
437
|
+
* - `agent` addresses a **peer agent** mounted on the same serve host by
|
|
438
|
+
* slug; it resolves to that agent's MCP endpoint (`/<slug>/v1/mcp`).
|
|
439
|
+
* - `cursorAccount` exposes the **Cursor account's MCP connectors** (the
|
|
440
|
+
* HTTP/SSE servers the operator already authorized in Cursor). It
|
|
441
|
+
* resolves to a bridge on this host that executes every tool **on the
|
|
442
|
+
* Cursor backend** with the account's stored OAuth credentials — tokens
|
|
443
|
+
* never reach this host.
|
|
444
|
+
*/
|
|
445
|
+
export type ConnectionTransport =
|
|
446
|
+
| {
|
|
447
|
+
type?: "stdio";
|
|
448
|
+
command: string;
|
|
449
|
+
args?: string[];
|
|
450
|
+
env?: Record<string, string>;
|
|
451
|
+
cwd?: string;
|
|
452
|
+
}
|
|
453
|
+
| {
|
|
454
|
+
type?: "http" | "sse";
|
|
455
|
+
url: string;
|
|
456
|
+
headers?: Record<string, string>;
|
|
457
|
+
}
|
|
458
|
+
| {
|
|
459
|
+
/** Slug of a peer agent mounted on the same serve host. */
|
|
460
|
+
agent: string;
|
|
461
|
+
}
|
|
462
|
+
| {
|
|
463
|
+
/** Expose the Cursor account's MCP connectors (backend-executed). */
|
|
464
|
+
cursorAccount: true;
|
|
465
|
+
/**
|
|
466
|
+
* Restrict to these connector names (as they appear in the Cursor
|
|
467
|
+
* account's MCP config, e.g. `["Linear", "Notion"]`). Omit to expose
|
|
468
|
+
* every connected HTTP/SSE server on the account.
|
|
469
|
+
*/
|
|
470
|
+
servers?: string[];
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
/** True for the peer-agent transport variant (`{ agent: "<slug>" }`). */
|
|
474
|
+
export function isPeerConnectionTransport(
|
|
475
|
+
transport: ConnectionTransport
|
|
476
|
+
): transport is { agent: string } {
|
|
477
|
+
return "agent" in transport;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/** True for the Cursor account transport variant (`{ cursorAccount: true }`). */
|
|
481
|
+
export function isCursorAccountTransport(
|
|
482
|
+
transport: ConnectionTransport
|
|
483
|
+
): transport is { cursorAccount: true; servers?: string[] } {
|
|
484
|
+
return "cursorAccount" in transport && transport.cursorAccount === true;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* True for transports that stay symbolic at discovery time and are resolved
|
|
489
|
+
* by the serve host once it is listening (peers and the Cursor account
|
|
490
|
+
* bridge). Symbolic transports never reach the SDK or the host MCP registry
|
|
491
|
+
* unresolved.
|
|
492
|
+
*/
|
|
493
|
+
export function isSymbolicConnectionTransport(
|
|
494
|
+
transport: ConnectionTransport
|
|
495
|
+
): boolean {
|
|
496
|
+
return (
|
|
497
|
+
isPeerConnectionTransport(transport) || isCursorAccountTransport(transport)
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
export type ConnectionConfig = ConnectionTransport & {
|
|
502
|
+
/** Documentation only; shown in `info` output. */
|
|
503
|
+
description?: string;
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* An MCP connection is always available in three places:
|
|
508
|
+
* - the Cursor agent (SDK `mcpServers`, local or cloud)
|
|
509
|
+
* - the agent-serve host (`ctx.host.mcp` on in-process tools)
|
|
510
|
+
* - channel / schedule handlers (`args.host.mcp`)
|
|
511
|
+
*/
|
|
512
|
+
export type ConnectionDefinition = ConnectionConfig &
|
|
513
|
+
BrandedDefinition<"connection">;
|
|
514
|
+
|
|
515
|
+
// ============================================================================
|
|
516
|
+
// Auth
|
|
517
|
+
// ============================================================================
|
|
518
|
+
|
|
519
|
+
/** Who initiated a session (or an authenticated channel request). */
|
|
520
|
+
export interface AuthContext {
|
|
521
|
+
/** Which policy authenticated the caller, e.g. `"local-dev"`. */
|
|
522
|
+
authenticator: string;
|
|
523
|
+
principalId: string;
|
|
524
|
+
principalType: "user" | "service" | "runtime";
|
|
525
|
+
attributes?: Record<string, string>;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export interface AuthRequestInfo {
|
|
529
|
+
/** Client IP, or null when the host cannot provide it. */
|
|
530
|
+
requestIp: string | null;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* A route auth policy. Return an {@link AuthContext} to admit the request,
|
|
535
|
+
* or null to pass to the next policy in the chain. A request is rejected
|
|
536
|
+
* with 401 when every policy in the chain returns null.
|
|
537
|
+
*/
|
|
538
|
+
export type AuthPolicy = (
|
|
539
|
+
request: Request,
|
|
540
|
+
info: AuthRequestInfo
|
|
541
|
+
) => AuthContext | null | Promise<AuthContext | null>;
|
|
542
|
+
|
|
543
|
+
// ============================================================================
|
|
544
|
+
// Session events (the NDJSON stream vocabulary)
|
|
545
|
+
// ============================================================================
|
|
546
|
+
|
|
547
|
+
export interface SessionEventEnvelope {
|
|
548
|
+
/** Monotonic per-session event index; reconnect with `?startIndex=`. */
|
|
549
|
+
index: number;
|
|
550
|
+
sessionId: string;
|
|
551
|
+
/** Present on turn-scoped events. */
|
|
552
|
+
turnId?: string;
|
|
553
|
+
/** ISO-8601 timestamp. */
|
|
554
|
+
at: string;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
export interface ActionCall {
|
|
558
|
+
callId: string;
|
|
559
|
+
toolName: string;
|
|
560
|
+
args?: unknown;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/** Human decision for a parked {@link ToolConfig.needsApproval} tool call. */
|
|
564
|
+
export type ApprovalDecision = "approve" | "deny";
|
|
565
|
+
|
|
566
|
+
/** Durable record of a tool call waiting on human approval. */
|
|
567
|
+
export interface PendingApproval {
|
|
568
|
+
callId: string;
|
|
569
|
+
turnId: string;
|
|
570
|
+
toolName: string;
|
|
571
|
+
args: unknown;
|
|
572
|
+
requestedAt: string;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export type SessionEventPayload =
|
|
576
|
+
| { type: "session.started"; data: { channelId: string } }
|
|
577
|
+
| {
|
|
578
|
+
/**
|
|
579
|
+
* Sticky A/B enrollment for one experiment (`defineAB` under `agent/ab`).
|
|
580
|
+
* Appended at session creation (before the first turn). `variant` is a
|
|
581
|
+
* key of the experiment's `variants`, or `null` for sticky skip.
|
|
582
|
+
*/
|
|
583
|
+
type: "ab.assigned";
|
|
584
|
+
data: { experiment: string; variant: string | null };
|
|
585
|
+
}
|
|
586
|
+
| {
|
|
587
|
+
/** Cursor SDK agent id is known (cloud: `bc-…`; local: session id). */
|
|
588
|
+
type: "agent.bound";
|
|
589
|
+
data: { sdkAgentId: string; url?: string };
|
|
590
|
+
}
|
|
591
|
+
| { type: "message.received"; data: { text: string } }
|
|
592
|
+
| { type: "turn.started"; data: Record<string, never> }
|
|
593
|
+
| { type: "step.started"; data: { stepId: number } }
|
|
594
|
+
| { type: "step.completed"; data: { stepId: number; durationMs: number } }
|
|
595
|
+
| { type: "reasoning.appended"; data: { delta: string; text: string } }
|
|
596
|
+
| { type: "reasoning.completed"; data: { durationMs?: number } }
|
|
597
|
+
| { type: "message.appended"; data: { delta: string; text: string } }
|
|
598
|
+
| {
|
|
599
|
+
type: "message.completed";
|
|
600
|
+
data: { text: string; finishReason: "stop" | "tool_call" };
|
|
601
|
+
}
|
|
602
|
+
| { type: "actions.requested"; data: { calls: ActionCall[] } }
|
|
603
|
+
| {
|
|
604
|
+
/**
|
|
605
|
+
* A server tool with {@link ToolConfig.needsApproval} is parked until
|
|
606
|
+
* a human resolves it. The turn stays running; send follow-ups
|
|
607
|
+
* after `session.waiting` as usual.
|
|
608
|
+
*/
|
|
609
|
+
type: "action.approval_requested";
|
|
610
|
+
data: {
|
|
611
|
+
callId: string;
|
|
612
|
+
toolName: string;
|
|
613
|
+
args?: unknown;
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
| {
|
|
617
|
+
type: "action.approval_resolved";
|
|
618
|
+
data: {
|
|
619
|
+
callId: string;
|
|
620
|
+
toolName: string;
|
|
621
|
+
decision: ApprovalDecision;
|
|
622
|
+
by?: string;
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
| {
|
|
626
|
+
type: "action.result";
|
|
627
|
+
data: {
|
|
628
|
+
callId: string;
|
|
629
|
+
toolName: string;
|
|
630
|
+
output?: unknown;
|
|
631
|
+
isError: boolean;
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
| {
|
|
635
|
+
type: "subagent.called";
|
|
636
|
+
data: { callId: string; name?: string; description?: string };
|
|
637
|
+
}
|
|
638
|
+
| { type: "subagent.completed"; data: { callId: string; name?: string } }
|
|
639
|
+
| {
|
|
640
|
+
type: "turn.completed";
|
|
641
|
+
data: { result?: string; usage?: TurnUsage };
|
|
642
|
+
}
|
|
643
|
+
| { type: "turn.failed"; data: { message: string } }
|
|
644
|
+
| { type: "session.waiting"; data: Record<string, never> }
|
|
645
|
+
| { type: "session.completed"; data: Record<string, never> }
|
|
646
|
+
| { type: "session.failed"; data: { message: string } };
|
|
647
|
+
|
|
648
|
+
export type SessionEvent = SessionEventEnvelope & SessionEventPayload;
|
|
649
|
+
export type SessionEventType = SessionEventPayload["type"];
|
|
650
|
+
|
|
651
|
+
export interface TurnUsage {
|
|
652
|
+
inputTokens: number;
|
|
653
|
+
outputTokens: number;
|
|
654
|
+
cacheReadTokens: number;
|
|
655
|
+
cacheWriteTokens: number;
|
|
656
|
+
reasoningTokens?: number;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// ============================================================================
|
|
660
|
+
// Sessions
|
|
661
|
+
// ============================================================================
|
|
662
|
+
|
|
663
|
+
export type SessionMode = "chat" | "task";
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Why the session exists. `"eval"` is regression traffic (`defineEval` /
|
|
667
|
+
* `agent-serve eval` / playground Evals) and is excluded from live A/B
|
|
668
|
+
* enrollment. Default `"live"`.
|
|
669
|
+
*/
|
|
670
|
+
export type SessionPurpose = "live" | "eval";
|
|
671
|
+
|
|
672
|
+
/** Read-only view of a session, handed to tools, hooks, and channel events. */
|
|
673
|
+
export interface SessionInfo {
|
|
674
|
+
id: string;
|
|
675
|
+
channelId: string;
|
|
676
|
+
mode: SessionMode;
|
|
677
|
+
/** Omit / `"live"` for production traffic; `"eval"` for eval harness sessions. */
|
|
678
|
+
purpose?: SessionPurpose;
|
|
679
|
+
auth: AuthContext | null;
|
|
680
|
+
title?: string;
|
|
681
|
+
/**
|
|
682
|
+
* Sticky A/B arms for this session (`defineAB`): experiment name → variant
|
|
683
|
+
* key, or `null` for sticky skip. Present after enrollment at session
|
|
684
|
+
* create (live traffic only). Tools/hooks/harness overlays read this.
|
|
685
|
+
*/
|
|
686
|
+
abs?: Readonly<Record<string, string | null>>;
|
|
687
|
+
/**
|
|
688
|
+
* Channel-local continuation key when the session is addressable for
|
|
689
|
+
* follow-ups / reminders. Null when the session is not re-keyable.
|
|
690
|
+
*/
|
|
691
|
+
continuationKey?: string | null;
|
|
692
|
+
/**
|
|
693
|
+
* Cursor SDK agent id once bound (cloud: `bc-…`, local: session id).
|
|
694
|
+
* Cloud ids are minted during the first send, so read this from a fresh
|
|
695
|
+
* `getSession()` handle after a turn completes — unless the session was
|
|
696
|
+
* created with a seeded {@link SendMessageOptions.sdkAgentId}.
|
|
697
|
+
*/
|
|
698
|
+
sdkAgentId?: string;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/** Persisted session record (stored at `sessions/<id>/session.json`). */
|
|
702
|
+
export interface SessionRecord {
|
|
703
|
+
sessionId: string;
|
|
704
|
+
channelId: string;
|
|
705
|
+
mode: SessionMode;
|
|
706
|
+
/**
|
|
707
|
+
* `"eval"` for harness sessions — skipped by {@link defineAB} enrollment.
|
|
708
|
+
* Older records omit this (treated as `"live"`).
|
|
709
|
+
*/
|
|
710
|
+
purpose?: SessionPurpose;
|
|
711
|
+
/**
|
|
712
|
+
* Denormalized sticky A/B arms (mirrors durable `ab.assigned` events) so
|
|
713
|
+
* the agent loop / tools can read arms without re-folding the log. Source
|
|
714
|
+
* of truth for stickiness remains the event stream.
|
|
715
|
+
*/
|
|
716
|
+
abs?: Record<string, string | null>;
|
|
717
|
+
/** Channel-local continuation key; null when the session is not addressable. */
|
|
718
|
+
continuationKey: string | null;
|
|
719
|
+
auth: AuthContext | null;
|
|
720
|
+
title?: string;
|
|
721
|
+
channelState?: JsonValue;
|
|
722
|
+
/**
|
|
723
|
+
* Cursor SDK agent id for this session. Local agents use the
|
|
724
|
+
* framework session id; cloud agents use a `bc-…` id (especially when
|
|
725
|
+
* `cloud.envVars` forces the server to mint).
|
|
726
|
+
*/
|
|
727
|
+
sdkAgentId?: string;
|
|
728
|
+
/**
|
|
729
|
+
* When set, local harness turns use this directory as `cwd` (e.g. a PR
|
|
730
|
+
* worktree). Session scaffold files still land under the session workspace.
|
|
731
|
+
*/
|
|
732
|
+
workspaceOverride?: string;
|
|
733
|
+
/**
|
|
734
|
+
* One-shot files to write into the harness cwd before the next turn
|
|
735
|
+
* (see {@link SendMessageOptions.workspaceFiles}). Cleared after apply.
|
|
736
|
+
*/
|
|
737
|
+
pendingWorkspaceFiles?: Record<string, string>;
|
|
738
|
+
/**
|
|
739
|
+
* Per-session cloud options captured at session creation, merged over the
|
|
740
|
+
* agent's static `cloud` config on every turn of this session. Lets a
|
|
741
|
+
* cloud agent target a per-session repo/PR (see {@link SendMessageOptions.cloud}).
|
|
742
|
+
*/
|
|
743
|
+
cloudOverride?: AgentCloudOptions;
|
|
744
|
+
/**
|
|
745
|
+
* Server-tool calls parked for human approval. Cleared when resolved
|
|
746
|
+
* or when the host process restarts without a live waiter (the in-flight
|
|
747
|
+
* SDK tool callback cannot be resumed after process restart).
|
|
748
|
+
*/
|
|
749
|
+
pendingApprovals?: PendingApproval[];
|
|
750
|
+
turnCount: number;
|
|
751
|
+
createdAt: string;
|
|
752
|
+
updatedAt: string;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
export interface TurnOutcome {
|
|
756
|
+
status: "finished" | "error" | "cancelled";
|
|
757
|
+
result?: string;
|
|
758
|
+
errorMessage?: string;
|
|
759
|
+
usage?: TurnUsage;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* Session metadata returned by `GET /v1/sessions` (and consumed by the
|
|
764
|
+
* bundled playground). Includes the current wire-format continuation token:
|
|
765
|
+
* the listing is a testing/observability surface for callers already
|
|
766
|
+
* admitted by the route auth chain.
|
|
767
|
+
*/
|
|
768
|
+
export interface SessionSummary {
|
|
769
|
+
sessionId: string;
|
|
770
|
+
channelId: string;
|
|
771
|
+
mode: SessionMode;
|
|
772
|
+
title?: string;
|
|
773
|
+
turnCount: number;
|
|
774
|
+
/** True while a turn is executing right now. */
|
|
775
|
+
running: boolean;
|
|
776
|
+
createdAt: string;
|
|
777
|
+
updatedAt: string;
|
|
778
|
+
/** `<channelId>:<key>` wire token, or null when not addressable. */
|
|
779
|
+
continuationToken: string | null;
|
|
780
|
+
/**
|
|
781
|
+
* Optional deep link to the external conversation (e.g. Slack thread).
|
|
782
|
+
* Populated for channel-driven sessions when the principal carries enough
|
|
783
|
+
* attributes to build a permalink.
|
|
784
|
+
*/
|
|
785
|
+
externalUrl?: string;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* A session handle scoped to the channel that owns it. This is what channel
|
|
790
|
+
* route handlers get back from `send()` / `getSession()`.
|
|
791
|
+
*/
|
|
792
|
+
export interface ChannelSession {
|
|
793
|
+
readonly id: string;
|
|
794
|
+
/** Channel-local continuation key currently addressing this session. */
|
|
795
|
+
readonly continuationToken: string | null;
|
|
796
|
+
/** True when this `send()` created the session. */
|
|
797
|
+
readonly isNew: boolean;
|
|
798
|
+
readonly info: SessionInfo;
|
|
799
|
+
/** Replay recorded events from `startIndex`, then follow live (NDJSON). */
|
|
800
|
+
getEventStream(options?: {
|
|
801
|
+
startIndex?: number;
|
|
802
|
+
}): Promise<ReadableStream<Uint8Array>>;
|
|
803
|
+
/** Resolves when the currently running turn reaches a terminal event. */
|
|
804
|
+
waitForCompletion(): Promise<TurnOutcome>;
|
|
805
|
+
/** Re-key the session's channel-local continuation token. */
|
|
806
|
+
setContinuationToken(token: string | null): Promise<void>;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
export interface SendMessageOptions {
|
|
810
|
+
/**
|
|
811
|
+
* Who is sending; flows to `session.auth` on newly created sessions.
|
|
812
|
+
* On HTTP channel routes, defaults to the request principal from
|
|
813
|
+
* {@link ChannelHandlerArgs.auth}. Pass explicitly to override (e.g.
|
|
814
|
+
* `null` or a Slack-derived principal).
|
|
815
|
+
*/
|
|
816
|
+
auth?: AuthContext | null;
|
|
817
|
+
/**
|
|
818
|
+
* Channel-local continuation token. When it addresses an existing session
|
|
819
|
+
* the message is a follow-up; otherwise a new session is created keyed by
|
|
820
|
+
* this token. Omit to always create a fresh session.
|
|
821
|
+
*/
|
|
822
|
+
continuationToken?: string;
|
|
823
|
+
/** Initial channel state for newly created sessions. */
|
|
824
|
+
state?: JsonValue;
|
|
825
|
+
/** Session display title (applied when creating a new session). */
|
|
826
|
+
title?: string;
|
|
827
|
+
/**
|
|
828
|
+
* Session purpose at create time. `"eval"` skips sticky A/B enrollment
|
|
829
|
+
* (`defineAB`) so regression runs do not mix into live metrics.
|
|
830
|
+
*/
|
|
831
|
+
purpose?: SessionPurpose;
|
|
832
|
+
/**
|
|
833
|
+
* Absolute directory used as the local harness `cwd` for this session.
|
|
834
|
+
* On create, sets the session workspace. On resume (continuation hit),
|
|
835
|
+
* refreshes `workspaceOverride` when the path differs — e.g. a newer PR
|
|
836
|
+
* worktree after synchronize.
|
|
837
|
+
*/
|
|
838
|
+
workspaceDir?: string;
|
|
839
|
+
/**
|
|
840
|
+
* Relative path → contents written into the session harness cwd after
|
|
841
|
+
* scaffold materialize and before the next turn. On create, queued for
|
|
842
|
+
* the first turn; on resume, replaces any pending files. Prefer this
|
|
843
|
+
* over {@link workspaceDir} when you only need to inject a few
|
|
844
|
+
* host-prepared files (skills/AGENTS.md still land in the normal
|
|
845
|
+
* session workspace).
|
|
846
|
+
*/
|
|
847
|
+
workspaceFiles?: Record<string, string>;
|
|
848
|
+
/**
|
|
849
|
+
* Per-session cloud options, merged over the agent's static `cloud`
|
|
850
|
+
* config (new sessions only). When set, this session runs as cloud even
|
|
851
|
+
* if the agent's default {@link AgentConfig.runtime} is `"local"` —
|
|
852
|
+
* so chat can stay local (server tools) while a handoff attaches a PR
|
|
853
|
+
* to a cloud VM. Ignored when the agent has no cloud capability and
|
|
854
|
+
* runtime is forced local with no override path.
|
|
855
|
+
*/
|
|
856
|
+
cloud?: AgentCloudOptions;
|
|
857
|
+
/**
|
|
858
|
+
* Seed the Cursor SDK agent id for a **new** session (ignored when the
|
|
859
|
+
* continuation token matches an existing session). For cloud agents this
|
|
860
|
+
* reattaches the session to an existing cloud conversation (`bc-…`): the
|
|
861
|
+
* first turn resumes that agent instead of creating a new one, so
|
|
862
|
+
* follow-ups keep landing on the same bcId even after the local session
|
|
863
|
+
* store is gone.
|
|
864
|
+
*/
|
|
865
|
+
sdkAgentId?: string;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
export type SendMessageFn = (
|
|
869
|
+
message: string,
|
|
870
|
+
options?: SendMessageOptions
|
|
871
|
+
) => Promise<ChannelSession>;
|
|
872
|
+
|
|
873
|
+
// ============================================================================
|
|
874
|
+
// Direct tool calls (deterministic invocation, no model turn)
|
|
875
|
+
// ============================================================================
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Channel id recorded on the synthetic session info handed to tools invoked
|
|
879
|
+
* directly (outside any existing session).
|
|
880
|
+
*/
|
|
881
|
+
export const DIRECT_TOOL_CALL_CHANNEL_ID = "direct";
|
|
882
|
+
|
|
883
|
+
/** Options for {@link CallToolFn} — calling an authored tool directly. */
|
|
884
|
+
export interface CallToolOptions {
|
|
885
|
+
/** Who is calling; becomes the tool context's session auth. */
|
|
886
|
+
auth?: AuthContext | null;
|
|
887
|
+
/**
|
|
888
|
+
* Run the tool inside an existing session: the tool sees that session's
|
|
889
|
+
* info and materialized workspace, and the call is recorded on the
|
|
890
|
+
* session's event stream (`actions.requested` / `action.result` under a
|
|
891
|
+
* per-call `turnId`). Rejected while a model turn is running on the
|
|
892
|
+
* session. Omit to run against an ephemeral scratch workspace under
|
|
893
|
+
* `<stateRoot>/tool-calls/<callId>` (materialized with seed files and
|
|
894
|
+
* removed after the call) with a synthetic
|
|
895
|
+
* {@link DIRECT_TOOL_CALL_CHANNEL_ID} session info.
|
|
896
|
+
*/
|
|
897
|
+
sessionId?: string;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/** Result of a direct (deterministic) tool call. */
|
|
901
|
+
export interface ToolCallOutcome {
|
|
902
|
+
toolName: string;
|
|
903
|
+
/** Correlates with the recorded events for session-bound calls. */
|
|
904
|
+
callId: string;
|
|
905
|
+
/** True when the tool threw or returned an error envelope. */
|
|
906
|
+
isError: boolean;
|
|
907
|
+
/** Normalized result, exactly as the model would receive it. */
|
|
908
|
+
result: unknown;
|
|
909
|
+
/**
|
|
910
|
+
* Human-readable failure text when {@link isError} is true (joined text
|
|
911
|
+
* parts from the error envelope, or a string result). Prefer this over
|
|
912
|
+
* re-parsing {@link result} in channel handlers.
|
|
913
|
+
*/
|
|
914
|
+
errorMessage?: string;
|
|
915
|
+
durationMs: number;
|
|
916
|
+
/** Present when the call ran inside an existing session. */
|
|
917
|
+
sessionId?: string;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* Call an authored server tool (`agent/tools/<name>.ts`) deterministically:
|
|
922
|
+
* the input is validated against the tool's schema (zod schemas validate;
|
|
923
|
+
* plain JSON Schema inputs pass through unvalidated, matching the model
|
|
924
|
+
* path) and `execute` runs in-process, without a model turn deciding to
|
|
925
|
+
* call it. Rejects unknown tools, `execution: "agent"` tools, and invalid
|
|
926
|
+
* input by throwing.
|
|
927
|
+
*/
|
|
928
|
+
export type CallToolFn = (
|
|
929
|
+
toolName: string,
|
|
930
|
+
input?: unknown,
|
|
931
|
+
options?: CallToolOptions
|
|
932
|
+
) => Promise<ToolCallOutcome>;
|
|
933
|
+
|
|
934
|
+
// ============================================================================
|
|
935
|
+
// Channels (agent/channels/*.ts)
|
|
936
|
+
// ============================================================================
|
|
937
|
+
|
|
938
|
+
export type RouteMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
939
|
+
|
|
940
|
+
export interface ChannelHandlerArgs {
|
|
941
|
+
/** Route parameters extracted from the path pattern. */
|
|
942
|
+
params: Record<string, string>;
|
|
943
|
+
requestIp: string | null;
|
|
944
|
+
/** Auth context resolved by the channel's auth chain. */
|
|
945
|
+
auth: AuthContext | null;
|
|
946
|
+
/**
|
|
947
|
+
* Validated JSON body when the route declares `bodySchema` (Zod).
|
|
948
|
+
* Prefer this over `request.json()` so the body is not read twice.
|
|
949
|
+
*/
|
|
950
|
+
body?: unknown;
|
|
951
|
+
/**
|
|
952
|
+
* Validated query object when the route declares `querySchema` (Zod).
|
|
953
|
+
* Built from `URLSearchParams` (string values) before validation.
|
|
954
|
+
*/
|
|
955
|
+
query?: unknown;
|
|
956
|
+
/** Shared host services (MCP / GitHub / Slack). Same as tool `ctx.host`. */
|
|
957
|
+
host: HostContext;
|
|
958
|
+
/** Start or resume a session on this channel. */
|
|
959
|
+
send: SendMessageFn;
|
|
960
|
+
/** Look up an existing session on this channel. */
|
|
961
|
+
getSession(sessionId: string): Promise<ChannelSession | null>;
|
|
962
|
+
/** Hand inbound work to a different channel (cross-channel hand-off). */
|
|
963
|
+
receive(
|
|
964
|
+
channel: ChannelDefinition | HttpChannelDefinition | string,
|
|
965
|
+
input: ReceiveInput
|
|
966
|
+
): Promise<ChannelSession>;
|
|
967
|
+
/** Call an authored server tool directly (no model turn). */
|
|
968
|
+
callTool: CallToolFn;
|
|
969
|
+
/** Extend server lifetime tracking for background work. */
|
|
970
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
971
|
+
/**
|
|
972
|
+
* Absolute playground + NDJSON trace URLs for a session on this agent
|
|
973
|
+
* mount (single-agent `""` or multi-agent `"/<slug>"`). Prefer this over
|
|
974
|
+
* rebuilding paths from the request URL.
|
|
975
|
+
*/
|
|
976
|
+
sessionUrls(
|
|
977
|
+
request: Request,
|
|
978
|
+
sessionId: string
|
|
979
|
+
): { playgroundUrl: string; traceUrl: string };
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
export type ChannelRouteHandler = (
|
|
983
|
+
request: Request,
|
|
984
|
+
args: ChannelHandlerArgs
|
|
985
|
+
) => Response | Promise<Response>;
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* Channel HTTP routes must declare a Zod schema (plain JSON Schema objects
|
|
989
|
+
* are not accepted — TypeScript will reject them).
|
|
990
|
+
*/
|
|
991
|
+
export type ChannelRouteSchema = z.ZodTypeAny;
|
|
992
|
+
|
|
993
|
+
/** Handler args with a required, schema-inferred `query`. */
|
|
994
|
+
export type ChannelHandlerArgsWithQuery<TQuery> = ChannelHandlerArgs & {
|
|
995
|
+
query: TQuery;
|
|
996
|
+
};
|
|
997
|
+
|
|
998
|
+
/** Handler args with a required, schema-inferred `body`. */
|
|
999
|
+
export type ChannelHandlerArgsWithBody<TBody> = ChannelHandlerArgs & {
|
|
1000
|
+
body: TBody;
|
|
1001
|
+
};
|
|
1002
|
+
|
|
1003
|
+
/** Handler args with inferred `body` and optional inferred `query`. */
|
|
1004
|
+
export type ChannelHandlerArgsWithBodyAndQuery<TBody, TQuery> =
|
|
1005
|
+
ChannelHandlerArgs & {
|
|
1006
|
+
body: TBody;
|
|
1007
|
+
query: TQuery;
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* GET routes must declare a Zod `querySchema` (use `z.object({})` when there
|
|
1012
|
+
* are no query params — path params still live on `args.params`).
|
|
1013
|
+
*/
|
|
1014
|
+
export interface ChannelGetRouteSpec<
|
|
1015
|
+
TQuery extends z.ZodTypeAny = z.ZodTypeAny,
|
|
1016
|
+
> {
|
|
1017
|
+
description?: string;
|
|
1018
|
+
querySchema: TQuery;
|
|
1019
|
+
handler: (
|
|
1020
|
+
request: Request,
|
|
1021
|
+
args: ChannelHandlerArgsWithQuery<z.infer<TQuery>>
|
|
1022
|
+
) => Response | Promise<Response>;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* POST / PUT / PATCH routes must declare a Zod `bodySchema`. Optional
|
|
1027
|
+
* `querySchema` when the route also reads search params.
|
|
1028
|
+
*/
|
|
1029
|
+
export interface ChannelBodyRouteSpec<
|
|
1030
|
+
TBody extends z.ZodTypeAny = z.ZodTypeAny,
|
|
1031
|
+
TQuery extends z.ZodTypeAny | undefined = undefined,
|
|
1032
|
+
> {
|
|
1033
|
+
description?: string;
|
|
1034
|
+
bodySchema: TBody;
|
|
1035
|
+
querySchema?: TQuery;
|
|
1036
|
+
handler: (
|
|
1037
|
+
request: Request,
|
|
1038
|
+
args: TQuery extends z.ZodTypeAny
|
|
1039
|
+
? ChannelHandlerArgsWithBodyAndQuery<z.infer<TBody>, z.infer<TQuery>>
|
|
1040
|
+
: ChannelHandlerArgsWithBody<z.infer<TBody>>
|
|
1041
|
+
) => Response | Promise<Response>;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* DELETE routes may declare Zod schemas when useful; neither is required.
|
|
1046
|
+
*/
|
|
1047
|
+
export interface ChannelDeleteRouteSpec<
|
|
1048
|
+
TBody extends z.ZodTypeAny | undefined = undefined,
|
|
1049
|
+
TQuery extends z.ZodTypeAny | undefined = undefined,
|
|
1050
|
+
> {
|
|
1051
|
+
description?: string;
|
|
1052
|
+
bodySchema?: TBody;
|
|
1053
|
+
querySchema?: TQuery;
|
|
1054
|
+
handler: ChannelRouteHandler;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
/** @deprecated Prefer {@link ChannelGetRouteSpec} / {@link ChannelBodyRouteSpec}. */
|
|
1058
|
+
export type ChannelRouteSpec =
|
|
1059
|
+
| ChannelGetRouteSpec
|
|
1060
|
+
| ChannelBodyRouteSpec
|
|
1061
|
+
| ChannelDeleteRouteSpec;
|
|
1062
|
+
|
|
1063
|
+
export interface ChannelRoute {
|
|
1064
|
+
method: RouteMethod;
|
|
1065
|
+
path: string;
|
|
1066
|
+
handler: ChannelRouteHandler;
|
|
1067
|
+
description?: string;
|
|
1068
|
+
bodySchema?: ChannelRouteSchema;
|
|
1069
|
+
querySchema?: ChannelRouteSchema;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/** Input to a channel's `receive` hook (and to `args.receive(...)`). */
|
|
1073
|
+
export interface ReceiveInput {
|
|
1074
|
+
message: string;
|
|
1075
|
+
auth: AuthContext | null;
|
|
1076
|
+
/** Channel-specific delivery target (e.g. a chat channel id). */
|
|
1077
|
+
target?: JsonObject;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/** Per-event channel context: live (persisted) state plus session ops. */
|
|
1081
|
+
export interface ChannelEventContext<TState = JsonValue> {
|
|
1082
|
+
channelId: string;
|
|
1083
|
+
state: TState;
|
|
1084
|
+
continuationToken: string | null;
|
|
1085
|
+
setContinuationToken(token: string | null): Promise<void>;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
export interface SessionContext {
|
|
1089
|
+
session: SessionInfo;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
export type ChannelEventHandler<
|
|
1093
|
+
TState = JsonValue,
|
|
1094
|
+
TEvent extends SessionEvent = SessionEvent,
|
|
1095
|
+
> = (
|
|
1096
|
+
event: TEvent,
|
|
1097
|
+
channel: ChannelEventContext<TState>,
|
|
1098
|
+
ctx: SessionContext
|
|
1099
|
+
) => void | Promise<void>;
|
|
1100
|
+
|
|
1101
|
+
/** Handlers are keyed by event type and receive the narrowed event. */
|
|
1102
|
+
export type ChannelEventHandlers<TState = JsonValue> = {
|
|
1103
|
+
[K in SessionEventType]?: ChannelEventHandler<
|
|
1104
|
+
TState,
|
|
1105
|
+
Extract<SessionEvent, { type: K }>
|
|
1106
|
+
>;
|
|
1107
|
+
} & {
|
|
1108
|
+
"*"?: ChannelEventHandler<TState, SessionEvent>;
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
/** Bound helpers passed to {@link ChannelConfig.onStart}. */
|
|
1112
|
+
export interface ChannelStartArgs {
|
|
1113
|
+
send: SendMessageFn;
|
|
1114
|
+
getSession(sessionId: string): Promise<ChannelSession | null>;
|
|
1115
|
+
receive(
|
|
1116
|
+
channel: ChannelDefinition | HttpChannelDefinition | string,
|
|
1117
|
+
input: ReceiveInput
|
|
1118
|
+
): Promise<ChannelSession>;
|
|
1119
|
+
/** Call an authored server tool directly (no model turn). */
|
|
1120
|
+
callTool: CallToolFn;
|
|
1121
|
+
/**
|
|
1122
|
+
* Append an assistant message to a session without a model turn and without
|
|
1123
|
+
* a user `message.received` bubble. Prefer this over `send()` when a host
|
|
1124
|
+
* task already produced the final text (e.g. after staged `callTool`s).
|
|
1125
|
+
*/
|
|
1126
|
+
emitAssistantMessage(sessionId: string, text: string): Promise<void>;
|
|
1127
|
+
/** Shared host services (MCP / GitHub / Slack). Same as {@link ChannelHandlerArgs.host}. */
|
|
1128
|
+
host: HostContext;
|
|
1129
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
1130
|
+
/**
|
|
1131
|
+
* Approve or deny a parked {@link ToolConfig.needsApproval} tool call
|
|
1132
|
+
* for a session on this channel. Channel packs (e.g. Slack Block Kit
|
|
1133
|
+
* buttons) use this to unblock the turn without going through the HTTP
|
|
1134
|
+
* approvals route.
|
|
1135
|
+
*/
|
|
1136
|
+
resolveApproval(
|
|
1137
|
+
sessionId: string,
|
|
1138
|
+
callId: string,
|
|
1139
|
+
decision: ApprovalDecision,
|
|
1140
|
+
auth: AuthContext | null,
|
|
1141
|
+
options?: { asSessionOwner?: boolean }
|
|
1142
|
+
): Promise<PendingApproval>;
|
|
1143
|
+
/**
|
|
1144
|
+
* Server log sink (same as {@link ServeOptions.logger}). Channel packs
|
|
1145
|
+
* should prefer this over `console.*` so CLI/eval hosts can redirect.
|
|
1146
|
+
*/
|
|
1147
|
+
logger: (line: string) => void;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
/**
|
|
1151
|
+
* Descriptive metadata a channel pack attaches for tooling. Read by
|
|
1152
|
+
* discovery / `projectInfo` and CLI helpers (e.g. `agent-serve github
|
|
1153
|
+
* forward`) — it never affects routing or dispatch.
|
|
1154
|
+
*/
|
|
1155
|
+
export interface ChannelMeta {
|
|
1156
|
+
/** Well-known pack kind, e.g. `"github"` or `"slack"`. */
|
|
1157
|
+
kind?: string;
|
|
1158
|
+
/**
|
|
1159
|
+
* For GitHub webhook packs: the webhook event names this channel is wired
|
|
1160
|
+
* to dispatch on. Used to derive `gh webhook forward --events`.
|
|
1161
|
+
*/
|
|
1162
|
+
githubWebhookEvents?: readonly string[];
|
|
1163
|
+
/**
|
|
1164
|
+
* For Slack packs with the opt-in channel watch: the allowlisted channels
|
|
1165
|
+
* (ids or `#names`) this channel dispatches on without a mention. Surfaced
|
|
1166
|
+
* by `info` so watched channels are auditable.
|
|
1167
|
+
*/
|
|
1168
|
+
slackChannelPosts?: readonly string[];
|
|
1169
|
+
/**
|
|
1170
|
+
* For Slack packs riding the signed-in Cursor account's Slack connection
|
|
1171
|
+
* (`slackChannel({ cursorAccount: true })`): inbound relays from
|
|
1172
|
+
* `/v0/slack-events` instead of Socket Mode.
|
|
1173
|
+
*/
|
|
1174
|
+
slackCursorAccount?: boolean;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
export interface ChannelConfig<TState = JsonValue> {
|
|
1178
|
+
/** Route auth chain. Defaults to `[localDevStrict()]`. */
|
|
1179
|
+
auth?: AuthPolicy[];
|
|
1180
|
+
routes?: ChannelRoute[];
|
|
1181
|
+
/**
|
|
1182
|
+
* Descriptive metadata for tooling (kind, webhook events). Attached by
|
|
1183
|
+
* channel packs; ignored by the router and session engine.
|
|
1184
|
+
*/
|
|
1185
|
+
meta?: ChannelMeta;
|
|
1186
|
+
/** Initial per-session channel state (JSON-serializable). */
|
|
1187
|
+
state?: TState;
|
|
1188
|
+
/**
|
|
1189
|
+
* Owns inbound cross-channel hand-offs. When omitted, `receive` starts a
|
|
1190
|
+
* fresh session with the input message.
|
|
1191
|
+
*/
|
|
1192
|
+
receive?: (
|
|
1193
|
+
input: ReceiveInput,
|
|
1194
|
+
args: { send: SendMessageFn }
|
|
1195
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: hooks may return a session, nothing, or an async nothing
|
|
1196
|
+
) => Promise<ChannelSession | undefined | void> | ChannelSession | void;
|
|
1197
|
+
/** Stream-event handlers for sessions owned by this channel. */
|
|
1198
|
+
events?: ChannelEventHandlers<TState>;
|
|
1199
|
+
/** Called once when the server mounts this channel. Optional stop via onStop. */
|
|
1200
|
+
onStart?: (args: ChannelStartArgs) => void | Promise<void>;
|
|
1201
|
+
/** Called when the server shuts down. */
|
|
1202
|
+
onStop?: () => void | Promise<void>;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
export type ChannelDefinition<TState = JsonValue> = ChannelConfig<TState> &
|
|
1206
|
+
BrandedDefinition<"channel">;
|
|
1207
|
+
|
|
1208
|
+
/** Configuration for the built-in HTTP session channel. */
|
|
1209
|
+
export interface HttpChannelConfig {
|
|
1210
|
+
/** Route auth chain. Defaults to `[localDevStrict()]`. */
|
|
1211
|
+
auth?: AuthPolicy[];
|
|
1212
|
+
/**
|
|
1213
|
+
* Transform the inbound message before the agent sees it (e.g. prepend
|
|
1214
|
+
* request-specific context).
|
|
1215
|
+
*/
|
|
1216
|
+
onMessage?: (
|
|
1217
|
+
message: string,
|
|
1218
|
+
info: { auth: AuthContext | null }
|
|
1219
|
+
) => string | Promise<string>;
|
|
1220
|
+
/** Stream-event handlers for sessions created over HTTP. */
|
|
1221
|
+
events?: ChannelEventHandlers;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
export type HttpChannelDefinition = HttpChannelConfig &
|
|
1225
|
+
BrandedDefinition<"http-channel">;
|
|
1226
|
+
|
|
1227
|
+
// ============================================================================
|
|
1228
|
+
// Hooks (agent/hooks/*.ts)
|
|
1229
|
+
// ============================================================================
|
|
1230
|
+
|
|
1231
|
+
export interface HookContext {
|
|
1232
|
+
agent: { name: string };
|
|
1233
|
+
channel: { id: string; continuationToken: string | null };
|
|
1234
|
+
session: SessionInfo;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
export type HookHandler<TEvent extends SessionEvent = SessionEvent> = (
|
|
1238
|
+
event: TEvent,
|
|
1239
|
+
ctx: HookContext
|
|
1240
|
+
) => void | Promise<void>;
|
|
1241
|
+
|
|
1242
|
+
/** Handlers are keyed by event type and receive the narrowed event. */
|
|
1243
|
+
export type HookEventHandlers = {
|
|
1244
|
+
[K in SessionEventType]?: HookHandler<Extract<SessionEvent, { type: K }>>;
|
|
1245
|
+
} & {
|
|
1246
|
+
"*"?: HookHandler;
|
|
1247
|
+
};
|
|
1248
|
+
|
|
1249
|
+
export interface HookConfig {
|
|
1250
|
+
events: HookEventHandlers;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
export type HookDefinition = HookConfig & BrandedDefinition<"hook">;
|
|
1254
|
+
|
|
1255
|
+
// ============================================================================
|
|
1256
|
+
// Schedules (agent/schedules/*)
|
|
1257
|
+
// ============================================================================
|
|
1258
|
+
|
|
1259
|
+
export interface ScheduleHandlerArgs {
|
|
1260
|
+
/** Hand the scheduled work to a channel. */
|
|
1261
|
+
receive: (
|
|
1262
|
+
channel: ChannelDefinition | HttpChannelDefinition | string,
|
|
1263
|
+
input: ReceiveInput
|
|
1264
|
+
) => Promise<ChannelSession>;
|
|
1265
|
+
/** Call an authored server tool directly (no model turn). */
|
|
1266
|
+
callTool: CallToolFn;
|
|
1267
|
+
/** Keep the dispatch alive past handler return. */
|
|
1268
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
1269
|
+
/** Pre-built app principal for work the agent does on its own behalf. */
|
|
1270
|
+
appAuth: AuthContext;
|
|
1271
|
+
/** Shared host services (MCP / GitHub / Slack). Same as tool `ctx.host`. */
|
|
1272
|
+
host: HostContext;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
export interface ScheduleConfig {
|
|
1276
|
+
/** Standard 5-field cron expression, evaluated in UTC. */
|
|
1277
|
+
cron: string;
|
|
1278
|
+
/** Fire-and-forget prompt (task mode). Mutually exclusive with `run`. */
|
|
1279
|
+
markdown?: string;
|
|
1280
|
+
/** Handler form: full control over dispatch. */
|
|
1281
|
+
run?: (args: ScheduleHandlerArgs) => void | Promise<void>;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
export type ScheduleDefinition = ScheduleConfig & BrandedDefinition<"schedule">;
|
|
1285
|
+
|
|
1286
|
+
// ============================================================================
|
|
1287
|
+
// Reminders (runtime per-session wakes)
|
|
1288
|
+
// ============================================================================
|
|
1289
|
+
|
|
1290
|
+
export type ReminderBusyPolicy = "skipIfBusy" | "queueBehindTurn";
|
|
1291
|
+
|
|
1292
|
+
export type ReminderStatus = "armed" | "completed" | "cancelled" | "disarmed";
|
|
1293
|
+
|
|
1294
|
+
export type ReminderScheduleKind = "every" | "cron" | "delay" | "at";
|
|
1295
|
+
|
|
1296
|
+
export type ReminderFireResult =
|
|
1297
|
+
| { action: "skip"; reschedule?: ReminderReschedule }
|
|
1298
|
+
| { action: "delivered"; reschedule?: ReminderReschedule }
|
|
1299
|
+
| { action: "stop" };
|
|
1300
|
+
|
|
1301
|
+
export interface ReminderReschedule {
|
|
1302
|
+
delay?: string | number;
|
|
1303
|
+
at?: Date | string;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
export interface ReminderTarget {
|
|
1307
|
+
channelId: string;
|
|
1308
|
+
continuationToken: string;
|
|
1309
|
+
[key: string]: unknown;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
export interface ReminderUntilContext {
|
|
1313
|
+
id: string;
|
|
1314
|
+
purpose: string;
|
|
1315
|
+
fireCount: number;
|
|
1316
|
+
target: ReminderTarget;
|
|
1317
|
+
host: HostContext;
|
|
1318
|
+
mcp: HostMcpRegistry;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
export interface ReminderFireContext extends ReminderUntilContext {
|
|
1322
|
+
appAuth: AuthContext;
|
|
1323
|
+
/** Wake the reminder's already-bound session (target is implicit). */
|
|
1324
|
+
followup(args: { message: string }): Promise<ChannelSession>;
|
|
1325
|
+
cancel(reason?: string): Promise<void>;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
/**
|
|
1329
|
+
* Create a durable wake bound to a channel continuation.
|
|
1330
|
+
*
|
|
1331
|
+
* Exactly one of `prompt` | `run`, and exactly one of
|
|
1332
|
+
* `every` | `cron` | `delay` | `at`. Prompt fires always follow up into the
|
|
1333
|
+
* bound session.
|
|
1334
|
+
*
|
|
1335
|
+
* @example Recurring (host policy)
|
|
1336
|
+
* ```ts
|
|
1337
|
+
* await host.reminders.create({
|
|
1338
|
+
* purpose: "merge_conflict_watch",
|
|
1339
|
+
* channelId: "drive",
|
|
1340
|
+
* continuationToken,
|
|
1341
|
+
* every: "30m",
|
|
1342
|
+
* async run({ followup, host }) {
|
|
1343
|
+
* if (await isPrClosed(host)) return { action: "stop" };
|
|
1344
|
+
* if (!(await isConflicted(host))) return { action: "skip" };
|
|
1345
|
+
* await followup({ message: "Merge conflict detected." });
|
|
1346
|
+
* return { action: "delivered" };
|
|
1347
|
+
* },
|
|
1348
|
+
* });
|
|
1349
|
+
* ```
|
|
1350
|
+
*
|
|
1351
|
+
* @example One-shot (agent tool / prompt form)
|
|
1352
|
+
* ```ts
|
|
1353
|
+
* await host.reminders.create({
|
|
1354
|
+
* purpose: "ci_recheck",
|
|
1355
|
+
* channelId: "drive",
|
|
1356
|
+
* continuationToken,
|
|
1357
|
+
* delay: "2h",
|
|
1358
|
+
* prompt: "Re-check CI. Only act if still failing.",
|
|
1359
|
+
* until: "Cancel once CI is green or the PR is merged.",
|
|
1360
|
+
* });
|
|
1361
|
+
* ```
|
|
1362
|
+
*/
|
|
1363
|
+
export interface ReminderCreateInput {
|
|
1364
|
+
purpose: string;
|
|
1365
|
+
/** Channel that owns the session (e.g. `drive`). */
|
|
1366
|
+
channelId: string;
|
|
1367
|
+
/** Channel-local continuation key for the bound session. */
|
|
1368
|
+
continuationToken: string;
|
|
1369
|
+
/** Optional opaque metadata (e.g. `{ prUrl }`). */
|
|
1370
|
+
target?: Record<string, unknown>;
|
|
1371
|
+
/** Exactly one of prompt or run. */
|
|
1372
|
+
prompt?: string;
|
|
1373
|
+
run?: (ctx: ReminderFireContext) => Promise<ReminderFireResult>;
|
|
1374
|
+
/** Exactly one schedule shape. */
|
|
1375
|
+
every?: string;
|
|
1376
|
+
cron?: string;
|
|
1377
|
+
delay?: string | number;
|
|
1378
|
+
at?: Date | string | number;
|
|
1379
|
+
/**
|
|
1380
|
+
* Auto-cancel: function (host evaluates, true → cancel) XOR prompt string
|
|
1381
|
+
* (agent-facing stop condition; platform does not interpret it).
|
|
1382
|
+
*/
|
|
1383
|
+
until?: string | ((ctx: ReminderUntilContext) => Promise<boolean>);
|
|
1384
|
+
/**
|
|
1385
|
+
* Defaults: recurring → `skipIfBusy`; one-shot → `queueBehindTurn`.
|
|
1386
|
+
*/
|
|
1387
|
+
busyPolicy?: ReminderBusyPolicy;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
export interface ReminderInfo {
|
|
1391
|
+
id: string;
|
|
1392
|
+
purpose: string;
|
|
1393
|
+
channelId: string;
|
|
1394
|
+
continuationToken: string;
|
|
1395
|
+
target?: Record<string, unknown>;
|
|
1396
|
+
scheduleKind: ReminderScheduleKind;
|
|
1397
|
+
scheduleValue: string;
|
|
1398
|
+
prompt?: string;
|
|
1399
|
+
untilPrompt?: string;
|
|
1400
|
+
busyPolicy: ReminderBusyPolicy;
|
|
1401
|
+
status: ReminderStatus;
|
|
1402
|
+
disarmReason?: string;
|
|
1403
|
+
fireCount: number;
|
|
1404
|
+
nextFireAt: string;
|
|
1405
|
+
createdAt: string;
|
|
1406
|
+
updatedAt: string;
|
|
1407
|
+
hasRunHandler: boolean;
|
|
1408
|
+
hasUntilFn: boolean;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
/** Host-facing reminder API attached to {@link HostContext.reminders}. */
|
|
1412
|
+
export interface ReminderHostApi {
|
|
1413
|
+
/** Arm a reminder. See {@link ReminderCreateInput}. */
|
|
1414
|
+
create(input: ReminderCreateInput): Promise<ReminderInfo>;
|
|
1415
|
+
/** List reminders, optionally filtered. */
|
|
1416
|
+
list(filter?: {
|
|
1417
|
+
status?: ReminderStatus;
|
|
1418
|
+
purpose?: string;
|
|
1419
|
+
continuationToken?: string;
|
|
1420
|
+
}): Promise<ReminderInfo[]>;
|
|
1421
|
+
/** Cancel one reminder by id. No-op (returns undefined) if unknown. */
|
|
1422
|
+
cancel(id: string, reason?: string): Promise<ReminderInfo | undefined>;
|
|
1423
|
+
/** Cancel all armed reminders for a continuation token. Returns count. */
|
|
1424
|
+
cancelForContinuation(
|
|
1425
|
+
continuationToken: string,
|
|
1426
|
+
reason: string
|
|
1427
|
+
): Promise<number>;
|
|
1428
|
+
/**
|
|
1429
|
+
* Fire immediately (dev / hillclimb).
|
|
1430
|
+
* `outcome` is `"noop"` when already firing or not armed.
|
|
1431
|
+
*/
|
|
1432
|
+
dispatch(id: string): Promise<{
|
|
1433
|
+
reminderId: string;
|
|
1434
|
+
outcome: "fired" | "noop";
|
|
1435
|
+
reason?: string;
|
|
1436
|
+
}>;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
// ============================================================================
|
|
1440
|
+
// Discovery / manifest
|
|
1441
|
+
// ============================================================================
|
|
1442
|
+
|
|
1443
|
+
export interface Diagnostic {
|
|
1444
|
+
severity: "error" | "warning";
|
|
1445
|
+
/** Repo-relative or absolute path of the offending file. */
|
|
1446
|
+
path?: string;
|
|
1447
|
+
message: string;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
export interface DiscoveredTool {
|
|
1451
|
+
name: string;
|
|
1452
|
+
description: string;
|
|
1453
|
+
/** JSON Schema advertised to the model. */
|
|
1454
|
+
inputSchema: JsonSchemaObject;
|
|
1455
|
+
/** Where the tool body runs. Defaults to `"server"`. */
|
|
1456
|
+
execution: ToolExecution;
|
|
1457
|
+
/**
|
|
1458
|
+
* True when the tool may park for human approval (boolean true or a
|
|
1459
|
+
* predicate). Runtime evaluation still runs the predicate per call.
|
|
1460
|
+
*/
|
|
1461
|
+
needsApproval: boolean;
|
|
1462
|
+
/**
|
|
1463
|
+
* Agent tools: script body materialized under
|
|
1464
|
+
* `.agent-serve/tools/<name>.sh`.
|
|
1465
|
+
*/
|
|
1466
|
+
script?: string;
|
|
1467
|
+
definition: ToolDefinition;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
/** A packaged-skill sibling file: inline contents or a file to copy. */
|
|
1471
|
+
export type SkillFileSource = { contents: string } | { sourcePath: string };
|
|
1472
|
+
|
|
1473
|
+
export interface DiscoveredSkill {
|
|
1474
|
+
name: string;
|
|
1475
|
+
description: string;
|
|
1476
|
+
/** SKILL.md body (without generated frontmatter). */
|
|
1477
|
+
markdown: string;
|
|
1478
|
+
/** Package-relative sibling files. */
|
|
1479
|
+
files: Record<string, SkillFileSource>;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
export interface DiscoveredConnection {
|
|
1483
|
+
name: string;
|
|
1484
|
+
transport: ConnectionTransport;
|
|
1485
|
+
description?: string;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
export interface DiscoveredChannel {
|
|
1489
|
+
id: string;
|
|
1490
|
+
definition: ChannelDefinition;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
export interface DiscoveredSchedule {
|
|
1494
|
+
name: string;
|
|
1495
|
+
cron: string;
|
|
1496
|
+
kind: "markdown" | "run";
|
|
1497
|
+
definition: ScheduleDefinition;
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
export interface DiscoveredHook {
|
|
1501
|
+
name: string;
|
|
1502
|
+
definition: HookDefinition;
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
/** Live A/B metrics experiment (`agent/ab.ts` or `agent/ab/<name>.ts`). */
|
|
1506
|
+
export interface DiscoveredAB {
|
|
1507
|
+
name: string;
|
|
1508
|
+
/** Branded `defineAB({ ... })` config (see `@anysphere/agent-serve/ab`). */
|
|
1509
|
+
definition: BrandedDefinition<"ab">;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
export interface SeedFile {
|
|
1513
|
+
/** Path inside the session workspace. */
|
|
1514
|
+
relativePath: string;
|
|
1515
|
+
/** Absolute path of the authored source file. */
|
|
1516
|
+
sourcePath: string;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
/** A fully resolved agent (the root agent or a subagent). */
|
|
1520
|
+
export interface ResolvedAgent {
|
|
1521
|
+
name: string;
|
|
1522
|
+
description?: string;
|
|
1523
|
+
model?: ModelSetting;
|
|
1524
|
+
/** Composed system prompt (instructions.md / instructions.ts / agent.ts). */
|
|
1525
|
+
instructions?: string;
|
|
1526
|
+
/** Execution runtime. Root agents default to `"local"`. */
|
|
1527
|
+
runtime: AgentRuntime;
|
|
1528
|
+
/** Cloud options when {@link runtime} is `"cloud"`. */
|
|
1529
|
+
cloud?: AgentCloudOptions;
|
|
1530
|
+
/**
|
|
1531
|
+
* Resolved local harness options from {@link AgentConfig.local}
|
|
1532
|
+
* (`cwd` is absolute — relative paths resolved against the project root).
|
|
1533
|
+
*/
|
|
1534
|
+
local?: AgentLocalOptions;
|
|
1535
|
+
tools: DiscoveredTool[];
|
|
1536
|
+
skills: DiscoveredSkill[];
|
|
1537
|
+
connections: DiscoveredConnection[];
|
|
1538
|
+
subagents: ResolvedAgent[];
|
|
1539
|
+
seedFiles: SeedFile[];
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
/** The compiled project manifest produced by `loadAgentProject`. */
|
|
1543
|
+
export interface AgentProject {
|
|
1544
|
+
/** App root (the directory containing package.json / agent/). */
|
|
1545
|
+
rootDir: string;
|
|
1546
|
+
/** The authored agent directory. */
|
|
1547
|
+
agentDir: string;
|
|
1548
|
+
name: string;
|
|
1549
|
+
agent: ResolvedAgent;
|
|
1550
|
+
/** Built-in HTTP channel config (authored override or default). */
|
|
1551
|
+
httpChannel: HttpChannelDefinition;
|
|
1552
|
+
channels: DiscoveredChannel[];
|
|
1553
|
+
schedules: DiscoveredSchedule[];
|
|
1554
|
+
hooks: DiscoveredHook[];
|
|
1555
|
+
/** Live A/B metric experiments (`defineAB`). */
|
|
1556
|
+
abs: DiscoveredAB[];
|
|
1557
|
+
/** Optional `agent/ab.config.ts` (`defineABConfig`). */
|
|
1558
|
+
abConfig?: ABConfigFile;
|
|
1559
|
+
diagnostics: Diagnostic[];
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
/** JSON-safe projection of one channel HTTP route on `GET /v1/info`. */
|
|
1563
|
+
export interface AgentChannelRouteInfo {
|
|
1564
|
+
method: RouteMethod;
|
|
1565
|
+
/** Authored path (e.g. `"/findings"`), or the absolute path for built-in http. */
|
|
1566
|
+
path: string;
|
|
1567
|
+
/** Mount path including `/v1/channels/<id>` (or absolute for built-in http). */
|
|
1568
|
+
url: string;
|
|
1569
|
+
description?: string;
|
|
1570
|
+
bodySchema?: JsonSchemaObject;
|
|
1571
|
+
querySchema?: JsonSchemaObject;
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
/** JSON-safe projection of the manifest returned by `GET /v1/info`. */
|
|
1575
|
+
export interface AgentProjectInfo {
|
|
1576
|
+
name: string;
|
|
1577
|
+
model?: ModelSetting;
|
|
1578
|
+
runtime: AgentRuntime;
|
|
1579
|
+
cloud?: AgentCloudPublicInfo;
|
|
1580
|
+
/** Local harness options when authored (`cwd` absolute). */
|
|
1581
|
+
local?: { cwd?: string };
|
|
1582
|
+
/**
|
|
1583
|
+
* The agent's own MCP surface (mounted at `<base>/v1/mcp`): other agents
|
|
1584
|
+
* and MCP clients delegate to this agent through these tools.
|
|
1585
|
+
*/
|
|
1586
|
+
mcp: { path: string; tools: string[] };
|
|
1587
|
+
instructions?: { chars: number; preview: string };
|
|
1588
|
+
tools: Array<{
|
|
1589
|
+
name: string;
|
|
1590
|
+
description: string;
|
|
1591
|
+
execution: ToolExecution;
|
|
1592
|
+
needsApproval: boolean;
|
|
1593
|
+
inputSchema: JsonSchemaObject;
|
|
1594
|
+
}>;
|
|
1595
|
+
skills: Array<{ name: string; description: string }>;
|
|
1596
|
+
connections: Array<{ name: string; transport: string }>;
|
|
1597
|
+
subagents: Array<{
|
|
1598
|
+
name: string;
|
|
1599
|
+
description?: string;
|
|
1600
|
+
model?: ModelSetting;
|
|
1601
|
+
}>;
|
|
1602
|
+
channels: Array<{
|
|
1603
|
+
id: string;
|
|
1604
|
+
routes: AgentChannelRouteInfo[];
|
|
1605
|
+
/** Pack kind when the channel declares one (e.g. `"github"`). */
|
|
1606
|
+
kind?: string;
|
|
1607
|
+
/** GitHub webhook events the channel dispatches on, when declared. */
|
|
1608
|
+
githubWebhookEvents?: readonly string[];
|
|
1609
|
+
/** Slack channels watched for posts (opt-in channel watch), when declared. */
|
|
1610
|
+
slackChannelPosts?: readonly string[];
|
|
1611
|
+
}>;
|
|
1612
|
+
schedules: Array<{ name: string; cron: string; kind: "markdown" | "run" }>;
|
|
1613
|
+
hooks: string[];
|
|
1614
|
+
/** Live A/B experiment names (`defineAB` under `agent/ab`). */
|
|
1615
|
+
abs: string[];
|
|
1616
|
+
/** Playground fold / persistence meta from `agent/ab.config.ts`. */
|
|
1617
|
+
abConfig?: {
|
|
1618
|
+
maxPlaygroundSessions?: number;
|
|
1619
|
+
durableSamples: boolean;
|
|
1620
|
+
durableSnapshots: boolean;
|
|
1621
|
+
};
|
|
1622
|
+
diagnostics: Diagnostic[];
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
// ============================================================================
|
|
1626
|
+
// Runner (the Cursor SDK seam)
|
|
1627
|
+
// ============================================================================
|
|
1628
|
+
|
|
1629
|
+
/**
|
|
1630
|
+
* A streaming update from the harness, re-exported from the Cursor SDK's
|
|
1631
|
+
* delta vocabulary.
|
|
1632
|
+
*/
|
|
1633
|
+
export type RunnerUpdate = InteractionUpdate;
|
|
1634
|
+
|
|
1635
|
+
export interface RunnerSubagent {
|
|
1636
|
+
name: string;
|
|
1637
|
+
description: string;
|
|
1638
|
+
prompt: string;
|
|
1639
|
+
model?: ModelSetting;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
export interface RunnerTurnRequest {
|
|
1643
|
+
sessionId: string;
|
|
1644
|
+
/**
|
|
1645
|
+
* Cursor SDK agent id to create/resume. Defaults to {@link sessionId}
|
|
1646
|
+
* for local agents; cloud agents use the persisted `bc-…` id after
|
|
1647
|
+
* the first turn.
|
|
1648
|
+
*/
|
|
1649
|
+
sdkAgentId?: string;
|
|
1650
|
+
/** Absolute path of the session's materialized workspace. */
|
|
1651
|
+
workspaceDir: string;
|
|
1652
|
+
/** Absolute path for runner-owned durable state (conversation store). */
|
|
1653
|
+
runnerStateDir: string;
|
|
1654
|
+
prompt: string;
|
|
1655
|
+
isFirstTurn: boolean;
|
|
1656
|
+
model?: ModelSetting;
|
|
1657
|
+
runtime: AgentRuntime;
|
|
1658
|
+
/** Cloud options when {@link runtime} is `"cloud"`. */
|
|
1659
|
+
cloud?: AgentCloudOptions;
|
|
1660
|
+
/** In-process tools, already bound to the session's tool context. */
|
|
1661
|
+
customTools: Record<string, SDKCustomTool>;
|
|
1662
|
+
/** MCP servers from `agent/mcp-connections/`. */
|
|
1663
|
+
mcpServers: Record<string, ConnectionTransport>;
|
|
1664
|
+
subagents: RunnerSubagent[];
|
|
1665
|
+
onUpdate: (update: RunnerUpdate) => void | Promise<void>;
|
|
1666
|
+
/** Called once the SDK agent is open so the engine can persist its id. */
|
|
1667
|
+
onSdkAgentId?: (sdkAgentId: string) => void | Promise<void>;
|
|
1668
|
+
/**
|
|
1669
|
+
* Abort the in-flight run when signalled. The engine aborts this when a
|
|
1670
|
+
* follow-up message preempts the current turn; the runner maps it to
|
|
1671
|
+
* `run.cancel()`, which tears down execution and marks the SDK run terminal.
|
|
1672
|
+
*/
|
|
1673
|
+
signal?: AbortSignal;
|
|
1674
|
+
/**
|
|
1675
|
+
* Expire any run still marked active on the SDK agent before starting this
|
|
1676
|
+
* one (local runtime `force`). Set on follow-up turns so a preempted or
|
|
1677
|
+
* crash-wedged run can never block the next send with "already has active
|
|
1678
|
+
* run".
|
|
1679
|
+
*/
|
|
1680
|
+
forceExpireActiveRun?: boolean;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
// ============================================================================
|
|
1684
|
+
// Serving
|
|
1685
|
+
// ============================================================================
|
|
1686
|
+
|
|
1687
|
+
export interface ServeOptions {
|
|
1688
|
+
/** Port to listen on. Defaults to 3000 (0 picks an ephemeral port). */
|
|
1689
|
+
port?: number;
|
|
1690
|
+
/** Host to bind. Defaults to 127.0.0.1. */
|
|
1691
|
+
host?: string;
|
|
1692
|
+
/**
|
|
1693
|
+
* Dev mode: mounts `POST /v1/dev/schedules/:scheduleId` and
|
|
1694
|
+
* `POST /v1/dev/reminders/:reminderId`, and disables the cron / reminder
|
|
1695
|
+
* auto-fire runners (dispatch by hand while iterating).
|
|
1696
|
+
*/
|
|
1697
|
+
dev?: boolean;
|
|
1698
|
+
/** Durable state directory. Defaults to `<rootDir>/.agent-serve`. */
|
|
1699
|
+
stateRoot?: string;
|
|
1700
|
+
/**
|
|
1701
|
+
* Cursor API key for the SDK runner and Cursor account MCP connections.
|
|
1702
|
+
* When omitted, falls back to `CURSOR_API_KEY`, then to the credential
|
|
1703
|
+
* stored by `agent-serve login`.
|
|
1704
|
+
*/
|
|
1705
|
+
apiKey?: string;
|
|
1706
|
+
/** Run schedules on their cron cadence. Defaults to `!dev`. */
|
|
1707
|
+
schedules?: boolean;
|
|
1708
|
+
/**
|
|
1709
|
+
* Arm reminder deadline timers automatically. Defaults to `!dev`
|
|
1710
|
+
* (same as schedules). Prompt-form reminders still persist in `--dev`;
|
|
1711
|
+
* fire them via `POST /v1/dev/reminders/:id` or `handle.dispatchReminder`.
|
|
1712
|
+
*/
|
|
1713
|
+
reminders?: boolean;
|
|
1714
|
+
/**
|
|
1715
|
+
* Serve the bundled web playground at `/playground` (chat, streaming,
|
|
1716
|
+
* tool calls, sessions, schedule dispatch). Defaults to true; the API
|
|
1717
|
+
* routes it drives keep their normal auth chain either way.
|
|
1718
|
+
*/
|
|
1719
|
+
playground?: boolean;
|
|
1720
|
+
/**
|
|
1721
|
+
* Serve the built documentation site at `/docs` ("docs" is a reserved
|
|
1722
|
+
* slug). Defaults to true. The site is auto-built when missing and the
|
|
1723
|
+
* vitepress toolchain is present; published installs ship it prebuilt.
|
|
1724
|
+
*/
|
|
1725
|
+
docs?: boolean;
|
|
1726
|
+
/**
|
|
1727
|
+
* Replace the default `[localDevStrict()]` route auth with
|
|
1728
|
+
* `[bearerAuth(authToken)]` on every channel that doesn't author its own
|
|
1729
|
+
* auth chain. Use when exposing the server beyond loopback (e.g. through
|
|
1730
|
+
* a tunnel, where every request arrives from 127.0.0.1 and loopback-only
|
|
1731
|
+
* policies would admit everyone). Authored `auth` arrays still win.
|
|
1732
|
+
*/
|
|
1733
|
+
authToken?: string;
|
|
1734
|
+
/**
|
|
1735
|
+
* Replace the default loopback-only route auth with `[allowAll()]` on every
|
|
1736
|
+
* channel that doesn't author its own auth chain. For temporary demos behind
|
|
1737
|
+
* a trusted network boundary (e.g. Tailscale) — do not combine with
|
|
1738
|
+
* {@link authToken}. Authored `auth` arrays still win.
|
|
1739
|
+
*/
|
|
1740
|
+
allowAnonymous?: boolean;
|
|
1741
|
+
/**
|
|
1742
|
+
* Public base URL where this server is reachable from outside the host
|
|
1743
|
+
* (e.g. `https://agents.example.com`). Used to resolve peer
|
|
1744
|
+
* connections (`defineConnection({ agent })`) for **cloud-runtime** turns:
|
|
1745
|
+
* a cloud VM cannot reach this host's loopback address, so without a
|
|
1746
|
+
* public URL peer tools are omitted from cloud turns (with a warning).
|
|
1747
|
+
* Local turns always use the loopback URL.
|
|
1748
|
+
*/
|
|
1749
|
+
publicUrl?: string;
|
|
1750
|
+
/**
|
|
1751
|
+
* Pull GitHub webhook metadata from `/v0/scm-events` (Cursor account auth).
|
|
1752
|
+
* The stream is read as the host's Cursor user, so this requires a signed-in
|
|
1753
|
+
* host: `serve` throws when no key resolves from `apiKey` here,
|
|
1754
|
+
* {@link ServeOptions.apiKey}, `CURSOR_API_KEY`, or `agent-serve login`.
|
|
1755
|
+
*/
|
|
1756
|
+
cursorEvents?: {
|
|
1757
|
+
repos: string[];
|
|
1758
|
+
baseUrl?: string;
|
|
1759
|
+
apiKey?: string;
|
|
1760
|
+
};
|
|
1761
|
+
logger?: (line: string) => void;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
/** One agent mounted on a server (its URL slug + compiled project). */
|
|
1765
|
+
export interface MountedAgentInfo {
|
|
1766
|
+
/**
|
|
1767
|
+
* URL slug the agent is mounted under. Empty string in single-agent mode
|
|
1768
|
+
* (routes at `/v1/...`); the directory name in multi-agent mode (routes at
|
|
1769
|
+
* `/<slug>/v1/...`).
|
|
1770
|
+
*/
|
|
1771
|
+
slug: string;
|
|
1772
|
+
project: AgentProject;
|
|
1773
|
+
/** Absolute base URL for this agent (server URL + `/<slug>` when slugged). */
|
|
1774
|
+
url: string;
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
export interface AgentServeHandle {
|
|
1778
|
+
url: string;
|
|
1779
|
+
port: number;
|
|
1780
|
+
/**
|
|
1781
|
+
* The single served agent's project. In multi-agent mode this is the first
|
|
1782
|
+
* mounted agent; use {@link agents} for the full set.
|
|
1783
|
+
*/
|
|
1784
|
+
project: AgentProject;
|
|
1785
|
+
/** Every agent mounted on this server. One entry in single-agent mode. */
|
|
1786
|
+
agents: MountedAgentInfo[];
|
|
1787
|
+
/**
|
|
1788
|
+
* Dispatch a schedule by name. In multi-agent mode pass the agent slug as
|
|
1789
|
+
* the second argument to target a specific agent.
|
|
1790
|
+
*/
|
|
1791
|
+
dispatchSchedule(
|
|
1792
|
+
name: string,
|
|
1793
|
+
slug?: string
|
|
1794
|
+
): Promise<{ sessionIds: string[] }>;
|
|
1795
|
+
/**
|
|
1796
|
+
* Create a per-session reminder. In multi-agent mode pass `slug` in options.
|
|
1797
|
+
*/
|
|
1798
|
+
createReminder(
|
|
1799
|
+
input: ReminderCreateInput,
|
|
1800
|
+
slug?: string
|
|
1801
|
+
): Promise<ReminderInfo>;
|
|
1802
|
+
/** List reminders for an agent. */
|
|
1803
|
+
listReminders(
|
|
1804
|
+
filter?: {
|
|
1805
|
+
status?: ReminderStatus;
|
|
1806
|
+
purpose?: string;
|
|
1807
|
+
continuationToken?: string;
|
|
1808
|
+
},
|
|
1809
|
+
slug?: string
|
|
1810
|
+
): Promise<ReminderInfo[]>;
|
|
1811
|
+
/** Cancel a reminder by id. */
|
|
1812
|
+
cancelReminder(
|
|
1813
|
+
id: string,
|
|
1814
|
+
options?: { reason?: string; slug?: string }
|
|
1815
|
+
): Promise<ReminderInfo | undefined>;
|
|
1816
|
+
/**
|
|
1817
|
+
* Fire a reminder immediately (same path as the deadline timer / dev route).
|
|
1818
|
+
* `outcome` is `"noop"` when the reminder was already firing or not armed.
|
|
1819
|
+
*/
|
|
1820
|
+
dispatchReminder(
|
|
1821
|
+
id: string,
|
|
1822
|
+
slug?: string
|
|
1823
|
+
): Promise<{
|
|
1824
|
+
reminderId: string;
|
|
1825
|
+
outcome: "fired" | "noop";
|
|
1826
|
+
reason?: string;
|
|
1827
|
+
}>;
|
|
1828
|
+
/**
|
|
1829
|
+
* Call an authored server tool deterministically (no model turn). In
|
|
1830
|
+
* multi-agent mode pass the agent slug in the options to target a
|
|
1831
|
+
* specific agent.
|
|
1832
|
+
*/
|
|
1833
|
+
callTool(
|
|
1834
|
+
toolName: string,
|
|
1835
|
+
input?: unknown,
|
|
1836
|
+
options?: CallToolOptions & { slug?: string }
|
|
1837
|
+
): Promise<ToolCallOutcome>;
|
|
1838
|
+
/**
|
|
1839
|
+
* Vite HMR playground URL when `serve --dev` auto-started it (local
|
|
1840
|
+
* checkout with the vite toolchain). Prefer this over the static
|
|
1841
|
+
* `/playground` mount while iterating on the SPA. Multi-agent HMR serves
|
|
1842
|
+
* the agents index at this URL and each SPA at `/<slug>/playground`.
|
|
1843
|
+
*/
|
|
1844
|
+
playgroundDevUrl?: string;
|
|
1845
|
+
/** Where the built documentation site is mounted (`<url>/docs`), when served. */
|
|
1846
|
+
docsUrl?: string;
|
|
1847
|
+
close(): Promise<void>;
|
|
1848
|
+
}
|