@cursor/bdk 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +1 -6
- package/dist/artifacts.d.ts +5 -2
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +5 -2
- package/dist/bin/agent-serve.js +23 -7
- package/dist/channels/github/auth.d.ts.map +1 -1
- package/dist/channels/github/auth.js +36 -5
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +3 -2
- package/dist/channels/slack/types.d.ts +6 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +1 -1
- package/dist/connections.js +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.JVQvbRO-.js → app.BOIHhrKi.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.D5L-b34G.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BkhY63uW.js → VPLocalSearchBox.D49zVZqM.js} +1 -1
- package/dist/docs/assets/chunks/{arc.Cc1unYd3.js → arc.hmjb-sc4.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CAY_TPVz.js → architectureDiagram-Q4EWVU46.CxEI1KqM.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.my2VD3Xm.js → baseUniq.DHHvBWoV.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.CQXAOmqd.js → blockDiagram-DXYQGD6D.DnXW-3bu.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.D0AsQFSX.js → c4Diagram-AHTNJAMY.e-47O2jM.js} +1 -1
- package/dist/docs/assets/chunks/channel.BbOGaJQP.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.DZjhgNls.js → chunk-4BX2VUAB.3ry4pYXB.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.qdcp_qbo.js → chunk-4TB4RGXK.DGIZFRx6.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.BHXoZhJ-.js → chunk-55IACEB6.DKBnqg9U.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.Cds_Vwj3.js → chunk-EDXVE4YY.BIU8Ue5k.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CSl0HknT.js → chunk-FMBD7UC4.DP-TFhjI.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.DJMvAt5N.js → chunk-OYMX7WX6.Ux0OYj5v.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BYQzBK9D.js → chunk-QZHKN3VN.BzHMwYox.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.BAvw7N4o.js → chunk-YZCP3GAM.D4OGAsSP.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Db58HCb1.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Db58HCb1.js +1 -0
- package/dist/docs/assets/chunks/clone.Co4MBflG.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Buf3seya.js → cose-bilkent-S5V4N54A.Jq_7BUNx.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.DMGGa3uA.js → dagre-KV5264BT.Di-skR2x.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.DDjnwRmY.js → diagram-5BDNPKRD.DeREHIdH.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.RwyrIr8Q.js → diagram-G4DWMVQ6.C7Kcqxro.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DRvQV16Z.js → diagram-MMDJMWI5.BK3eohyo.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.Dw8W9BTk.js → diagram-TYMM5635.C6TyymXT.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DQT1Hnwf.js → erDiagram-SMLLAGMA.DYGG-gGx.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.6_Aky-ut.js → flowDiagram-DWJPFMVM.C9nBcSV4.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.DHIwqnqN.js → ganttDiagram-T4ZO3ILL.wAg_ymsp.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CGd_eJbn.js → gitGraphDiagram-UUTBAWPF.B87j9Oeg.js} +1 -1
- package/dist/docs/assets/chunks/{graph.ChMEylkh.js → graph.CuFMj31w.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.Cd4gMyAz.js → infoDiagram-42DDH7IO.P_mLGumP.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.D1uw7MXq.js → ishikawaDiagram-UXIWVN3A.DyuL_MsT.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.AWLXtelc.js → journeyDiagram-VCZTEJTY.CtP09IoJ.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CagPhAn5.js → kanban-definition-6JOO6SKY.BoeSYPZo.js} +1 -1
- package/dist/docs/assets/chunks/{layout.ClTBBkE_.js → layout.B0lMMtNo.js} +1 -1
- package/dist/docs/assets/chunks/{linear.SwS2rOLA.js → linear.HxRBiAFX.js} +1 -1
- package/dist/docs/assets/chunks/{min.By_x-Btb.js → min.BGlFFHwS.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.By_RAMaP.js → mindmap-definition-QFDTVHPH.JyLBD9M8.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DfAl9sy4.js → pieDiagram-DEJITSTG.DnSmNZF8.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CNuqFRBj.js → quadrantDiagram-34T5L4WZ.CUCnbfCa.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DJ5CmTCl.js → requirementDiagram-MS252O5E.py0IVUn5.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.D-T_AKJj.js → sankeyDiagram-XADWPNL6.Bkc-HWYp.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.BRn9WcrR.js → sequenceDiagram-FGHM5R23.Dqn8Mlv2.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.F12urmm7.js → stateDiagram-FHFEXIEX.JikkoQUU.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CMsKhrW0.js +1 -0
- package/dist/docs/assets/chunks/{theme.zK3OJa_C.js → theme.b6HQ6zG_.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.B7GiQBeC.js → timeline-definition-GMOUNBTQ.BvpSXiBj.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.D0niwuY_.js → vennDiagram-DHZGUBPP.CU7MVnZx.js} +1 -1
- package/dist/docs/assets/chunks/{wardley-RL74JXVD.1zhHNRsx.js → wardley-RL74JXVD.BKwC4ctG.js} +1 -1
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.DKaqpT7K.js → wardleyDiagram-NUSXRM2D.BfaF6Uhe.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.e8BPicch.js → xychartDiagram-5P7HB3ND.Bg5dcpj4.js} +1 -1
- package/dist/docs/assets/{deployment.md.nGo1yIsa.js → deployment.md.BJ8i7Q6p.js} +5 -8
- package/dist/docs/assets/{deployment.md.nGo1yIsa.lean.js → deployment.md.BJ8i7Q6p.lean.js} +1 -1
- package/dist/docs/assets/{guides_github.md.C2_DSWlE.js → guides_github.md.Bq9kQU9B.js} +9 -3
- package/dist/docs/assets/{guides_github.md.C2_DSWlE.lean.js → guides_github.md.Bq9kQU9B.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.ZbHQETOT.js → guides_slack.md.diqqXTTm.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.ZbHQETOT.lean.js → guides_slack.md.diqqXTTm.lean.js} +1 -1
- package/dist/docs/assets/{quickstart.md.wG4shE1f.js → quickstart.md.CHpHPBUN.js} +5 -3
- package/dist/docs/assets/{quickstart.md.wG4shE1f.lean.js → quickstart.md.CHpHPBUN.lean.js} +1 -1
- package/dist/docs/assets/{reference_artifacts.md.IFFC5Zln.js → reference_artifacts.md.CQfKq8F2.js} +1 -1
- package/dist/docs/assets/reference_cli.md.DgeLTO18.js +91 -0
- package/dist/docs/assets/reference_cli.md.DgeLTO18.lean.js +1 -0
- package/dist/docs/assets/{reference_connections.md._XpKiOaF.js → reference_connections.md.COq--gAm.js} +7 -3
- package/dist/docs/assets/{reference_connections.md._XpKiOaF.lean.js → reference_connections.md.COq--gAm.lean.js} +1 -1
- package/dist/docs/assets/{reference_evals.md.DqNyHMA6.js → reference_evals.md.CJm3uCUm.js} +4 -4
- package/dist/docs/assets/{reference_evals.md.DqNyHMA6.lean.js → reference_evals.md.CJm3uCUm.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.Dg3dEugd.js → reference_hooks.md.DbthhtIR.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.BtpTjZmh.js → reference_sessions.md.DeRUItHD.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.Cw5PKa3t.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.BzZSu1Gz.lean.js → troubleshooting.md.Cw5PKa3t.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +35 -35
- package/dist/docs/deployment.html +40 -43
- package/dist/docs/deployment.md +45 -15
- package/dist/docs/evals.html +35 -35
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +35 -35
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/github.html +43 -37
- package/dist/docs/guides/github.md +34 -0
- package/dist/docs/guides/gitlab.html +35 -35
- package/dist/docs/guides/grokbot-agents.html +35 -35
- package/dist/docs/guides/hooks.html +35 -35
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +35 -35
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/opentelemetry.html +35 -35
- package/dist/docs/guides/slack.html +37 -37
- package/dist/docs/guides/slack.md +5 -0
- package/dist/docs/guides/webhooks.html +35 -35
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +35 -35
- package/dist/docs/index.html +35 -35
- package/dist/docs/llms-full.txt +205 -97
- package/dist/docs/quickstart.html +40 -38
- package/dist/docs/quickstart.md +7 -1
- package/dist/docs/reference/agent-config.html +35 -35
- package/dist/docs/reference/artifacts.html +37 -37
- package/dist/docs/reference/artifacts.md +1 -1
- package/dist/docs/reference/channels.html +35 -35
- package/dist/docs/reference/cli.html +55 -61
- package/dist/docs/reference/cli.md +65 -63
- package/dist/docs/reference/connections.html +42 -38
- package/dist/docs/reference/connections.md +28 -2
- package/dist/docs/reference/evals.html +39 -39
- package/dist/docs/reference/evals.md +6 -7
- package/dist/docs/reference/extensions.html +35 -35
- package/dist/docs/reference/hooks.html +37 -37
- package/dist/docs/reference/hooks.md +3 -2
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +35 -35
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +36 -36
- package/dist/docs/reference/sessions.md +4 -3
- package/dist/docs/reference/skills.html +35 -35
- package/dist/docs/reference/subagents.html +35 -35
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/docs/troubleshooting.md +7 -3
- package/dist/extensions/cursor-cloud-agents/extension.d.ts +16 -4
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/extension.js +7 -3
- package/dist/extensions/cursor-cloud-agents/lib/channels.d.ts +3 -0
- package/dist/extensions/cursor-cloud-agents/lib/channels.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/channels.js +7 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts +4 -2
- package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +21 -12
- package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/cancel.js +2 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +3 -1
- package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/reply.js +2 -0
- package/dist/extensions/cursor-grokbot-agents/extension.d.ts +77 -0
- package/dist/extensions/cursor-grokbot-agents/extension.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/extension.js +63 -0
- package/dist/extensions/cursor-grokbot-agents/lib/agents.d.ts +11 -0
- package/dist/extensions/cursor-grokbot-agents/lib/agents.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/agents.js +31 -0
- package/dist/extensions/cursor-grokbot-agents/lib/backend.d.ts +56 -0
- package/dist/extensions/cursor-grokbot-agents/lib/backend.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/backend.js +158 -0
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.d.ts +28 -0
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +59 -0
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.d.ts +53 -0
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +206 -0
- package/dist/extensions/cursor-grokbot-agents/lib/inputs.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/lib/inputs.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/inputs.js +15 -0
- package/dist/extensions/cursor-grokbot-agents/lib/lock.d.ts +12 -0
- package/dist/extensions/cursor-grokbot-agents/lib/lock.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/lib/lock.js +25 -0
- package/dist/extensions/cursor-grokbot-agents/skills/consult.md +40 -0
- package/dist/extensions/cursor-grokbot-agents/tools/ask.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/ask.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/ask.js +37 -0
- package/dist/extensions/cursor-grokbot-agents/tools/check.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/check.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/check.js +32 -0
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.js +24 -0
- package/dist/extensions/cursor-grokbot-agents/tools/list.d.ts +4 -0
- package/dist/extensions/cursor-grokbot-agents/tools/list.d.ts.map +1 -0
- package/dist/extensions/cursor-grokbot-agents/tools/list.js +34 -0
- package/dist/files-backends/cursor-hosted.js +4 -4
- package/dist/internal/artifacts-store.d.ts +12 -2
- package/dist/internal/artifacts-store.d.ts.map +1 -1
- package/dist/internal/artifacts-store.js +8 -4
- package/dist/internal/cli-ax.d.ts +1 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +43 -10
- package/dist/internal/cli-deploy.d.ts +5 -1
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +22 -4
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +2 -1
- package/dist/internal/cli-skills.d.ts +1 -1
- package/dist/internal/cli-skills.d.ts.map +1 -1
- package/dist/internal/cli-skills.js +5 -5
- package/dist/internal/connection-env.d.ts +31 -0
- package/dist/internal/connection-env.d.ts.map +1 -0
- package/dist/internal/connection-env.js +84 -0
- package/dist/internal/cursor/backend-client.js +5 -0
- package/dist/internal/deploy-client.d.ts +30 -6
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +45 -9
- package/dist/internal/discovery/connections.d.ts.map +1 -1
- package/dist/internal/discovery/connections.js +11 -0
- package/dist/internal/event-mapper.d.ts +46 -4
- package/dist/internal/event-mapper.d.ts.map +1 -1
- package/dist/internal/event-mapper.js +316 -25
- package/dist/internal/hosted-delivery-protocol.d.ts +36 -11
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +31 -8
- package/dist/internal/hosted-delivery.d.ts +2 -2
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +229 -49
- package/dist/internal/hosting.d.ts +2 -2
- package/dist/internal/hosting.d.ts.map +1 -1
- package/dist/internal/hosting.js +9 -3
- package/dist/internal/install-cursor-skills.d.ts +20 -24
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +50 -48
- package/dist/internal/legacy-command-guard.d.ts +2 -0
- package/dist/internal/legacy-command-guard.d.ts.map +1 -1
- package/dist/internal/legacy-command-guard.js +10 -1
- package/dist/internal/mcp-host.d.ts +6 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +35 -16
- package/dist/internal/sdk-runner.d.ts +2 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +10 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +11 -1
- package/dist/internal/session-engine.d.ts +1 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +33 -8
- package/dist/playground/assets/index-6BbTPnaT.css +1 -0
- package/dist/playground/assets/{index-FFdUqTt_.js → index-CI7FAmOP.js} +43 -43
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +50 -4
- package/dist/types.d.ts.map +1 -1
- package/docs/deployment.md +45 -15
- package/docs/guides/github.md +34 -0
- package/docs/guides/slack.md +5 -0
- package/docs/quickstart.md +7 -1
- package/docs/reference/artifacts.md +1 -1
- package/docs/reference/cli.md +65 -63
- package/docs/reference/connections.md +28 -2
- package/docs/reference/evals.md +6 -7
- package/docs/reference/hooks.md +3 -2
- package/docs/reference/sessions.md +4 -3
- package/docs/troubleshooting.md +7 -3
- package/package.json +2 -4
- package/scripts/install-cursor-skills.mjs +1 -1
- package/skills/create-agent/SKILL.md +1 -1
- package/skills/debug/SKILL.md +1 -1
- package/skills/deploy/SKILL.md +1 -1
- package/skills/evals/SKILL.md +1 -1
- package/skills/framework-map/SKILL.md +1 -1
- package/skills/github/SKILL.md +1 -1
- package/skills/hillclimb/SKILL.md +1 -1
- package/skills/mcp-auth/SKILL.md +1 -1
- package/skills/otel/SKILL.md +1 -1
- package/skills/setup-slack/SKILL.md +1 -1
- package/src/artifacts.ts +5 -2
- package/src/bin/agent-serve.ts +27 -6
- package/src/channels/github/auth.ts +44 -5
- package/src/channels/slack/manifest.ts +2 -1
- package/src/channels/slack/types.ts +6 -1
- package/src/connections.ts +1 -1
- package/src/extensions/cursor-cloud-agents/extension.ts +23 -6
- package/src/extensions/cursor-cloud-agents/lib/channels.ts +11 -0
- package/src/extensions/cursor-cloud-agents/lib/repos.ts +19 -7
- package/src/extensions/cursor-cloud-agents/tools/cancel.ts +2 -0
- package/src/extensions/cursor-cloud-agents/tools/launch.ts +3 -1
- package/src/extensions/cursor-cloud-agents/tools/reply.ts +2 -0
- package/src/extensions/cursor-grokbot-agents/extension.ts +132 -0
- package/src/extensions/cursor-grokbot-agents/lib/agents.ts +42 -0
- package/src/extensions/cursor-grokbot-agents/lib/backend.ts +208 -0
- package/src/extensions/cursor-grokbot-agents/lib/contacts.ts +74 -0
- package/src/extensions/cursor-grokbot-agents/lib/conversation.ts +260 -0
- package/src/extensions/cursor-grokbot-agents/lib/inputs.ts +21 -0
- package/src/extensions/cursor-grokbot-agents/lib/lock.ts +26 -0
- package/src/extensions/cursor-grokbot-agents/skills/consult.md +40 -0
- package/src/extensions/cursor-grokbot-agents/tools/ask.ts +32 -0
- package/src/extensions/cursor-grokbot-agents/tools/check.ts +25 -0
- package/src/extensions/cursor-grokbot-agents/tools/interrupt.ts +17 -0
- package/src/extensions/cursor-grokbot-agents/tools/list.ts +26 -0
- package/src/files-backends/cursor-hosted.ts +4 -4
- package/src/internal/artifacts-store.ts +14 -3
- package/src/internal/cli-ax.ts +52 -7
- package/src/internal/cli-deploy.ts +39 -6
- package/src/internal/cli-mcp-oauth.ts +2 -1
- package/src/internal/cli-skills.ts +4 -5
- package/src/internal/connection-env.ts +106 -0
- package/src/internal/cursor/backend-client.ts +6 -0
- package/src/internal/deploy-client.ts +79 -9
- package/src/internal/discovery/connections.ts +11 -0
- package/src/internal/event-mapper.ts +367 -36
- package/src/internal/hosted-delivery-protocol.ts +57 -20
- package/src/internal/hosted-delivery.ts +487 -229
- package/src/internal/hosting.ts +10 -3
- package/src/internal/install-cursor-skills.ts +56 -53
- package/src/internal/legacy-command-guard.ts +13 -1
- package/src/internal/mcp-host.ts +45 -17
- package/src/internal/sdk-runner.ts +11 -0
- package/src/internal/server.ts +13 -1
- package/src/internal/session-engine.ts +33 -13
- package/src/types.ts +56 -5
- package/templates/agents-md/bot/lib/collect.ts +1 -4
- package/templates/code-wiki/bot/channels/github.ts +2 -2
- package/templates/demo/bot/channels/github.ts +5 -1
- package/templates/pr-autofixer/bot/lib/start-drive.ts +4 -4
- package/templates/triage/bot/lib/types.ts +6 -6
- package/dist/docs/assets/chunks/@localSearchIndexroot.Caw9W1pM.js +0 -1
- package/dist/docs/assets/chunks/channel.Sapo9HJZ.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.NPiy3Hz7.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.NPiy3Hz7.js +0 -1
- package/dist/docs/assets/chunks/clone.zl2qolPE.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2._auCa3fR.js +0 -1
- package/dist/docs/assets/reference_cli.md.BK2QUH67.js +0 -97
- package/dist/docs/assets/reference_cli.md.BK2QUH67.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.BzZSu1Gz.js +0 -1
- package/dist/playground/assets/index-BMV_IcEE.css +0 -1
- /package/dist/docs/assets/{reference_artifacts.md.IFFC5Zln.lean.js → reference_artifacts.md.CQfKq8F2.lean.js} +0 -0
- /package/dist/docs/assets/{reference_hooks.md.Dg3dEugd.lean.js → reference_hooks.md.DbthhtIR.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.BtpTjZmh.lean.js → reference_sessions.md.DeRUItHD.lean.js} +0 -0
package/src/internal/hosting.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* locally with the same grammar the server enforces.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
/** `hosting.egressDomains` cap (
|
|
11
|
-
export const MAX_EGRESS_DOMAINS =
|
|
10
|
+
/** `hosting.egressDomains` cap (the manifest schema and deploy body agree). */
|
|
11
|
+
export const MAX_EGRESS_DOMAINS = 64;
|
|
12
12
|
/** Max secrets per deployment. */
|
|
13
13
|
export const MAX_SECRETS = 32;
|
|
14
14
|
/** Max secret value size in bytes. */
|
|
@@ -46,12 +46,19 @@ const SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
|
46
46
|
// leading `*.` wildcard. Labels: alphanumeric with interior hyphens.
|
|
47
47
|
const EGRESS_DOMAIN_PATTERN = /^(\*\.)?([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]+$/;
|
|
48
48
|
|
|
49
|
+
/** `host:port` asks for raw TCP egress; a wildcard host has no address to open. */
|
|
50
|
+
const EGRESS_TCP_PATTERN = /^([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]+:([1-9]\d{0,4})$/;
|
|
51
|
+
|
|
49
52
|
/** Returns a human error message, or undefined when the domain is valid. */
|
|
50
53
|
export function validateEgressDomain(domain: string): string | undefined {
|
|
51
54
|
if (EGRESS_DOMAIN_PATTERN.test(domain)) {
|
|
52
55
|
return undefined;
|
|
53
56
|
}
|
|
54
|
-
|
|
57
|
+
const tcp = EGRESS_TCP_PATTERN.exec(domain);
|
|
58
|
+
if (tcp !== null && Number(tcp[3]) <= 65535) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
return `Invalid egress domain ${JSON.stringify(domain)}: use a lowercase hostname with at least two labels and an alphabetic TLD (e.g. "api.example.com"), optionally with a single leading "*." wildcard or a trailing ":port" for raw TCP.`;
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Offer to install the package's coding-agent skills into the user's
|
|
3
|
-
* personal Cursor skills dir under `~/.cursor/skills/
|
|
3
|
+
* personal Cursor skills dir under `~/.cursor/skills/bdk/<skill>/`.
|
|
4
4
|
*
|
|
5
|
-
* Cursor walks `~/.cursor/skills` recursively, so the `
|
|
5
|
+
* Cursor walks `~/.cursor/skills` recursively, so the `bdk/` folder is
|
|
6
6
|
* only organizational — identity comes from the leaf folder that holds
|
|
7
7
|
* SKILL.md. Installed copies get `alwaysApply: true` so Cursor injects the
|
|
8
8
|
* skill body as a global rule instead of leaving it as an on-demand catalog
|
|
@@ -22,10 +22,13 @@ import { parseFrontmatter } from "./frontmatter.js";
|
|
|
22
22
|
import { stdoutPalette } from "./terminal-style.js";
|
|
23
23
|
|
|
24
24
|
/** Category folder under ~/.cursor/skills (Cursor discovers nested skills). */
|
|
25
|
-
export const CURSOR_SKILLS_NAMESPACE = "
|
|
25
|
+
export const CURSOR_SKILLS_NAMESPACE = "bdk";
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Earlier install folders. Deleted on install so stale skill ids stop
|
|
29
|
+
* being discovered next to the current copies.
|
|
30
|
+
*/
|
|
31
|
+
const LEGACY_CURSOR_SKILLS_NAMESPACES = ["agentsdk", "agentkit"] as const;
|
|
29
32
|
|
|
30
33
|
/** How long the `init` offer waits for an answer before skipping the install. */
|
|
31
34
|
export const SKILL_PROMPT_TIMEOUT_MS = 45_000;
|
|
@@ -40,9 +43,9 @@ export const CURSOR_JULY_SKILLS_HOME_ENV = "CURSOR_JULY_SKILLS_HOME";
|
|
|
40
43
|
export const CURSOR_JULY_SKIP_SKILL_INSTALL_ENV = "CURSOR_JULY_SKIP_SKILL_INSTALL";
|
|
41
44
|
|
|
42
45
|
export interface PackageSkill {
|
|
43
|
-
/** Frontmatter `name` (e.g.
|
|
46
|
+
/** Frontmatter `name` (e.g. bdk-create-agent). */
|
|
44
47
|
name: string;
|
|
45
|
-
/** Leaf install directory under
|
|
48
|
+
/** Leaf install directory under bdk/ (e.g. create-agent). */
|
|
46
49
|
leafDir: string;
|
|
47
50
|
/** Absolute path to the source skill directory in the package. */
|
|
48
51
|
sourceDir: string;
|
|
@@ -71,27 +74,26 @@ export function isConsumerPackageInstall(packageRoot: string): boolean {
|
|
|
71
74
|
return packageRoot.split(/[\\/]/).includes("node_modules");
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
/** `~/.cursor/skills/
|
|
75
|
-
export function
|
|
77
|
+
/** `~/.cursor/skills/bdk` — where package skills are installed. */
|
|
78
|
+
export function bdkCursorSkillsDir(skillsHome: string = cursorSkillsHome()): string {
|
|
76
79
|
return join(skillsHome, CURSOR_SKILLS_NAMESPACE);
|
|
77
80
|
}
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return join(skillsHome, LEGACY_CURSOR_SKILLS_NAMESPACE);
|
|
82
|
+
function legacyCursorSkillsDirs(skillsHome: string): string[] {
|
|
83
|
+
return LEGACY_CURSOR_SKILLS_NAMESPACES.map(name => join(skillsHome, name));
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
/** Absolute install path for one skill: `…/
|
|
86
|
+
/** Absolute install path for one skill: `…/bdk/<leafDir>`. */
|
|
85
87
|
export function skillInstallPath(
|
|
86
88
|
skill: Pick<PackageSkill, "leafDir">,
|
|
87
89
|
skillsHome: string = cursorSkillsHome(),
|
|
88
90
|
): string {
|
|
89
|
-
return join(
|
|
91
|
+
return join(bdkCursorSkillsDir(skillsHome), skill.leafDir);
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
/**
|
|
93
95
|
* Skills shipped next to the running package. Uses the frontmatter `name`
|
|
94
|
-
* when present, otherwise `
|
|
96
|
+
* when present, otherwise `bdk-<dir>`.
|
|
95
97
|
*/
|
|
96
98
|
export async function listShippedPackageSkills(
|
|
97
99
|
packageRoot: string = packageRootDir(),
|
|
@@ -137,7 +139,7 @@ async function readPackageVersion(packageRoot: string): Promise<string> {
|
|
|
137
139
|
}
|
|
138
140
|
|
|
139
141
|
/**
|
|
140
|
-
* Skills that do not yet have a SKILL.md under ~/.cursor/skills/
|
|
142
|
+
* Skills that do not yet have a SKILL.md under ~/.cursor/skills/bdk/.
|
|
141
143
|
* Install still overwrites every shipped skill when the user confirms — this
|
|
142
144
|
* helper is for messaging (fresh install vs update).
|
|
143
145
|
*/
|
|
@@ -163,22 +165,22 @@ export interface SkillInstallResult {
|
|
|
163
165
|
installed: string[];
|
|
164
166
|
/** Leaf dirs deleted because the package no longer ships them. */
|
|
165
167
|
removed: string[];
|
|
166
|
-
/**
|
|
167
|
-
|
|
168
|
+
/** Leftover namespace dirs deleted (`…/agentsdk`, `…/agentkit`). */
|
|
169
|
+
removedLegacyDirs: string[];
|
|
168
170
|
}
|
|
169
171
|
|
|
170
172
|
/**
|
|
171
|
-
* Copy each skill directory into `skillsHome/
|
|
173
|
+
* Copy each skill directory into `skillsHome/bdk/<leafDir>/`.
|
|
172
174
|
* Always overwrites so a package upgrade refreshes local Cursor skills.
|
|
173
175
|
* Strips monorepo-only frontmatter, sets `alwaysApply: true` so Cursor
|
|
174
176
|
* loads the body into context, and removes leaf dirs no longer shipped.
|
|
175
|
-
* Also deletes leftover `skillsHome/
|
|
177
|
+
* Also deletes leftover `skillsHome/agentsdk/` and `skillsHome/agentkit/`.
|
|
176
178
|
*/
|
|
177
179
|
export async function installCursorSkills(
|
|
178
180
|
skills: readonly PackageSkill[],
|
|
179
181
|
skillsHome: string = cursorSkillsHome(),
|
|
180
182
|
): Promise<SkillInstallResult> {
|
|
181
|
-
const namespaceDir =
|
|
183
|
+
const namespaceDir = bdkCursorSkillsDir(skillsHome);
|
|
182
184
|
await mkdir(namespaceDir, { recursive: true });
|
|
183
185
|
|
|
184
186
|
const removed = await orphanLeaves(namespaceDir, skills);
|
|
@@ -203,8 +205,8 @@ export async function installCursorSkills(
|
|
|
203
205
|
}
|
|
204
206
|
installed.push(skill.leafDir);
|
|
205
207
|
}
|
|
206
|
-
const
|
|
207
|
-
return { installed, removed,
|
|
208
|
+
const removedLegacyDirs = await removeLegacyCursorSkillsNamespaces(skillsHome);
|
|
209
|
+
return { installed, removed, removedLegacyDirs };
|
|
208
210
|
}
|
|
209
211
|
|
|
210
212
|
async function makeTreeWritable(root: string): Promise<void> {
|
|
@@ -245,25 +247,26 @@ async function orphanLeaves(
|
|
|
245
247
|
.map(entry => entry.name);
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
/** Drop leftover
|
|
249
|
-
async function
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
await
|
|
253
|
-
} catch {
|
|
254
|
-
return false;
|
|
250
|
+
/** Drop leftover earlier install folders so stale skill ids are not discovered. */
|
|
251
|
+
async function removeLegacyCursorSkillsNamespaces(skillsHome: string): Promise<string[]> {
|
|
252
|
+
const present = await existingLegacyCursorSkillsDirs(skillsHome);
|
|
253
|
+
for (const dir of present) {
|
|
254
|
+
await rm(dir, { recursive: true, force: true });
|
|
255
255
|
}
|
|
256
|
-
|
|
257
|
-
return true;
|
|
256
|
+
return present;
|
|
258
257
|
}
|
|
259
258
|
|
|
260
|
-
async function
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
259
|
+
async function existingLegacyCursorSkillsDirs(skillsHome: string): Promise<string[]> {
|
|
260
|
+
const present: string[] = [];
|
|
261
|
+
for (const dir of legacyCursorSkillsDirs(skillsHome)) {
|
|
262
|
+
try {
|
|
263
|
+
await stat(dir);
|
|
264
|
+
present.push(dir);
|
|
265
|
+
} catch {
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
266
268
|
}
|
|
269
|
+
return present;
|
|
267
270
|
}
|
|
268
271
|
|
|
269
272
|
/**
|
|
@@ -289,7 +292,7 @@ export function prepareSkillMarkdownForCursorInstall(
|
|
|
289
292
|
adjustedBody.includes(PACKAGE_VERSION_PLACEHOLDER) &&
|
|
290
293
|
(packageVersion === undefined || packageVersion.trim() === "")
|
|
291
294
|
) {
|
|
292
|
-
throw new Error("Cannot install
|
|
295
|
+
throw new Error("Cannot install a BDK skill without a package version.");
|
|
293
296
|
}
|
|
294
297
|
const versionBoundBody =
|
|
295
298
|
packageVersion === undefined
|
|
@@ -333,7 +336,7 @@ export interface SkillInstallPlan {
|
|
|
333
336
|
shipped: PackageSkill[];
|
|
334
337
|
/** Resolved `~/.cursor/skills`, to install into. */
|
|
335
338
|
skillsHome: string;
|
|
336
|
-
/** Install target: `<skillsHome>/
|
|
339
|
+
/** Install target: `<skillsHome>/bdk`. */
|
|
337
340
|
directory: string;
|
|
338
341
|
/** Leaf dirs the package ships. */
|
|
339
342
|
leaves: string[];
|
|
@@ -341,8 +344,8 @@ export interface SkillInstallPlan {
|
|
|
341
344
|
firstInstall: boolean;
|
|
342
345
|
/** Installed leaf dirs the package dropped; installing deletes them. */
|
|
343
346
|
orphans: string[];
|
|
344
|
-
/**
|
|
345
|
-
|
|
347
|
+
/** Leftover namespace dirs that still exist. Installing deletes them. */
|
|
348
|
+
legacyDirs: string[];
|
|
346
349
|
}
|
|
347
350
|
|
|
348
351
|
/** What an install would do, for the offer and for `install-skills`. */
|
|
@@ -351,7 +354,7 @@ export async function planSkillInstall(options?: {
|
|
|
351
354
|
skillsHome?: string;
|
|
352
355
|
}): Promise<SkillInstallPlan> {
|
|
353
356
|
const skillsHome = options?.skillsHome ?? cursorSkillsHome();
|
|
354
|
-
const directory =
|
|
357
|
+
const directory = bdkCursorSkillsDir(skillsHome);
|
|
355
358
|
const shipped = await listShippedPackageSkills(options?.packageRoot);
|
|
356
359
|
const present = await Promise.all(
|
|
357
360
|
shipped.map(async skill => {
|
|
@@ -370,20 +373,20 @@ export async function planSkillInstall(options?: {
|
|
|
370
373
|
leaves: shipped.map(skill => skill.leafDir),
|
|
371
374
|
firstInstall: present.every(isPresent => !isPresent),
|
|
372
375
|
orphans: await orphanLeaves(directory, shipped),
|
|
373
|
-
|
|
376
|
+
legacyDirs: await existingLegacyCursorSkillsDirs(skillsHome),
|
|
374
377
|
};
|
|
375
378
|
}
|
|
376
379
|
|
|
377
|
-
/** `Installed 9
|
|
380
|
+
/** `Installed 9 BDK skills`, what it dropped, and where it went. */
|
|
378
381
|
export function formatSkillInstall(plan: SkillInstallPlan, result: SkillInstallResult): string {
|
|
379
382
|
const noun = result.installed.length === 1 ? "skill" : "skills";
|
|
380
383
|
const verb = plan.firstInstall ? "Installed" : "Updated";
|
|
381
|
-
const lines = [`${verb} ${result.installed.length}
|
|
384
|
+
const lines = [`${verb} ${result.installed.length} BDK ${noun}`];
|
|
382
385
|
if (result.removed.length > 0) {
|
|
383
386
|
lines.push(` removed: ${result.removed.join(", ")}`);
|
|
384
387
|
}
|
|
385
|
-
|
|
386
|
-
lines.push(` removed: ${
|
|
388
|
+
for (const dir of result.removedLegacyDirs) {
|
|
389
|
+
lines.push(` removed: ${dir}`);
|
|
387
390
|
}
|
|
388
391
|
lines.push(` location: ${plan.directory}`);
|
|
389
392
|
return `${lines.join("\n")}\n`;
|
|
@@ -406,7 +409,7 @@ export interface SyncCursorSkillsOnPackageInstallOptions {
|
|
|
406
409
|
}
|
|
407
410
|
|
|
408
411
|
/**
|
|
409
|
-
* Copy shipped coding-agent skills into ~/.cursor/skills/
|
|
412
|
+
* Copy shipped coding-agent skills into ~/.cursor/skills/bdk during a
|
|
410
413
|
* consumer `npm install` / `npx`. Never throws: a failed copy must not fail
|
|
411
414
|
* the package install. No-op in the monorepo source tree and when
|
|
412
415
|
* `CURSOR_JULY_SKIP_SKILL_INSTALL=1`.
|
|
@@ -459,7 +462,7 @@ export interface OfferInstallCursorSkillsOptions {
|
|
|
459
462
|
|
|
460
463
|
/**
|
|
461
464
|
* On a TTY, offer to install/update every shipped package skill into
|
|
462
|
-
* ~/.cursor/skills/
|
|
465
|
+
* ~/.cursor/skills/bdk (always overwriting). No-op when non-interactive
|
|
463
466
|
* or the package ships no skills. An unanswered prompt skips the install
|
|
464
467
|
* rather than blocking the caller — see `SKILL_PROMPT_TIMEOUT_MS`.
|
|
465
468
|
*/
|
|
@@ -484,7 +487,7 @@ export async function offerInstallCursorSkills(
|
|
|
484
487
|
const noun = plan.shipped.length === 1 ? "skill" : "skills";
|
|
485
488
|
const verb = plan.firstInstall ? "Install" : "Update";
|
|
486
489
|
const c = stdoutPalette();
|
|
487
|
-
out(`${verb} ${plan.shipped.length}
|
|
490
|
+
out(`${verb} ${plan.shipped.length} BDK ${noun} in ${plan.directory}?\n`);
|
|
488
491
|
out(c.dim(` ${plan.leaves.join(", ")}\n`));
|
|
489
492
|
if (!plan.firstInstall) {
|
|
490
493
|
out(c.dim(" (overwrites existing copies with the package version)\n"));
|
|
@@ -492,8 +495,8 @@ export async function offerInstallCursorSkills(
|
|
|
492
495
|
if (plan.orphans.length > 0) {
|
|
493
496
|
out(c.dim(` (deletes ${plan.orphans.join(", ")})\n`));
|
|
494
497
|
}
|
|
495
|
-
|
|
496
|
-
out(c.dim(` (deletes leftover ${
|
|
498
|
+
for (const dir of plan.legacyDirs) {
|
|
499
|
+
out(c.dim(` (deletes leftover ${dir})\n`));
|
|
497
500
|
}
|
|
498
501
|
|
|
499
502
|
const confirm =
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type AgentServeDeployClient, DeployApiError } from "./deploy-client.js";
|
|
2
|
+
import { CLI_COMMAND_NAME } from "./distribution.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Classify a hosted slug by probing the v2 control plane.
|
|
@@ -27,9 +28,20 @@ export async function deploymentArchitecture(args: {
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
/** `run --prod` returns a delivery; read the session after it is allocated. */
|
|
32
|
+
export function v2HostedVerifyHint(slug = "<slug>"): string {
|
|
33
|
+
return (
|
|
34
|
+
`\`${CLI_COMMAND_NAME} run --prod\` returns a delivery. ` +
|
|
35
|
+
`An accept without sessionId is expected. ` +
|
|
36
|
+
`Poll the delivery until the session is allocated, then ` +
|
|
37
|
+
`\`${CLI_COMMAND_NAME} session <ses_> --prod --slug ${slug}\`.`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
30
41
|
export function unsupportedV2LegacyCommandError(slug: string): DeployApiError {
|
|
31
42
|
return new DeployApiError(
|
|
32
|
-
`This command is not supported for architecture v2 deployment "${slug}".
|
|
43
|
+
`This command is not supported for architecture v2 deployment "${slug}". ` +
|
|
44
|
+
`call and sessions stay on the v1 API. ${v2HostedVerifyHint(slug)}`,
|
|
33
45
|
409,
|
|
34
46
|
);
|
|
35
47
|
}
|
package/src/internal/mcp-host.ts
CHANGED
|
@@ -24,6 +24,10 @@ import {
|
|
|
24
24
|
type JsonObject,
|
|
25
25
|
type McpToolAnnotations,
|
|
26
26
|
} from "../types.js";
|
|
27
|
+
import {
|
|
28
|
+
connectionCredentialsFingerprint,
|
|
29
|
+
resolveConnectionEnvTemplates,
|
|
30
|
+
} from "./connection-env.js";
|
|
27
31
|
import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
|
|
28
32
|
import { createHostMcpOAuthProvider } from "./mcp-oauth.js";
|
|
29
33
|
import { instrumentedMcpFetch, mcpTraceMeta, runMcpClientSpan } from "./otel/mcp.js";
|
|
@@ -67,6 +71,12 @@ interface OpenedConnection {
|
|
|
67
71
|
close: () => Promise<void>;
|
|
68
72
|
}
|
|
69
73
|
|
|
74
|
+
interface CachedClient {
|
|
75
|
+
/** Fingerprint of the credentials this client opened with. */
|
|
76
|
+
credentials: string;
|
|
77
|
+
opened: Promise<OpenedConnection>;
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
/**
|
|
71
81
|
* A non-caching view of one connection: every operation opens a fresh
|
|
72
82
|
* client and closes it afterwards. See {@link McpHost.oneOff}.
|
|
@@ -78,7 +88,7 @@ export interface HostMcpOneOff {
|
|
|
78
88
|
|
|
79
89
|
export class McpHost implements HostMcpRegistry {
|
|
80
90
|
private readonly byName = new Map<string, DiscoveredConnection>();
|
|
81
|
-
private readonly clients = new Map<string,
|
|
91
|
+
private readonly clients = new Map<string, CachedClient>();
|
|
82
92
|
private oauthRedirectUrl: string | undefined;
|
|
83
93
|
|
|
84
94
|
constructor(connections: DiscoveredConnection[]) {
|
|
@@ -187,20 +197,20 @@ export class McpHost implements HostMcpRegistry {
|
|
|
187
197
|
}
|
|
188
198
|
|
|
189
199
|
async dropClient(name: string): Promise<void> {
|
|
190
|
-
const
|
|
200
|
+
const cached = this.clients.get(name);
|
|
191
201
|
this.clients.delete(name);
|
|
192
|
-
if (
|
|
202
|
+
if (cached === undefined) {
|
|
193
203
|
return;
|
|
194
204
|
}
|
|
195
205
|
try {
|
|
196
|
-
await (await
|
|
206
|
+
await (await cached.opened).close();
|
|
197
207
|
} catch {
|
|
198
208
|
// Best-effort teardown.
|
|
199
209
|
}
|
|
200
210
|
}
|
|
201
211
|
|
|
202
212
|
async close(): Promise<void> {
|
|
203
|
-
const opened = await Promise.allSettled([...this.clients.values()]);
|
|
213
|
+
const opened = await Promise.allSettled([...this.clients.values()].map(entry => entry.opened));
|
|
204
214
|
this.clients.clear();
|
|
205
215
|
await Promise.allSettled(
|
|
206
216
|
opened.map(async settled => {
|
|
@@ -234,23 +244,41 @@ export class McpHost implements HostMcpRegistry {
|
|
|
234
244
|
}
|
|
235
245
|
}
|
|
236
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Cached per connection, but only for as long as the credentials it opened
|
|
249
|
+
* with still apply: a hosted deployment binds its secrets per request, so a
|
|
250
|
+
* rotated (or first-ever) value would otherwise never reach a client opened
|
|
251
|
+
* on an earlier turn.
|
|
252
|
+
*/
|
|
237
253
|
private getClient(name: string): Promise<OpenedConnection> {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
this.
|
|
254
|
+
const credentials = connectionCredentialsFingerprint(this.requireConnection(name).transport);
|
|
255
|
+
const cached = this.clients.get(name);
|
|
256
|
+
if (cached !== undefined) {
|
|
257
|
+
if (cached.credentials === credentials) {
|
|
258
|
+
return cached.opened;
|
|
259
|
+
}
|
|
260
|
+
void this.dropClient(name);
|
|
245
261
|
}
|
|
246
|
-
|
|
262
|
+
// Only evict this entry: a connect that fails after its credentials were
|
|
263
|
+
// replaced would otherwise orphan the client that replaced it.
|
|
264
|
+
const entry: CachedClient = {
|
|
265
|
+
credentials,
|
|
266
|
+
opened: this.connect(name).catch(error => {
|
|
267
|
+
if (this.clients.get(name) === entry) {
|
|
268
|
+
this.clients.delete(name);
|
|
269
|
+
}
|
|
270
|
+
throw error;
|
|
271
|
+
}),
|
|
272
|
+
};
|
|
273
|
+
this.clients.set(name, entry);
|
|
274
|
+
return entry.opened;
|
|
247
275
|
}
|
|
248
276
|
|
|
249
277
|
private async invalidateClient(name: string, opened: OpenedConnection): Promise<void> {
|
|
250
|
-
const
|
|
251
|
-
if (
|
|
278
|
+
const cached = this.clients.get(name);
|
|
279
|
+
if (cached !== undefined) {
|
|
252
280
|
try {
|
|
253
|
-
if ((await
|
|
281
|
+
if ((await cached.opened) === opened) {
|
|
254
282
|
this.clients.delete(name);
|
|
255
283
|
}
|
|
256
284
|
} catch {
|
|
@@ -385,7 +413,7 @@ async function openConnection(
|
|
|
385
413
|
}
|
|
386
414
|
|
|
387
415
|
async function createTransport(connection: DiscoveredConnection, oauthRedirectUrl?: string) {
|
|
388
|
-
const transport = connection.transport;
|
|
416
|
+
const transport = resolveConnectionEnvTemplates(connection.transport);
|
|
389
417
|
if ("agent" in transport) {
|
|
390
418
|
// Peers are resolved to concrete URLs by the serve host before any call
|
|
391
419
|
// (SessionEngine.setResolvedConnections); reaching here means the
|
|
@@ -210,12 +210,23 @@ export function isModelCapacityError(
|
|
|
210
210
|
message: string | undefined,
|
|
211
211
|
code?: string | undefined,
|
|
212
212
|
): boolean {
|
|
213
|
+
if (isGithubApiRateLimitMessage(message)) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
213
216
|
if (code !== undefined && /^(resource_exhausted|unavailable)$/i.test(code)) {
|
|
214
217
|
return true;
|
|
215
218
|
}
|
|
216
219
|
return message !== undefined && /resource_exhausted|\[unavailable\]/i.test(message);
|
|
217
220
|
}
|
|
218
221
|
|
|
222
|
+
/** GitHub token 429s share `resource_exhausted` with model capacity. */
|
|
223
|
+
export function isGithubApiRateLimitMessage(message: string | undefined): boolean {
|
|
224
|
+
if (message === undefined) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return /github/i.test(message) && /(rate limit|\b429\b)/i.test(message);
|
|
228
|
+
}
|
|
229
|
+
|
|
219
230
|
export function isModelCapacityErrorMessage(message: string | undefined): boolean {
|
|
220
231
|
return isModelCapacityError(message);
|
|
221
232
|
}
|
package/src/internal/server.ts
CHANGED
|
@@ -377,8 +377,14 @@ export async function startServer(
|
|
|
377
377
|
// The SCM relay reads the event stream as the signed-in user, so
|
|
378
378
|
// `cursorEvents` cannot work signed out. Require the credential before any
|
|
379
379
|
// slow or stateful startup work (playground build, channel onStart, cron).
|
|
380
|
+
// Not on a hosted v2 guest: under `--no-control-plane` with no v1 mount
|
|
381
|
+
// this process never polls `/v0/scm-events` (the hosted control plane
|
|
382
|
+
// owns ingest), and a persistent slot starts before its first credential
|
|
383
|
+
// is bound, so demanding one here would refuse a guest that never needed it.
|
|
384
|
+
const hostedControlPlaneOwnsIngest =
|
|
385
|
+
noControlPlane && mounts.every(mount => isV2Project(mount.project));
|
|
380
386
|
const cursorEventsAuth =
|
|
381
|
-
effectiveCursorEvents === undefined
|
|
387
|
+
effectiveCursorEvents === undefined || hostedControlPlaneOwnsIngest
|
|
382
388
|
? undefined
|
|
383
389
|
: requireCursorEventsAuth(effectiveCursorEvents, accountKey);
|
|
384
390
|
|
|
@@ -1136,6 +1142,12 @@ export async function startServer(
|
|
|
1136
1142
|
"[agent-sdk] cursor-events: skipping v2 scm-events poll (--no-control-plane); hosted CP owns ingest",
|
|
1137
1143
|
);
|
|
1138
1144
|
}
|
|
1145
|
+
} else if (hostedControlPlaneOwnsIngest && effectiveCursorEvents !== undefined) {
|
|
1146
|
+
// No credential was required above, so no relay object was built; the
|
|
1147
|
+
// outcome is the same skip.
|
|
1148
|
+
logger(
|
|
1149
|
+
"[agent-sdk] cursor-events: skipping v2 scm-events poll (--no-control-plane); hosted CP owns ingest",
|
|
1150
|
+
);
|
|
1139
1151
|
}
|
|
1140
1152
|
|
|
1141
1153
|
// Cursor deployment-events relay: automatic when a mounted agent authored
|
|
@@ -104,6 +104,7 @@ import {
|
|
|
104
104
|
isUnpricedCompletedTurn,
|
|
105
105
|
mapSdkTokenUsage,
|
|
106
106
|
} from "./cloud-turn-cost.js";
|
|
107
|
+
import { resolveConnectionEnvTemplates } from "./connection-env.js";
|
|
107
108
|
import {
|
|
108
109
|
applyAgentContinuationDefaults,
|
|
109
110
|
channelContinuationIdentity,
|
|
@@ -644,6 +645,16 @@ export class SessionEngine {
|
|
|
644
645
|
agentName: options.project.name,
|
|
645
646
|
config: options.project.artifacts,
|
|
646
647
|
sink: managedV2Files?.(),
|
|
648
|
+
// v1 and self-hosted v2 still evict oldest-updated rows past max.
|
|
649
|
+
// Hosted v2 does not: the installation file store keeps every row,
|
|
650
|
+
// and tag must not list the prefix. Read per tag so a generation
|
|
651
|
+
// env bound after serve start takes effect.
|
|
652
|
+
enforceCap: () => {
|
|
653
|
+
const hosting = resolveAgentV2Hosting({
|
|
654
|
+
architecture: options.project.agent.architecture,
|
|
655
|
+
});
|
|
656
|
+
return hosting.kind !== "cursor-managed" && hosting.kind !== "cursor-managed-persistent";
|
|
657
|
+
},
|
|
647
658
|
});
|
|
648
659
|
// Peer and Cursor-account transports are symbolic until the serve host
|
|
649
660
|
// resolves them; the host-side MCP registry starts with the concrete
|
|
@@ -2992,7 +3003,7 @@ export class SessionEngine {
|
|
|
2992
3003
|
if (evaluated === undefined) {
|
|
2993
3004
|
continue;
|
|
2994
3005
|
}
|
|
2995
|
-
const transport = connection.transport;
|
|
3006
|
+
const transport = resolveConnectionEnvTemplates(connection.transport);
|
|
2996
3007
|
if ("url" in transport) {
|
|
2997
3008
|
servers[connection.name] = {
|
|
2998
3009
|
...transport,
|
|
@@ -3001,7 +3012,9 @@ export class SessionEngine {
|
|
|
3001
3012
|
}
|
|
3002
3013
|
continue;
|
|
3003
3014
|
}
|
|
3004
|
-
|
|
3015
|
+
// Templated credentials resolve here, once per turn: the module that
|
|
3016
|
+
// declared them was imported before the platform bound any secret.
|
|
3017
|
+
servers[connection.name] = resolveConnectionEnvTemplates(connection.transport);
|
|
3005
3018
|
}
|
|
3006
3019
|
for (const resolved of this.resolvedConnections) {
|
|
3007
3020
|
if (advertisedNames.has(resolved.name) || hostConnectionNames.has(resolved.name)) {
|
|
@@ -3650,11 +3663,12 @@ export class SessionEngine {
|
|
|
3650
3663
|
if (!isHostOauthConnectionTransport(authored.transport)) {
|
|
3651
3664
|
return undefined;
|
|
3652
3665
|
}
|
|
3666
|
+
const transport = resolveConnectionEnvTemplates(authored.transport);
|
|
3653
3667
|
return await this.oauthHub.mint({
|
|
3654
3668
|
connection,
|
|
3655
|
-
url:
|
|
3656
|
-
type:
|
|
3657
|
-
headers:
|
|
3669
|
+
url: transport.url,
|
|
3670
|
+
type: transport.type === "sse" ? "sse" : "http",
|
|
3671
|
+
headers: transport.headers,
|
|
3658
3672
|
sessionId,
|
|
3659
3673
|
});
|
|
3660
3674
|
}
|
|
@@ -3813,7 +3827,7 @@ export class SessionEngine {
|
|
|
3813
3827
|
*
|
|
3814
3828
|
* With `options.sessionId` the tool runs inside that session (its info
|
|
3815
3829
|
* and materialized workspace) and the call is recorded on the session's
|
|
3816
|
-
* event stream as `actions.requested` / `
|
|
3830
|
+
* event stream as `actions.requested` / `actions.completed` under a
|
|
3817
3831
|
* per-call `turnId` (the call id), so it shows up in trajectories.
|
|
3818
3832
|
* While a model turn is running, a read-effect call runs alongside it
|
|
3819
3833
|
* (the turn's workspace is read as-is) and a write-effect call is
|
|
@@ -4258,16 +4272,22 @@ export class SessionEngine {
|
|
|
4258
4272
|
this.logger(`[session] tool ${toolName} done (direct ${callId}, ${durationMs}ms)`);
|
|
4259
4273
|
|
|
4260
4274
|
if (record !== undefined) {
|
|
4275
|
+
const resultData = {
|
|
4276
|
+
callId,
|
|
4277
|
+
toolName,
|
|
4278
|
+
output: result,
|
|
4279
|
+
isError,
|
|
4280
|
+
stubbed: stubbed ? (true as const) : undefined,
|
|
4281
|
+
};
|
|
4261
4282
|
await this.appendEvent(record.sessionId, {
|
|
4262
4283
|
type: "action.result",
|
|
4263
4284
|
turnId: callId,
|
|
4264
|
-
data:
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
},
|
|
4285
|
+
data: resultData,
|
|
4286
|
+
});
|
|
4287
|
+
await this.appendEvent(record.sessionId, {
|
|
4288
|
+
type: "actions.completed",
|
|
4289
|
+
turnId: callId,
|
|
4290
|
+
data: { results: [resultData] },
|
|
4271
4291
|
});
|
|
4272
4292
|
}
|
|
4273
4293
|
|