@cursor/bdk 0.2.2 → 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/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/connections.d.ts +1 -1
- package/dist/connections.js +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.DtYVVVyK.js → app.BOIHhrKi.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.D5L-b34G.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.D47xT7J4.js → VPLocalSearchBox.D49zVZqM.js} +1 -1
- package/dist/docs/assets/chunks/{arc.CDJ6xzxR.js → arc.hmjb-sc4.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.l1Xnjd3N.js → architectureDiagram-Q4EWVU46.CxEI1KqM.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.x-finShZ.js → baseUniq.DHHvBWoV.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.COC3qynH.js → blockDiagram-DXYQGD6D.DnXW-3bu.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.DdQO850E.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.Dpn8omLk.js → chunk-4BX2VUAB.3ry4pYXB.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.C0XWStUN.js → chunk-4TB4RGXK.DGIZFRx6.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.DsKSZfIM.js → chunk-55IACEB6.DKBnqg9U.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.dNU6JDu6.js → chunk-EDXVE4YY.BIU8Ue5k.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.DN41fxKE.js → chunk-FMBD7UC4.DP-TFhjI.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.COpKCZus.js → chunk-OYMX7WX6.Ux0OYj5v.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.HDB-azx2.js → chunk-QZHKN3VN.BzHMwYox.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.DEeX_a2j.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.C3yGL2A8.js → cose-bilkent-S5V4N54A.Jq_7BUNx.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.Bpl24en4.js → dagre-KV5264BT.Di-skR2x.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.nFco6seU.js → diagram-5BDNPKRD.DeREHIdH.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.DXhA6DWR.js → diagram-G4DWMVQ6.C7Kcqxro.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.8GoOYcwk.js → diagram-MMDJMWI5.BK3eohyo.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.DDBlqvlJ.js → diagram-TYMM5635.C6TyymXT.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.vl_N81P4.js → erDiagram-SMLLAGMA.DYGG-gGx.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.Cteg8g7I.js → flowDiagram-DWJPFMVM.C9nBcSV4.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.D4aMhlMM.js → ganttDiagram-T4ZO3ILL.wAg_ymsp.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.DF_J0D4q.js → gitGraphDiagram-UUTBAWPF.B87j9Oeg.js} +1 -1
- package/dist/docs/assets/chunks/{graph.DJs0LDCf.js → graph.CuFMj31w.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.Bb-4RQwg.js → infoDiagram-42DDH7IO.P_mLGumP.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DEtQRSbc.js → ishikawaDiagram-UXIWVN3A.DyuL_MsT.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.DhQQ75FA.js → journeyDiagram-VCZTEJTY.CtP09IoJ.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.C4gEw3Rk.js → kanban-definition-6JOO6SKY.BoeSYPZo.js} +1 -1
- package/dist/docs/assets/chunks/{layout.DT-PGlXa.js → layout.B0lMMtNo.js} +1 -1
- package/dist/docs/assets/chunks/{linear.BMMe__JW.js → linear.HxRBiAFX.js} +1 -1
- package/dist/docs/assets/chunks/{min.XyaU9K9Q.js → min.BGlFFHwS.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.CbBM6xZ-.js → mindmap-definition-QFDTVHPH.JyLBD9M8.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DFJoIVou.js → pieDiagram-DEJITSTG.DnSmNZF8.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CQjkDYqb.js → quadrantDiagram-34T5L4WZ.CUCnbfCa.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.D-mK-JQu.js → requirementDiagram-MS252O5E.py0IVUn5.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.BStQInpd.js → sankeyDiagram-XADWPNL6.Bkc-HWYp.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.CA_eooPJ.js → sequenceDiagram-FGHM5R23.Dqn8Mlv2.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.BXl-b7ad.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.q37tOs4x.js → theme.b6HQ6zG_.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.vjuaGOSe.js → timeline-definition-GMOUNBTQ.BvpSXiBj.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.BxduJl-F.js → vennDiagram-DHZGUBPP.CU7MVnZx.js} +1 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.BKwC4ctG.js +162 -0
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.D1z3ds0D.js → wardleyDiagram-NUSXRM2D.BfaF6Uhe.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CRU5Ti9b.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.CFMNPreZ.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_skills.md.CRFTxt9M.js → reference_skills.md.Cy00QMKS.js} +3 -3
- package/dist/docs/assets/{reference_skills.md.CRFTxt9M.lean.js → reference_skills.md.Cy00QMKS.lean.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 +198 -92
- 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 +35 -35
- 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 +35 -35
- package/dist/docs/reference/skills.html +38 -38
- 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-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/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/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 +228 -48
- 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.map +1 -1
- package/dist/internal/session-engine.js +9 -5
- package/dist/types.d.ts +11 -1
- 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/troubleshooting.md +7 -3
- package/package.json +1 -3
- 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/bin/agent-serve.ts +27 -6
- package/src/channels/github/auth.ts +44 -5
- package/src/connections.ts +1 -1
- 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/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/hosted-delivery-protocol.ts +57 -20
- package/src/internal/hosted-delivery.ts +486 -228
- 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 +9 -5
- package/src/types.ts +11 -1
- 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.BgTA2tV1.js +0 -1
- package/dist/docs/assets/chunks/channel.B2nMEx82.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.D8iCH2ve.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.D8iCH2ve.js +0 -1
- package/dist/docs/assets/chunks/clone.5XNLjby0.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.yGM2uLZQ.js +0 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.DKfyIejL.js +0 -162
- 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/docs/assets/{reference_artifacts.md.CFMNPreZ.lean.js → reference_artifacts.md.CQfKq8F2.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,
|
|
@@ -3002,7 +3003,7 @@ export class SessionEngine {
|
|
|
3002
3003
|
if (evaluated === undefined) {
|
|
3003
3004
|
continue;
|
|
3004
3005
|
}
|
|
3005
|
-
const transport = connection.transport;
|
|
3006
|
+
const transport = resolveConnectionEnvTemplates(connection.transport);
|
|
3006
3007
|
if ("url" in transport) {
|
|
3007
3008
|
servers[connection.name] = {
|
|
3008
3009
|
...transport,
|
|
@@ -3011,7 +3012,9 @@ export class SessionEngine {
|
|
|
3011
3012
|
}
|
|
3012
3013
|
continue;
|
|
3013
3014
|
}
|
|
3014
|
-
|
|
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);
|
|
3015
3018
|
}
|
|
3016
3019
|
for (const resolved of this.resolvedConnections) {
|
|
3017
3020
|
if (advertisedNames.has(resolved.name) || hostConnectionNames.has(resolved.name)) {
|
|
@@ -3660,11 +3663,12 @@ export class SessionEngine {
|
|
|
3660
3663
|
if (!isHostOauthConnectionTransport(authored.transport)) {
|
|
3661
3664
|
return undefined;
|
|
3662
3665
|
}
|
|
3666
|
+
const transport = resolveConnectionEnvTemplates(authored.transport);
|
|
3663
3667
|
return await this.oauthHub.mint({
|
|
3664
3668
|
connection,
|
|
3665
|
-
url:
|
|
3666
|
-
type:
|
|
3667
|
-
headers:
|
|
3669
|
+
url: transport.url,
|
|
3670
|
+
type: transport.type === "sse" ? "sse" : "http",
|
|
3671
|
+
headers: transport.headers,
|
|
3668
3672
|
sessionId,
|
|
3669
3673
|
});
|
|
3670
3674
|
}
|
package/src/types.ts
CHANGED
|
@@ -342,7 +342,10 @@ export interface AgentHostingOptions {
|
|
|
342
342
|
* Domains the deployed engine pod may reach (egress allowlist), e.g.
|
|
343
343
|
* `"api.example.com"` or `"*.example.com"` (single leading wildcard).
|
|
344
344
|
* Lowercase hostnames with at least two labels and an alphabetic TLD;
|
|
345
|
-
* max
|
|
345
|
+
* max 64. A `"host:port"` entry (e.g. `"clickhouse.example.com:9440"`)
|
|
346
|
+
* opens raw TCP to that host's addresses, for wire protocols the proxy
|
|
347
|
+
* cannot read a TLS hostname from.
|
|
348
|
+
* `agent-sdk deploy` sends these as `egressAllowedDomains`
|
|
346
349
|
* (unioned with any `--allow-domain` flags). Only valid on repo-backed
|
|
347
350
|
* deployments. Deployment-scoped like {@link secretNames}: not capped by
|
|
348
351
|
* the team's Cloud Agent egress allowlist. The platform still merges a
|
|
@@ -1219,6 +1222,13 @@ export interface DiscoveredExtension {
|
|
|
1219
1222
|
* resolves to a bridge on this host that executes every tool **on the
|
|
1220
1223
|
* Cursor backend** with the account's stored OAuth credentials — tokens
|
|
1221
1224
|
* never reach this host.
|
|
1225
|
+
*
|
|
1226
|
+
* Credentials belong in `headers` (http/sse) and `env` (stdio) as `${NAME}`
|
|
1227
|
+
* templates, which the transport keeps verbatim and expands from the
|
|
1228
|
+
* environment each time a client opens. Reading `process.env` in the
|
|
1229
|
+
* connection module instead pins whatever the variable held when discovery
|
|
1230
|
+
* imported it, which on Cursor hosting is nothing: the platform binds a
|
|
1231
|
+
* deployment's secrets per request, long after that import.
|
|
1222
1232
|
*/
|
|
1223
1233
|
export type ConnectionTransport =
|
|
1224
1234
|
| {
|
|
@@ -335,10 +335,7 @@ async function readFile(
|
|
|
335
335
|
): Promise<string | undefined> {
|
|
336
336
|
try {
|
|
337
337
|
const { data } = await octokit.rest.repos.getContent(args);
|
|
338
|
-
if (Array.isArray(data) || data.encoding !== "base64") {
|
|
339
|
-
return undefined;
|
|
340
|
-
}
|
|
341
|
-
if (typeof data.content !== "string") {
|
|
338
|
+
if (Array.isArray(data) || data.type !== "file" || data.encoding !== "base64") {
|
|
342
339
|
return undefined;
|
|
343
340
|
}
|
|
344
341
|
return Buffer.from(data.content, "base64").toString("utf8");
|
|
@@ -12,7 +12,11 @@ function wake(url: string, github: GitHubHandle) {
|
|
|
12
12
|
if (start === undefined || ref === undefined) {
|
|
13
13
|
return null;
|
|
14
14
|
}
|
|
15
|
-
return {
|
|
15
|
+
return {
|
|
16
|
+
task: async () => {
|
|
17
|
+
await startDemo(start, github, ref);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
export default githubChannel({
|
|
@@ -7,13 +7,13 @@ import { fetchPrState, isTerminalPrState } from "./pr-state.js";
|
|
|
7
7
|
|
|
8
8
|
export type StartDriveErrorCode = "missing_pr" | "unrecognized_pr";
|
|
9
9
|
|
|
10
|
-
export
|
|
10
|
+
export type StartDriveError = {
|
|
11
11
|
ok: false;
|
|
12
12
|
code: StartDriveErrorCode;
|
|
13
13
|
error: string;
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
15
|
|
|
16
|
-
export
|
|
16
|
+
export type StartDriveSuccess = {
|
|
17
17
|
ok: true;
|
|
18
18
|
pr: string;
|
|
19
19
|
sessionId: string | null;
|
|
@@ -23,7 +23,7 @@ export interface StartDriveSuccess {
|
|
|
23
23
|
status: string;
|
|
24
24
|
result: string | null;
|
|
25
25
|
mergeConflictReminderId: string | null;
|
|
26
|
-
}
|
|
26
|
+
};
|
|
27
27
|
|
|
28
28
|
export type StartDriveResult = StartDriveError | StartDriveSuccess;
|
|
29
29
|
|