@cursor/bdk 0.2.20 → 0.2.21
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/channels/github/defaults.d.ts +1 -1
- package/dist/channels/github/defaults.d.ts.map +1 -1
- package/dist/channels/github/defaults.js +1 -1
- package/dist/channels/github/progress.d.ts +1 -1
- package/dist/channels/github/progress.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BzgJFr_T.js → app.C0diulDR.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot._fglLrPa.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.Bn5QyUDM.js → VPLocalSearchBox.mlUwkfRQ.js} +1 -1
- package/dist/docs/assets/chunks/{arc.D734Gm5d.js → arc.DM5RRfvb.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.NX1jj-YX.js → architectureDiagram-Q4EWVU46.CNHCBbQl.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.nd8dxdeO.js → baseUniq.25Udb_uV.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DG8faTim.js → blockDiagram-DXYQGD6D.Bg-f3-qN.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.zD31AJ3b.js → c4Diagram-AHTNJAMY.BywSQvK9.js} +1 -1
- package/dist/docs/assets/chunks/channel.C4s-x2x3.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.BHQj6Rko.js → chunk-4BX2VUAB.C3IdWWlO.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.Cs38Yh16.js → chunk-4TB4RGXK.D_t-pAXu.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.CFUR21JO.js → chunk-55IACEB6.DvlNSQE5.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.C80-Sneg.js → chunk-EDXVE4YY.6LpTrDTf.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CdT1MGza.js → chunk-FMBD7UC4.BZxXsutI.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.BctEzab0.js → chunk-OYMX7WX6.CrtynS_e.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.DTneeX3k.js → chunk-QZHKN3VN.CUOQY0pM.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.Cz47F_-o.js → chunk-YZCP3GAM.Dv3biZVN.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.h-fLya-M.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.h-fLya-M.js +1 -0
- package/dist/docs/assets/chunks/clone.BM9yCOiZ.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.BPYgB-_O.js → cose-bilkent-S5V4N54A.DDzCqntx.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.Cu6hECod.js → dagre-KV5264BT.DoiV-U_C.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.BMgp95Tz.js → diagram-5BDNPKRD.LHX1aUDr.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.towWdhDi.js → diagram-G4DWMVQ6.lTnkbDQp.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.D9IfOvE9.js → diagram-MMDJMWI5.CclJPnEx.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.NTX57RPu.js → diagram-TYMM5635.CLmB0KKs.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DIQLqDqu.js → erDiagram-SMLLAGMA.qKkkB7iQ.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.DhqpItRe.js → flowDiagram-DWJPFMVM.HIkXNLJ3.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.B998R3Ps.js → ganttDiagram-T4ZO3ILL.YN9lDgHe.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.B45nTn8-.js → gitGraphDiagram-UUTBAWPF.CL6gf7f9.js} +1 -1
- package/dist/docs/assets/chunks/{graph.DPseWzzM.js → graph.DMkP70rB.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO._GhhBBai.js → infoDiagram-42DDH7IO.CT98u6Zd.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.CTUMcaMM.js → ishikawaDiagram-UXIWVN3A.CF88w8YD.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.DkJBUddC.js → journeyDiagram-VCZTEJTY.BoWKk6Rz.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.B5Q3uwhy.js → kanban-definition-6JOO6SKY.CrmPv2sG.js} +1 -1
- package/dist/docs/assets/chunks/{layout.CDY13IKh.js → layout.CEiPTQln.js} +1 -1
- package/dist/docs/assets/chunks/{linear.BPd1ql9p.js → linear.gkXuWu8G.js} +1 -1
- package/dist/docs/assets/chunks/{min.dlGuqIBP.js → min.C4EHK60v.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.Cp7zCtmb.js → mindmap-definition-QFDTVHPH.C-JqTP4s.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.CRH034nu.js → pieDiagram-DEJITSTG.t2HgQOCt.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.BspgZ-pX.js → quadrantDiagram-34T5L4WZ.D1k-BEKc.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.CQZqZ0nZ.js → requirementDiagram-MS252O5E.CUu9VVrt.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.DllwFU3k.js → sankeyDiagram-XADWPNL6.HroiBrt1.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.B5fTXycf.js → sequenceDiagram-FGHM5R23.CeJapdwH.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.12GQjmbD.js → stateDiagram-FHFEXIEX.CLj6JnXZ.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CLFLHNN0.js +1 -0
- package/dist/docs/assets/chunks/{theme.BgocqONV.js → theme.B9ZHHvCq.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.DXKUL5rH.js → timeline-definition-GMOUNBTQ.BzKGPAdN.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.BrsjYCjp.js → vennDiagram-DHZGUBPP.DtBNkpF9.js} +1 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.D_iarxve.js +162 -0
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.C4oM69gv.js → wardleyDiagram-NUSXRM2D.rOXEXIA9.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.qzHH9efW.js → xychartDiagram-5P7HB3ND.BrM71_SA.js} +1 -1
- package/dist/docs/assets/{deployment.md.D0uprX2p.js → deployment.md.CtSJ6sF9.js} +2 -2
- package/dist/docs/assets/{deployment.md.D0uprX2p.lean.js → deployment.md.CtSJ6sF9.lean.js} +1 -1
- package/dist/docs/assets/{guides_hooks.md.B_bKG1oA.js → guides_hooks.md.Bfj0pK91.js} +1 -1
- package/dist/docs/assets/{guides_hooks.md.B_bKG1oA.lean.js → guides_hooks.md.Bfj0pK91.lean.js} +1 -1
- package/dist/docs/assets/{guides_opentelemetry.md.BHPm32OR.js → guides_opentelemetry.md.ByW1Fs7b.js} +4 -4
- package/dist/docs/assets/{guides_opentelemetry.md.BHPm32OR.lean.js → guides_opentelemetry.md.ByW1Fs7b.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.CP3FENFJ.js → reference_hooks.md.B1jq3oGl.js} +2 -2
- package/dist/docs/assets/{reference_hooks.md.CP3FENFJ.lean.js → reference_hooks.md.B1jq3oGl.lean.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md.SNzIvnmC.js → reference_project-layout.md.mFcS8yDD.js} +3 -3
- package/dist/docs/assets/{reference_project-layout.md.SNzIvnmC.lean.js → reference_project-layout.md.mFcS8yDD.lean.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.C_uzIWuy.js → reference_sessions.md.C8FXuGwk.js} +1 -1
- package/dist/docs/assets/{reference_subagents.md.gmPt5J-M.js → reference_subagents.md.ChNGh6HK.js} +1 -1
- package/dist/docs/assets/{reference_subagents.md.gmPt5J-M.lean.js → reference_subagents.md.ChNGh6HK.lean.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.PCafNCb5.js → troubleshooting.md.DFnoTDlQ.js} +1 -1
- package/dist/docs/building-with-agents.html +35 -35
- package/dist/docs/deployment.html +37 -37
- package/dist/docs/deployment.md +10 -3
- package/dist/docs/evals.html +35 -35
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +35 -35
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/export-grokbot.html +35 -35
- package/dist/docs/guides/github.html +35 -35
- package/dist/docs/guides/gitlab.html +35 -35
- package/dist/docs/guides/grokbot-agents.html +35 -35
- package/dist/docs/guides/hooks.html +37 -37
- package/dist/docs/guides/hooks.md +3 -1
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +35 -35
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/migrate.html +35 -35
- package/dist/docs/guides/opentelemetry.html +39 -39
- package/dist/docs/guides/opentelemetry.md +26 -13
- package/dist/docs/guides/slack.html +35 -35
- package/dist/docs/guides/webhooks.html +35 -35
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +35 -35
- package/dist/docs/index.html +35 -35
- package/dist/docs/llms-full.txt +51 -23
- package/dist/docs/quickstart.html +35 -35
- package/dist/docs/reference/agent-config.html +35 -35
- package/dist/docs/reference/artifacts.html +35 -35
- package/dist/docs/reference/channels.html +35 -35
- package/dist/docs/reference/cli.html +35 -35
- package/dist/docs/reference/connections.html +35 -35
- package/dist/docs/reference/evals.html +35 -35
- package/dist/docs/reference/extensions.html +35 -35
- package/dist/docs/reference/hooks.html +37 -37
- package/dist/docs/reference/hooks.md +4 -1
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/memory.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +37 -37
- package/dist/docs/reference/project-layout.md +4 -1
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +36 -36
- package/dist/docs/reference/sessions.md +1 -3
- package/dist/docs/reference/skills.html +35 -35
- package/dist/docs/reference/subagents.html +36 -36
- package/dist/docs/reference/subagents.md +2 -0
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/grokbot-agents.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/docs/troubleshooting.md +1 -1
- package/dist/evals/assertions.d.ts +3 -3
- package/dist/evals/assertions.d.ts.map +1 -1
- package/dist/evals/assertions.js +2 -2
- package/dist/evals/judge.d.ts +5 -4
- package/dist/evals/judge.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/extension.d.ts +4 -1
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/extension.js +20 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +22 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts +3 -3
- package/dist/extensions/cursor-cloud-agents/lib/launch-agent.d.ts.map +1 -1
- package/dist/filesystem.js +1 -1
- package/dist/internal/cursor/account-mcp.d.ts +1 -1
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +1 -1
- package/dist/internal/cursor/github-credentials.d.ts +1 -1
- package/dist/internal/cursor/github-credentials.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +20 -1
- package/dist/internal/discovery/agent.d.ts +1 -1
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/eval-judge-model.d.ts +1 -1
- package/dist/internal/eval-judge-model.d.ts.map +1 -1
- package/dist/internal/eval-runner.d.ts +2 -2
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +1 -1
- package/dist/internal/evals-client.d.ts +1 -1
- package/dist/internal/evals-client.d.ts.map +1 -1
- package/dist/internal/evals-client.js +1 -1
- package/dist/internal/event-log.d.ts.map +1 -1
- package/dist/internal/event-log.js +4 -1
- package/dist/internal/event-mapper.d.ts.map +1 -1
- package/dist/internal/event-mapper.js +5 -1
- package/dist/internal/filesystem/nearest.d.ts +1 -1
- package/dist/internal/filesystem/nearest.d.ts.map +1 -1
- package/dist/internal/filesystem/walk.d.ts +1 -1
- package/dist/internal/filesystem/walk.d.ts.map +1 -1
- package/dist/internal/filesystem/walk.js +1 -1
- package/dist/internal/host-otel.d.ts.map +1 -1
- package/dist/internal/memory-dir.d.ts +8 -0
- package/dist/internal/memory-dir.d.ts.map +1 -0
- package/dist/internal/memory-dir.js +7 -0
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +61 -23
- package/dist/internal/otel/computer-use-attrs.d.ts +8 -3
- package/dist/internal/otel/computer-use-attrs.d.ts.map +1 -1
- package/dist/internal/otel/computer-use-attrs.js +10 -9
- package/dist/internal/otel/config.d.ts +1 -1
- package/dist/internal/otel/config.d.ts.map +1 -1
- package/dist/internal/otel/config.js +1 -1
- package/dist/internal/otel/runtime.d.ts +2 -6
- package/dist/internal/otel/runtime.d.ts.map +1 -1
- package/dist/internal/otel/runtime.js +54 -43
- package/dist/internal/otel/tool-error-class.d.ts +4 -0
- package/dist/internal/otel/tool-error-class.d.ts.map +1 -0
- package/dist/internal/otel/tool-error-class.js +36 -0
- package/dist/internal/tool-result.d.ts +2 -2
- package/dist/internal/tool-result.d.ts.map +1 -1
- package/dist/internal/tool-result.js +16 -11
- package/dist/internal/workspace-sync.js +1 -1
- package/dist/internal/workspace.js +1 -1
- package/dist/memory.d.ts +0 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +1 -2
- package/dist/playground/assets/index-BfePgvWh.css +1 -0
- package/dist/playground/assets/index-DAlf9lxD.js +71 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +8 -3
- package/dist/types.d.ts.map +1 -1
- package/docs/deployment.md +10 -3
- package/docs/guides/hooks.md +3 -1
- package/docs/guides/opentelemetry.md +26 -13
- package/docs/reference/hooks.md +4 -1
- package/docs/reference/project-layout.md +4 -1
- package/docs/reference/sessions.md +1 -3
- package/docs/reference/subagents.md +2 -0
- package/docs/troubleshooting.md +1 -1
- package/package.json +4 -4
- package/skills/evals/SKILL.md +1 -1
- package/skills/framework-map/SKILL.md +3 -1
- package/skills/otel/SKILL.md +4 -3
- package/templates/pr-autofixer/bot/tools/drive_pr.ts +1 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.gGwBYU3d.js +0 -1
- package/dist/docs/assets/chunks/channel.DQLJQMi3.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.j55aerUT.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.j55aerUT.js +0 -1
- package/dist/docs/assets/chunks/clone.XimRS84I.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.Ctv5WEMu.js +0 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.DZDndEXQ.js +0 -162
- package/dist/playground/assets/index-C77_FdOx.css +0 -1
- package/dist/playground/assets/index-CvzI2lhj.js +0 -71
- /package/dist/docs/assets/{reference_sessions.md.C_uzIWuy.lean.js → reference_sessions.md.C8FXuGwk.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.PCafNCb5.lean.js → troubleshooting.md.DFnoTDlQ.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.C0diulDR.js";import{p as Ft}from"./chunk-4BX2VUAB.C3IdWWlO.js";import{p as Ot}from"./wardley-RL74JXVD.D_iarxve.js";import"./framework.BNw1pucY.js";import"./theme.B9ZHHvCq.js";import"./min.C4EHK60v.js";import"./baseUniq.25Udb_uV.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.C0diulDR.js";import{i as _i}from"./init.Gi6I4Gst.js";import{o as ki}from"./ordinal.DBvzRdQf.js";import{l as zt}from"./linear.gkXuWu8G.js";import"./framework.BNw1pucY.js";import"./theme.B9ZHHvCq.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()+`
|
|
@@ -6,7 +6,7 @@ import{_ as s,c as t,o as a,a3 as n}from"./chunks/framework.BNw1pucY.js";const u
|
|
|
6
6
|
<span class="line"><span> --repo https://github.com/acme/agents \\</span></span>
|
|
7
7
|
<span class="line"><span> --ref main \\</span></span>
|
|
8
8
|
<span class="line"><span> --path agents/weather \\</span></span>
|
|
9
|
-
<span class="line"><span> --slug weather-agent</span></span></code></pre></div><p>The source repository must be available through the team's repository integration, and a nested <code>--path</code> must contain an installable BDK project.</p><h3 id="connect-deployed-peers" tabindex="-1">Connect deployed peers <a class="header-anchor" href="#connect-deployed-peers" aria-label="Permalink to "Connect deployed peers""></a></h3><p>A team-owned deployment can call another agent deployed by the same team with <code>defineConnection({ agent: "weather-agent" })</code>. Deploy the specialist and the caller; Cursor-managed hosting resolves the slug and authenticates the call, so you don't configure a peer URL, header, or secret.</p><p>Redeploy the caller after adding or changing a peer connection. An agent last deployed before hosted peer connections became available also needs one redeploy. See <a href="./guides/agent-to-agent.html">Peer agents</a> for delegation, session affinity, and local development.</p><h3 id="privacy-mode" tabindex="-1">Privacy Mode <a class="header-anchor" href="#privacy-mode" aria-label="Permalink to "Privacy Mode""></a></h3><p>A hosted deployment stores a snapshot of its source repository, along with the sessions, KV, files, and logs the agent creates for your team. Whether
|
|
9
|
+
<span class="line"><span> --slug weather-agent</span></span></code></pre></div><p>The source repository must be available through the team's repository integration, and a nested <code>--path</code> must contain an installable BDK project.</p><h3 id="connect-deployed-peers" tabindex="-1">Connect deployed peers <a class="header-anchor" href="#connect-deployed-peers" aria-label="Permalink to "Connect deployed peers""></a></h3><p>A team-owned deployment can call another agent deployed by the same team with <code>defineConnection({ agent: "weather-agent" })</code>. Deploy the specialist and the caller; Cursor-managed hosting resolves the slug and authenticates the call, so you don't configure a peer URL, header, or secret.</p><p>Redeploy the caller after adding or changing a peer connection. An agent last deployed before hosted peer connections became available also needs one redeploy. See <a href="./guides/agent-to-agent.html">Peer agents</a> for delegation, session affinity, and local development.</p><h3 id="privacy-mode" tabindex="-1">Privacy Mode <a class="header-anchor" href="#privacy-mode" aria-label="Permalink to "Privacy Mode""></a></h3><p>A hosted deployment stores a snapshot of its source repository, along with the sessions, KV, files, and logs the agent creates for your team. Whether managed hosting is available depends on the privacy setting that applies to you, which is your team's setting when the team enforces one:</p><table tabindex="0"><thead><tr><th>Privacy setting</th><th>Managed hosting</th></tr></thead><tbody><tr><td>Privacy Mode</td><td>Available. Cursor stores deployment data the same way it does without Privacy Mode, and the agent's model requests get the same Privacy Mode handling as your other Cursor requests.</td></tr><tr><td>Privacy Mode (Legacy)</td><td>Not available. <code>deploy</code>, a hosted session, and an eval run all refuse.</td></tr></tbody></table><p><code>deploy</code> refuses because a deployment stores a snapshot of your repository. A hosted session refuses, and Cursor does not store the message. An eval run refuses because it stores prompts and replies. Switch to Privacy Mode, or ask a team admin when your team enforces this setting.</p><p>The stored data includes the <a href="./reference/memory.html">memory</a> journal, which <code>bdk init</code> turns on. The journal holds user messages and the agent's replies. With Privacy Mode, Cursor stores it only to run your agent and doesn't train on it.</p><h2 id="add-egress-and-secrets" tabindex="-1">Add egress and secrets <a class="header-anchor" href="#add-egress-and-secrets" aria-label="Permalink to "Add egress and secrets""></a></h2><p>Declare the external hosts and secret names the agent needs. Mounted extensions add the ones they declare, so list only what your own code calls; <code>bdk info --dir .</code> shows the combined list and what each mount adds. After the deployment exists, set each value at the hidden prompt and follow the CLI or dashboard instruction to redeploy.</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/agent.ts</span></span>
|
|
10
10
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineAgent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/bdk"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
11
11
|
<span class="line"></span>
|
|
12
12
|
<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;"> defineAgent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -28,4 +28,4 @@ import{_ as s,c as t,o as a,a3 as n}from"./chunks/framework.BNw1pucY.js";const u
|
|
|
28
28
|
<span class="line"><span> --host 127.0.0.1 \\</span></span>
|
|
29
29
|
<span class="line"><span> --port 3000 \\</span></span>
|
|
30
30
|
<span class="line"><span> --state-root /var/lib/bdk \\</span></span>
|
|
31
|
-
<span class="line"><span> --bearer-token "$BDK_BEARER_TOKEN"</span></span></code></pre></div><p>Before exposing the host:</p><ul><li><p>Put TLS or an authenticating proxy in front of the loopback server.</p></li><li><p>Keep <code>--bearer-token</code> on shared hosts. Use <code>--allow-anonymous</code> only behind a proxy that authenticates every caller.</p></li><li><p>Mount <code>--state-root</code> on a persistent volume outside the agent repository and back it up.</p></li><li><p>Inject credentials at startup instead of baking them into an image.</p></li><li><p>Run the process under a supervisor and enable schedules on exactly one serving process per project.</p></li></ul><p>Containers use the same command with <code>--host 0.0.0.0</code>, a mounted state volume, and an authenticating network boundary. The <a href="./reference/channels.html#auth-policies">Channels reference</a> covers per-caller and channel-specific auth.</p><h2 id="observability" tabindex="-1">Observability <a class="header-anchor" href="#observability" aria-label="Permalink to "Observability""></a></h2><p>Use <code>bdk logs --prod</code> and <code>bdk session <sessionId> --prod</code> for a hosted session's runs and logs, <a href="./guides/opentelemetry.html">OpenTelemetry</a> for traces and metrics, and <a href="./reference/sessions.html#inspect-a-saved-event-stream">session traces</a> for a local conversation.</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/migrate.html">Early-alpha migration</a>: move a hosted architecture v1 project to v2 through a reviewed pull request</li><li><a href="./reference/cli.html#deploy">CLI reference</a>: inspect, update, stop, delete, and rotate deployments</li><li><a href="./guides/github.html">GitHub</a>: Cursor-event repositories and direct webhook delivery</li><li><a href="./guides/slack.html">Slack</a>: provision a dedicated hosted Slack app</li><li><a href="./guides/mcp-oauth.html">Host MCP OAuth</a>: reach OAuth-backed MCP servers from a hosted agent</li><li><a href="./troubleshooting.html">Troubleshooting</a>: diagnose failed or stale deployments</li></ul>`,
|
|
31
|
+
<span class="line"><span> --bearer-token "$BDK_BEARER_TOKEN"</span></span></code></pre></div><p>Before exposing the host:</p><ul><li><p>Put TLS or an authenticating proxy in front of the loopback server.</p></li><li><p>Keep <code>--bearer-token</code> on shared hosts. Use <code>--allow-anonymous</code> only behind a proxy that authenticates every caller.</p></li><li><p>Mount <code>--state-root</code> on a persistent volume outside the agent repository and back it up.</p></li><li><p>Inject credentials at startup instead of baking them into an image.</p></li><li><p>Run the process under a supervisor and enable schedules on exactly one serving process per project.</p></li></ul><p>Containers use the same command with <code>--host 0.0.0.0</code>, a mounted state volume, and an authenticating network boundary. The <a href="./reference/channels.html#auth-policies">Channels reference</a> covers per-caller and channel-specific auth.</p><h2 id="observability" tabindex="-1">Observability <a class="header-anchor" href="#observability" aria-label="Permalink to "Observability""></a></h2><p>Use <code>bdk logs --prod</code> and <code>bdk session <sessionId> --prod</code> for a hosted session's runs and logs, <a href="./guides/opentelemetry.html">OpenTelemetry</a> for traces and metrics, and <a href="./reference/sessions.html#inspect-a-saved-event-stream">session traces</a> for a local conversation.</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/migrate.html">Early-alpha migration</a>: move a hosted architecture v1 project to v2 through a reviewed pull request</li><li><a href="./reference/cli.html#deploy">CLI reference</a>: inspect, update, stop, delete, and rotate deployments</li><li><a href="./guides/github.html">GitHub</a>: Cursor-event repositories and direct webhook delivery</li><li><a href="./guides/slack.html">Slack</a>: provision a dedicated hosted Slack app</li><li><a href="./guides/mcp-oauth.html">Host MCP OAuth</a>: reach OAuth-backed MCP servers from a hosted agent</li><li><a href="./troubleshooting.html">Troubleshooting</a>: diagnose failed or stale deployments</li></ul>`,65)])])}const g=s(o,[["render",i]]);export{u as __pageData,g as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as s,c as t,o as a,a3 as n}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Deployment","description":"Deploy a BDK project from Git with Cursor-managed hosting, or run one secure process on your own infrastructure.","frontmatter":{"title":"Deployment","description":"Deploy a BDK project from Git with Cursor-managed hosting, or run one secure process on your own infrastructure."},"headers":[],"relativePath":"deployment.md","filePath":"deployment.md"}'),o={name:"deployment.md"};function i(r,e,d,l,h,p){return a(),t("div",null,[...e[0]||(e[0]=[n("",
|
|
1
|
+
import{_ as s,c as t,o as a,a3 as n}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Deployment","description":"Deploy a BDK project from Git with Cursor-managed hosting, or run one secure process on your own infrastructure.","frontmatter":{"title":"Deployment","description":"Deploy a BDK project from Git with Cursor-managed hosting, or run one secure process on your own infrastructure."},"headers":[],"relativePath":"deployment.md","filePath":"deployment.md"}'),o={name:"deployment.md"};function i(r,e,d,l,h,p){return a(),t("div",null,[...e[0]||(e[0]=[n("",65)])])}const g=s(o,[["render",i]]);export{u as __pageData,g as default};
|
|
@@ -47,4 +47,4 @@ import{_ as i,c as a,o as n,a3 as e}from"./chunks/framework.BNw1pucY.js";const E
|
|
|
47
47
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
|
|
48
48
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
49
49
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
50
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="events-when-hooks-run" tabindex="-1">Events / when hooks run <a class="header-anchor" href="#events-when-hooks-run" aria-label="Permalink to "Events / when hooks run""></a></h2><p>Use event names from the <a href="./../reference/sessions.html#stream-events">session event vocabulary</a>. A hook receives each matching event after it is recorded, and the model does not wait for the handler.</p><p>Within one session, handlers run one at a time. A slow handler delays later handlers for that session, but it does not delay the model or handlers for other sessions. Hooks also fire for evals, so check <code>ctx.session.purpose === "eval"</code> before metering or paging. A restart does not replay recorded events into hooks.</p><h2 id="when-not-to-use-a-hook" tabindex="-1">When not to use a hook <a class="header-anchor" href="#when-not-to-use-a-hook" aria-label="Permalink to "When not to use a hook""></a></h2><table tabindex="0"><thead><tr><th>Want</th><th>Use instead</th></tr></thead><tbody><tr><td>Add context before the model</td><td><code>instructions.md</code>, skills, or <code>workspaceFiles</code></td></tr><tr><td>Deliver to Slack or a PR</td><td>Channel <a href="./../reference/channels.html#events"><code>events</code></a> or packs</td></tr><tr><td>Gate
|
|
50
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="events-when-hooks-run" tabindex="-1">Events / when hooks run <a class="header-anchor" href="#events-when-hooks-run" aria-label="Permalink to "Events / when hooks run""></a></h2><p>Use event names from the <a href="./../reference/sessions.html#stream-events">session event vocabulary</a>. A hook receives each matching event after it is recorded, and the model does not wait for the handler.</p><p>Within one session, handlers run one at a time. A slow handler delays later handlers for that session, but it does not delay the model or handlers for other sessions. Hooks also fire for evals, so check <code>ctx.session.purpose === "eval"</code> before metering or paging. A restart does not replay recorded events into hooks.</p><h2 id="when-not-to-use-a-hook" tabindex="-1">When not to use a hook <a class="header-anchor" href="#when-not-to-use-a-hook" aria-label="Permalink to "When not to use a hook""></a></h2><table tabindex="0"><thead><tr><th>Want</th><th>Use instead</th></tr></thead><tbody><tr><td>Add context before the model</td><td><code>instructions.md</code>, skills, or <code>workspaceFiles</code></td></tr><tr><td>Deliver to Slack or a PR</td><td>Channel <a href="./../reference/channels.html#events"><code>events</code></a> or packs</td></tr><tr><td>Gate behavior</td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><p>To act on a turn's decision, have the model record it with an authored <a href="./../reference/tools.html">tool</a>, then act on it from a <code>turn.completed</code> hook.</p><p><a href="https://cursor.com/docs/agent/hooks" target="_blank" rel="noreferrer">Cursor Agent hooks</a> in <code>.cursor/hooks.json</code> are a different product. They can observe, block, or modify the local agent loop.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./../reference/hooks.html">Hooks reference</a>: payloads, context, and discovery</li><li><a href="./../reference/sessions.html#stream-events">Sessions: stream events</a>: event vocabulary and payload sequence</li><li><a href="./opentelemetry.html">OpenTelemetry</a>: export traces and custom metrics</li><li><a href="./../reference/channels.html#events">Channels: events</a>: deliver replies back to Slack, source control, or another surface</li></ul>`,17)])])}const c=i(t,[["render",h]]);export{E as __pageData,c as default};
|
package/dist/docs/assets/{guides_hooks.md.B_bKG1oA.lean.js → guides_hooks.md.Bfj0pK91.lean.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as i,c as a,o as n,a3 as e}from"./chunks/framework.BNw1pucY.js";const E=JSON.parse('{"title":"Hooks","description":"Observe session events for metrics, alerts, and other side effects without changing the turn.","frontmatter":{"title":"Hooks","description":"Observe session events for metrics, alerts, and other side effects without changing the turn."},"headers":[],"relativePath":"guides/hooks.md","filePath":"guides/hooks.md"}'),t={name:"guides/hooks.md"};function h(l,s,k,p,r,o){return n(),a("div",null,[...s[0]||(s[0]=[e("",
|
|
1
|
+
import{_ as i,c as a,o as n,a3 as e}from"./chunks/framework.BNw1pucY.js";const E=JSON.parse('{"title":"Hooks","description":"Observe session events for metrics, alerts, and other side effects without changing the turn.","frontmatter":{"title":"Hooks","description":"Observe session events for metrics, alerts, and other side effects without changing the turn."},"headers":[],"relativePath":"guides/hooks.md","filePath":"guides/hooks.md"}'),t={name:"guides/hooks.md"};function h(l,s,k,p,r,o){return n(),a("div",null,[...s[0]||(s[0]=[e("",17)])])}const c=i(t,[["render",h]]);export{E as __pageData,c as default};
|
package/dist/docs/assets/{guides_opentelemetry.md.BHPm32OR.js → guides_opentelemetry.md.ByW1Fs7b.js}
RENAMED
|
@@ -16,12 +16,12 @@ import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const k
|
|
|
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
18
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
19
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Use environment variables when you start the agent with <code>bdk serve</code>. Use <code>serve({ otel })</code> when your TypeScript application starts the server itself.</p><h2 id="follow-one-conversation" tabindex="-1">Follow one conversation <a class="header-anchor" href="#follow-one-conversation" aria-label="Permalink to "Follow one conversation""></a></h2><p>Copy the complete session ID from the playground or session API, then filter your observability system on either <code>agent_sdk.session_id</code> or <code>cursor.conversation.id</code>. Every turn in that conversation carries the same value, including follow-ups and tool work.</p><p>The trace shape stays small:</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>request: agent_sdk.http</span></span>
|
|
19
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>Use environment variables when you start the agent with <code>bdk serve</code>. Use <code>serve({ otel })</code> when your TypeScript application starts the server itself. When that application already uses OpenTelemetry, BDK sends its traces, metrics, and logs to the collector configured here.</p><h2 id="follow-one-conversation" tabindex="-1">Follow one conversation <a class="header-anchor" href="#follow-one-conversation" aria-label="Permalink to "Follow one conversation""></a></h2><p>Copy the complete session ID from the playground or session API, then filter your observability system on either <code>agent_sdk.session_id</code> or <code>cursor.conversation.id</code>. Every turn in that conversation carries the same value, including follow-ups and tool work.</p><p>The trace shape stays small:</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>request: agent_sdk.http</span></span>
|
|
20
20
|
<span class="line"><span></span></span>
|
|
21
21
|
<span class="line"><span>turn: agent_sdk.turn</span></span>
|
|
22
22
|
<span class="line"><span> |- agent_sdk.tool</span></span>
|
|
23
23
|
<span class="line"><span> \`- agent_sdk.subagent</span></span>
|
|
24
|
-
<span class="line"><span> \`- agent_sdk.tool</span></span></code></pre></div><p>A conversation can produce several turn traces, so use the session ID as the join key instead of expecting one long-lived session span.</p><h3 id="computer-use" tabindex="-1">Computer use <a class="header-anchor" href="#computer-use" aria-label="Permalink to "Computer use""></a></h3><p>Each computer use
|
|
24
|
+
<span class="line"><span> \`- agent_sdk.tool</span></span></code></pre></div><p>A conversation can produce several turn traces, so use the session ID as the join key instead of expecting one long-lived session span.</p><h3 id="subagents" tabindex="-1">Subagents <a class="header-anchor" href="#subagents" aria-label="Permalink to "Subagents""></a></h3><p>A subagent's tool calls are <code>agent_sdk.tool</code> spans under its <code>agent_sdk.subagent</code> span. Its <code>reasoning.completed</code> and <code>message.completed</code> events sit on that span too, so the subagent span shows where its time went. Time between two tool spans is the model choosing the next step. A subagent that fails or is cancelled ends its span with ERROR status when it stops.</p><h3 id="computer-use" tabindex="-1">Computer use <a class="header-anchor" href="#computer-use" aria-label="Permalink to "Computer use""></a></h3><p>Each computer use action is an <code>agent_sdk.tool</code> span with <code>cursor.tool.name</code> set to <code>computerUse</code>, under the computer use subagent's span. A failed action has ERROR status. These attributes describe the action without typed text, coordinates, or screenshots:</p><table tabindex="0"><thead><tr><th>Attribute</th><th>Value</th></tr></thead><tbody><tr><td><code>agent_sdk.computer.actions</code></td><td>The action type, such as <code>click</code>, <code>type</code>, or <code>screenshot</code></td></tr><tr><td><code>agent_sdk.computer.executor_duration_ms</code></td><td>Time the desktop took to run the action and capture the screen</td></tr><tr><td><code>agent_sdk.computer.settle_ms</code></td><td>Part of that time spent waiting for the screen to settle</td></tr></tbody></table><p>The two durations appear only on actions that succeed.</p><p>To export the full actions, turn on tool content as shown in <a href="#control-what-leaves-the-process">Control what leaves the process</a>. Tool content includes the text the agent typed, which can contain passwords.</p><h2 id="add-domain-telemetry" tabindex="-1">Add domain telemetry <a class="header-anchor" href="#add-domain-telemetry" aria-label="Permalink to "Add domain telemetry""></a></h2><p>Use <code>ctx.host.otel</code> when your dashboard should answer questions the built-in telemetry cannot, such as which incident a turn handled or how long approval took. Attributes appear on the active turn and tool spans, while counters and histograms give you metrics to graph and alert on.</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:#24292E;--shiki-dark:#E1E4E8;">ctx.host.otel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">setAttributes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
25
25
|
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "support.ticket_id"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"INC-123"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
26
26
|
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "support.queue"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"p1"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
27
27
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span>
|
|
@@ -32,6 +32,6 @@ import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const k
|
|
|
32
32
|
<span class="line"></span>
|
|
33
33
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">ctx.host.otel.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">record</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"support.approval.duration_ms"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1420</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, {</span></span>
|
|
34
34
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> outcome: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"approved"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
35
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This API is available in tools, hooks, and channel handlers. A session-bound context adds <code>cursor.conversation.id</code> and <code>agent_sdk.agent</code> automatically, so custom measurements join the first-party telemetry without extra plumbing.</p><p>Prefix custom names with your team or agent. First-party metric names and join keys are reserved, and this surface does not create custom spans.</p><h2 id="choose-signals" tabindex="-1">Choose signals <a class="header-anchor" href="#choose-signals" aria-label="Permalink to "Choose signals""></a></h2><p>Once export has a destination, traces and metrics are on by default; logs remain off until you opt in.</p><table tabindex="0"><thead><tr><th>Signal</th><th>What appears</th></tr></thead><tbody><tr><td>Traces</td><td>HTTP requests, turns, tools, and subagents</td></tr><tr><td>Metrics</td><td>Token usage, tool calls, cost, and BDK session or turn counts</td></tr><tr><td>Logs</td><td>Session events, after you enable log export</td></tr></tbody></table><p>The first metrics to look for are <code>cursor.token.usage</code>, <code>cursor.tool.calls</code>, and <code>cursor.cost.usage</code>. Configure <code>traces: false</code>, <code>metrics: false</code>, or <code>logs: true</code> under <code>serve({ otel })</code> when you need a different signal mix.</p><h2 id="control-what-leaves-the-process" tabindex="-1">Control what leaves the process <a class="header-anchor" href="#control-what-leaves-the-process" aria-label="Permalink to "Control what leaves the process""></a></h2><p>
|
|
35
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This API is available in tools, hooks, and channel handlers. A session-bound context adds <code>cursor.conversation.id</code> and <code>agent_sdk.agent</code> automatically, so custom measurements join the first-party telemetry without extra plumbing.</p><p>Prefix custom names with your team or agent. First-party metric names and join keys are reserved, and this surface does not create custom spans.</p><h2 id="choose-signals" tabindex="-1">Choose signals <a class="header-anchor" href="#choose-signals" aria-label="Permalink to "Choose signals""></a></h2><p>Once export has a destination, traces and metrics are on by default; logs remain off until you opt in.</p><table tabindex="0"><thead><tr><th>Signal</th><th>What appears</th></tr></thead><tbody><tr><td>Traces</td><td>HTTP requests, turns, tools, and subagents</td></tr><tr><td>Metrics</td><td>Token usage, tool calls, cost, and BDK session or turn counts</td></tr><tr><td>Logs</td><td>Session events, after you enable log export</td></tr></tbody></table><p>The first metrics to look for are <code>cursor.token.usage</code>, <code>cursor.tool.calls</code>, and <code>cursor.cost.usage</code>. Configure <code>traces: false</code>, <code>metrics: false</code>, or <code>logs: true</code> under <code>serve({ otel })</code> when you need a different signal mix.</p><h2 id="control-what-leaves-the-process" tabindex="-1">Control what leaves the process <a class="header-anchor" href="#control-what-leaves-the-process" aria-label="Permalink to "Control what leaves the process""></a></h2><p>Traces include structure, tool names, usage metrics, and span status. A failed tool's status includes a short failure reason. A tool or subagent that is still open when the turn ends gets ERROR status with the reason <code>no result</code>. User prompts, tool arguments, and full tool results stay off the wire until you opt in.</p><p>Turn on logs first, then opt into prompt or tool content separately:</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:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> OTEL_LOGS_EXPORTER</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">otlp</span></span>
|
|
36
36
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> OTEL_LOG_USER_PROMPTS</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span></span>
|
|
37
|
-
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> OTEL_LOG_TOOL_CONTENT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span></span></code></pre></div><p><code>OTEL_LOG_USER_PROMPTS</code> exports user text. <code>OTEL_LOG_TOOL_CONTENT</code> exports tool inputs, outputs, and failure details. Enable either only when the collector's access and retention policies are appropriate for that data.</p><p>The same controls are available as <code>logs: { userPrompts, toolContent }</code> under <code>serve({ otel })</code>.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./../../skills/otel/SKILL.html"><code>skills/otel/SKILL.md</code></a>: compact configuration and custom-metric reference for coding agents</li><li><a href="./../reference/hooks.html">Hooks</a>: emit domain telemetry from session events</li><li><a href="./../deployment.html">Deployment</a>: set collector endpoints and secrets on hosted or self-hosted agents</li><li><a href="https://cursor.com/docs/enterprise/opentelemetry-export" target="_blank" rel="noreferrer">Cursor enterprise OpenTelemetry Export</a>: send organization-wide Cursor telemetry to the same collector</li></ul>`,
|
|
37
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> OTEL_LOG_TOOL_CONTENT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span></span></code></pre></div><p><code>OTEL_LOG_USER_PROMPTS</code> exports user text. <code>OTEL_LOG_TOOL_CONTENT</code> exports tool inputs, outputs, and failure details. Enable either only when the collector's access and retention policies are appropriate for that data.</p><p>The same controls are available as <code>logs: { userPrompts, toolContent }</code> under <code>serve({ otel })</code>.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./../../skills/otel/SKILL.html"><code>skills/otel/SKILL.md</code></a>: compact configuration and custom-metric reference for coding agents</li><li><a href="./../reference/hooks.html">Hooks</a>: emit domain telemetry from session events</li><li><a href="./../deployment.html">Deployment</a>: set collector endpoints and secrets on hosted or self-hosted agents</li><li><a href="https://cursor.com/docs/enterprise/opentelemetry-export" target="_blank" rel="noreferrer">Cursor enterprise OpenTelemetry Export</a>: send organization-wide Cursor telemetry to the same collector</li></ul>`,38)])])}const E=e(n,[["render",o]]);export{k as __pageData,E as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const k=JSON.parse('{"title":"OpenTelemetry","description":"Send agent traces and metrics to an OTLP collector, follow one conversation, and add domain telemetry.","frontmatter":{"title":"OpenTelemetry","description":"Send agent traces and metrics to an OTLP collector, follow one conversation, and add domain telemetry."},"headers":[],"relativePath":"guides/opentelemetry.md","filePath":"guides/opentelemetry.md"}'),n={name:"guides/opentelemetry.md"};function o(l,s,r,p,h,d){return a(),t("div",null,[...s[0]||(s[0]=[i("",
|
|
1
|
+
import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const k=JSON.parse('{"title":"OpenTelemetry","description":"Send agent traces and metrics to an OTLP collector, follow one conversation, and add domain telemetry.","frontmatter":{"title":"OpenTelemetry","description":"Send agent traces and metrics to an OTLP collector, follow one conversation, and add domain telemetry."},"headers":[],"relativePath":"guides/opentelemetry.md","filePath":"guides/opentelemetry.md"}'),n={name:"guides/opentelemetry.md"};function o(l,s,r,p,h,d){return a(),t("div",null,[...s[0]||(s[0]=[i("",38)])])}const E=e(n,[["render",o]]);export{k as __pageData,E as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
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,
|
|
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,c){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>
|
|
@@ -42,4 +42,4 @@ import{_ as e,c as t,o as a,a3 as i}from"./chunks/framework.BNw1pucY.js";const k
|
|
|
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>
|
|
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>Gate a change on behavior</td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><p>To act on a turn's decision, such as a label or a ticket, have the model record it with an authored <a href="./tools.html">tool</a>. A <code>turn.completed</code> hook then reads the recorded decision and acts on it through <code>ctx.host</code>.</p><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>`,32)])])}const E=e(n,[["render",o]]);export{k as __pageData,E as default};
|
package/dist/docs/assets/{reference_hooks.md.CP3FENFJ.lean.js → reference_hooks.md.B1jq3oGl.lean.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,c){return a(),t("div",null,[...s[0]||(s[0]=[i("",32)])])}const E=e(n,[["render",o]]);export{k as __pageData,E as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as t,c as o,o as s,a3 as a}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules.","frontmatter":{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),
|
|
1
|
+
import{_ as t,c as o,o as s,a3 as a}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules.","frontmatter":{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),n={name:"reference/project-layout.md"};function d(r,e,c,i,l,p){return s(),o("div",null,[...e[0]||(e[0]=[a(`<h1 id="project-layout" tabindex="-1">Project layout <a class="header-anchor" href="#project-layout" aria-label="Permalink to "Project layout""></a></h1><p>A Bot Development Kit (BDK) project keeps agent files under <code>bot/</code>. Each file's path determines how BDK loads it.</p><p>Existing projects rooted at <code>agent/</code> remain supported.</p><h2 id="folder-structure" tabindex="-1">Folder structure <a class="header-anchor" href="#folder-structure" aria-label="Permalink to "Folder structure""></a></h2><p>For the capabilities below, identity comes from the path.</p><table tabindex="0"><thead><tr><th>Path under <code>bot/</code></th><th>Resolves to</th></tr></thead><tbody><tr><td><code>tools/approve_pr.ts</code></td><td>tool <code>approve_pr</code></td></tr><tr><td><code>mcp-connections/linear.ts</code></td><td>MCP connection <code>linear</code> (model + host)</td></tr><tr><td><code>host-connections/inventory.ts</code></td><td>Host MCP connection <code>inventory</code> (host + <code>mcp oauth</code> only)</td></tr><tr><td><code>skills/pr-review.md</code></td><td>skill <code>pr-review</code></td></tr><tr><td><code>subagents/reviewer/</code></td><td>subagent <code>reviewer</code></td></tr><tr><td><code>extensions/ci.ts</code></td><td>extension mount <code>ci</code>; its contributions become <code>ci__<name></code></td></tr><tr><td><code>extensions/notion.ts</code></td><td>Cursor plugin mount <code>notion</code> (<code>cursorPlugin</code>); its skills, agents, and MCP servers become <code>notion__<name></code></td></tr><tr><td><code>channels/drive.ts</code></td><td>channel <code>drive</code>, routes under <code>/v1/channels/drive</code></td></tr></tbody></table><p>The root agent takes its name from <code>package.json</code> <code>name</code>, falling back to the directory name. When serving multiple agents, the slug is the directory name and must match <code>[A-Za-z0-9][A-Za-z0-9_-]*</code> (and not the reserved <code>v1</code>, <code>playground</code>, or <code>docs</code> segments).</p><h2 id="project-tree" tabindex="-1">Project tree <a class="header-anchor" href="#project-tree" aria-label="Permalink to "Project tree""></a></h2><p>Most projects start with this shape.</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>my-agent/</span></span>
|
|
2
2
|
<span class="line"><span>├── package.json</span></span>
|
|
3
3
|
<span class="line"><span>├── bot/</span></span>
|
|
4
4
|
<span class="line"><span>│ ├── agent.ts # model and local harness config</span></span>
|
|
@@ -20,6 +20,6 @@ import{_ as t,c as o,o as s,a3 as a}from"./chunks/framework.BNw1pucY.js";const u
|
|
|
20
20
|
<span class="line"><span>│ └── hooks/</span></span>
|
|
21
21
|
<span class="line"><span>│ └── audit.ts # observe session events</span></span>
|
|
22
22
|
<span class="line"><span>└── evals/</span></span>
|
|
23
|
-
<span class="line"><span> └── readiness.eval.ts # regression cases</span></span></code></pre></div><p>Evals stay in <code>evals/</code> at the project root, as a sibling of <code>bot/</code>, never inside it. See <a href="./../evals.html">Evals</a>.</p><h2 id="folder-reference" tabindex="-1">Folder reference <a class="header-anchor" href="#folder-reference" aria-label="Permalink to "Folder reference""></a></h2><p>Each path maps to a capability and a reference page.</p><table tabindex="0"><thead><tr><th>Path under <code>bot/</code></th><th>What it is</th><th>Reference</th></tr></thead><tbody><tr><td><code>agent.ts</code></td><td><code>defineAgent({ model?, local? })</code>; the model defaults to <code>grok-4.5</code> with <code>effort=high</code>, <code>fast=true</code></td><td><a href="./agent-config.html">Agent config</a></td></tr><tr><td><code>instructions.md</code></td><td>Always-on system prompt, required on the root agent (<code>.ts</code> and directory forms exist)</td><td><a href="./instructions.html">Instructions</a></td></tr><tr><td><code>tools/<name>.ts</code></td><td>One typed tool; filename = tool name. <code>execution: "server"</code> (in-process, default) or <code>"agent"</code> (a script that runs where the agent runs)</td><td><a href="./tools.html">Tools</a></td></tr><tr><td><code>skills/*</code></td><td>SKILL.md-convention procedures, loaded on demand</td><td><a href="./skills.html">Skills</a></td></tr><tr><td><code>mcp-connections/<name>.ts</code></td><td>MCP servers, available to the model, to server tools (<code>ctx.host.mcp</code>), and to channel/schedule handlers (<code>args.host.mcp</code>)</td><td><a href="./connections.html">MCP connections</a></td></tr><tr><td><code>host-connections/<name>.ts</code></td><td>Privileged MCP servers for <code>ctx.host.mcp</code> and <code>mcp oauth</code>. The model never sees them.</td><td><a href="./connections.html">MCP connections</a></td></tr><tr><td><code>subagents/<id>/</code></td><td>Child agent directory; <code>description</code> required</td><td><a href="./subagents.html">Subagents</a></td></tr><tr><td><code>extensions/<ns>.ts</code> or <code>extensions/<ns>/</code></td><td>A mounted extension or Cursor plugin; its contributions become <code><ns>__<name></code></td><td><a href="./extensions.html">Extensions</a></td></tr><tr><td><code>channels/*.ts</code></td><td>HTTP surfaces beyond the built-in session API; <code>slack.ts</code> and <code>github.ts</code> use the platform packs</td><td><a href="./channels.html">Channels</a></td></tr><tr><td><code>hooks/*.ts</code></td><td>Observe-only event subscribers, never fatal</td><td><a href="./hooks.html">Hooks</a></td></tr><tr><td><code>artifacts.ts</code></td><td><code>defineArtifacts</code> kinds, the <code>tag_artifact</code> opt-in, and retention</td><td><a href="./artifacts.html">Artifacts</a></td></tr><tr><td><code>
|
|
23
|
+
<span class="line"><span> └── readiness.eval.ts # regression cases</span></span></code></pre></div><p>Evals stay in <code>evals/</code> at the project root, as a sibling of <code>bot/</code>, never inside it. See <a href="./../evals.html">Evals</a>.</p><h2 id="folder-reference" tabindex="-1">Folder reference <a class="header-anchor" href="#folder-reference" aria-label="Permalink to "Folder reference""></a></h2><p>Each path maps to a capability and a reference page.</p><table tabindex="0"><thead><tr><th>Path under <code>bot/</code></th><th>What it is</th><th>Reference</th></tr></thead><tbody><tr><td><code>agent.ts</code></td><td><code>defineAgent({ model?, local? })</code>; the model defaults to <code>grok-4.5</code> with <code>effort=high</code>, <code>fast=true</code></td><td><a href="./agent-config.html">Agent config</a></td></tr><tr><td><code>instructions.md</code></td><td>Always-on system prompt, required on the root agent (<code>.ts</code> and directory forms exist)</td><td><a href="./instructions.html">Instructions</a></td></tr><tr><td><code>tools/<name>.ts</code></td><td>One typed tool; filename = tool name. <code>execution: "server"</code> (in-process, default) or <code>"agent"</code> (a script that runs where the agent runs)</td><td><a href="./tools.html">Tools</a></td></tr><tr><td><code>skills/*</code></td><td>SKILL.md-convention procedures, loaded on demand</td><td><a href="./skills.html">Skills</a></td></tr><tr><td><code>mcp-connections/<name>.ts</code></td><td>MCP servers, available to the model, to server tools (<code>ctx.host.mcp</code>), and to channel/schedule handlers (<code>args.host.mcp</code>)</td><td><a href="./connections.html">MCP connections</a></td></tr><tr><td><code>host-connections/<name>.ts</code></td><td>Privileged MCP servers for <code>ctx.host.mcp</code> and <code>mcp oauth</code>. The model never sees them.</td><td><a href="./connections.html">MCP connections</a></td></tr><tr><td><code>subagents/<id>/</code></td><td>Child agent directory; <code>description</code> required</td><td><a href="./subagents.html">Subagents</a></td></tr><tr><td><code>extensions/<ns>.ts</code> or <code>extensions/<ns>/</code></td><td>A mounted extension or Cursor plugin; its contributions become <code><ns>__<name></code></td><td><a href="./extensions.html">Extensions</a></td></tr><tr><td><code>channels/*.ts</code></td><td>HTTP surfaces beyond the built-in session API; <code>slack.ts</code> and <code>github.ts</code> use the platform packs</td><td><a href="./channels.html">Channels</a></td></tr><tr><td><code>hooks/*.ts</code></td><td>Observe-only event subscribers, never fatal</td><td><a href="./hooks.html">Hooks</a></td></tr><tr><td><code>artifacts.ts</code></td><td><code>defineArtifacts</code> kinds, the <code>tag_artifact</code> opt-in, and retention</td><td><a href="./artifacts.html">Artifacts</a></td></tr><tr><td><code>schedules/*</code></td><td>Cron-driven runs (UTC, 5-field; never auto-fire under <code>--dev</code>)</td><td><a href="./schedules.html">Schedules</a></td></tr><tr><td><code>reminders/*.ts</code></td><td>Named reminder handlers that stay armed across restarts</td><td><a href="./schedules.html#reminders">Schedules</a></td></tr><tr><td><code>sandbox/workspace/**</code></td><td>Seed files copied into each local session workspace</td><td><a href="./sessions.html#local-session-workspace">Sessions</a></td></tr><tr><td><code>lib/</code></td><td>Import-only shared code, never discovered</td><td>None</td></tr></tbody></table><p>Discovery rejects a <code>bot/result.ts</code> file. To act on a turn's decision, have the model record it with an authored <a href="./tools.html">tool</a>, then act on it from a <code>turn.completed</code> <a href="./hooks.html">hook</a>.</p><p>Evals use project-root paths:</p><table tabindex="0"><thead><tr><th>Project-root path</th><th>What it is</th><th>Reference</th></tr></thead><tbody><tr><td><code>evals/evals.config.ts</code></td><td>Shared eval settings (e.g. <code>maxConcurrency</code>); required when evals exist</td><td><a href="./../evals.html">Evals</a></td></tr><tr><td><code>evals/**/*.eval.ts</code></td><td>Filesystem evals; case id = path under <code>evals/</code></td><td><a href="./../evals.html">Evals</a></td></tr></tbody></table><p>Use <code>bot/lib/</code> for shared imports. A <code>.ts</code> file in one of the listed discovery folders loads as a definition; unrecognized directories produce a validation warning.</p><h2 id="inspect-discovery" tabindex="-1">Inspect discovery <a class="header-anchor" href="#inspect-discovery" aria-label="Permalink to "Inspect discovery""></a></h2><p>Run <code>bdk validate --dir .</code> and <code>bdk info --dir .</code>. <code>validate</code> prints diagnostics, and <code>serve</code> refuses to start on error-severity ones. Warnings print but don't block. <code>info</code> lists the discovered surface, so a missing tool or channel shows up immediately. From there, check the folder reference: the file is usually in the wrong directory or has the wrong extension.</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 validate --dir . # diagnostics; non-zero exit on errors</span></span>
|
|
24
24
|
<span class="line"><span>bdk info --dir . # human-readable surface</span></span>
|
|
25
|
-
<span class="line"><span>bdk info --dir . --json # machine-readable project info (same shape as GET /v1/info)</span></span></code></pre></div><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./agent-config.html">Agent config</a>: the config at the project root</li><li><a href="./tools.html">Tools</a>: add typed actions under <code>tools/</code></li><li><a href="./cli.html">CLI</a>: commands that discover this tree</li></ul>`,
|
|
25
|
+
<span class="line"><span>bdk info --dir . --json # machine-readable project info (same shape as GET /v1/info)</span></span></code></pre></div><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./agent-config.html">Agent config</a>: the config at the project root</li><li><a href="./tools.html">Tools</a>: add typed actions under <code>tools/</code></li><li><a href="./cli.html">CLI</a>: commands that discover this tree</li></ul>`,23)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as t,c as o,o as s,a3 as a}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules.","frontmatter":{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),
|
|
1
|
+
import{_ as t,c as o,o as s,a3 as a}from"./chunks/framework.BNw1pucY.js";const u=JSON.parse('{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules.","frontmatter":{"title":"Project layout","description":"The canonical bot/ folder layout and its path-derived naming rules."},"headers":[],"relativePath":"reference/project-layout.md","filePath":"reference/project-layout.md"}'),n={name:"reference/project-layout.md"};function d(r,e,c,i,l,p){return s(),o("div",null,[...e[0]||(e[0]=[a("",23)])])}const m=t(n,[["render",d]]);export{u as __pageData,m as default};
|
package/dist/docs/assets/{reference_sessions.md.C_uzIWuy.js → reference_sessions.md.C8FXuGwk.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, 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>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, 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>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.</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};
|