@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/bin/agent-serve.ts
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
cmdDeployments,
|
|
49
49
|
cmdEventRepos,
|
|
50
50
|
cmdKill,
|
|
51
|
+
cmdRollback,
|
|
51
52
|
cmdRotateToken,
|
|
52
53
|
cmdSecretsList,
|
|
53
54
|
cmdSecretsSet,
|
|
@@ -66,6 +67,7 @@ import {
|
|
|
66
67
|
PACKAGE_NAME,
|
|
67
68
|
packageVersion,
|
|
68
69
|
} from "../internal/distribution.js";
|
|
70
|
+
import { v2HostedVerifyHint } from "../internal/legacy-command-guard.js";
|
|
69
71
|
import { loadAgentLocalEnv } from "../internal/local-env.js";
|
|
70
72
|
import {
|
|
71
73
|
ENTER_RESTART_EXIT_CODE,
|
|
@@ -97,6 +99,7 @@ Usage:
|
|
|
97
99
|
[--slug <slug>] [--team <id>] [--dir <path>]
|
|
98
100
|
${CLI} sessions [--url <baseUrl> | --prod] [--json]
|
|
99
101
|
[--slug <slug>] [--team <id>] [--dir <path>]
|
|
102
|
+
v2: unsupported. ${v2HostedVerifyHint()}
|
|
100
103
|
${CLI} session <sessionId> [--url <baseUrl> | --prod]
|
|
101
104
|
[--json | --text | --events] [--out <file.ndjson>]
|
|
102
105
|
[--slug <slug>] [--team <id>] [--dir <path>]
|
|
@@ -114,6 +117,7 @@ Usage:
|
|
|
114
117
|
${CLI} trajectory --events <file.ndjson> [--text]
|
|
115
118
|
${CLI} call <tool> [--input <json>] [--dir <path> | --url <baseUrl> | --prod]
|
|
116
119
|
[--session <id>] [--slug <slug>] [--team <id>]
|
|
120
|
+
v2: unsupported. ${v2HostedVerifyHint()}
|
|
117
121
|
${CLI} skill <name> [--dir <path> | --url <baseUrl> | --prod]
|
|
118
122
|
[--slug <slug>] [--team <id>] [--text]
|
|
119
123
|
${CLI} init [dir] [--template <name>] [--var id=value]... [--json]
|
|
@@ -157,6 +161,7 @@ Usage:
|
|
|
157
161
|
${CLI} cancel-runs <slug> [--team <id>] [--json]
|
|
158
162
|
${CLI} event-repos <slug> [--repo <owner/name>]... [--team <id>] [--json]
|
|
159
163
|
${CLI} upgrade <slug> [--release <id|version>] [--team <id>] [--json]
|
|
164
|
+
${CLI} rollback <slug> [--release <id|version>] [--team <id>] [--json]
|
|
160
165
|
${CLI} delete <slug> [--team <id>] [--json] [--no-wait]
|
|
161
166
|
${CLI} rotate-token <slug> [--team <id>]
|
|
162
167
|
${CLI} secrets set <slug> NAME... | list <slug> | unset <slug> NAME
|
|
@@ -189,8 +194,10 @@ Commands:
|
|
|
189
194
|
the current buffer. --prod shows deploy progress until the
|
|
190
195
|
hosted deployment is running, then tails runtime logs. Without
|
|
191
196
|
--prod, tails the local server (or --url).
|
|
192
|
-
sessions List sessions on a running agent
|
|
193
|
-
|
|
197
|
+
sessions List sessions on a running agent or a v1 --prod deployment.
|
|
198
|
+
Unsupported on architecture v2. ${v2HostedVerifyHint()}
|
|
199
|
+
session Show one session. On v2: \`${CLI} session <ses_> --prod --slug <slug>\`.
|
|
200
|
+
Default: text trajectory. --json for trajectory
|
|
194
201
|
JSON; --events for the raw event list. To continue interactively,
|
|
195
202
|
use \`${CLI} resume [id]\`.
|
|
196
203
|
cost Pull cost metrics. With a session id: per-turn token usage and
|
|
@@ -208,13 +215,14 @@ Commands:
|
|
|
208
215
|
Streams tool calls and reply text to stderr when stderr is a TTY.
|
|
209
216
|
Pass --prod to hit the hosted deployment instead of a local server.
|
|
210
217
|
On an AgentSDK v2 slug, --prod starts a hosted session through
|
|
211
|
-
the control plane (Temporal, no resident engine)
|
|
212
|
-
ses_… resumes that exact session. A 404 falls back to the v1
|
|
218
|
+
the control plane (Temporal, no resident engine). ${v2HostedVerifyHint()}
|
|
219
|
+
--session ses_… resumes that exact session. A 404 falls back to the v1
|
|
213
220
|
engine alias.
|
|
214
221
|
trajectory Summarize an events.ndjson file into a trajectory.
|
|
215
222
|
call Call an authored server tool deterministically (no model turn)
|
|
216
223
|
via POST /v1/tools/:toolName. --session runs it inside an
|
|
217
224
|
existing session and records it on that session's event stream.
|
|
225
|
+
Unsupported on architecture v2. ${v2HostedVerifyHint()}
|
|
218
226
|
skill Read an authored skill deterministically (no model turn)
|
|
219
227
|
via GET /v1/skills/:skillName. --text prints SKILL.md.
|
|
220
228
|
init Scaffold a project (skipping existing files), npm install,
|
|
@@ -234,8 +242,8 @@ Commands:
|
|
|
234
242
|
-> MCP). Review the project, then run \`validate\` / \`dev\`.
|
|
235
243
|
Warnings never fail the command.
|
|
236
244
|
install-skills
|
|
237
|
-
Refresh the
|
|
238
|
-
~/.cursor/skills/
|
|
245
|
+
Refresh the BDK skills for coding agents in
|
|
246
|
+
~/.cursor/skills/bdk and print where they landed.
|
|
239
247
|
Installed copies set alwaysApply so Cursor injects them
|
|
240
248
|
into context. \`npm install\` / \`npx\` already copies them
|
|
241
249
|
(postinstall); this command overwrites with the package
|
|
@@ -306,6 +314,9 @@ Commands:
|
|
|
306
314
|
upgrade Move this team's install onto a release, the newest ready one
|
|
307
315
|
by default. Deploying a multi-tenant application publishes a
|
|
308
316
|
release without moving any tenant onto it.
|
|
317
|
+
rollback Move this team's install onto an earlier ready release, the
|
|
318
|
+
nearest one by default. Does not publish a release. Pass
|
|
319
|
+
--release to choose an older id or version.
|
|
309
320
|
delete Delete a deployment (teardown + purge the record) and wait
|
|
310
321
|
until GET 404s. The slug is then free to redeploy.
|
|
311
322
|
rotate-token Mint a new alias token for a deployment (shown once); the old
|
|
@@ -392,7 +403,10 @@ Options:
|
|
|
392
403
|
--dir basename. Mutually exclusive with --url. Requires
|
|
393
404
|
\`${CLI} login\`. For eval, this is how you opt into the
|
|
394
405
|
persisted server-side batch (default is local).
|
|
406
|
+
v2: ${v2HostedVerifyHint()} call --prod and
|
|
407
|
+
sessions --prod stay on v1.
|
|
395
408
|
--dry-run run/session --prod: mark the hosted v2 turn non-mutating.
|
|
409
|
+
${v2HostedVerifyHint()}
|
|
396
410
|
--component run/session --prod: wake this v2 component key,
|
|
397
411
|
not the application default.
|
|
398
412
|
--as-of run/session --prod: freeze the session clock at this
|
|
@@ -893,6 +907,13 @@ async function main(argv: string[]): Promise<number> {
|
|
|
893
907
|
);
|
|
894
908
|
}
|
|
895
909
|
|
|
910
|
+
case "rollback": {
|
|
911
|
+
return cmdRollback(
|
|
912
|
+
{ slug: positionals[0], release: values.release },
|
|
913
|
+
deployOptionsFromValues(values),
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
|
|
896
917
|
case "delete": {
|
|
897
918
|
return cmdDelete(positionals[0], deployOptionsFromValues(values));
|
|
898
919
|
}
|
|
@@ -215,11 +215,50 @@ export async function createGitHubInstallationToken(input: {
|
|
|
215
215
|
privateKey,
|
|
216
216
|
...(input.api?.apiBaseUrl === undefined ? {} : { baseUrl: input.api.apiBaseUrl }),
|
|
217
217
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
218
|
+
try {
|
|
219
|
+
const result = await auth({
|
|
220
|
+
type: "installation",
|
|
221
|
+
installationId: input.installationId,
|
|
222
|
+
});
|
|
223
|
+
return result.token;
|
|
224
|
+
} catch (error) {
|
|
225
|
+
throw installationTokenMintError(error, {
|
|
226
|
+
appId,
|
|
227
|
+
installationId: input.installationId,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Octokit's bare mint failure ("Not Found - <docs url>") names neither the
|
|
234
|
+
* app nor the installation, which makes a revoked installation or an
|
|
235
|
+
* app/installation credential mismatch undiagnosable from production logs.
|
|
236
|
+
* Rewrap with both ids and, for 404, the two causes that produce it.
|
|
237
|
+
*/
|
|
238
|
+
function installationTokenMintError(
|
|
239
|
+
error: unknown,
|
|
240
|
+
context: { appId: string; installationId: number },
|
|
241
|
+
): Error {
|
|
242
|
+
const status =
|
|
243
|
+
typeof error === "object" &&
|
|
244
|
+
error !== null &&
|
|
245
|
+
"status" in error &&
|
|
246
|
+
typeof (error as { status: unknown }).status === "number"
|
|
247
|
+
? (error as { status: number }).status
|
|
248
|
+
: undefined;
|
|
249
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
250
|
+
const hint =
|
|
251
|
+
status === 404
|
|
252
|
+
? " — the installation does not exist for this app: it was uninstalled or suspended, or the configured app credentials belong to a different GitHub App than the one this installation id refers to"
|
|
253
|
+
: "";
|
|
254
|
+
const wrapped = new Error(
|
|
255
|
+
`githubChannel: failed to mint an installation access token (app ${context.appId}, installation ${context.installationId}): ${detail}${hint}`,
|
|
256
|
+
error instanceof Error ? { cause: error } : undefined,
|
|
257
|
+
);
|
|
258
|
+
if (status !== undefined) {
|
|
259
|
+
(wrapped as Error & { status?: number }).status = status;
|
|
260
|
+
}
|
|
261
|
+
return wrapped;
|
|
223
262
|
}
|
|
224
263
|
|
|
225
264
|
/**
|
package/src/connections.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
* export default defineConnection({
|
|
20
20
|
* url: "https://mcp.linear.app/mcp",
|
|
21
|
-
* headers: { authorization:
|
|
21
|
+
* headers: { authorization: "Bearer ${LINEAR_TOKEN}" },
|
|
22
22
|
* });
|
|
23
23
|
*
|
|
24
24
|
* // TypeScript tools, packaged as stdio MCP for the agent environment:
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Your Grok Bot agents as an extension. Mount it and the agent can talk to
|
|
3
|
+
* the Grok Bot agents of the host's account: send a message, read the
|
|
4
|
+
* reply, keep waiting on a long turn, interrupt one.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* // agent/extensions/grokbot.ts
|
|
8
|
+
* import cursorGrokBotAgents from "@cursor/bdk/extensions/cursor-grokbot-agents";
|
|
9
|
+
*
|
|
10
|
+
* export default cursorGrokBotAgents({
|
|
11
|
+
* agents: [
|
|
12
|
+
* { name: "Plan Keeper", description: "Keeps or moves outdoor plans." },
|
|
13
|
+
* ],
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Contributes `grokbot__ask`, `grokbot__check`, `grokbot__interrupt`,
|
|
18
|
+
* `grokbot__list` and the `grokbot__consult` skill (the namespace is the
|
|
19
|
+
* mount filename), over the same public `/v0/grokbot` session API the
|
|
20
|
+
* grokbot runtime uses, under the serve host's Cursor API key
|
|
21
|
+
* (`CURSOR_API_KEY`, key file, or `login`). Agents are addressed by name and
|
|
22
|
+
* resolved on the account the key belongs to; a message lands in that
|
|
23
|
+
* account's own conversation with the agent, and the reply is what the agent
|
|
24
|
+
* sends back during that turn. The tools run on the serve host, so they
|
|
25
|
+
* need the local runtime.
|
|
26
|
+
*
|
|
27
|
+
* This is the other direction from `defineAgent({ runtime: "grokbot" })`:
|
|
28
|
+
* the runtime runs *this* agent's turns on the hosted Grok Bot harness; the
|
|
29
|
+
* extension keeps the agent where it is and lets it talk to *other* Grok
|
|
30
|
+
* Bot agents.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { z } from "zod";
|
|
34
|
+
import { defineExtension } from "../../extensions.js";
|
|
35
|
+
import type { Extension } from "../../types.js";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A Grok Bot agent the model may address, by the name shown in the app.
|
|
39
|
+
* Type alias, not an interface: `list` returns these.
|
|
40
|
+
*/
|
|
41
|
+
export type ConfiguredGrokBotAgent = {
|
|
42
|
+
name: string;
|
|
43
|
+
/** What the agent is for; shown to the model by `list`. */
|
|
44
|
+
description?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** Mount options; every field is optional. */
|
|
48
|
+
export interface CursorGrokBotAgentsOptions {
|
|
49
|
+
/**
|
|
50
|
+
* The Grok Bot agents the model may talk to, by name. This is the
|
|
51
|
+
* allowlist for a call's own `agent`: names outside it are refused, and a
|
|
52
|
+
* lone configured agent is the default when a call names none. Without
|
|
53
|
+
* it, any name goes through and `needsApproval` defaults to true, since
|
|
54
|
+
* an unknown name creates an agent of that name on the account.
|
|
55
|
+
*/
|
|
56
|
+
agents?: Array<string | ConfiguredGrokBotAgent>;
|
|
57
|
+
/**
|
|
58
|
+
* Park messages for a human approval. Defaults to `true` when no `agents`
|
|
59
|
+
* are configured; `false` once they are. Pass an explicit boolean to
|
|
60
|
+
* override. Configured names still bound the model's choice regardless.
|
|
61
|
+
*/
|
|
62
|
+
needsApproval?: boolean;
|
|
63
|
+
/** Cursor API key. Defaults to the serve host's own key. */
|
|
64
|
+
apiKey?: string;
|
|
65
|
+
/**
|
|
66
|
+
* How often to read the agent's transcript while waiting for a reply, in
|
|
67
|
+
* milliseconds. Defaults to 750.
|
|
68
|
+
*/
|
|
69
|
+
pollIntervalMs?: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** {@link CursorGrokBotAgentsOptions} with defaults applied. */
|
|
73
|
+
export interface CursorGrokBotAgentsConfig {
|
|
74
|
+
agents?: ConfiguredGrokBotAgent[];
|
|
75
|
+
needsApproval: boolean;
|
|
76
|
+
apiKey?: string;
|
|
77
|
+
pollIntervalMs: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** The backend's session name limit. */
|
|
81
|
+
export const AGENT_NAME_MAX_LENGTH = 255;
|
|
82
|
+
const DEFAULT_POLL_INTERVAL_MS = 750;
|
|
83
|
+
|
|
84
|
+
const agentName = z
|
|
85
|
+
.string()
|
|
86
|
+
.trim()
|
|
87
|
+
.min(1, "Grok Bot agent names must not be empty.")
|
|
88
|
+
.max(AGENT_NAME_MAX_LENGTH);
|
|
89
|
+
|
|
90
|
+
const configuredAgent: z.ZodType<
|
|
91
|
+
ConfiguredGrokBotAgent,
|
|
92
|
+
z.ZodTypeDef,
|
|
93
|
+
string | ConfiguredGrokBotAgent
|
|
94
|
+
> = z
|
|
95
|
+
.union([agentName, z.object({ name: agentName, description: z.string().optional() })])
|
|
96
|
+
.transform(agent => (typeof agent === "string" ? { name: agent } : agent));
|
|
97
|
+
|
|
98
|
+
const agents = z
|
|
99
|
+
.array(configuredAgent)
|
|
100
|
+
.min(1, "agents must name at least one Grok Bot agent; omit it to allow any.")
|
|
101
|
+
.refine(
|
|
102
|
+
list => new Set(list.map(agent => agent.name.toLowerCase())).size === list.length,
|
|
103
|
+
"agents must not repeat a name (names match case-insensitively).",
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const config: z.ZodType<
|
|
107
|
+
CursorGrokBotAgentsConfig,
|
|
108
|
+
z.ZodTypeDef,
|
|
109
|
+
CursorGrokBotAgentsOptions | undefined
|
|
110
|
+
> = z
|
|
111
|
+
.object({
|
|
112
|
+
agents: agents.optional(),
|
|
113
|
+
needsApproval: z.boolean().optional(),
|
|
114
|
+
apiKey: z.string().optional(),
|
|
115
|
+
pollIntervalMs: z.number().int().min(1).default(DEFAULT_POLL_INTERVAL_MS),
|
|
116
|
+
})
|
|
117
|
+
.default({})
|
|
118
|
+
.transform(options => ({
|
|
119
|
+
...options,
|
|
120
|
+
needsApproval: options.needsApproval ?? options.agents === undefined,
|
|
121
|
+
}));
|
|
122
|
+
|
|
123
|
+
const cursorGrokBotAgents: Extension<
|
|
124
|
+
CursorGrokBotAgentsConfig,
|
|
125
|
+
CursorGrokBotAgentsOptions | undefined
|
|
126
|
+
> = defineExtension({
|
|
127
|
+
root: import.meta.dirname,
|
|
128
|
+
description: "Talk to your Grok Bot agents and read their replies.",
|
|
129
|
+
config,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
export default cursorGrokBotAgents;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which Grok Bot agent a call addresses. The model names one per call, but
|
|
3
|
+
* the author's `agents` are the allowlist: with them configured, a name
|
|
4
|
+
* outside the list is refused (the backend would create an agent of that
|
|
5
|
+
* name), and a lone configured agent stands in when the call names none.
|
|
6
|
+
* Matching is case-insensitive and resolves to the configured spelling,
|
|
7
|
+
* since the backend looks names up exactly.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ConfiguredGrokBotAgent } from "../extension.js";
|
|
11
|
+
|
|
12
|
+
export function resolveAgentName(
|
|
13
|
+
requested: string | undefined,
|
|
14
|
+
configured: ConfiguredGrokBotAgent[] | undefined,
|
|
15
|
+
): string {
|
|
16
|
+
const name = requested?.trim();
|
|
17
|
+
if (configured === undefined) {
|
|
18
|
+
if (name === undefined || name === "") {
|
|
19
|
+
throw new Error("`agent` is required: this extension has no configured Grok Bot agents.");
|
|
20
|
+
}
|
|
21
|
+
return name;
|
|
22
|
+
}
|
|
23
|
+
const names = configured.map(agent => `"${agent.name}"`).join(", ");
|
|
24
|
+
if (name === undefined || name === "") {
|
|
25
|
+
const only = configured.length === 1 ? configured[0] : undefined;
|
|
26
|
+
if (only === undefined) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`\`agent\` is required: this extension configures several Grok Bot agents (${names}).`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return only.name;
|
|
32
|
+
}
|
|
33
|
+
const match =
|
|
34
|
+
configured.find(agent => agent.name === name) ??
|
|
35
|
+
configured.find(agent => agent.name.toLowerCase() === name.toLowerCase());
|
|
36
|
+
if (match === undefined) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`"${name}" is not one of this extension's configured Grok Bot agents (${names}).`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return match.name;
|
|
42
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/v0/grokbot` session API as the tools use it: the same four routes
|
|
3
|
+
* the grokbot runtime drives, on the external API host (`api.cursor.com`;
|
|
4
|
+
* they 404 on api2), under the host's Cursor API key. A session is a hosted
|
|
5
|
+
* Grok Bot agent of the key's account, get-or-created by name; messages go
|
|
6
|
+
* into its one conversation, and the transcript is read back as entries
|
|
7
|
+
* after a cursor, with the turn's status alongside.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { randomUUID } from "node:crypto";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import {
|
|
13
|
+
cursorExternalApiUrl,
|
|
14
|
+
resolveApiKeySync,
|
|
15
|
+
SIGN_IN_HINT,
|
|
16
|
+
} from "../../../internal/cursor/credentials.js";
|
|
17
|
+
import extension from "../extension.js";
|
|
18
|
+
|
|
19
|
+
const REQUEST_TIMEOUT_MS = 60_000;
|
|
20
|
+
|
|
21
|
+
export class GrokBotApiError extends Error {
|
|
22
|
+
constructor(
|
|
23
|
+
message: string,
|
|
24
|
+
readonly status?: number,
|
|
25
|
+
) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "GrokBotApiError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Type aliases, not interfaces: these flow into tool results.
|
|
32
|
+
export type GrokBotSession = {
|
|
33
|
+
/** The hosted agent's durable id; every other route addresses it. */
|
|
34
|
+
sessionId: string;
|
|
35
|
+
/** The name as the backend stores it (trimmed). */
|
|
36
|
+
name: string;
|
|
37
|
+
createdAtMs: number;
|
|
38
|
+
/** Transcript tail: reading after it skips the conversation's history. */
|
|
39
|
+
latestUpdatedSeq: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type GrokBotEntry = {
|
|
43
|
+
seq: string;
|
|
44
|
+
updatedSeq: string;
|
|
45
|
+
kind: string;
|
|
46
|
+
role?: string;
|
|
47
|
+
text?: string;
|
|
48
|
+
createdAtMs: number;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type GrokBotTurnStatus = {
|
|
52
|
+
idle: boolean;
|
|
53
|
+
inFlight: boolean;
|
|
54
|
+
queued: number;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export type GrokBotEntriesPage = {
|
|
58
|
+
entries: GrokBotEntry[];
|
|
59
|
+
latestUpdatedSeq: string;
|
|
60
|
+
turn: GrokBotTurnStatus;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const sessionSchema = z.object({
|
|
64
|
+
id: z.string(),
|
|
65
|
+
name: z.string(),
|
|
66
|
+
createdAtMs: z.number(),
|
|
67
|
+
latestUpdatedSeq: z.string(),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const sendSchema = z.object({
|
|
71
|
+
messageId: z.string(),
|
|
72
|
+
delivery: z.string(),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const entriesSchema: z.ZodType<GrokBotEntriesPage> = z.object({
|
|
76
|
+
entries: z.array(
|
|
77
|
+
z.object({
|
|
78
|
+
seq: z.string(),
|
|
79
|
+
updatedSeq: z.string(),
|
|
80
|
+
kind: z.string(),
|
|
81
|
+
role: z.string().optional(),
|
|
82
|
+
text: z.string().optional(),
|
|
83
|
+
createdAtMs: z.number(),
|
|
84
|
+
}),
|
|
85
|
+
),
|
|
86
|
+
latestUpdatedSeq: z.string(),
|
|
87
|
+
turn: z.object({
|
|
88
|
+
idle: z.boolean(),
|
|
89
|
+
inFlight: z.boolean(),
|
|
90
|
+
queued: z.number(),
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
export class GrokBotAgentsBackend {
|
|
95
|
+
constructor(
|
|
96
|
+
private readonly apiKey: () => string,
|
|
97
|
+
private readonly fetchImpl: typeof fetch = fetch,
|
|
98
|
+
) {}
|
|
99
|
+
|
|
100
|
+
/** `POST /v0/grokbot/sessions`: the account's agent of that name, created when missing. */
|
|
101
|
+
async session(name: string): Promise<GrokBotSession> {
|
|
102
|
+
// No `instructions`: the agent is somebody's, configured in the app, and
|
|
103
|
+
// an omitted field never touches its stored profile.
|
|
104
|
+
const parsed = sessionSchema.parse(
|
|
105
|
+
await this.request("POST", "/v0/grokbot/sessions", { name }),
|
|
106
|
+
);
|
|
107
|
+
return {
|
|
108
|
+
sessionId: parsed.id,
|
|
109
|
+
name: parsed.name,
|
|
110
|
+
createdAtMs: parsed.createdAtMs,
|
|
111
|
+
latestUpdatedSeq: parsed.latestUpdatedSeq,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Deliver one user message to the agent's conversation. */
|
|
116
|
+
async send(sessionId: string, text: string): Promise<void> {
|
|
117
|
+
const { delivery } = sendSchema.parse(
|
|
118
|
+
await this.request("POST", `/v0/grokbot/sessions/${sessionId}/messages`, {
|
|
119
|
+
text,
|
|
120
|
+
messageId: randomUUID(),
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
123
|
+
if (delivery !== "accepted_temporal" && delivery !== "duplicate") {
|
|
124
|
+
throw new GrokBotApiError(
|
|
125
|
+
`The Grok Bot agent's harness did not accept the message (delivery: ${delivery}).`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Transcript entries after `afterUpdatedSeq`, oldest first, with the turn's status. */
|
|
131
|
+
async entries(sessionId: string, afterUpdatedSeq: string): Promise<GrokBotEntriesPage> {
|
|
132
|
+
return entriesSchema.parse(
|
|
133
|
+
await this.request(
|
|
134
|
+
"GET",
|
|
135
|
+
`/v0/grokbot/sessions/${sessionId}/entries?afterUpdatedSeq=${encodeURIComponent(afterUpdatedSeq)}`,
|
|
136
|
+
),
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async interrupt(sessionId: string, reason: string): Promise<void> {
|
|
141
|
+
await this.request("POST", `/v0/grokbot/sessions/${sessionId}/interrupt`, {
|
|
142
|
+
reason,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private async request(method: "GET" | "POST", path: string, body?: unknown): Promise<unknown> {
|
|
147
|
+
const headers: Record<string, string> = {
|
|
148
|
+
authorization: `Bearer ${this.apiKey()}`,
|
|
149
|
+
"x-cursor-client-type": "agent-serve",
|
|
150
|
+
"x-request-id": randomUUID(),
|
|
151
|
+
};
|
|
152
|
+
if (body !== undefined) {
|
|
153
|
+
headers["content-type"] = "application/json";
|
|
154
|
+
}
|
|
155
|
+
let response: Response;
|
|
156
|
+
try {
|
|
157
|
+
response = await this.fetchImpl(`${cursorExternalApiUrl()}${path}`, {
|
|
158
|
+
method,
|
|
159
|
+
headers,
|
|
160
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
161
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
162
|
+
});
|
|
163
|
+
} catch (error) {
|
|
164
|
+
throw new GrokBotApiError(
|
|
165
|
+
`Grok Bot API ${method} ${path} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const text = await response.text();
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
throw new GrokBotApiError(
|
|
171
|
+
`Grok Bot API ${method} ${path} failed (${response.status}): ${apiErrorMessage(text)}`,
|
|
172
|
+
response.status,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
return JSON.parse(text) as unknown;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let backend: GrokBotAgentsBackend | undefined;
|
|
180
|
+
|
|
181
|
+
/** The process-wide backend for this mount, built on first use. */
|
|
182
|
+
export function grokBotAgentsBackend(): GrokBotAgentsBackend {
|
|
183
|
+
backend ??= new GrokBotAgentsBackend(apiKey);
|
|
184
|
+
return backend;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export function apiKey(): string {
|
|
188
|
+
// Read per call: the host can sign in after the mount.
|
|
189
|
+
const key = resolveApiKeySync({ apiKey: extension.config.apiKey });
|
|
190
|
+
if (key === undefined) {
|
|
191
|
+
throw new Error(`Grok Bot agents need a Cursor API key. ${SIGN_IN_HINT}`);
|
|
192
|
+
}
|
|
193
|
+
return key.apiKey;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** The route's `{ error }` envelope when it is one, the raw body otherwise. */
|
|
197
|
+
function apiErrorMessage(text: string): string {
|
|
198
|
+
try {
|
|
199
|
+
const parsed = JSON.parse(text) as { error?: unknown; message?: unknown };
|
|
200
|
+
const message = parsed.error ?? parsed.message;
|
|
201
|
+
if (typeof message === "string" && message !== "") {
|
|
202
|
+
return message;
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
// Not JSON; fall through to the raw body.
|
|
206
|
+
}
|
|
207
|
+
return text.slice(0, 300);
|
|
208
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who has talked to which Grok Bot agent, and how far into its transcript
|
|
3
|
+
* they have read. The tools authenticate with the serve host's one Cursor
|
|
4
|
+
* API key, so every agent is that account's; what the host keeps per
|
|
5
|
+
* principal is the read cursor, so `check` returns what the agent said
|
|
6
|
+
* since that caller last read, and a lookup by name for `check` and
|
|
7
|
+
* `interrupt`, which never create an agent the caller has not spoken to.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import type { ToolContext } from "../../../types.js";
|
|
12
|
+
import { KeyedLock } from "./lock.js";
|
|
13
|
+
|
|
14
|
+
const PREFIX = "grokbot-agents";
|
|
15
|
+
|
|
16
|
+
// Type alias, not an interface: contacts flow into tool results.
|
|
17
|
+
export type Contact = {
|
|
18
|
+
/** The agent's name as the backend stores it. */
|
|
19
|
+
name: string;
|
|
20
|
+
/** The hosted agent's `/v0/grokbot` session id. */
|
|
21
|
+
sessionId: string;
|
|
22
|
+
/** Newest transcript `updatedSeq` this principal has read. */
|
|
23
|
+
cursor: string;
|
|
24
|
+
firstContactAt: string;
|
|
25
|
+
lastContactAt: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const contactsSchema: z.ZodType<Contact[]> = z.array(
|
|
29
|
+
z.object({
|
|
30
|
+
name: z.string(),
|
|
31
|
+
sessionId: z.string(),
|
|
32
|
+
cursor: z.string(),
|
|
33
|
+
firstContactAt: z.string(),
|
|
34
|
+
lastContactAt: z.string(),
|
|
35
|
+
}),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const locks = new KeyedLock();
|
|
39
|
+
|
|
40
|
+
/** Unauthenticated sessions (local dev, direct calls) share one principal. */
|
|
41
|
+
export function principalOf(ctx: ToolContext): string {
|
|
42
|
+
const auth = ctx.session.auth;
|
|
43
|
+
return auth === null ? "anonymous" : `${auth.principalType}:${auth.principalId}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The caller's contacts, most recently spoken to first. */
|
|
47
|
+
export async function listContacts(ctx: ToolContext): Promise<Contact[]> {
|
|
48
|
+
const contacts = contactsSchema.safeParse(await ctx.host.kv.get(contactsKey(principalOf(ctx))));
|
|
49
|
+
return contacts.success ? contacts.data : [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The contact of that name, exact spelling first, then case-insensitively. */
|
|
53
|
+
export function findContact(contacts: Contact[], name: string): Contact | undefined {
|
|
54
|
+
const wanted = name.trim();
|
|
55
|
+
return (
|
|
56
|
+
contacts.find(contact => contact.name === wanted) ??
|
|
57
|
+
contacts.find(contact => contact.name.toLowerCase() === wanted.toLowerCase())
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Insert or replace the caller's record of one agent, newest first. */
|
|
62
|
+
export async function saveContact(ctx: ToolContext, contact: Contact): Promise<void> {
|
|
63
|
+
const key = contactsKey(principalOf(ctx));
|
|
64
|
+
await locks.run(key, async () => {
|
|
65
|
+
const others = (await listContacts(ctx)).filter(
|
|
66
|
+
existing => existing.sessionId !== contact.sessionId,
|
|
67
|
+
);
|
|
68
|
+
await ctx.host.kv.put(key, [contact, ...others]);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function contactsKey(principal: string): string {
|
|
73
|
+
return `${PREFIX}/principals/${encodeURIComponent(principal)}`;
|
|
74
|
+
}
|