@cursor/bdk 0.2.11 → 0.2.13
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/dist/bin/agent-serve.js +28 -26
- package/dist/channels/bitbucket/api.js +8 -8
- package/dist/channels/bitbucket/binding.js +4 -4
- package/dist/channels/bitbucket/bitbucket-channel.js +1 -1
- package/dist/channels/bitbucket/bitbucket-webhook.js +1 -1
- package/dist/channels/bitbucket/checks.js +1 -1
- package/dist/channels/bitbucket/cursor-account.js +1 -1
- package/dist/channels/bitbucket/events.js +1 -1
- package/dist/channels/change-monitors/change-monitors-channel.js +1 -1
- package/dist/channels/checks.js +2 -2
- package/dist/channels/deployments/deployments-channel.js +1 -1
- package/dist/channels/github/cursor-account.js +3 -3
- package/dist/channels/github/defaults.js +3 -3
- package/dist/channels/github/events.js +1 -1
- package/dist/channels/github/forward.js +8 -8
- package/dist/channels/github/github-channel.js +2 -2
- package/dist/channels/github/index.d.ts +22 -12
- package/dist/channels/github/index.d.ts.map +1 -1
- package/dist/channels/github/index.js +11 -12
- package/dist/channels/gitlab/binding.js +4 -4
- package/dist/channels/gitlab/checks.js +1 -1
- package/dist/channels/gitlab/cursor-account.js +1 -1
- package/dist/channels/gitlab/events.js +1 -1
- package/dist/channels/gitlab/gitlab-channel.js +1 -1
- package/dist/channels/gitlab/gitlab-webhook.js +1 -1
- package/dist/channels/gitlab/replay.js +2 -2
- package/dist/channels/origin/binding.js +3 -3
- package/dist/channels/origin/checks.js +1 -1
- package/dist/channels/origin/cursor-account.js +1 -1
- package/dist/channels/origin/events.js +1 -1
- package/dist/channels/origin/index.d.ts +21 -11
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +10 -11
- package/dist/channels/origin/origin-channel.js +1 -1
- package/dist/channels/origin/origin-webhook.js +2 -2
- package/dist/channels/slack/agentic-delivery.js +3 -3
- package/dist/channels/slack/agentic-signals.js +1 -1
- package/dist/channels/slack/api.js +5 -5
- package/dist/channels/slack/approvals.js +1 -1
- package/dist/channels/slack/attachments.js +3 -3
- package/dist/channels/slack/blocks.js +3 -3
- package/dist/channels/slack/bot-mentions.js +4 -4
- package/dist/channels/slack/channel-watch.js +4 -4
- package/dist/channels/slack/cli-project.js +3 -3
- package/dist/channels/slack/dispatch.js +1 -1
- package/dist/channels/slack/doctor.js +1 -1
- package/dist/channels/slack/eval-directive.js +1 -1
- package/dist/channels/slack/footer.js +1 -1
- package/dist/channels/slack/interactive.js +2 -2
- package/dist/channels/slack/log.d.ts.map +1 -1
- package/dist/channels/slack/log.js +1 -1
- package/dist/channels/slack/manifest.js +1 -1
- package/dist/channels/slack/nudge-carrier.js +1 -1
- package/dist/channels/slack/nudge-store.js +2 -2
- package/dist/channels/slack/recording-sink.js +6 -6
- package/dist/channels/slack/reply-options.js +6 -6
- package/dist/channels/slack/self-identity.d.ts +7 -4
- package/dist/channels/slack/self-identity.d.ts.map +1 -1
- package/dist/channels/slack/self-identity.js +17 -8
- package/dist/channels/slack/sender-name.d.ts.map +1 -1
- package/dist/channels/slack/sender-name.js +2 -6
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +1 -1
- package/dist/channels/slack/slack-channel.js +2 -2
- package/dist/channels/slack/socket-mode.js +2 -2
- package/dist/channels/slack/thread-context.js +8 -8
- package/dist/channels/slack/tool-cards.js +1 -1
- package/dist/channels/slack/user-info.d.ts +2 -1
- package/dist/channels/slack/user-info.d.ts.map +1 -1
- package/dist/channels/slack/user-info.js +16 -1
- package/dist/channels.js +1 -1
- package/dist/docs/404.html +3 -3
- package/dist/docs/assets/{app.DXI7bwox.js → app.CaLG1pPt.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.DvlKuIO-.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BrbO5mEe.js → VPLocalSearchBox.YsP_2wqD.js} +2 -2
- package/dist/docs/assets/chunks/{arc.BOG1yms8.js → arc.C2j9hR7c.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.C0hsMZnZ.js → architectureDiagram-Q4EWVU46.C5qkGp7y.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.H044KjKs.js → baseUniq.U6GgTHOD.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.BsRW6GoB.js → blockDiagram-DXYQGD6D.D51mJop2.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.B9HV5PFR.js → c4Diagram-AHTNJAMY.w1d6QxV7.js} +1 -1
- package/dist/docs/assets/chunks/channel.BRSFxCcD.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CPoT_ajl.js → chunk-4BX2VUAB.B_A815un.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DZBwWuCL.js → chunk-4TB4RGXK.DMrm-ZCb.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.CZ3yTiyq.js → chunk-55IACEB6.8qw6Xdal.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.6DfvHSd8.js → chunk-EDXVE4YY.Cq_nHODn.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CpBj8HfK.js → chunk-FMBD7UC4.B67ohCYn.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.BdKo8YqS.js → chunk-OYMX7WX6.Bo8rQI8F.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BnXNyxJx.js → chunk-QZHKN3VN.BERUMfE9.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.Cg1OcF8G.js → chunk-YZCP3GAM.DWG2tXIX.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Cmtm6WkN.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Cmtm6WkN.js +1 -0
- package/dist/docs/assets/chunks/clone.JMC96Eo6.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.1SP8al9c.js → cose-bilkent-S5V4N54A.tezXBs9b.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.DS1L6hJt.js → dagre-KV5264BT.aSbEUwT7.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.ChsausbG.js → diagram-5BDNPKRD.vnT6aJ57.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.3XsptNWj.js → diagram-G4DWMVQ6.hGYdrDa2.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DPA9Dk_P.js → diagram-MMDJMWI5.CmdSUP6L.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.BVswXWrB.js → diagram-TYMM5635.BbAnLEBB.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.BSak5OSP.js → erDiagram-SMLLAGMA.H40W4HWE.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.CQgN4TTz.js → flowDiagram-DWJPFMVM.BFMtUSv-.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.GrT0kA4a.js → ganttDiagram-T4ZO3ILL.CbYiu7Dt.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CdS7Ucll.js → gitGraphDiagram-UUTBAWPF.Cyc5mzZD.js} +1 -1
- package/dist/docs/assets/chunks/{graph.BVqKRmRo.js → graph.BRptDG1H.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.C3C9FRto.js → infoDiagram-42DDH7IO.Bz6KCA3a.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.2FuAh_Zj.js → ishikawaDiagram-UXIWVN3A.DDJ_7_Fq.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CaHMfK4b.js → journeyDiagram-VCZTEJTY.D0t_ltlb.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CjhIUwcA.js → kanban-definition-6JOO6SKY.DyyNsMfi.js} +1 -1
- package/dist/docs/assets/chunks/{layout.CGU3gfSf.js → layout.Cbxq-Rhp.js} +1 -1
- package/dist/docs/assets/chunks/{linear.DaihpW_n.js → linear.DxGYL0MP.js} +1 -1
- package/dist/docs/assets/chunks/{min.BS-j8kHQ.js → min.DA5KL8wu.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.BVJ1Bbnk.js → mindmap-definition-QFDTVHPH.Bc72Utls.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.Cz1WIv9r.js → pieDiagram-DEJITSTG.BtpHnIB_.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.DKLFxcjy.js → quadrantDiagram-34T5L4WZ.Cx4oCSRR.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.BHegiK7x.js → requirementDiagram-MS252O5E.BC0hXWlW.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.DYkY6yPc.js → sankeyDiagram-XADWPNL6.Dg8T1SEp.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.DYQ1QUrI.js → sequenceDiagram-FGHM5R23.CWSdHYAF.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.Iru8BsFo.js → stateDiagram-FHFEXIEX.0MVPRI28.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.N4Am6sXd.js +1 -0
- package/dist/docs/assets/chunks/{theme.DaplWQhQ.js → theme.DO1avLBn.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BwFA8hiX.js → timeline-definition-GMOUNBTQ.BuRinAVi.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CZ60W1C_.js → vennDiagram-DHZGUBPP.DXf0PCoJ.js} +1 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD._eATmGtu.js +162 -0
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.B69D2r8-.js → wardleyDiagram-NUSXRM2D.T4ThngYV.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CLPZEIU9.js → xychartDiagram-5P7HB3ND.b4pZF3D5.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.Bljpve-y.js → reference_connections.md.DLrgAd5f.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.C5LCJ1R3.js → reference_hooks.md.B-eGa2km.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.C5LCJ1R3.lean.js → reference_hooks.md.B-eGa2km.lean.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.CM5zo3w4.js → reference_sessions.md.CyM7ARz1.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.ClkMoQsV.js → reference_skills.md.C0guGcH0.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.v3SXVSs_.js → reference_tools.md.DzIY9JzY.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.v3SXVSs_.lean.js → reference_tools.md.DzIY9JzY.lean.js} +1 -1
- package/dist/docs/assets/{style.C130MVnH.css → style.Dwls12uf.css} +1 -1
- package/dist/docs/building-with-agents.html +37 -37
- package/dist/docs/deployment.html +37 -37
- package/dist/docs/evals.html +37 -37
- package/dist/docs/guides/agent-to-agent.html +37 -37
- package/dist/docs/guides/bitbucket.html +37 -37
- package/dist/docs/guides/cloud-agents.html +37 -37
- package/dist/docs/guides/convert-automation.html +37 -37
- package/dist/docs/guides/github.html +37 -37
- package/dist/docs/guides/gitlab.html +37 -37
- package/dist/docs/guides/grokbot-agents.html +37 -37
- package/dist/docs/guides/hooks.html +37 -37
- package/dist/docs/guides/improve.html +37 -37
- package/dist/docs/guides/jev.html +37 -37
- package/dist/docs/guides/mcp-oauth.html +37 -37
- package/dist/docs/guides/migrate.html +37 -37
- package/dist/docs/guides/opentelemetry.html +37 -37
- package/dist/docs/guides/slack.html +37 -37
- package/dist/docs/guides/webhooks.html +37 -37
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +37 -37
- package/dist/docs/index.html +37 -37
- package/dist/docs/llms-full.txt +15 -2
- package/dist/docs/quickstart.html +37 -37
- package/dist/docs/reference/agent-config.html +37 -37
- package/dist/docs/reference/artifacts.html +37 -37
- package/dist/docs/reference/channels.html +37 -37
- package/dist/docs/reference/cli.html +37 -37
- package/dist/docs/reference/connections.html +39 -39
- package/dist/docs/reference/connections.md +2 -1
- package/dist/docs/reference/evals.html +37 -37
- package/dist/docs/reference/extensions.html +37 -37
- package/dist/docs/reference/hooks.html +39 -39
- package/dist/docs/reference/hooks.md +1 -0
- package/dist/docs/reference/http-api.html +37 -37
- package/dist/docs/reference/instructions.html +37 -37
- package/dist/docs/reference/playground.html +36 -36
- package/dist/docs/reference/project-layout.html +37 -37
- package/dist/docs/reference/prompt.html +37 -37
- package/dist/docs/reference/schedules.html +37 -37
- package/dist/docs/reference/sessions.html +37 -37
- package/dist/docs/reference/sessions.md +1 -1
- package/dist/docs/reference/skills.html +40 -40
- package/dist/docs/reference/subagents.html +37 -37
- package/dist/docs/reference/tools.html +39 -39
- package/dist/docs/reference/tools.md +11 -0
- package/dist/docs/templates/agentic-owners.html +37 -37
- package/dist/docs/templates/grokbot-agents.html +37 -37
- package/dist/docs/templates/security-reviewer.html +37 -37
- package/dist/docs/templates/thermo-quality-review.html +37 -37
- package/dist/docs/templates/thermo-review.html +37 -37
- package/dist/docs/templates/triage.html +37 -37
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/evals/assertions.d.ts.map +1 -1
- package/dist/evals/assertions.js +21 -19
- package/dist/evals/expect.js +1 -1
- package/dist/evals/judge.js +1 -1
- package/dist/evals/reporters.js +8 -8
- package/dist/evals/run-facts.js +2 -2
- package/dist/evals.js +6 -6
- package/dist/extensions/cursor-cloud-agents/extension.d.ts +2 -0
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/extension.js +2 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +16 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +44 -3
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts +23 -0
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.js +32 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +2 -2
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -2
- package/dist/extensions/cursor-cloud-agents/lib/watch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/watch.js +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +3 -8
- package/dist/extensions/cursor-cloud-agents/tools/list.js +1 -1
- package/dist/extensions/cursor-grokbot-agents/extension.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/agents.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +4 -4
- package/dist/extensions/cursor-grokbot-agents/tools/list.js +1 -1
- package/dist/extensions/improve/skills/yourself.js +1 -1
- package/dist/extensions/jev/extension.js +2 -2
- package/dist/extensions/jev/tools/evaluate.js +1 -1
- package/dist/extensions/slack-communication/tools/react.js +1 -1
- package/dist/files-backends/cursor-hosted.js +8 -8
- package/dist/files-backends/local-fs.js +1 -1
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +15 -15
- package/dist/internal/advertise-tools.d.ts +3 -2
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +11 -9
- package/dist/internal/approval-gate.js +1 -1
- package/dist/internal/artifacts-store.js +13 -13
- package/dist/internal/as-of.js +2 -2
- package/dist/internal/authored-alias-hooks.d.ts +4 -3
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
- package/dist/internal/authored-alias-hooks.js +16 -7
- package/dist/internal/authored-loaders.d.ts.map +1 -1
- package/dist/internal/authored-loaders.js +21 -5
- package/dist/internal/builtin-tools/reminders.js +2 -2
- package/dist/internal/chat-client.js +5 -5
- package/dist/internal/cli-ax.js +14 -14
- package/dist/internal/cli-bitbucket.js +10 -10
- package/dist/internal/cli-convert-automation.js +2 -2
- package/dist/internal/cli-cursor.js +2 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +40 -40
- package/dist/internal/cli-docs.js +5 -5
- package/dist/internal/cli-github.js +15 -15
- package/dist/internal/cli-gitlab.js +10 -10
- package/dist/internal/cli-images.js +16 -16
- package/dist/internal/cli-manifest.js +1 -1
- package/dist/internal/cli-mcp-oauth.js +5 -5
- package/dist/internal/cli-mcp.js +3 -3
- package/dist/internal/cli-migrate.js +1 -1
- package/dist/internal/cli-skills.js +2 -2
- package/dist/internal/cli-slack.js +5 -5
- package/dist/internal/cloud-turn-cost.js +1 -1
- package/dist/internal/continuation-identity.js +6 -6
- package/dist/internal/conversation-mirror.js +5 -5
- package/dist/internal/convert-automation/convert-workflow.js +24 -24
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +20 -20
- package/dist/internal/cursor/backend-client.js +6 -6
- package/dist/internal/cursor/credentials.js +1 -1
- package/dist/internal/cursor/store-api-client.js +1 -1
- package/dist/internal/cursor-account-mcp-auth.js +9 -9
- package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
- package/dist/internal/cursor-deployment-relay.js +9 -9
- package/dist/internal/cursor-event-relay.js +10 -10
- package/dist/internal/cursor-relay-core.js +2 -2
- package/dist/internal/deploy-manifest.d.ts +14 -0
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +33 -10
- package/dist/internal/discovery/agent-config.js +2 -2
- package/dist/internal/discovery/agent.js +6 -6
- package/dist/internal/discovery/connections.js +5 -5
- package/dist/internal/discovery/cursor-plugin.js +12 -12
- package/dist/internal/discovery/extension-overlay.js +3 -3
- package/dist/internal/discovery/extensions.js +6 -6
- package/dist/internal/discovery/info.js +9 -9
- package/dist/internal/discovery/instructions.js +1 -1
- package/dist/internal/discovery/project.js +3 -3
- package/dist/internal/discovery/services.js +1 -1
- package/dist/internal/discovery/tools.js +1 -1
- package/dist/internal/docs-site.js +2 -2
- package/dist/internal/env-file.js +1 -1
- package/dist/internal/eval-run-store.js +7 -7
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +14 -14
- package/dist/internal/eval-transport.js +1 -1
- package/dist/internal/evals-client.d.ts.map +1 -1
- package/dist/internal/evals-client.js +4 -4
- package/dist/internal/event-log.js +8 -8
- package/dist/internal/event-mapper.js +13 -13
- package/dist/internal/expected-delivery-failure.js +2 -2
- package/dist/internal/filesystem/format.js +2 -2
- package/dist/internal/filesystem/nearest.js +3 -3
- package/dist/internal/filesystem/scratch.js +3 -3
- package/dist/internal/filesystem/tools.js +6 -6
- package/dist/internal/filesystem/walk.d.ts.map +1 -1
- package/dist/internal/filesystem/walk.js +2 -2
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +6 -5
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +4 -2
- package/dist/internal/github-fanout.d.ts.map +1 -1
- package/dist/internal/github-fanout.js +3 -3
- package/dist/internal/guest-network.js +4 -4
- package/dist/internal/host-files.js +1 -1
- package/dist/internal/host-kv.js +2 -2
- package/dist/internal/hosted-catch-protocol.js +1 -1
- package/dist/internal/hosted-catch.js +1 -1
- package/dist/internal/hosted-delivery-protocol.d.ts +24 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +58 -14
- package/dist/internal/hosted-delivery.d.ts +6 -0
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +64 -13
- package/dist/internal/hosted-eval-cases.js +4 -4
- package/dist/internal/hosted-execution-diag.js +3 -3
- package/dist/internal/hosted-managed-automation.d.ts +3 -3
- package/dist/internal/hosted-managed-automation.js +3 -3
- package/dist/internal/hosting.js +1 -1
- package/dist/internal/http-channel.js +1 -1
- package/dist/internal/http-control-plane-session.js +2 -2
- package/dist/internal/init-interview.js +7 -7
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +12 -12
- package/dist/internal/inline-stdio-mcp.js +2 -2
- package/dist/internal/install-cursor-skills.js +11 -11
- package/dist/internal/json-schema.js +1 -1
- package/dist/internal/local-control-plane.js +3 -3
- package/dist/internal/local-env.js +3 -3
- package/dist/internal/log-ring.js +1 -1
- package/dist/internal/logs-client.js +1 -1
- package/dist/internal/mcp-endpoint.js +8 -8
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +5 -5
- package/dist/internal/mcp-oauth-on-demand.js +3 -3
- package/dist/internal/mcp-oauth.js +5 -5
- package/dist/internal/net.js +2 -2
- package/dist/internal/otel/config.js +3 -3
- package/dist/internal/otel/runtime.js +13 -13
- package/dist/internal/peer-connections.js +2 -2
- package/dist/internal/persistent-stage-log-mirror.d.ts +57 -0
- package/dist/internal/persistent-stage-log-mirror.d.ts.map +1 -0
- package/dist/internal/persistent-stage-log-mirror.js +231 -0
- package/dist/internal/platform-schedule-sync.js +1 -1
- package/dist/internal/platform-timers.js +1 -1
- package/dist/internal/playground/static.js +2 -2
- package/dist/internal/playground/toolchain.js +2 -2
- package/dist/internal/playground-proxy.js +3 -3
- package/dist/internal/process-memory-telemetry.js +1 -1
- package/dist/internal/reminder-runner.d.ts +1 -1
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +14 -16
- package/dist/internal/reminder-store.js +1 -1
- package/dist/internal/resolved-connections.js +8 -8
- package/dist/internal/router.js +4 -4
- package/dist/internal/run-client.js +2 -2
- package/dist/internal/schedule-runner.d.ts +13 -2
- package/dist/internal/schedule-runner.d.ts.map +1 -1
- package/dist/internal/schedule-runner.js +48 -9
- package/dist/internal/sdk-runner.d.ts +2 -1
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +13 -8
- package/dist/internal/serve-restart.js +1 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +101 -76
- package/dist/internal/session-cost.js +3 -3
- package/dist/internal/session-engine.d.ts +8 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +183 -118
- package/dist/internal/session-live-publisher.d.ts +48 -0
- package/dist/internal/session-live-publisher.d.ts.map +1 -0
- package/dist/internal/session-live-publisher.js +415 -0
- package/dist/internal/session-run-log.js +6 -6
- package/dist/internal/sessions-client.js +3 -3
- package/dist/internal/skill-catalog.js +2 -2
- package/dist/internal/sleep.js +1 -1
- package/dist/internal/start-log-store.d.ts +5 -1
- package/dist/internal/start-log-store.d.ts.map +1 -1
- package/dist/internal/start-log-store.js +5 -3
- package/dist/internal/storage-coordinator.js +12 -12
- package/dist/internal/store-api-protocol.d.ts +51 -0
- package/dist/internal/store-api-protocol.d.ts.map +1 -1
- package/dist/internal/store-api-protocol.js +39 -2
- package/dist/internal/store-mirror.js +4 -4
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +4 -0
- package/dist/internal/terminal-style.js +2 -2
- package/dist/internal/testing/conversation-identity-vectors.d.ts +48 -0
- package/dist/internal/testing/conversation-identity-vectors.d.ts.map +1 -0
- package/dist/internal/testing/conversation-identity-vectors.js +136 -0
- package/dist/internal/tool-call-retry.d.ts +87 -0
- package/dist/internal/tool-call-retry.d.ts.map +1 -0
- package/dist/internal/tool-call-retry.js +387 -0
- package/dist/internal/tool-result.js +3 -3
- package/dist/internal/trajectory.js +7 -7
- package/dist/internal/turn-governor.js +2 -2
- package/dist/internal/turn-outbox.js +1 -1
- package/dist/internal/update-check.d.ts.map +1 -1
- package/dist/internal/update-check.js +4 -2
- package/dist/internal/v2-hosting.d.ts +6 -0
- package/dist/internal/v2-hosting.d.ts.map +1 -1
- package/dist/internal/v2-hosting.js +7 -1
- package/dist/internal/workspace.js +4 -4
- package/dist/kv/memory-kv.js +3 -3
- package/dist/playground/assets/index-CzttDc-d.css +1 -0
- package/dist/playground/assets/{index-Be0-1hw2.js → index-DIiKbZ25.js} +42 -42
- package/dist/playground/index.html +2 -2
- package/dist/prompt.js +1 -1
- package/dist/storage-backends/cursor-hosted-v2.js +2 -2
- package/dist/storage-backends/file-kv.js +7 -7
- package/dist/storage-protocol.d.ts +7 -0
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +7 -0
- package/dist/storage.js +3 -3
- package/dist/types.d.ts +21 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -4
- package/docs/reference/connections.md +2 -1
- package/docs/reference/hooks.md +1 -0
- package/docs/reference/sessions.md +1 -1
- package/docs/reference/tools.md +11 -0
- package/package.json +6 -6
- package/templates/agentic-owners/bot/channels/github.ts +2 -2
- package/templates/agentic-owners/bot/lib/github.ts +7 -5
- package/templates/agentic-owners/bot/lib/owners/decision.ts +9 -9
- package/templates/agentic-owners/bot/lib/owners/handles.ts +2 -2
- package/templates/agentic-owners/bot/lib/owners/match.ts +5 -3
- package/templates/agentic-owners/bot/lib/owners/matching.ts +1 -1
- package/templates/agentic-owners/bot/lib/owners/parse.ts +4 -4
- package/templates/agentic-owners/bot/lib/owners/prompt.ts +1 -1
- package/templates/agentic-owners/bot/lib/review.ts +18 -17
- package/templates/agentic-owners/evals/owners.eval.ts +2 -2
- package/templates/agents-md/bot/lib/collect.ts +6 -6
- package/templates/agents-md/bot/lib/config.ts +1 -1
- package/templates/agents-md/bot/tools/apply_agents.ts +4 -4
- package/templates/code-wiki/bot/channels/github.ts +3 -3
- package/templates/code-wiki/bot/lib/repos.ts +1 -1
- package/templates/code-wiki/bot/tools/apply_wiki.ts +2 -2
- package/templates/demo/bot/lib/collect.ts +1 -1
- package/templates/demo/bot/lib/repos.ts +1 -1
- package/templates/demo/bot/tools/record_demo.ts +1 -1
- package/templates/pr-autofixer/bot/channels/github.ts +2 -2
- package/templates/pr-autofixer/bot/lib/merge-watch.ts +2 -2
- package/templates/pr-autofixer/bot/lib/repos.ts +2 -2
- package/templates/pr-autofixer/bot/lib/webhook-routing.ts +1 -1
- package/templates/security-help/bot/lib/repos.ts +1 -1
- package/templates/security-reviewer/bot/lib/repos.ts +1 -1
- package/templates/triage/bot/lib/actuate.ts +15 -15
- package/dist/docs/assets/chunks/@localSearchIndexroot.CtLtpWcx.js +0 -1
- package/dist/docs/assets/chunks/channel.CBwrU9rP.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CbC_mrvB.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CbC_mrvB.js +0 -1
- package/dist/docs/assets/chunks/clone.BTvFyY1a.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.BYXl4LW6.js +0 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.iXazD3Z7.js +0 -162
- package/dist/playground/assets/index-Clz6uHj9.css +0 -1
- /package/dist/docs/assets/{reference_connections.md.Bljpve-y.lean.js → reference_connections.md.DLrgAd5f.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.CM5zo3w4.lean.js → reference_sessions.md.CyM7ARz1.lean.js} +0 -0
- /package/dist/docs/assets/{reference_skills.md.ClkMoQsV.lean.js → reference_skills.md.C0guGcH0.lean.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as y,s as Nt,g as zt,t as At,q as Xt,a as Ct,b as Et,l as et,L as Tt,e as Yt,A as Bt,c as H,i as Rt}from"../app.
|
|
1
|
+
import{_ as y,s as Nt,g as zt,t as At,q as Xt,a as Ct,b as Et,l as et,L as Tt,e as Yt,A as Bt,c as H,i as Rt}from"../app.CaLG1pPt.js";import{p as Ft}from"./chunk-4BX2VUAB.B_A815un.js";import{p as Ot}from"./wardley-RL74JXVD._eATmGtu.js";import"./framework.BNw1pucY.js";import"./theme.DO1avLBn.js";import"./min.DA5KL8wu.js";import"./baseUniq.U6GgTHOD.js";var q=y((a,r)=>{const e=a<=1?a*100:a;if(e<0||e>100)throw new Error(`${r} must be between 0-1 (decimal) or 0-100 (percentage). Received: ${a}`);return e},"toPercent"),Y=y((a,r,e)=>({x:q(r,`${e} evolution`),y:q(a,`${e} visibility`)}),"toCoordinates"),tt=y(a=>{if(a){if(a==="+<>")return"bidirectional";if(a==="+<")return"backward";if(a==="+>")return"forward"}},"getFlowFromPort"),It=y(a=>{if(!(a!=null&&a.startsWith("+")))return{};const r=/^\+'([^']*)'/.exec(a),e=r==null?void 0:r[1];return a.includes("<>")?{flow:"bidirectional",label:e}:a.includes("<")?{flow:"backward",label:e}:a.includes(">")?{flow:"forward",label:e}:{label:e}},"extractFlowFromArrow"),Wt=y((a,r)=>{if(Ft(a,r),a.size&&r.setSize(a.size.width,a.size.height),a.evolution){const e=a.evolution.stages.map(o=>o.secondName?`${o.name.trim()} / ${o.secondName.trim()}`:o.name.trim()),h=a.evolution.stages.filter(o=>o.boundary!==void 0).map(o=>o.boundary);r.updateAxes({stages:e,stageBoundaries:h})}if(a.anchors.forEach(e=>{const h=Y(e.visibility,e.evolution,`Anchor "${e.name}"`);r.addNode(e.name,e.name,h.x,h.y,"anchor")}),a.components.forEach(e=>{var v;const h=Y(e.visibility,e.evolution,`Component "${e.name}"`),o=e.label?(e.label.negX?-1:1)*e.label.offsetX:void 0,d=e.label?(e.label.negY?-1:1)*e.label.offsetY:void 0,m=(v=e.decorator)==null?void 0:v.strategy;r.addNode(e.name,e.name,h.x,h.y,"component",o,d,e.inertia,m)}),a.notes.forEach(e=>{const h=Y(e.visibility,e.evolution,`Note "${e.text}"`);r.addNote(e.text,h.x,h.y)}),a.pipelines.forEach(e=>{const h=r.getNode(e.parent);if(!h||typeof h.y!="number")throw new Error(`Pipeline "${e.parent}" must reference an existing component with coordinates.`);const o=h.y;r.startPipeline(e.parent),e.components.forEach(d=>{const m=`${e.parent}_${d.name}`,v=d.label?(d.label.negX?-1:1)*d.label.offsetX:void 0,g=d.label?(d.label.negY?-1:1)*d.label.offsetY:void 0,X=q(d.evolution,`Pipeline component "${d.name}" evolution`);r.addNode(m,d.name,X,o,"pipeline-component",v,g),r.addPipelineComponent(e.parent,m)})}),a.links.forEach(e=>{const h=!!e.arrow&&(e.arrow.includes("-.->")||e.arrow.includes(".-."));let o=tt(e.fromPort)??tt(e.toPort);const{flow:d,label:m}=It(e.arrow);!o&&d&&(o=d);const v=e.linkLabel,g=m??v;r.addLink(e.from,e.to,h,g,o)}),a.evolves.forEach(e=>{const h=r.getNode(e.component);if((h==null?void 0:h.y)!==void 0){const o=q(e.target,`Evolve target for "${e.component}"`);r.addTrend(e.component,o,h.y)}}),a.annotations.length>0){const e=a.annotations[0],h=Y(e.x,e.y,"Annotations box");r.setAnnotationsBox(h.x,h.y)}a.annotation.forEach(e=>{const h=Y(e.x,e.y,`Annotation ${e.number}`);r.addAnnotation(e.number,[{x:h.x,y:h.y}],e.text)}),a.accelerators.forEach(e=>{const h=Y(e.x,e.y,`Accelerator "${e.name}"`);r.addAccelerator(e.name,h.x,h.y)}),a.deaccelerators.forEach(e=>{const h=Y(e.x,e.y,`Deaccelerator "${e.name}"`);r.addDeaccelerator(e.name,h.x,h.y)})},"populateDb"),at={parser:{yy:void 0},parse:y(async a=>{var h;const r=await Ot("wardley",a);et.debug(r);const e=(h=at.parser)==null?void 0:h.yy;if(!e||typeof e.addNode!="function")throw new Error("parser.parser?.yy was not a WardleyDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");Wt(r,e)},"parse")},R,Dt=(R=class{constructor(){this.nodes=new Map,this.links=[],this.trends=new Map,this.pipelines=new Map,this.annotations=[],this.notes=[],this.accelerators=[],this.deaccelerators=[],this.axes={}}addNode(r){const e=this.nodes.get(r.id)??{id:r.id,label:r.label},h={...e,...r,className:r.className??e.className,labelOffsetX:r.labelOffsetX??e.labelOffsetX,labelOffsetY:r.labelOffsetY??e.labelOffsetY};this.nodes.set(r.id,h)}addLink(r){this.links.push(r)}addTrend(r){this.trends.set(r.nodeId,r)}startPipeline(r){this.pipelines.set(r,{nodeId:r,componentIds:[]});const e=this.nodes.get(r);e&&(e.isPipelineParent=!0)}addPipelineComponent(r,e){const h=this.pipelines.get(r);h&&h.componentIds.push(e);const o=this.nodes.get(e);o&&(o.inPipeline=!0)}addAnnotation(r){this.annotations.push(r)}addNote(r){this.notes.push(r)}addAccelerator(r){this.accelerators.push(r)}addDeaccelerator(r){this.deaccelerators.push(r)}setAnnotationsBox(r,e){this.annotationsBox={x:r,y:e}}setAxes(r){this.axes={...this.axes,...r}}setSize(r,e){this.size={width:r,height:e}}getNode(r){return this.nodes.get(r)}build(){const r=[];for(const e of this.nodes.values()){if(typeof e.x!="number"||typeof e.y!="number")throw new Error(`Node "${e.label}" is missing coordinates`);r.push(e)}return{nodes:r,links:[...this.links],trends:[...this.trends.values()],pipelines:[...this.pipelines.values()],annotations:[...this.annotations],notes:[...this.notes],accelerators:[...this.accelerators],deaccelerators:[...this.deaccelerators],annotationsBox:this.annotationsBox,axes:{...this.axes},size:this.size}}clear(){this.nodes.clear(),this.links=[],this.trends.clear(),this.pipelines.clear(),this.annotations=[],this.notes=[],this.accelerators=[],this.deaccelerators=[],this.annotationsBox=void 0,this.axes={},this.size=void 0}},y(R,"WardleyBuilder"),R),P=new Dt;function L(a){const r=H();return Rt(a.trim(),r)}y(L,"textSanitizer");function rt(){return H()["wardley-beta"]}y(rt,"getConfig");function ot(a,r,e,h,o,d,m,v,g){P.addNode({id:a,label:L(r),x:e,y:h,className:o,labelOffsetX:d,labelOffsetY:m,inertia:v,sourceStrategy:g})}y(ot,"addNode");function st(a,r,e=!1,h,o){P.addLink({source:a,target:r,dashed:e,label:h,flow:o})}y(st,"addLink");function nt(a,r,e){P.addTrend({nodeId:a,targetX:r,targetY:e})}y(nt,"addTrend");function it(a,r,e){P.addAnnotation({number:a,coordinates:r,text:e?L(e):void 0})}y(it,"addAnnotation");function dt(a,r,e){P.addNote({text:L(a),x:r,y:e})}y(dt,"addNote");function lt(a,r,e){P.addAccelerator({name:L(a),x:r,y:e})}y(lt,"addAccelerator");function ct(a,r,e){P.addDeaccelerator({name:L(a),x:r,y:e})}y(ct,"addDeaccelerator");function pt(a,r){P.setAnnotationsBox(a,r)}y(pt,"setAnnotationsBox");function ht(a,r){P.setSize(a,r)}y(ht,"setSize");function xt(a){P.startPipeline(a)}y(xt,"startPipeline");function ft(a,r){P.addPipelineComponent(a,r)}y(ft,"addPipelineComponent");function gt(a){const r={};a.xLabel&&(r.xLabel=L(a.xLabel)),a.yLabel&&(r.yLabel=L(a.yLabel)),a.stages&&(r.stages=a.stages.map(e=>L(e))),a.stageBoundaries&&(r.stageBoundaries=a.stageBoundaries),P.setAxes(r)}y(gt,"updateAxes");function ut(a){return P.getNode(a)}y(ut,"getNode");function yt(){return P.build()}y(yt,"getWardleyData");function mt(){P.clear(),Bt()}y(mt,"clear");var Gt={getConfig:rt,addNode:ot,addLink:st,addTrend:nt,addAnnotation:it,addNote:dt,addAccelerator:lt,addDeaccelerator:ct,setAnnotationsBox:pt,setSize:ht,startPipeline:xt,addPipelineComponent:ft,updateAxes:gt,getNode:ut,getWardleyData:yt,clear:mt,setAccTitle:Et,getAccTitle:Ct,setDiagramTitle:Xt,getDiagramTitle:At,getAccDescription:zt,setAccDescription:Nt},qt=["Genesis","Custom Built","Product","Commodity"],Ht=y(()=>{var r,e,h,o,d,m,v,g,X,M,b,N;const{themeVariables:a}=H();return{backgroundColor:((r=a.wardley)==null?void 0:r.backgroundColor)??a.background??"#fff",axisColor:((e=a.wardley)==null?void 0:e.axisColor)??"#000",axisTextColor:((h=a.wardley)==null?void 0:h.axisTextColor)??a.primaryTextColor??"#222",gridColor:((o=a.wardley)==null?void 0:o.gridColor)??"rgba(100, 100, 100, 0.2)",componentFill:((d=a.wardley)==null?void 0:d.componentFill)??"#fff",componentStroke:((m=a.wardley)==null?void 0:m.componentStroke)??"#000",componentLabelColor:((v=a.wardley)==null?void 0:v.componentLabelColor)??a.primaryTextColor??"#222",linkStroke:((g=a.wardley)==null?void 0:g.linkStroke)??"#000",evolutionStroke:((X=a.wardley)==null?void 0:X.evolutionStroke)??"#dc3545",annotationStroke:((M=a.wardley)==null?void 0:M.annotationStroke)??"#000",annotationTextColor:((b=a.wardley)==null?void 0:b.annotationTextColor)??a.primaryTextColor??"#222",annotationFill:((N=a.wardley)==null?void 0:N.annotationFill)??a.background??"#fff"}},"getTheme"),jt=y(()=>{const a=H()["wardley-beta"];return{width:(a==null?void 0:a.width)??900,height:(a==null?void 0:a.height)??600,padding:(a==null?void 0:a.padding)??48,nodeRadius:(a==null?void 0:a.nodeRadius)??6,nodeLabelOffset:(a==null?void 0:a.nodeLabelOffset)??8,axisFontSize:(a==null?void 0:a.axisFontSize)??12,labelFontSize:(a==null?void 0:a.labelFontSize)??10,showGrid:(a==null?void 0:a.showGrid)??!1,useMaxWidth:(a==null?void 0:a.useMaxWidth)??!0}},"getConfigValues"),_t=y((a,r,e,h)=>{var K,Q;et.debug(`Rendering Wardley map
|
|
2
2
|
`+a);const o=jt(),d=Ht(),m=o.nodeRadius*1.6,v=h.db,g=v.getWardleyData(),X=v.getDiagramTitle(),M=((K=g.size)==null?void 0:K.width)??o.width,b=((Q=g.size)==null?void 0:Q.height)??o.height,N=Tt(r);N.selectAll("*").remove(),Yt(N,b,M,o.useMaxWidth),N.attr("viewBox",`0 0 ${M} ${b}`);const S=N.append("g").attr("class","wardley-map"),j=N.append("defs");j.append("marker").attr("id",`arrow-${r}`).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerWidth",6).attr("markerHeight",6).attr("orient","auto-start-reverse").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("fill",d.evolutionStroke).attr("stroke","none"),j.append("marker").attr("id",`link-arrow-end-${r}`).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerWidth",5).attr("markerHeight",5).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("fill",d.linkStroke).attr("stroke","none"),j.append("marker").attr("id",`link-arrow-start-${r}`).attr("viewBox","0 0 10 10").attr("refX",1).attr("refY",5).attr("markerWidth",5).attr("markerHeight",5).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z").attr("fill",d.linkStroke).attr("stroke","none"),S.append("rect").attr("class","wardley-background").attr("width",M).attr("height",b).attr("fill",d.backgroundColor);const F=M-o.padding*2,O=b-o.padding*2;X&&S.append("text").attr("class","wardley-title").attr("x",M/2).attr("y",o.padding/2).attr("fill",d.axisTextColor).attr("font-size",o.axisFontSize*1.05).attr("font-weight","bold").attr("text-anchor","middle").attr("dominant-baseline","middle").text(X);const C=y(t=>o.padding+t/100*F,"projectX"),E=y(t=>b-o.padding-t/100*O,"projectY"),W=S.append("g").attr("class","wardley-axes");W.append("line").attr("x1",o.padding).attr("x2",M-o.padding).attr("y1",b-o.padding).attr("y2",b-o.padding).attr("stroke",d.axisColor).attr("stroke-width",1),W.append("line").attr("x1",o.padding).attr("x2",o.padding).attr("y1",o.padding).attr("y2",b-o.padding).attr("stroke",d.axisColor).attr("stroke-width",1);const wt=g.axes.xLabel??"Evolution",bt=g.axes.yLabel??"Visibility";W.append("text").attr("class","wardley-axis-label wardley-axis-label-x").attr("x",o.padding+F/2).attr("y",b-o.padding/4).attr("fill",d.axisTextColor).attr("font-size",o.axisFontSize).attr("font-weight","bold").attr("text-anchor","middle").text(wt),W.append("text").attr("class","wardley-axis-label wardley-axis-label-y").attr("x",o.padding/3).attr("y",o.padding+O/2).attr("fill",d.axisTextColor).attr("font-size",o.axisFontSize).attr("font-weight","bold").attr("text-anchor","middle").attr("transform",`rotate(-90 ${o.padding/3} ${o.padding+O/2})`).text(bt);const I=g.axes.stages&&g.axes.stages.length>0?g.axes.stages:qt;if(I.length>0){const t=S.append("g").attr("class","wardley-stages"),n=g.axes.stageBoundaries,s=[];if(n&&n.length===I.length){let i=0;n.forEach(p=>{s.push({start:i,end:p}),i=p})}else{const i=1/I.length;I.forEach((p,l)=>{s.push({start:l*i,end:(l+1)*i})})}I.forEach((i,p)=>{const l=s[p],x=o.padding+l.start*F,f=o.padding+l.end*F,u=(x+f)/2;p>0&&t.append("line").attr("x1",x).attr("x2",x).attr("y1",o.padding).attr("y2",b-o.padding).attr("stroke","#000").attr("stroke-width",1).attr("stroke-dasharray","5 5").attr("opacity",.8),t.append("text").attr("class","wardley-stage-label").attr("x",u).attr("y",b-o.padding/1.5).attr("fill",d.axisTextColor).attr("font-size",o.axisFontSize-2).attr("text-anchor","middle").text(i)})}if(o.showGrid){const t=S.append("g").attr("class","wardley-grid");for(let n=1;n<4;n++){const s=n/4,i=o.padding+F*s;t.append("line").attr("x1",i).attr("x2",i).attr("y1",o.padding).attr("y2",b-o.padding).attr("stroke",d.gridColor).attr("stroke-dasharray","2 6"),t.append("line").attr("x1",o.padding).attr("x2",M-o.padding).attr("y1",b-o.padding-O*s).attr("y2",b-o.padding-O*s).attr("stroke",d.gridColor).attr("stroke-dasharray","2 6")}}const c=new Map;if(g.nodes.forEach(t=>{c.set(t.id,{x:C(t.x),y:E(t.y),node:t})}),g.pipelines.length>0){const t=S.append("g").attr("class","wardley-pipelines"),n=S.append("g").attr("class","wardley-pipeline-links");g.pipelines.forEach(s=>{if(s.componentIds.length===0)return;const i=s.componentIds.map(f=>({id:f,pos:c.get(f),node:g.nodes.find(u=>u.id===f)})).filter(f=>f.pos&&f.node).sort((f,u)=>f.node.x-u.node.x);for(let f=0;f<i.length-1;f++){const u=i[f],w=i[f+1];n.append("line").attr("class","wardley-pipeline-evolution-link").attr("x1",u.pos.x).attr("y1",u.pos.y).attr("x2",w.pos.x).attr("y2",w.pos.y).attr("stroke",d.linkStroke).attr("stroke-width",1).attr("stroke-dasharray","4 4")}let p=1/0,l=-1/0,x=0;if(s.componentIds.forEach(f=>{const u=c.get(f);u&&(p=Math.min(p,u.x),l=Math.max(l,u.x),x=u.y)}),p!==1/0&&l!==-1/0){const u=o.nodeRadius*4,w=x-u/2,$=c.get(s.nodeId);if($){const A=(p+l)/2;$.x=A,$.y=w-m/6}t.append("rect").attr("class","wardley-pipeline-box").attr("x",p-15).attr("y",w).attr("width",l-p+15*2).attr("height",u).attr("fill","none").attr("stroke",d.axisColor).attr("stroke-width",1.5).attr("rx",4).attr("ry",4)}})}const Z=S.append("g").attr("class","wardley-links"),U=new Map;g.pipelines.forEach(t=>{U.set(t.nodeId,new Set(t.componentIds))});const J=g.links.filter(t=>{if(!c.has(t.source)||!c.has(t.target))return!1;const n=U.get(t.target);return!(n!=null&&n.has(t.source))});Z.selectAll("line").data(J).enter().append("line").attr("class",t=>`wardley-link${t.dashed?" wardley-link--dashed":""}`).attr("x1",t=>{const n=c.get(t.source),s=c.get(t.target),p=g.nodes.find(u=>u.id===t.source).isPipelineParent?m/Math.sqrt(2):o.nodeRadius,l=s.x-n.x,x=s.y-n.y,f=Math.sqrt(l*l+x*x);return n.x+l/f*p}).attr("y1",t=>{const n=c.get(t.source),s=c.get(t.target),p=g.nodes.find(u=>u.id===t.source).isPipelineParent?m/Math.sqrt(2):o.nodeRadius,l=s.x-n.x,x=s.y-n.y,f=Math.sqrt(l*l+x*x);return n.y+x/f*p}).attr("x2",t=>{const n=c.get(t.source),s=c.get(t.target),p=g.nodes.find(u=>u.id===t.target).isPipelineParent?m/Math.sqrt(2):o.nodeRadius,l=n.x-s.x,x=n.y-s.y,f=Math.sqrt(l*l+x*x);return s.x+l/f*p}).attr("y2",t=>{const n=c.get(t.source),s=c.get(t.target),p=g.nodes.find(u=>u.id===t.target).isPipelineParent?m/Math.sqrt(2):o.nodeRadius,l=n.x-s.x,x=n.y-s.y,f=Math.sqrt(l*l+x*x);return s.y+x/f*p}).attr("stroke",d.linkStroke).attr("stroke-width",1).attr("stroke-dasharray",t=>t.dashed?"6 6":null).attr("marker-end",t=>t.flow==="forward"||t.flow==="bidirectional"?`url(#link-arrow-end-${r})`:null).attr("marker-start",t=>t.flow==="backward"||t.flow==="bidirectional"?`url(#link-arrow-start-${r})`:null),Z.selectAll("text").data(J.filter(t=>t.label)).enter().append("text").attr("class","wardley-link-label").attr("x",t=>{const n=c.get(t.source),s=c.get(t.target),i=(n.x+s.x)/2,p=s.y-n.y,l=s.x-n.x,x=Math.sqrt(l*l+p*p),f=8,u=p/x;return i+u*f}).attr("y",t=>{const n=c.get(t.source),s=c.get(t.target),i=(n.y+s.y)/2,p=s.x-n.x,l=s.y-n.y,x=Math.sqrt(p*p+l*l),f=8,u=-p/x;return i+u*f}).attr("fill",d.axisTextColor).attr("font-size",o.labelFontSize).attr("text-anchor","middle").attr("dominant-baseline","middle").attr("transform",t=>{const n=c.get(t.source),s=c.get(t.target),i=(n.x+s.x)/2,p=(n.y+s.y)/2,l=s.x-n.x,x=s.y-n.y,f=Math.sqrt(l*l+x*x),u=8,w=x/f,$=-l/f,A=i+w*u,D=p+$*u;let B=Math.atan2(x,l)*180/Math.PI;return(B>90||B<-90)&&(B+=180),`rotate(${B} ${A} ${D})`}).text(t=>t.label);const kt=S.append("g").attr("class","wardley-trends"),Pt=g.trends.map(t=>{const n=c.get(t.nodeId);if(!n)return null;const s=C(t.targetX),i=E(t.targetY),p=s-n.x,l=i-n.y,x=Math.sqrt(p*p+l*l),f=o.nodeRadius+2,u=x>f?s-p/x*f:s,w=x>f?i-l/x*f:i;return{origin:n,targetX:s,targetY:i,adjustedX2:u,adjustedY2:w}}).filter(t=>t!==null);kt.selectAll("line").data(Pt).enter().append("line").attr("class","wardley-trend").attr("x1",t=>t.origin.x).attr("y1",t=>t.origin.y).attr("x2",t=>t.adjustedX2).attr("y2",t=>t.adjustedY2).attr("stroke",d.evolutionStroke).attr("stroke-width",1).attr("stroke-dasharray","4 4").attr("marker-end",`url(#arrow-${r})`);const z=S.append("g").attr("class","wardley-nodes").selectAll("g").data(g.nodes).enter().append("g").attr("class",t=>["wardley-node",t.className?`wardley-node--${t.className}`:""].filter(Boolean).join(" "));z.filter(t=>t.sourceStrategy==="outsource").append("circle").attr("class","wardley-outsource-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",o.nodeRadius*2).attr("fill","#666").attr("stroke",d.componentStroke).attr("stroke-width",1),z.filter(t=>t.sourceStrategy==="buy").append("circle").attr("class","wardley-buy-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",o.nodeRadius*2).attr("fill","#ccc").attr("stroke",d.componentStroke).attr("stroke-width",1),z.filter(t=>t.sourceStrategy==="build").append("circle").attr("class","wardley-build-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",o.nodeRadius*2).attr("fill","#eee").attr("stroke","#000").attr("stroke-width",1);const T=z.filter(t=>t.sourceStrategy==="market");T.append("circle").attr("class","wardley-market-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",o.nodeRadius*2).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",1),z.filter(t=>!t.isPipelineParent&&t.sourceStrategy!=="market"&&t.className!=="anchor").append("circle").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",o.nodeRadius).attr("fill",d.componentFill).attr("stroke",d.componentStroke).attr("stroke-width",1);const _=o.nodeRadius*.7,k=o.nodeRadius*1.2;if(T.append("line").attr("class","wardley-market-line").attr("x1",t=>c.get(t.id).x).attr("y1",t=>c.get(t.id).y-k).attr("x2",t=>c.get(t.id).x-k*Math.cos(Math.PI/6)).attr("y2",t=>c.get(t.id).y+k*Math.sin(Math.PI/6)).attr("stroke",d.componentStroke).attr("stroke-width",1),T.append("line").attr("class","wardley-market-line").attr("x1",t=>c.get(t.id).x-k*Math.cos(Math.PI/6)).attr("y1",t=>c.get(t.id).y+k*Math.sin(Math.PI/6)).attr("x2",t=>c.get(t.id).x+k*Math.cos(Math.PI/6)).attr("y2",t=>c.get(t.id).y+k*Math.sin(Math.PI/6)).attr("stroke",d.componentStroke).attr("stroke-width",1),T.append("line").attr("class","wardley-market-line").attr("x1",t=>c.get(t.id).x+k*Math.cos(Math.PI/6)).attr("y1",t=>c.get(t.id).y+k*Math.sin(Math.PI/6)).attr("x2",t=>c.get(t.id).x).attr("y2",t=>c.get(t.id).y-k).attr("stroke",d.componentStroke).attr("stroke-width",1),T.append("circle").attr("class","wardley-market-dot").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y-k).attr("r",_).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",2),T.append("circle").attr("class","wardley-market-dot").attr("cx",t=>c.get(t.id).x-k*Math.cos(Math.PI/6)).attr("cy",t=>c.get(t.id).y+k*Math.sin(Math.PI/6)).attr("r",_).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",2),T.append("circle").attr("class","wardley-market-dot").attr("cx",t=>c.get(t.id).x+k*Math.cos(Math.PI/6)).attr("cy",t=>c.get(t.id).y+k*Math.sin(Math.PI/6)).attr("r",_).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",2),z.filter(t=>t.isPipelineParent===!0).append("rect").attr("x",t=>c.get(t.id).x-m/2).attr("y",t=>c.get(t.id).y-m/2).attr("width",m).attr("height",m).attr("fill",d.componentFill).attr("stroke",d.componentStroke).attr("stroke-width",1),z.filter(t=>t.inertia===!0).append("line").attr("class","wardley-inertia").attr("x1",t=>{const n=c.get(t.id);let s=t.isPipelineParent?m/2+15:o.nodeRadius+15;return t.sourceStrategy&&(s+=o.nodeRadius+10),n.x+s}).attr("y1",t=>{const n=c.get(t.id),s=t.isPipelineParent?m:o.nodeRadius*2;return n.y-s/2}).attr("x2",t=>{const n=c.get(t.id);let s=t.isPipelineParent?m/2+15:o.nodeRadius+15;return t.sourceStrategy&&(s+=o.nodeRadius+10),n.x+s}).attr("y2",t=>{const n=c.get(t.id),s=t.isPipelineParent?m:o.nodeRadius*2;return n.y+s/2}).attr("stroke",d.componentStroke).attr("stroke-width",6),z.append("text").attr("x",t=>{const n=c.get(t.id);if(t.className==="anchor")return t.labelOffsetX!==void 0?n.x+t.labelOffsetX:n.x;let s=o.nodeLabelOffset;t.sourceStrategy&&t.labelOffsetX===void 0&&(s+=10);const i=t.labelOffsetX??s;return n.x+i}).attr("y",t=>{const n=c.get(t.id);if(t.className==="anchor")return t.labelOffsetY!==void 0?n.y+t.labelOffsetY:n.y-3;let s=-o.nodeLabelOffset;t.sourceStrategy&&t.labelOffsetY===void 0&&(s-=10);const i=t.labelOffsetY??s;return n.y+i}).attr("class","wardley-node-label").attr("fill",t=>t.className==="evolved"?d.evolutionStroke:t.className==="anchor"?"#000":d.componentLabelColor).attr("font-size",o.labelFontSize).attr("font-weight",t=>t.className==="anchor"?"bold":"normal").attr("text-anchor",t=>t.className==="anchor"?"middle":"start").attr("dominant-baseline",t=>t.className==="anchor"?"middle":"auto").text(t=>t.label),g.annotations.length>0){const t=S.append("g").attr("class","wardley-annotations");if(g.annotations.forEach(n=>{const s=n.coordinates.map(i=>({x:C(i.x),y:E(i.y)}));if(s.length>1)for(let i=0;i<s.length-1;i++)t.append("line").attr("class","wardley-annotation-line").attr("x1",s[i].x).attr("y1",s[i].y).attr("x2",s[i+1].x).attr("y2",s[i+1].y).attr("stroke",d.axisColor).attr("stroke-width",1.5).attr("stroke-dasharray","4 4");s.forEach(i=>{const p=t.append("g").attr("class","wardley-annotation");p.append("circle").attr("cx",i.x).attr("cy",i.y).attr("r",10).attr("fill","white").attr("stroke",d.axisColor).attr("stroke-width",1.5),p.append("text").attr("x",i.x).attr("y",i.y).attr("text-anchor","middle").attr("dominant-baseline","central").attr("font-size",10).attr("fill",d.axisTextColor).attr("font-weight","bold").text(n.number)})}),g.annotationsBox){let n=C(g.annotationsBox.x),s=E(g.annotationsBox.y);const i=10,p=16,l=11,x=t.append("g").attr("class","wardley-annotations-box"),f=[...g.annotations].filter(w=>w.text).sort((w,$)=>w.number-$.number),u=[];if(f.forEach((w,$)=>{const A=x.append("text").attr("x",n+i).attr("y",s+i+($+1)*p).attr("font-size",l).attr("fill",d.axisTextColor).attr("text-anchor","start").attr("dominant-baseline","middle").text(`${w.number}. ${w.text}`);u.push(A)}),u.length>0){let w=0,$=0;u.forEach(V=>{const G=V.node(),Mt=G.getComputedTextLength();w=Math.max(w,Mt);const Lt=G.getBBox();$=Math.max($,Lt.height)});const A=w+i*2+105,D=f.length*p+i*2+$/2,B=o.padding,vt=M-o.padding-A,St=o.padding,$t=b-o.padding-D;n=Math.max(B,Math.min(n,vt)),s=Math.max(St,Math.min(s,$t)),u.forEach((V,G)=>{V.attr("x",n+i).attr("y",s+i+(G+1)*p)}),x.insert("rect","text").attr("x",n).attr("y",s).attr("width",A).attr("height",D).attr("fill","white").attr("stroke",d.axisColor).attr("stroke-width",1.5).attr("rx",4).attr("ry",4)}}}if(g.notes.length>0){const t=S.append("g").attr("class","wardley-notes");g.notes.forEach(n=>{const s=C(n.x),i=E(n.y);t.append("text").attr("x",s).attr("y",i).attr("text-anchor","start").attr("font-size",11).attr("fill",d.axisTextColor).attr("font-weight","bold").text(n.text)})}if(g.accelerators.length>0){const t=S.append("g").attr("class","wardley-accelerators");g.accelerators.forEach(n=>{const s=C(n.x),i=E(n.y),p=60,l=30,x=20,f=`
|
|
3
3
|
M ${s} ${i-l/2}
|
|
4
4
|
L ${s+p-x} ${i-l/2}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as a,s as gi,g as xi,t as Xt,q as di,a as fi,b as pi,l as Yt,L as mi,e as yi,A as bi,F as _t,H as Nt,I as Ai,a1 as wi,i as Ci,aC as Si,a9 as Wt}from"../app.
|
|
1
|
+
import{_ as a,s as gi,g as xi,t as Xt,q as di,a as fi,b as pi,l as Yt,L as mi,e as yi,A as bi,F as _t,H as Nt,I as Ai,a1 as wi,i as Ci,aC as Si,a9 as Wt}from"../app.CaLG1pPt.js";import{i as _i}from"./init.Gi6I4Gst.js";import{o as ki}from"./ordinal.DBvzRdQf.js";import{l as zt}from"./linear.DxGYL0MP.js";import"./framework.BNw1pucY.js";import"./theme.DO1avLBn.js";import"./defaultLocale.C4B-KCzX.js";function Ri(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s<n;)o[s]=e+s*i;return o}function bt(){var e=ki().unknown(void 0),t=e.domain,i=e.range,s=0,n=1,o,u,p=!1,f=0,T=0,P=.5;delete e.unknown;function _(){var y=t().length,E=n<s,v=E?n:s,L=E?s:n;o=(L-v)/Math.max(1,y-f+T*2),p&&(o=Math.floor(o)),v+=(L-v-o*(y-f))*P,u=o*(1-f),p&&(v=Math.round(v),u=Math.round(u));var I=Ri(y).map(function(m){return v+o*m});return i(E?I.reverse():I)}return e.domain=function(y){return arguments.length?(t(y),_()):t()},e.range=function(y){return arguments.length?([s,n]=y,s=+s,n=+n,_()):[s,n]},e.rangeRound=function(y){return[s,n]=y,s=+s,n=+n,p=!0,_()},e.bandwidth=function(){return u},e.step=function(){return o},e.round=function(y){return arguments.length?(p=!!y,_()):p},e.padding=function(y){return arguments.length?(f=Math.min(1,T=+y),_()):f},e.paddingInner=function(y){return arguments.length?(f=Math.min(1,y),_()):f},e.paddingOuter=function(y){return arguments.length?(T=+y,_()):T},e.align=function(y){return arguments.length?(P=Math.max(0,Math.min(1,y)),_()):P},e.copy=function(){return bt(t(),[s,n]).round(p).paddingInner(f).paddingOuter(T).align(P)},_i.apply(_(),arguments)}var At=function(){var e=a(function(F,h,c,g){for(c=c||{},g=F.length;g--;c[F[g]]=h);return c},"o"),t=[1,10,12,14,16,18,19,21,23],i=[2,6],s=[1,3],n=[1,5],o=[1,6],u=[1,7],p=[1,5,10,12,14,16,18,19,21,23,34,35,36],f=[1,25],T=[1,26],P=[1,28],_=[1,29],y=[1,30],E=[1,31],v=[1,32],L=[1,33],I=[1,34],m=[1,35],R=[1,36],l=[1,37],W=[1,43],O=[1,42],X=[1,47],Y=[1,50],S=[1,10,12,14,16,18,19,21,23,34,35,36],U=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],b=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],w=[1,64],V={trace:a(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:a(function(h,c,g,x,C,r,rt){var d=r.length-1;switch(C){case 5:x.setOrientation(r[d]);break;case 9:x.setDiagramTitle(r[d].text.trim());break;case 12:x.setLineData({text:"",type:"text"},r[d]);break;case 13:x.setLineData(r[d-1],r[d]);break;case 14:x.setBarData({text:"",type:"text"},r[d]);break;case 15:x.setBarData(r[d-1],r[d]);break;case 16:this.$=r[d].trim(),x.setAccTitle(this.$);break;case 17:case 18:this.$=r[d].trim(),x.setAccDescription(this.$);break;case 19:this.$=r[d-1];break;case 20:this.$=[Number(r[d-2]),...r[d]];break;case 21:this.$=[Number(r[d])];break;case 22:x.setXAxisTitle(r[d]);break;case 23:x.setXAxisTitle(r[d-1]);break;case 24:x.setXAxisTitle({type:"text",text:""});break;case 25:x.setXAxisBand(r[d]);break;case 26:x.setXAxisRangeData(Number(r[d-2]),Number(r[d]));break;case 27:this.$=r[d-1];break;case 28:this.$=[r[d-2],...r[d]];break;case 29:this.$=[r[d]];break;case 30:x.setYAxisTitle(r[d]);break;case 31:x.setYAxisTitle(r[d-1]);break;case 32:x.setYAxisTitle({type:"text",text:""});break;case 33:x.setYAxisRangeData(Number(r[d-2]),Number(r[d]));break;case 37:this.$={text:r[d],type:"text"};break;case 38:this.$={text:r[d],type:"text"};break;case 39:this.$={text:r[d],type:"markdown"};break;case 40:this.$=r[d];break;case 41:this.$=r[d-1]+""+r[d];break}},"anonymous"),table:[e(t,i,{3:1,4:2,7:4,5:s,34:n,35:o,36:u}),{1:[3]},e(t,i,{4:2,7:4,3:8,5:s,34:n,35:o,36:u}),e(t,i,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:o,36:u}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},e(p,[2,34]),e(p,[2,35]),e(p,[2,36]),{1:[2,1]},e(t,i,{4:2,7:4,3:21,5:s,34:n,35:o,36:u}),{1:[2,3]},e(p,[2,5]),e(t,[2,7],{4:22,34:n,35:o,36:u}),{11:23,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:39,13:38,24:W,27:O,29:40,30:41,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:45,15:44,27:X,33:46,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:49,17:48,24:Y,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{11:52,17:51,24:Y,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},{20:[1,53]},{22:[1,54]},e(S,[2,18]),{1:[2,2]},e(S,[2,8]),e(S,[2,9]),e(U,[2,37],{40:55,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l}),e(U,[2,38]),e(U,[2,39]),e(b,[2,40]),e(b,[2,42]),e(b,[2,43]),e(b,[2,44]),e(b,[2,45]),e(b,[2,46]),e(b,[2,47]),e(b,[2,48]),e(b,[2,49]),e(b,[2,50]),e(b,[2,51]),e(S,[2,10]),e(S,[2,22],{30:41,29:56,24:W,27:O}),e(S,[2,24]),e(S,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},e(S,[2,11]),e(S,[2,30],{33:60,27:X}),e(S,[2,32]),{31:[1,61]},e(S,[2,12]),{17:62,24:Y},{25:63,27:w},e(S,[2,14]),{17:65,24:Y},e(S,[2,16]),e(S,[2,17]),e(b,[2,41]),e(S,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},e(S,[2,31]),{27:[1,69]},e(S,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},e(S,[2,15]),e(S,[2,26]),e(S,[2,27]),{11:59,32:72,37:24,38:f,39:T,40:27,41:P,42:_,43:y,44:E,45:v,46:L,47:I,48:m,49:R,50:l},e(S,[2,33]),e(S,[2,19]),{25:73,27:w},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:a(function(h,c){if(c.recoverable)this.trace(h);else{var g=new Error(h);throw g.hash=c,g}},"parseError"),parse:a(function(h){var c=this,g=[0],x=[],C=[null],r=[],rt=this.table,d="",ct=0,It=0,hi=2,Mt=1,li=r.slice.call(arguments,1),D=Object.create(this.lexer),$={yy:{}};for(var ft in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ft)&&($.yy[ft]=this.yy[ft]);D.setInput(h,$.yy),$.yy.lexer=D,$.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var pt=D.yylloc;r.push(pt);var ci=D.options&&D.options.ranges;typeof $.yy.parseError=="function"?this.parseError=$.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ui(B){g.length=g.length-2*B,C.length=C.length-B,r.length=r.length-B}a(ui,"popStack");function Vt(){var B;return B=x.pop()||D.lex()||Mt,typeof B!="number"&&(B instanceof Array&&(x=B,B=x.pop()),B=c.symbols_[B]||B),B}a(Vt,"lex");for(var M,q,z,mt,G={},ut,N,Bt,gt;;){if(q=g[g.length-1],this.defaultActions[q]?z=this.defaultActions[q]:((M===null||typeof M>"u")&&(M=Vt()),z=rt[q]&&rt[q][M]),typeof z>"u"||!z.length||!z[0]){var yt="";gt=[];for(ut in rt[q])this.terminals_[ut]&&ut>hi&>.push("'"+this.terminals_[ut]+"'");D.showPosition?yt="Parse error on line "+(ct+1)+`:
|
|
2
2
|
`+D.showPosition()+`
|
|
3
3
|
Expecting `+gt.join(", ")+", got '"+(this.terminals_[M]||M)+"'":yt="Parse error on line "+(ct+1)+": Unexpected "+(M==Mt?"end of input":"'"+(this.terminals_[M]||M)+"'"),this.parseError(yt,{text:D.match,token:this.terminals_[M]||M,line:D.yylineno,loc:pt,expected:gt})}if(z[0]instanceof Array&&z.length>1)throw new Error("Parse Error: multiple actions possible at state: "+q+", token: "+M);switch(z[0]){case 1:g.push(M),C.push(D.yytext),r.push(D.yylloc),g.push(z[1]),M=null,It=D.yyleng,d=D.yytext,ct=D.yylineno,pt=D.yylloc;break;case 2:if(N=this.productions_[z[1]][1],G.$=C[C.length-N],G._$={first_line:r[r.length-(N||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(N||1)].first_column,last_column:r[r.length-1].last_column},ci&&(G._$.range=[r[r.length-(N||1)].range[0],r[r.length-1].range[1]]),mt=this.performAction.apply(G,[d,It,ct,$.yy,z[1],C,r].concat(li)),typeof mt<"u")return mt;N&&(g=g.slice(0,-1*N*2),C=C.slice(0,-1*N),r=r.slice(0,-1*N)),g.push(this.productions_[z[1]][0]),C.push(G.$),r.push(G._$),Bt=rt[g[g.length-2]][g[g.length-1]],g.push(Bt);break;case 3:return!0}}return!0},"parse")},k=function(){var F={EOF:1,parseError:a(function(c,g){if(this.yy.parser)this.yy.parser.parseError(c,g);else throw new Error(c)},"parseError"),setInput:a(function(h,c){return this.yy=c||this.yy||{},this._input=h,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:a(function(){var h=this._input[0];this.yytext+=h,this.yyleng++,this.offset++,this.match+=h,this.matched+=h;var c=h.match(/(?:\r\n?|\n).*/g);return c?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),h},"input"),unput:a(function(h){var c=h.length,g=h.split(/(?:\r\n?|\n)/g);this._input=h+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-c),this.offset-=c;var x=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),g.length-1&&(this.yylineno-=g.length-1);var C=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:g?(g.length===x.length?this.yylloc.first_column:0)+x[x.length-g.length].length-g[0].length:this.yylloc.first_column-c},this.options.ranges&&(this.yylloc.range=[C[0],C[0]+this.yyleng-c]),this.yyleng=this.yytext.length,this},"unput"),more:a(function(){return this._more=!0,this},"more"),reject:a(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
|
|
4
4
|
`+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:a(function(h){this.unput(this.match.slice(h))},"less"),pastInput:a(function(){var h=this.matched.substr(0,this.matched.length-this.match.length);return(h.length>20?"...":"")+h.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:a(function(){var h=this.match;return h.length<20&&(h+=this._input.substr(0,20-h.length)),(h.substr(0,20)+(h.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:a(function(){var h=this.pastInput(),c=new Array(h.length+1).join("-");return h+this.upcomingInput()+`
|
|
@@ -21,7 +21,7 @@ import{_ as i,c as a,o as e,a3 as t}from"./chunks/framework.BNw1pucY.js";const c
|
|
|
21
21
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"https://api.cursor.com/v1/mcp/plugins"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
22
22
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> auth</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">async</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">session</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ({ headers: </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> headersForSession</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(session) }),</span></span>
|
|
23
23
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> advertiseTools: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
24
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Listing, authentication, invalid tool name, and name collision failures fail the turn by default. Set <code>optional: true</code> to omit an unavailable connection instead. Advertised tools behave like server tools, and <a href="./tools.html#call-a-tool-without-a-model-turn">direct tool calls</a> use the same names.</p><p>In a dry-run session, MCP tools marked read-only run normally. Tools marked as writes are stubbed. Tools without effect annotations are unavailable.</p><h2 id="filter-connection-tools" tabindex="-1">Filter connection tools <a class="header-anchor" href="#filter-connection-tools" aria-label="Permalink to "Filter connection tools""></a></h2><p>Use <code>tools</code> the same way you allowlist harness tools on the agent. When set, the connection serves only those names. Use <code>disallowedTools</code> to drop names instead. The two combine as deny-wins. The model and <code>host.mcp</code> only see what remains. A model-visible filter requires <code>advertiseTools: true</code>.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineConnection</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
24
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Listing, authentication, invalid tool name, and name collision failures fail the turn by default. Set <code>optional: true</code> to omit an unavailable connection instead. Advertised tools behave like server tools, and <a href="./tools.html#call-a-tool-without-a-model-turn">direct tool calls</a> use the same names.</p><p>In a dry-run session, MCP tools marked read-only run normally. Tools marked as writes are stubbed. Tools without effect annotations are unavailable. A tool annotated read-only uses the same transient retry as an authored read. A tool with no effect annotation runs once.</p><h2 id="filter-connection-tools" tabindex="-1">Filter connection tools <a class="header-anchor" href="#filter-connection-tools" aria-label="Permalink to "Filter connection tools""></a></h2><p>Use <code>tools</code> the same way you allowlist harness tools on the agent. When set, the connection serves only those names. Use <code>disallowedTools</code> to drop names instead. The two combine as deny-wins. The model and <code>host.mcp</code> only see what remains. A model-visible filter requires <code>advertiseTools: true</code>.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineConnection</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
25
25
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"https://mcp.example.com/inventory"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
26
26
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> advertiseTools: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
27
27
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> tools: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"search_skus"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"get_stock"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const
|
|
1
|
+
import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const k=JSON.parse('{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state.","frontmatter":{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state."},"headers":[],"relativePath":"reference/hooks.md","filePath":"reference/hooks.md"}'),n={name:"reference/hooks.md"};function o(d,s,h,l,r,p){return a(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="hooks" tabindex="-1">Hooks <a class="header-anchor" href="#hooks" aria-label="Permalink to "Hooks""></a></h1><p>A hook subscribes to selected session events and can run a side effect after each matching event is recorded: an audit line, a metric, a transcript copy, or derived state. Hooks run in the serving process for every session of the agent. They cannot change the turn, the prompt, or the reply; a handler that throws is logged and skipped.</p><p>Treat the event as read-only. Later subscribers see the same object. That makes hooks safe to add to a production agent, and the wrong surface for anything that must run before the model or must fail a turn; see <a href="#hook-boundaries">Hook boundaries</a>.</p><p><code>defineHook</code> is unrelated to <a href="https://cursor.com/docs/agent/hooks" target="_blank" rel="noreferrer">Cursor Agent hooks</a>, the <code>.cursor/hooks.json</code> scripts that can observe, block, or modify the agent loop. Those still run inside a local session workspace.</p><h2 id="author-a-hook" tabindex="-1">Author a hook <a class="header-anchor" href="#author-a-hook" aria-label="Permalink to "Author a hook""></a></h2><p>Author <code>bot/hooks/<name>.ts</code> with <code>defineHook</code> from <code>@cursor/bdk/hooks</code>. This one meters tokens:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// bot/hooks/usage.ts</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineHook } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/bdk/hooks"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
3
3
|
<span class="line"></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineHook</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -15,7 +15,7 @@ import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const c
|
|
|
15
15
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ctx.host.otel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">increment</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"acme.turn.failed"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, { channel: ctx.channel.id });</span></span>
|
|
16
16
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
17
17
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
18
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Any module under <code>bot/hooks/</code>, subfolders included, is a hook named by its path without the extension: <code>bot/hooks/audit/usage.ts</code> is <code>audit/usage</code>. <code>*.test.ts</code> and <code>*.spec.ts</code> files are skipped. The default export must be <code>defineHook(...)</code>, names can't contain <code>__</code>, and an empty <code>events</code> map skips the hook with a warning; <code>bdk validate</code> reports all three. An extension mounts its hooks as <code><ns>__<name></code>, and <code>disableHook()</code> removes one (<a href="./extensions.html#adjust-a-mounted-extension">Adjust a mounted extension</a>).</p><p><code>bdk init</code> scaffolds <code>bot/hooks/memory.ts</code>, which exports <code>memoryHook()</code> from <code>@cursor/bdk/memory</code> and journals every turn for later sessions to read. Delete the file to opt out.</p><h2 id="events-and-payloads" tabindex="-1">Events and payloads <a class="header-anchor" href="#events-and-payloads" aria-label="Permalink to "Events and payloads""></a></h2><p>Keys are event types from the <a href="./sessions.html#stream-events">event vocabulary</a>, or <code>"*"</code> for every event. A typed key narrows <code>event.data</code>; a <code>"*"</code> handler receives the union, so switch on <code>event.type</code>. Every event carries the stream envelope <code>{ type, index, sessionId, turnId?, at, data }</code>, with <code>turnId</code> set on turn-scoped events. Skip <code>*.appended</code> deltas when you want the final text; <code>message.completed</code> already has it.</p><table tabindex="0"><thead><tr><th>Event</th><th><code>event.data</code></th></tr></thead><tbody><tr><td><code>message.received</code></td><td><code>{ text }</code></td></tr><tr><td><code>turn.completed</code></td><td><code>{ result?, usage?, cost? }</code>. <code>usage</code> has <code>inputTokens</code>, <code>outputTokens</code>, <code>cacheReadTokens</code>, <code>cacheWriteTokens</code>, and optional <code>reasoningTokens</code>. <code>cost</code> has <code>totalUsd</code> and the <code>model</code> it was priced against</td></tr><tr><td><code>turn.failed</code></td><td><code>{ message, status? }</code>. <code>status</code> is <code>"error"</code> or <code>"cancelled"</code> when present</td></tr><tr><td><code>actions.requested</code></td><td><code>{ calls: [{ callId, toolName, args?, parentCallId? }], parentCallId? }</code>. One envelope per model step once that step has listed its tools. A single tool is a batch of one. <code>parentCallId</code> marks subagent work</td></tr><tr><td><code>actions.completed</code></td><td><code>{ results: [{ callId, toolName, output?, isError, stubbed?, parentCallId? }], parentCallId? }</code>. Pair with <code>actions.requested</code>; emitted when every call in that batch has a result</td></tr><tr><td><code>action.result</code></td><td><code>{ callId, toolName, output?, isError, stubbed?, parentCallId? }</code>. Live per-call envelope for chips and spans. <code>stubbed</code> means a dry-run session answered a write without running it</td></tr></tbody></table><p>The types are <code>SessionEvent</code>, <code>SessionEventType</code>, and <code>HookContext</code>, exported from <code>@cursor/bdk</code>.</p><h2 id="handler-context" tabindex="-1">Handler context <a class="header-anchor" href="#handler-context" aria-label="Permalink to "Handler context""></a></h2><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>ctx.session</code></td><td>Read-only session info: <code>id</code>, <code>channelId</code>, <code>mode</code> (<code>chat</code> or <code>task</code>), <code>purpose</code> (<code>live</code> or <code>eval</code>), <code>auth</code>, plus <code>title</code> and <code>sdkAgentId</code> when set</td></tr><tr><td><code>ctx.agent</code></td><td><code>{ name }</code> of the agent the event belongs to</td></tr><tr><td><code>ctx.channel</code></td><td><code>{ id, continuationToken }</code>. The token is <code>null</code> when the session can't take follow-ups</td></tr><tr><td><code>ctx.host.kv</code></td><td>Durable JSON, shared by every session of the agent. Prefix keys with <code>ctx.session.id</code> for per-session state</td></tr><tr><td><code>ctx.host.files</code></td><td>Durable files, bound to this session. Pass <code>{ scope: "deployment" }</code> for agent-wide files</td></tr><tr><td><code>ctx.host.otel</code></td><td>Counters, histograms, and tags, attributed to this session</td></tr><tr><td><code>ctx.host.mcp</code>, <code>ctx.host.github</code>, <code>ctx.host.slack</code></td><td>The same shared clients tools get</td></tr><tr><td><code>ctx.host.reminders</code></td><td>Per-session <a href="./schedules.html#reminders">reminders</a>, the same API tools get</td></tr><tr><td><code>ctx.artifacts</code></td><td>Session-bound <a href="./artifacts.html">artifacts</a> facade: <code>tag</code> fills in <code>sessionId</code> and <code>turnId</code></td></tr><tr><td><code>ctx.stateRoot</code></td><td>Absolute path of the local state root. It resets when a hosted deployment is replaced; keep derived state in <code>kv</code> or <code>files</code></td></tr></tbody></table><h2 id="hook-dispatch" tabindex="-1">Hook dispatch <a class="header-anchor" href="#hook-dispatch" aria-label="Permalink to "Hook dispatch""></a></h2><p>A hook runs after the event is recorded. It never delays the model and never sees an event that wasn't recorded.</p><table tabindex="0"><thead><tr><th>Rule</th><th>What happens</th></tr></thead><tbody><tr><td>Same session</td><td>Events dispatch one at a time</td></tr><tr><td>Eval sessions</td><td>The same stream fires; skip metering or paging when <code>ctx.session.purpose === "eval"</code></td></tr><tr><td>Host restart</td><td>Recorded events are not replayed into hooks, so a mirror needs no dedupe</td></tr><tr><td>Slow handler</td><td>Holds the next event's handlers on that session, not the model. Keep handlers short and queue anything slow</td></tr></tbody></table><p>Read hosted secrets inside the handler, not at module scope. Give outbound calls a timeout; a stalled request holds later handlers on that session. Skip cancelled turns when paging; they record interrupted work.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// bot/hooks/page-on-failure.ts</span></span>
|
|
18
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Any module under <code>bot/hooks/</code>, subfolders included, is a hook named by its path without the extension: <code>bot/hooks/audit/usage.ts</code> is <code>audit/usage</code>. <code>*.test.ts</code> and <code>*.spec.ts</code> files are skipped. The default export must be <code>defineHook(...)</code>, names can't contain <code>__</code>, and an empty <code>events</code> map skips the hook with a warning; <code>bdk validate</code> reports all three. An extension mounts its hooks as <code><ns>__<name></code>, and <code>disableHook()</code> removes one (<a href="./extensions.html#adjust-a-mounted-extension">Adjust a mounted extension</a>).</p><p><code>bdk init</code> scaffolds <code>bot/hooks/memory.ts</code>, which exports <code>memoryHook()</code> from <code>@cursor/bdk/memory</code> and journals every turn for later sessions to read. Delete the file to opt out.</p><h2 id="events-and-payloads" tabindex="-1">Events and payloads <a class="header-anchor" href="#events-and-payloads" aria-label="Permalink to "Events and payloads""></a></h2><p>Keys are event types from the <a href="./sessions.html#stream-events">event vocabulary</a>, or <code>"*"</code> for every event. A typed key narrows <code>event.data</code>; a <code>"*"</code> handler receives the union, so switch on <code>event.type</code>. Every event carries the stream envelope <code>{ type, index, sessionId, turnId?, at, data }</code>, with <code>turnId</code> set on turn-scoped events. Skip <code>*.appended</code> deltas when you want the final text; <code>message.completed</code> already has it.</p><table tabindex="0"><thead><tr><th>Event</th><th><code>event.data</code></th></tr></thead><tbody><tr><td><code>message.received</code></td><td><code>{ text }</code></td></tr><tr><td><code>turn.completed</code></td><td><code>{ result?, usage?, cost? }</code>. <code>usage</code> has <code>inputTokens</code>, <code>outputTokens</code>, <code>cacheReadTokens</code>, <code>cacheWriteTokens</code>, and optional <code>reasoningTokens</code>. <code>cost</code> has <code>totalUsd</code> and the <code>model</code> it was priced against</td></tr><tr><td><code>turn.failed</code></td><td><code>{ message, status? }</code>. <code>status</code> is <code>"error"</code> or <code>"cancelled"</code> when present</td></tr><tr><td><code>actions.requested</code></td><td><code>{ calls: [{ callId, toolName, args?, parentCallId? }], parentCallId? }</code>. One envelope per model step once that step has listed its tools. A single tool is a batch of one. <code>parentCallId</code> marks subagent work</td></tr><tr><td><code>actions.completed</code></td><td><code>{ results: [{ callId, toolName, output?, isError, stubbed?, parentCallId? }], parentCallId? }</code>. Pair with <code>actions.requested</code>; emitted when every call in that batch has a result</td></tr><tr><td><code>action.result</code></td><td><code>{ callId, toolName, output?, isError, stubbed?, parentCallId? }</code>. Live per-call envelope for chips and spans. <code>stubbed</code> means a dry-run session answered a write without running it</td></tr><tr><td><code>action.tool_retry</code></td><td><code>{ callId, toolName, attempt, reason, connection? }</code>. A read is running again after a transient failure. <code>attempt</code> is the try about to run. <code>reason</code> is a class such as <code>transport</code> or <code>http_503</code></td></tr></tbody></table><p>The types are <code>SessionEvent</code>, <code>SessionEventType</code>, and <code>HookContext</code>, exported from <code>@cursor/bdk</code>.</p><h2 id="handler-context" tabindex="-1">Handler context <a class="header-anchor" href="#handler-context" aria-label="Permalink to "Handler context""></a></h2><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>ctx.session</code></td><td>Read-only session info: <code>id</code>, <code>channelId</code>, <code>mode</code> (<code>chat</code> or <code>task</code>), <code>purpose</code> (<code>live</code> or <code>eval</code>), <code>auth</code>, plus <code>title</code> and <code>sdkAgentId</code> when set</td></tr><tr><td><code>ctx.agent</code></td><td><code>{ name }</code> of the agent the event belongs to</td></tr><tr><td><code>ctx.channel</code></td><td><code>{ id, continuationToken }</code>. The token is <code>null</code> when the session can't take follow-ups</td></tr><tr><td><code>ctx.host.kv</code></td><td>Durable JSON, shared by every session of the agent. Prefix keys with <code>ctx.session.id</code> for per-session state</td></tr><tr><td><code>ctx.host.files</code></td><td>Durable files, bound to this session. Pass <code>{ scope: "deployment" }</code> for agent-wide files</td></tr><tr><td><code>ctx.host.otel</code></td><td>Counters, histograms, and tags, attributed to this session</td></tr><tr><td><code>ctx.host.mcp</code>, <code>ctx.host.github</code>, <code>ctx.host.slack</code></td><td>The same shared clients tools get</td></tr><tr><td><code>ctx.host.reminders</code></td><td>Per-session <a href="./schedules.html#reminders">reminders</a>, the same API tools get</td></tr><tr><td><code>ctx.artifacts</code></td><td>Session-bound <a href="./artifacts.html">artifacts</a> facade: <code>tag</code> fills in <code>sessionId</code> and <code>turnId</code></td></tr><tr><td><code>ctx.stateRoot</code></td><td>Absolute path of the local state root. It resets when a hosted deployment is replaced; keep derived state in <code>kv</code> or <code>files</code></td></tr></tbody></table><h2 id="hook-dispatch" tabindex="-1">Hook dispatch <a class="header-anchor" href="#hook-dispatch" aria-label="Permalink to "Hook dispatch""></a></h2><p>A hook runs after the event is recorded. It never delays the model and never sees an event that wasn't recorded.</p><table tabindex="0"><thead><tr><th>Rule</th><th>What happens</th></tr></thead><tbody><tr><td>Same session</td><td>Events dispatch one at a time</td></tr><tr><td>Eval sessions</td><td>The same stream fires; skip metering or paging when <code>ctx.session.purpose === "eval"</code></td></tr><tr><td>Host restart</td><td>Recorded events are not replayed into hooks, so a mirror needs no dedupe</td></tr><tr><td>Slow handler</td><td>Holds the next event's handlers on that session, not the model. Keep handlers short and queue anything slow</td></tr></tbody></table><p>Read hosted secrets inside the handler, not at module scope. Give outbound calls a timeout; a stalled request holds later handlers on that session. Skip cancelled turns when paging; they record interrupted work.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// bot/hooks/page-on-failure.ts</span></span>
|
|
19
19
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineHook } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/bdk/hooks"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
20
20
|
<span class="line"></span>
|
|
21
21
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineHook</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -42,4 +42,4 @@ import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const c
|
|
|
42
42
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
|
|
43
43
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
44
44
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
45
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="hooks-vs-channels-vs-evals" tabindex="-1">Hooks vs channels vs evals <a class="header-anchor" href="#hooks-vs-channels-vs-evals" aria-label="Permalink to "Hooks vs channels vs evals""></a></h2><p>All three consume the same stream, for different jobs:</p><table tabindex="0"><thead><tr><th></th><th>Hooks</th><th>Channel <code>events</code></th><th>Evals</th></tr></thead><tbody><tr><td>Scope</td><td>every session of the agent</td><td>sessions the channel owns</td><td>one test turn</td></tr><tr><td>Job</td><td>observe: audit, metrics, mirrors, derived state</td><td>deliver: replies back to the channel's surface</td><td>assert: gates over the trajectory</td></tr><tr><td>Context</td><td><code>ctx.host</code>, <code>ctx.artifacts</code>, session info</td><td><code>channel.state</code>, <code>setContinuationToken</code>, <code>ctx.host</code>, session info</td><td>the <code>t</code> assertion helpers</td></tr><tr><td>Can affect the run</td><td>no</td><td>yes, it owns the surface</td><td>n/a</td></tr><tr><td>Authored at</td><td><code>bot/hooks/*.ts</code></td><td>channel config</td><td><code>evals/**/*.eval.ts</code></td></tr></tbody></table><h2 id="hook-boundaries" tabindex="-1">Hook boundaries <a class="header-anchor" href="#hook-boundaries" aria-label="Permalink to "Hook boundaries""></a></h2><table tabindex="0"><thead><tr><th>You want to</th><th>Use instead</th></tr></thead><tbody><tr><td>Add context before the model runs</td><td>The channel's <code>send</code> message and <code>workspaceFiles</code>, <code>instructions.md</code>, skills, or <code>sandbox/workspace/</code> seed files</td></tr><tr><td>Reply on Slack, comment on a PR, or post any other delivery</td><td>The channel's <code>events</code> map, or the Slack and GitHub packs</td></tr><tr><td>Show PR progress (merge-box check, sticky banner)</td><td><code>githubChannel({ progress: { commitStatus, banner } })</code>; see <a href="./../guides/github.html">GitHub agents</a></td></tr><tr><td>Block, approve, or rewrite a tool call</td><td><a href="./tools.html#gate-a-tool-on-human-approval"><code>needsApproval</code></a> on the tool</td></tr><tr><td>Act on the final assistant text, reject it for a same-turn repair, or fail a bad turn</td><td><code>defineResult</code></td></tr><tr><td>Gate a change on behavior</td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><h2 id="test-a-hook" tabindex="-1">Test a hook <a class="header-anchor" href="#test-a-hook" aria-label="Permalink to "Test a hook""></a></h2><p>A hook definition is a plain object, so a unit test calls <code>hook.events["turn.completed"]</code> directly with an event and a stub <code>HookContext</code>. Discovery skips <code>*.test.ts</code>, so the test can live next to the hook.</p><table tabindex="0"><thead><tr><th>Command</th><th>What it reports</th></tr></thead><tbody><tr><td><code>bdk validate --dir .</code></td><td>Discovery errors and the empty-handlers warning</td></tr><tr><td><code>bdk info --dir . --json</code></td><td>Loaded hooks under <code>agents[].hooks</code></td></tr><tr><td><code>bdk run --dir . --message "…"</code></td><td>Serve log on stderr, including <code>hook "<name>" handler for <event> threw: …</code></td></tr></tbody></table><p>On hosting, read the same log with <a href="./cli.html#logs"><code>bdk logs</code></a>.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./../guides/hooks.html">Hooks guide</a>: meter usage and page on failure</li><li><a href="./sessions.html">Sessions and streaming</a>: the event vocabulary hooks observe</li><li><a href="./../guides/opentelemetry.html">OpenTelemetry</a>: OTLP traces and metrics from the same event stream</li><li><a href="./../deployment.html#observability">Deployment</a>: runtime logs and export paths</li><li><a href="./channels.html#events">Channels</a>: the delivery-side counterpart</li></ul>`,31)])])}const E=e(n,[["render",o]]);export{
|
|
45
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="hooks-vs-channels-vs-evals" tabindex="-1">Hooks vs channels vs evals <a class="header-anchor" href="#hooks-vs-channels-vs-evals" aria-label="Permalink to "Hooks vs channels vs evals""></a></h2><p>All three consume the same stream, for different jobs:</p><table tabindex="0"><thead><tr><th></th><th>Hooks</th><th>Channel <code>events</code></th><th>Evals</th></tr></thead><tbody><tr><td>Scope</td><td>every session of the agent</td><td>sessions the channel owns</td><td>one test turn</td></tr><tr><td>Job</td><td>observe: audit, metrics, mirrors, derived state</td><td>deliver: replies back to the channel's surface</td><td>assert: gates over the trajectory</td></tr><tr><td>Context</td><td><code>ctx.host</code>, <code>ctx.artifacts</code>, session info</td><td><code>channel.state</code>, <code>setContinuationToken</code>, <code>ctx.host</code>, session info</td><td>the <code>t</code> assertion helpers</td></tr><tr><td>Can affect the run</td><td>no</td><td>yes, it owns the surface</td><td>n/a</td></tr><tr><td>Authored at</td><td><code>bot/hooks/*.ts</code></td><td>channel config</td><td><code>evals/**/*.eval.ts</code></td></tr></tbody></table><h2 id="hook-boundaries" tabindex="-1">Hook boundaries <a class="header-anchor" href="#hook-boundaries" aria-label="Permalink to "Hook boundaries""></a></h2><table tabindex="0"><thead><tr><th>You want to</th><th>Use instead</th></tr></thead><tbody><tr><td>Add context before the model runs</td><td>The channel's <code>send</code> message and <code>workspaceFiles</code>, <code>instructions.md</code>, skills, or <code>sandbox/workspace/</code> seed files</td></tr><tr><td>Reply on Slack, comment on a PR, or post any other delivery</td><td>The channel's <code>events</code> map, or the Slack and GitHub packs</td></tr><tr><td>Show PR progress (merge-box check, sticky banner)</td><td><code>githubChannel({ progress: { commitStatus, banner } })</code>; see <a href="./../guides/github.html">GitHub agents</a></td></tr><tr><td>Block, approve, or rewrite a tool call</td><td><a href="./tools.html#gate-a-tool-on-human-approval"><code>needsApproval</code></a> on the tool</td></tr><tr><td>Act on the final assistant text, reject it for a same-turn repair, or fail a bad turn</td><td><code>defineResult</code></td></tr><tr><td>Gate a change on behavior</td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><h2 id="test-a-hook" tabindex="-1">Test a hook <a class="header-anchor" href="#test-a-hook" aria-label="Permalink to "Test a hook""></a></h2><p>A hook definition is a plain object, so a unit test calls <code>hook.events["turn.completed"]</code> directly with an event and a stub <code>HookContext</code>. Discovery skips <code>*.test.ts</code>, so the test can live next to the hook.</p><table tabindex="0"><thead><tr><th>Command</th><th>What it reports</th></tr></thead><tbody><tr><td><code>bdk validate --dir .</code></td><td>Discovery errors and the empty-handlers warning</td></tr><tr><td><code>bdk info --dir . --json</code></td><td>Loaded hooks under <code>agents[].hooks</code></td></tr><tr><td><code>bdk run --dir . --message "…"</code></td><td>Serve log on stderr, including <code>hook "<name>" handler for <event> threw: …</code></td></tr></tbody></table><p>On hosting, read the same log with <a href="./cli.html#logs"><code>bdk logs</code></a>.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./../guides/hooks.html">Hooks guide</a>: meter usage and page on failure</li><li><a href="./sessions.html">Sessions and streaming</a>: the event vocabulary hooks observe</li><li><a href="./../guides/opentelemetry.html">OpenTelemetry</a>: OTLP traces and metrics from the same event stream</li><li><a href="./../deployment.html#observability">Deployment</a>: runtime logs and export paths</li><li><a href="./channels.html#events">Channels</a>: the delivery-side counterpart</li></ul>`,31)])])}const E=e(n,[["render",o]]);export{k as __pageData,E as default};
|
package/dist/docs/assets/{reference_hooks.md.C5LCJ1R3.lean.js → reference_hooks.md.B-eGa2km.lean.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const
|
|
1
|
+
import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const k=JSON.parse('{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state.","frontmatter":{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state."},"headers":[],"relativePath":"reference/hooks.md","filePath":"reference/hooks.md"}'),n={name:"reference/hooks.md"};function o(d,s,h,l,r,p){return a(),t("div",null,[...s[0]||(s[0]=[i("",31)])])}const E=e(n,[["render",o]]);export{k as __pageData,E as default};
|
package/dist/docs/assets/{reference_sessions.md.CM5zo3w4.js → reference_sessions.md.CyM7ARz1.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as t,c as s,o,a3 as a}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives.","frontmatter":{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives."},"headers":[],"relativePath":"reference/sessions.md","filePath":"reference/sessions.md"}'),n={name:"reference/sessions.md"};function d(r,e,i,c,l,h){return o(),s("div",null,[...e[0]||(e[0]=[a('<h1 id="sessions-events-and-streaming" tabindex="-1">Sessions, events, and streaming <a class="header-anchor" href="#sessions-events-and-streaming" aria-label="Permalink to "Sessions, events, and streaming""></a></h1><p>A session keeps one conversation, its workspace, and an append-only record of every message and tool call. Continue it with a continuation token, inspect it with a session ID, and follow progress on the NDJSON stream. Chat sessions wait for follow-ups; task sessions run once and stop.</p><h2 id="session-contents" tabindex="-1">Session contents <a class="header-anchor" href="#session-contents" aria-label="Permalink to "Session contents""></a></h2><p>Each session combines:</p><ul><li>A channel and authenticated caller</li><li>A conversation the caller can continue</li><li>A workspace for local turns</li><li>An NDJSON event stream</li><li>State that lets the conversation resume after a restart</li></ul><p>Sessions belong to the principal that created them. Follow-up, stream, and list routes return <code>403</code> when another caller tries to access one.</p><h2 id="session-identifiers" tabindex="-1">Session identifiers <a class="header-anchor" href="#session-identifiers" aria-label="Permalink to "Session identifiers""></a></h2><p>Sessions have two identifiers because conversation routing and inspection are different jobs.</p><table tabindex="0"><thead><tr><th>Identifier</th><th>Use it for</th></tr></thead><tbody><tr><td><code>continuationToken</code></td><td>Continue a conversation through its channel</td></tr><tr><td><code>sessionId</code></td><td>Stream events, inspect state, resolve approvals, or run a session-bound tool call</td></tr></tbody></table><p>Channels decide what a continuation token looks like. Slack uses its thread identity. A PR channel can use a key such as <code>pr:owner/repo#1</code>. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up. Reusing a stale HTTP token returns <code>409</code>.</p><p>Use the continuation token to keep talking. Use the session ID to observe or manage the stored session.</p><h2 id="session-modes" tabindex="-1">Session modes <a class="header-anchor" href="#session-modes" aria-label="Permalink to "Session modes""></a></h2><table tabindex="0"><thead><tr><th>Mode</th><th>Created by</th><th>What happens after a turn</th></tr></thead><tbody><tr><td><code>chat</code></td><td>HTTP sessions, channel <code>send</code>, Slack, or MCP <code>ask</code></td><td>Waits in <code>session.waiting</code> and accepts follow-ups</td></tr><tr><td><code>task</code></td><td>Markdown schedules and fire-and-forget dispatch</td><td>Ends in <code>session.completed</code> or <code>session.failed</code></td></tr></tbody></table><p>Task sessions don't accept follow-ups. Trying one returns <code>409</code>.</p><h2 id="follow-ups" tabindex="-1">Follow-ups <a class="header-anchor" href="#follow-ups" aria-label="Permalink to "Follow-ups""></a></h2><p>A follow-up to an idle chat session starts another turn. Admission when the session is already busy depends on the channel:</p><table tabindex="0"><thead><tr><th>Path</th><th>Busy-session policy</th></tr></thead><tbody><tr><td>HTTP playground / <code>POST /v1/session/:id</code> / MCP <code>ask</code></td><td><strong>Preempt</strong> (default): interrupt the in-flight turn, wait for it to settle, then run the new message</td></tr><tr><td>Slack mentions / DMs / alert-watch</td><td><strong>Coalesce</strong>: leave the active turn running and queue the follow-up. The running turn may receive it at a tool boundary; any asks that remain become one follow-up turn when it finishes</td></tr></tbody></table><p>Pass <code>admission: "coalesce"</code> on <code>send()</code> to opt into the Slack policy from other callers. Omit it (or pass <code>"preempt"</code>) to keep interrupt semantics.</p><p><code>POST /v1/session/:id/stop</code> interrupts a turn without sending a new message. The stream records <code>turn.failed</code> with <code>status: "cancelled"</code>; the session stays a chat session and can take another follow-up. A whole-message Slack <code>stop</code> / <code>@agent stop</code> does the same for that thread and clears pending coalesced follow-ups.</p><p>See <a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a> for direct-call behavior while a session is busy.</p><h2 id="stream-events" tabindex="-1">Stream events <a class="header-anchor" href="#stream-events" aria-label="Permalink to "Stream events""></a></h2><p>Each NDJSON line uses this envelope: <code>{ type, index, sessionId, turnId?, at, data }</code>. The <code>index</code> increases within one session. The <code>at</code> field is an ISO-8601 timestamp.</p><table tabindex="0"><thead><tr><th>Phase</th><th>Events</th><th>What they tell you</th></tr></thead><tbody><tr><td>Session</td><td><code>session.started</code>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, readiness, and task completion</td></tr><tr><td>Input</td><td><code>message.received</code></td><td>A user message was accepted</td></tr><tr><td>Turn</td><td><code>turn.queued</code>, <code>turn.started</code>, <code>turn.completed</code>, <code>turn.failed</code></td><td>Queue position under a <a href="./agent-config.html#concurrency"><code>maxRunningTurns</code> cap</a>, then turn status, final result, and token usage</td></tr><tr><td>Steps</td><td><code>step.started</code>, <code>step.completed</code></td><td>Model step boundaries and duration</td></tr><tr><td>Reasoning</td><td><code>reasoning.appended</code>, <code>reasoning.completed</code></td><td>Streamed reasoning blocks</td></tr><tr><td>Reply</td><td><code>message.appended</code>, <code>message.completed</code></td><td>Text deltas and finalized assistant messages</td></tr><tr><td>Tools</td><td><code>actions.requested</code>, <code>actions.completed</code>, <code>action.result</code></td><td>Tool names, validated arguments, outputs, and errors</td></tr><tr><td>Approvals</td><td><code>action.approval_requested</code>, <code>action.approval_resolved</code></td><td>A parked tool call and the human decision</td></tr><tr><td>Subagents</td><td><code>subagent.called</code>, <code>subagent.completed</code></td><td>Delegated work</td></tr><tr><td>Artifacts</td><td><code>artifact.tagged</code></td><td>A durable <a href="./artifacts.html">artifact</a> was tagged for this session, by host code or <code>tag_artifact</code></td></tr></tbody></table><p>Pair <code>actions.requested</code> with <code>actions.completed</code> for each model-step batch. <code>action.result</code> is the live per-call envelope. Read <code>turn.completed.data.usage</code> for input, output, and cache token counts. With <code>bot/result.ts</code>, <code>turn.failed</code> is emitted when <code>commit</code> throws, the turn has no assistant text, or <code>ctx.reject(message)</code> doesn't lead to an accepted revision.</p><h2 id="stream-or-replay-events" tabindex="-1">Stream or replay events <a class="header-anchor" href="#stream-or-replay-events" aria-label="Permalink to "Stream or replay events""></a></h2><p>One endpoint handles both live streaming and replay:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -N</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'http://127.0.0.1:3000/<slug>/v1/session/ses_…/stream?startIndex=0'</span></span></code></pre></div><p>Pass <code>startIndex</code> to continue after the last event you received, including after a server restart. Omit it or pass <code>0</code> to replay the full session before following new events. <code>GET /v1/session/:id/events</code> returns a one-time dump without staying connected.</p><h2 id="local-session-workspace" tabindex="-1">Local session workspace <a class="header-anchor" href="#local-session-workspace" aria-label="Permalink to "Local session workspace""></a></h2><p>BDK creates a workspace before the first local turn:</p><table tabindex="0"><thead><tr><th>Source path</th><th>Lands as</th></tr></thead><tbody><tr><td><code>skills/*</code></td><td><code>.cursor/skills/<name>/SKILL.md</code></td></tr><tr><td>agent tools (<code>execution: "agent"</code>)</td><td>scripts in the session workspace, with a catalog in <code>AGENTS.md</code></td></tr><tr><td><code>sandbox/workspace/**</code></td><td>copied in as seed files</td></tr><tr><td>per-send <code>workspaceFiles</code></td><td>written before the turn</td></tr></tbody></table><p>Instructions reach the model as its system prompt; they aren't written into the workspace. See <a href="./instructions.html#delivery">Instructions</a>.</p><p>Local turns use this workspace as their working directory. Parent directories can contribute <code>AGENTS.md</code> and <code>.cursor</code> settings. Set <code>local.cwd</code> when you need a clean parent directory. A channel can also provide a different working directory for one session, such as a PR worktree.</p><p>See <a href="./agent-config.html#local-cwd">Agent config: local cwd</a> for the inheritance rules.</p><h2 id="session-storage" tabindex="-1">Session storage <a class="header-anchor" href="#session-storage" aria-label="Permalink to "Session storage""></a></h2><p>Local session state lives under <code>--state-root</code>. A slugged mount stores it in a subdirectory named for the slug.</p><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued.</p><h2 id="inspect-a-saved-event-stream" tabindex="-1">Inspect a saved event stream <a class="header-anchor" href="#inspect-a-saved-event-stream" aria-label="Permalink to "Inspect a saved event stream""></a></h2><p>Use <code>trajectory</code> with a saved trace:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>bdk trajectory --events <state-root>/traces/<sessionId>.ndjson</span></span></code></pre></div><p>The command prints tool calls, the reply, and token usage in the same JSON shape as <code>run</code>. Open the session's <strong>Trace</strong> view in the playground for a visual timeline.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./http-api.html">HTTP API</a></li><li><a href="./hooks.html">Hooks</a></li><li><a href="./tools.html">Tools</a></li></ul>',43)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
|
|
1
|
+
import{_ as t,c as s,o,a3 as a}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives.","frontmatter":{"title":"Sessions, events, and streaming","description":"Understand how conversations continue, how events stream, and where session data lives."},"headers":[],"relativePath":"reference/sessions.md","filePath":"reference/sessions.md"}'),n={name:"reference/sessions.md"};function d(r,e,i,c,l,h){return o(),s("div",null,[...e[0]||(e[0]=[a('<h1 id="sessions-events-and-streaming" tabindex="-1">Sessions, events, and streaming <a class="header-anchor" href="#sessions-events-and-streaming" aria-label="Permalink to "Sessions, events, and streaming""></a></h1><p>A session keeps one conversation, its workspace, and an append-only record of every message and tool call. Continue it with a continuation token, inspect it with a session ID, and follow progress on the NDJSON stream. Chat sessions wait for follow-ups; task sessions run once and stop.</p><h2 id="session-contents" tabindex="-1">Session contents <a class="header-anchor" href="#session-contents" aria-label="Permalink to "Session contents""></a></h2><p>Each session combines:</p><ul><li>A channel and authenticated caller</li><li>A conversation the caller can continue</li><li>A workspace for local turns</li><li>An NDJSON event stream</li><li>State that lets the conversation resume after a restart</li></ul><p>Sessions belong to the principal that created them. Follow-up, stream, and list routes return <code>403</code> when another caller tries to access one.</p><h2 id="session-identifiers" tabindex="-1">Session identifiers <a class="header-anchor" href="#session-identifiers" aria-label="Permalink to "Session identifiers""></a></h2><p>Sessions have two identifiers because conversation routing and inspection are different jobs.</p><table tabindex="0"><thead><tr><th>Identifier</th><th>Use it for</th></tr></thead><tbody><tr><td><code>continuationToken</code></td><td>Continue a conversation through its channel</td></tr><tr><td><code>sessionId</code></td><td>Stream events, inspect state, resolve approvals, or run a session-bound tool call</td></tr></tbody></table><p>Channels decide what a continuation token looks like. Slack uses its thread identity. A PR channel can use a key such as <code>pr:owner/repo#1</code>. The built-in HTTP API returns an opaque token and rotates it after each accepted follow-up. Reusing a stale HTTP token returns <code>409</code>.</p><p>Use the continuation token to keep talking. Use the session ID to observe or manage the stored session.</p><h2 id="session-modes" tabindex="-1">Session modes <a class="header-anchor" href="#session-modes" aria-label="Permalink to "Session modes""></a></h2><table tabindex="0"><thead><tr><th>Mode</th><th>Created by</th><th>What happens after a turn</th></tr></thead><tbody><tr><td><code>chat</code></td><td>HTTP sessions, channel <code>send</code>, Slack, or MCP <code>ask</code></td><td>Waits in <code>session.waiting</code> and accepts follow-ups</td></tr><tr><td><code>task</code></td><td>Markdown schedules and fire-and-forget dispatch</td><td>Ends in <code>session.completed</code> or <code>session.failed</code></td></tr></tbody></table><p>Task sessions don't accept follow-ups. Trying one returns <code>409</code>.</p><h2 id="follow-ups" tabindex="-1">Follow-ups <a class="header-anchor" href="#follow-ups" aria-label="Permalink to "Follow-ups""></a></h2><p>A follow-up to an idle chat session starts another turn. Admission when the session is already busy depends on the channel:</p><table tabindex="0"><thead><tr><th>Path</th><th>Busy-session policy</th></tr></thead><tbody><tr><td>HTTP playground / <code>POST /v1/session/:id</code> / MCP <code>ask</code></td><td><strong>Preempt</strong> (default): interrupt the in-flight turn, wait for it to settle, then run the new message</td></tr><tr><td>Slack mentions / DMs / alert-watch</td><td><strong>Coalesce</strong>: leave the active turn running and queue the follow-up. The running turn may receive it at a tool boundary; any asks that remain become one follow-up turn when it finishes</td></tr></tbody></table><p>Pass <code>admission: "coalesce"</code> on <code>send()</code> to opt into the Slack policy from other callers. Omit it (or pass <code>"preempt"</code>) to keep interrupt semantics.</p><p><code>POST /v1/session/:id/stop</code> interrupts a turn without sending a new message. The stream records <code>turn.failed</code> with <code>status: "cancelled"</code>; the session stays a chat session and can take another follow-up. A whole-message Slack <code>stop</code> / <code>@agent stop</code> does the same for that thread and clears pending coalesced follow-ups.</p><p>See <a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a> for direct-call behavior while a session is busy.</p><h2 id="stream-events" tabindex="-1">Stream events <a class="header-anchor" href="#stream-events" aria-label="Permalink to "Stream events""></a></h2><p>Each NDJSON line uses this envelope: <code>{ type, index, sessionId, turnId?, at, data }</code>. The <code>index</code> increases within one session. The <code>at</code> field is an ISO-8601 timestamp.</p><table tabindex="0"><thead><tr><th>Phase</th><th>Events</th><th>What they tell you</th></tr></thead><tbody><tr><td>Session</td><td><code>session.started</code>, <code>session.waiting</code>, <code>session.completed</code>, <code>session.failed</code></td><td>Session creation, readiness, and task completion</td></tr><tr><td>Input</td><td><code>message.received</code></td><td>A user message was accepted</td></tr><tr><td>Turn</td><td><code>turn.queued</code>, <code>turn.started</code>, <code>turn.completed</code>, <code>turn.failed</code></td><td>Queue position under a <a href="./agent-config.html#concurrency"><code>maxRunningTurns</code> cap</a>, then turn status, final result, and token usage</td></tr><tr><td>Steps</td><td><code>step.started</code>, <code>step.completed</code></td><td>Model step boundaries and duration</td></tr><tr><td>Reasoning</td><td><code>reasoning.appended</code>, <code>reasoning.completed</code></td><td>Streamed reasoning blocks</td></tr><tr><td>Reply</td><td><code>message.appended</code>, <code>message.completed</code></td><td>Text deltas and finalized assistant messages</td></tr><tr><td>Tools</td><td><code>actions.requested</code>, <code>actions.completed</code>, <code>action.result</code>, <code>action.tool_retry</code></td><td>Tool names, validated arguments, outputs, and errors. <code>action.tool_retry</code> means a read is running again after a transient failure</td></tr><tr><td>Approvals</td><td><code>action.approval_requested</code>, <code>action.approval_resolved</code></td><td>A parked tool call and the human decision</td></tr><tr><td>Subagents</td><td><code>subagent.called</code>, <code>subagent.completed</code></td><td>Delegated work</td></tr><tr><td>Artifacts</td><td><code>artifact.tagged</code></td><td>A durable <a href="./artifacts.html">artifact</a> was tagged for this session, by host code or <code>tag_artifact</code></td></tr></tbody></table><p>Pair <code>actions.requested</code> with <code>actions.completed</code> for each model-step batch. <code>action.result</code> is the live per-call envelope. Read <code>turn.completed.data.usage</code> for input, output, and cache token counts. With <code>bot/result.ts</code>, <code>turn.failed</code> is emitted when <code>commit</code> throws, the turn has no assistant text, or <code>ctx.reject(message)</code> doesn't lead to an accepted revision.</p><h2 id="stream-or-replay-events" tabindex="-1">Stream or replay events <a class="header-anchor" href="#stream-or-replay-events" aria-label="Permalink to "Stream or replay events""></a></h2><p>One endpoint handles both live streaming and replay:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">curl</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -N</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'http://127.0.0.1:3000/<slug>/v1/session/ses_…/stream?startIndex=0'</span></span></code></pre></div><p>Pass <code>startIndex</code> to continue after the last event you received, including after a server restart. Omit it or pass <code>0</code> to replay the full session before following new events. <code>GET /v1/session/:id/events</code> returns a one-time dump without staying connected.</p><h2 id="local-session-workspace" tabindex="-1">Local session workspace <a class="header-anchor" href="#local-session-workspace" aria-label="Permalink to "Local session workspace""></a></h2><p>BDK creates a workspace before the first local turn:</p><table tabindex="0"><thead><tr><th>Source path</th><th>Lands as</th></tr></thead><tbody><tr><td><code>skills/*</code></td><td><code>.cursor/skills/<name>/SKILL.md</code></td></tr><tr><td>agent tools (<code>execution: "agent"</code>)</td><td>scripts in the session workspace, with a catalog in <code>AGENTS.md</code></td></tr><tr><td><code>sandbox/workspace/**</code></td><td>copied in as seed files</td></tr><tr><td>per-send <code>workspaceFiles</code></td><td>written before the turn</td></tr></tbody></table><p>Instructions reach the model as its system prompt; they aren't written into the workspace. See <a href="./instructions.html#delivery">Instructions</a>.</p><p>Local turns use this workspace as their working directory. Parent directories can contribute <code>AGENTS.md</code> and <code>.cursor</code> settings. Set <code>local.cwd</code> when you need a clean parent directory. A channel can also provide a different working directory for one session, such as a PR worktree.</p><p>See <a href="./agent-config.html#local-cwd">Agent config: local cwd</a> for the inheritance rules.</p><h2 id="session-storage" tabindex="-1">Session storage <a class="header-anchor" href="#session-storage" aria-label="Permalink to "Session storage""></a></h2><p>Local session state lives under <code>--state-root</code>. A slugged mount stores it in a subdirectory named for the slug.</p><p>Deleting a session directory removes the session from the server: it disappears from listings and can no longer be streamed or continued.</p><h2 id="inspect-a-saved-event-stream" tabindex="-1">Inspect a saved event stream <a class="header-anchor" href="#inspect-a-saved-event-stream" aria-label="Permalink to "Inspect a saved event stream""></a></h2><p>Use <code>trajectory</code> with a saved trace:</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>bdk trajectory --events <state-root>/traces/<sessionId>.ndjson</span></span></code></pre></div><p>The command prints tool calls, the reply, and token usage in the same JSON shape as <code>run</code>. Open the session's <strong>Trace</strong> view in the playground for a visual timeline.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./http-api.html">HTTP API</a></li><li><a href="./hooks.html">Hooks</a></li><li><a href="./tools.html">Tools</a></li></ul>',43)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
|
package/dist/docs/assets/{reference_skills.md.ClkMoQsV.js → reference_skills.md.C0guGcH0.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{_ as i,c as e,o as t,a3 as a}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),l={name:"reference/skills.md"};function n(h,s,r,o,d,p){return t(),e("div",null,[...s[0]||(s[0]=[a(`<h1 id="skills" tabindex="-1">Skills <a class="header-anchor" href="#skills" aria-label="Permalink to "Skills""></a></h1><p>A skill is an on-demand procedure following the <code>SKILL.md</code> convention: the harness advertises each skill by its description, and the model loads the full content only when the task calls for it. Skills are how you give an agent a multi-step workflow without carrying it in the always-on <a href="./instructions.html">instructions</a>.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to "Authoring forms""></a></h2><p>Skills support three authoring forms.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>bot/skills/<name>.md</code></td><td>Static Markdown. Optional <code>description</code> frontmatter; the first body line is the fallback.</td></tr><tr><td><code>bot/skills/<name>/SKILL.md</code> plus siblings</td><td>A packaged directory with reference files (<code>references/…</code>). Requires <code>description</code> frontmatter.</td></tr><tr><td><code>bot/skills/<name>.ts</code></td><td>Generated content, with <code>defineSkill</code> from <code>@cursor/bdk/skills</code>.</td></tr></tbody></table><p>Use flat Markdown for static content:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#
|
|
2
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">
|
|
3
|
-
<span class="line"><span style="--shiki-light:#
|
|
1
|
+
import{_ as i,c as e,o as t,a3 as a}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),l={name:"reference/skills.md"};function n(h,s,r,o,d,p){return t(),e("div",null,[...s[0]||(s[0]=[a(`<h1 id="skills" tabindex="-1">Skills <a class="header-anchor" href="#skills" aria-label="Permalink to "Skills""></a></h1><p>A skill is an on-demand procedure following the <code>SKILL.md</code> convention: the harness advertises each skill by its description, and the model loads the full content only when the task calls for it. Skills are how you give an agent a multi-step workflow without carrying it in the always-on <a href="./instructions.html">instructions</a>.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to "Authoring forms""></a></h2><p>Skills support three authoring forms.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>bot/skills/<name>.md</code></td><td>Static Markdown. Optional <code>description</code> frontmatter; the first body line is the fallback.</td></tr><tr><td><code>bot/skills/<name>/SKILL.md</code> plus siblings</td><td>A packaged directory with reference files (<code>references/…</code>). Requires <code>description</code> frontmatter.</td></tr><tr><td><code>bot/skills/<name>.ts</code></td><td>Generated content, with <code>defineSkill</code> from <code>@cursor/bdk/skills</code>.</td></tr></tbody></table><p>Use flat Markdown for static content:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">---</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">description</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">Use when a pull request needs a structured approval checklist.</span></span>
|
|
3
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">---</span></span>
|
|
4
4
|
<span class="line"></span>
|
|
5
5
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;"># PR review checklist</span></span>
|
|
6
6
|
<span class="line"></span>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as i,c as a,o as
|
|
1
|
+
import{_ as i,c as a,o as e,a3 as t}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"Tools","description":"Define typed actions the model can call, gate the sensitive ones on approval, and call any server tool without a model turn.","frontmatter":{"title":"Tools","description":"Define typed actions the model can call, gate the sensitive ones on approval, and call any server tool without a model turn."},"headers":[],"relativePath":"reference/tools.md","filePath":"reference/tools.md"}'),n={name:"reference/tools.md"};function l(h,s,o,p,r,d){return e(),a("div",null,[...s[0]||(s[0]=[t(`<h1 id="tools" tabindex="-1">Tools <a class="header-anchor" href="#tools" aria-label="Permalink to "Tools""></a></h1><p>A tool is a typed action the model can call: hit an API, run a query, write a file. Each file in <code>bot/tools/</code> defines one tool, and the filename becomes the tool name the model sees. Tools come in two execution flavors: server tools run on the serving host, and agent tools run as scripts where the agent runs. Every server tool can also be called directly, with no model turn.</p><h2 id="define-a-server-tool" tabindex="-1">Define a server tool <a class="header-anchor" href="#define-a-server-tool" aria-label="Permalink to "Define a server tool""></a></h2><p>By default, <code>execute</code> runs in-process on the serving host with full access to <code>process.env</code> and your <code>bot/lib/</code> code.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// bot/tools/inspect_pr.ts</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineTool } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/bdk/tools"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { z } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "zod"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
4
4
|
<span class="line"></span>
|
|
@@ -42,7 +42,7 @@ import{_ as i,c as a,o as t,a3 as e}from"./chunks/framework.BNw1pucY.js";const c
|
|
|
42
42
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> execute</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">version</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }) {</span></span>
|
|
43
43
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> publishRelease</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(version);</span></span>
|
|
44
44
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
45
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p><code>dryRunResult</code> keeps the result shape stable. Without it, a stubbed write returns <code>"Operation acknowledged."</code>. Traces mark the result as stubbed.</p><h3 id="bound-time-arguments-under-asof" tabindex="-1">Bound time arguments under <code>asOf</code> <a class="header-anchor" href="#bound-time-arguments-under-asof" aria-label="Permalink to "Bound time arguments under \`asOf\`""></a></h3><p>Declare <code>timeArgs</code> with the input properties that carry time bounds. In a session created with <code>asOf</code>, every named argument must be an absolute ISO-8601 instant with a timezone, no later than the session's frozen instant. A call that omits one, or supplies a relative or later value, is refused with an error telling the model to retry with absolute bounds. Sessions without <code>asOf</code> ignore the declaration.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
45
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p><code>dryRunResult</code> keeps the result shape stable. Without it, a stubbed write returns <code>"Operation acknowledged."</code>. Traces mark the result as stubbed.</p><h3 id="retry-a-transient-read" tabindex="-1">Retry a transient read <a class="header-anchor" href="#retry-a-transient-read" aria-label="Permalink to "Retry a transient read""></a></h3><p>When a read fails because the service or the network was briefly unavailable, BDK runs that call again before the model sees the error. A write, and a tool that does not declare an effect, runs once. An advertised MCP tool follows the same rule from its read-only annotation. Declaring <code>effect: "read"</code> opts the call into the default policy of 3 attempts.</p><p>If the read still fails, the tool error includes <code>failed after 3 attempts</code>. That tells the model to stop repeating the call.</p><h3 id="bound-time-arguments-under-asof" tabindex="-1">Bound time arguments under <code>asOf</code> <a class="header-anchor" href="#bound-time-arguments-under-asof" aria-label="Permalink to "Bound time arguments under \`asOf\`""></a></h3><p>Declare <code>timeArgs</code> with the input properties that carry time bounds. In a session created with <code>asOf</code>, every named argument must be an absolute ISO-8601 instant with a timezone, no later than the session's frozen instant. A call that omits one, or supplies a relative or later value, is refused with an error telling the model to retry with absolute bounds. Sessions without <code>asOf</code> ignore the declaration.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
46
46
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> description: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Query telemetry between two instants."</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
47
47
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> inputSchema: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">object</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ since: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(), until: z.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() }),</span></span>
|
|
48
48
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> effect: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"read"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
@@ -87,4 +87,4 @@ import{_ as i,c as a,o as t,a3 as e}from"./chunks/framework.BNw1pucY.js";const c
|
|
|
87
87
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (outcome.isError) {</span></span>
|
|
88
88
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> outcome;</span></span>
|
|
89
89
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
|
|
90
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// { toolName, callId, isError, result, durationMs }</span></span></code></pre></div><p>Omit both identifiers to run against an ephemeral workspace that is removed when the call returns. Pass <code>sessionId</code> (HTTP body, <code>--session</code>, or <code>options.sessionId</code>) or <code>continuationToken</code> (<code><channelId>:<key></code> as <code>/v1/sessions</code> lists it) to bind the call. The two are mutually exclusive.</p><table tabindex="0"><thead><tr><th>Rule</th><th>What happens</th></tr></thead><tbody><tr><td>Existing <code>sessionId</code>, or a token that maps to an existing session</td><td>Session workspace, owner check, and event recording</td></tr><tr><td>Token with no matching session</td><td>Scratch workspace; the token's channel id and key are the call identity</td></tr><tr><td>Busy session, <code>effect: "read"</code> (or an advertised MCP tool marked read-only)</td><td>Runs alongside the turn, reading the workspace as the turn left it; recorded under its own <code>turnId</code></td></tr><tr><td>Busy session, write or undeclared</td><td><code>409 session_busy</code> until the turn finishes</td></tr><tr><td>Session workspace cannot be created, read</td><td>Scratch workspace; the outcome has <code>scratchWorkspace: true</code></td></tr><tr><td>Session workspace cannot be created, write</td><td><code>500 workspace_unavailable</code></td></tr></tbody></table><table tabindex="0"><thead><tr><th>Error</th><th>When</th></tr></thead><tbody><tr><td><code>404 unknown_tool</code></td><td>Name is not a callable server tool; the response lists available names</td></tr><tr><td><code>400 tool_not_callable</code></td><td>Agent-execution tools cannot run on the host</td></tr><tr><td><code>400 invalid_tool_input</code></td><td>Zod rejected the input before <code>execute</code>. Plain JSON Schema is forwarded unvalidated</td></tr><tr><td><code>400 invalid_continuation_token</code></td><td>Malformed token, or passed together with <code>sessionId</code></td></tr><tr><td><code>404 session_not_found</code></td><td><code>sessionId</code> does not exist</td></tr><tr><td><code>409 session_busy</code></td><td>Write-effect call while a model turn is running</td></tr><tr><td><code>500 workspace_unavailable</code></td><td>Write-effect call when the session workspace cannot be created</td></tr><tr><td><code>isError: true</code></td><td>The tool body threw; same envelope the model would see</td></tr></tbody></table><h2 id="design-habits" tabindex="-1">Design habits <a class="header-anchor" href="#design-habits" aria-label="Permalink to "Design habits""></a></h2><p>Keep one decision per tool. Small tools with crisp descriptions beat multi-purpose tools with mode flags. The model chooses better and evals gate cleaner.</p><p>Put deterministic policy in tool code, not model judgment. A PR-approval tool should re-read the live PR inside the tool before acting, so a spoofed payload can't steer it.</p><p>Test tools with <code>call</code> before blaming prompts. If the tool's output is wrong, no instruction change fixes it.</p><p>Gate side effects with <code>needsApproval</code>. Declare each tool's <code>effect</code> so dry-run sessions can execute reads and stub writes.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./connections.html">MCP connections</a>: tools that come from MCP servers instead</li><li><a href="./extensions.html">Extensions</a>: tools installed as a package under a namespace</li><li><a href="./../evals.html">Evals</a>: gating tool decisions with <code>calledTool</code></li></ul>`,
|
|
90
|
+
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// { toolName, callId, isError, result, durationMs }</span></span></code></pre></div><p>Omit both identifiers to run against an ephemeral workspace that is removed when the call returns. Pass <code>sessionId</code> (HTTP body, <code>--session</code>, or <code>options.sessionId</code>) or <code>continuationToken</code> (<code><channelId>:<key></code> as <code>/v1/sessions</code> lists it) to bind the call. The two are mutually exclusive.</p><table tabindex="0"><thead><tr><th>Rule</th><th>What happens</th></tr></thead><tbody><tr><td>Existing <code>sessionId</code>, or a token that maps to an existing session</td><td>Session workspace, owner check, and event recording</td></tr><tr><td>Token with no matching session</td><td>Scratch workspace; the token's channel id and key are the call identity</td></tr><tr><td>Busy session, <code>effect: "read"</code> (or an advertised MCP tool marked read-only)</td><td>Runs alongside the turn, reading the workspace as the turn left it; recorded under its own <code>turnId</code></td></tr><tr><td>Busy session, write or undeclared</td><td><code>409 session_busy</code> until the turn finishes</td></tr><tr><td>Session workspace cannot be created, read</td><td>Scratch workspace; the outcome has <code>scratchWorkspace: true</code></td></tr><tr><td>Session workspace cannot be created, write</td><td><code>500 workspace_unavailable</code></td></tr></tbody></table><table tabindex="0"><thead><tr><th>Error</th><th>When</th></tr></thead><tbody><tr><td><code>404 unknown_tool</code></td><td>Name is not a callable server tool; the response lists available names</td></tr><tr><td><code>400 tool_not_callable</code></td><td>Agent-execution tools cannot run on the host</td></tr><tr><td><code>400 invalid_tool_input</code></td><td>Zod rejected the input before <code>execute</code>. Plain JSON Schema is forwarded unvalidated</td></tr><tr><td><code>400 invalid_continuation_token</code></td><td>Malformed token, or passed together with <code>sessionId</code></td></tr><tr><td><code>404 session_not_found</code></td><td><code>sessionId</code> does not exist</td></tr><tr><td><code>409 session_busy</code></td><td>Write-effect call while a model turn is running</td></tr><tr><td><code>500 workspace_unavailable</code></td><td>Write-effect call when the session workspace cannot be created</td></tr><tr><td><code>isError: true</code></td><td>The tool body threw; same envelope the model would see</td></tr></tbody></table><h2 id="design-habits" tabindex="-1">Design habits <a class="header-anchor" href="#design-habits" aria-label="Permalink to "Design habits""></a></h2><p>Keep one decision per tool. Small tools with crisp descriptions beat multi-purpose tools with mode flags. The model chooses better and evals gate cleaner.</p><p>Put deterministic policy in tool code, not model judgment. A PR-approval tool should re-read the live PR inside the tool before acting, so a spoofed payload can't steer it.</p><p>Test tools with <code>call</code> before blaming prompts. If the tool's output is wrong, no instruction change fixes it.</p><p>Gate side effects with <code>needsApproval</code>. Declare each tool's <code>effect</code> so dry-run sessions can execute reads and stub writes.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./connections.html">MCP connections</a>: tools that come from MCP servers instead</li><li><a href="./extensions.html">Extensions</a>: tools installed as a package under a namespace</li><li><a href="./../evals.html">Evals</a>: gating tool decisions with <code>calledTool</code></li></ul>`,60)])])}const E=i(n,[["render",l]]);export{c as __pageData,E as default};
|
package/dist/docs/assets/{reference_tools.md.v3SXVSs_.lean.js → reference_tools.md.DzIY9JzY.lean.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as i,c as a,o as
|
|
1
|
+
import{_ as i,c as a,o as e,a3 as t}from"./chunks/framework.BNw1pucY.js";const c=JSON.parse('{"title":"Tools","description":"Define typed actions the model can call, gate the sensitive ones on approval, and call any server tool without a model turn.","frontmatter":{"title":"Tools","description":"Define typed actions the model can call, gate the sensitive ones on approval, and call any server tool without a model turn."},"headers":[],"relativePath":"reference/tools.md","filePath":"reference/tools.md"}'),n={name:"reference/tools.md"};function l(h,s,o,p,r,d){return e(),a("div",null,[...s[0]||(s[0]=[t("",60)])])}const E=i(n,[["render",l]]);export{c as __pageData,E as default};
|