@cursor/bdk 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/agent-serve.js +9 -1
- package/dist/channels/slack/attachments.d.ts +2 -1
- package/dist/channels/slack/attachments.d.ts.map +1 -1
- package/dist/channels/slack/attachments.js +19 -9
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +26 -24
- package/dist/channels/slack/thread-context.d.ts +21 -11
- package/dist/channels/slack/thread-context.d.ts.map +1 -1
- package/dist/channels/slack/thread-context.js +75 -27
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BOIHhrKi.js → app.4kQ8Db_q.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.CvuAJ0My.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.D49zVZqM.js → VPLocalSearchBox.DY1RwB8Q.js} +1 -1
- package/dist/docs/assets/chunks/{arc.hmjb-sc4.js → arc.CxE_fSPK.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CxEI1KqM.js → architectureDiagram-Q4EWVU46.CPX426ui.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.DHHvBWoV.js → baseUniq.CB52JrKG.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DnXW-3bu.js → blockDiagram-DXYQGD6D.J0cNaQCL.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.e-47O2jM.js → c4Diagram-AHTNJAMY.DJn3vEGT.js} +1 -1
- package/dist/docs/assets/chunks/channel.BoNycAoN.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.3ry4pYXB.js → chunk-4BX2VUAB.Dao618F6.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DGIZFRx6.js → chunk-4TB4RGXK.QW8Rhjai.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.DKBnqg9U.js → chunk-55IACEB6.DfRLLKF_.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.BIU8Ue5k.js → chunk-EDXVE4YY.CIV2ApKQ.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.DP-TFhjI.js → chunk-FMBD7UC4.BEheSuxp.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.Ux0OYj5v.js → chunk-OYMX7WX6.CUN88ENB.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BzHMwYox.js → chunk-QZHKN3VN.CgqCs8b_.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.D4OGAsSP.js → chunk-YZCP3GAM.iCH0nnTJ.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.C4x07Gkj.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.C4x07Gkj.js +1 -0
- package/dist/docs/assets/chunks/clone.Db22cH_-.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Jq_7BUNx.js → cose-bilkent-S5V4N54A.BLcUxhWE.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.Di-skR2x.js → dagre-KV5264BT.Ep7LofOm.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.DeREHIdH.js → diagram-5BDNPKRD.Bzf4GSQ4.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.C7Kcqxro.js → diagram-G4DWMVQ6.DD6Jh-eM.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BK3eohyo.js → diagram-MMDJMWI5.oOIl8bWd.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.C6TyymXT.js → diagram-TYMM5635.DHs85Ade.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DYGG-gGx.js → erDiagram-SMLLAGMA.BIb5ghCk.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.C9nBcSV4.js → flowDiagram-DWJPFMVM.DV4paY9k.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.wAg_ymsp.js → ganttDiagram-T4ZO3ILL.AyEKA6_v.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.B87j9Oeg.js → gitGraphDiagram-UUTBAWPF.BltiCDFo.js} +1 -1
- package/dist/docs/assets/chunks/{graph.CuFMj31w.js → graph.DzuEYGdC.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.P_mLGumP.js → infoDiagram-42DDH7IO.BV2l981J.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DyuL_MsT.js → ishikawaDiagram-UXIWVN3A.BA4Izf-m.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CtP09IoJ.js → journeyDiagram-VCZTEJTY.DjaFbFS3.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.BoeSYPZo.js → kanban-definition-6JOO6SKY.CfTFieDs.js} +1 -1
- package/dist/docs/assets/chunks/{layout.B0lMMtNo.js → layout.DzfWqTBV.js} +1 -1
- package/dist/docs/assets/chunks/{linear.HxRBiAFX.js → linear.BO6mpulV.js} +1 -1
- package/dist/docs/assets/chunks/{min.BGlFFHwS.js → min.BGgTadgT.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.JyLBD9M8.js → mindmap-definition-QFDTVHPH.DPuIXVWY.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DnSmNZF8.js → pieDiagram-DEJITSTG.BOnl3bBg.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CUCnbfCa.js → quadrantDiagram-34T5L4WZ.DNB6Ckdc.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.py0IVUn5.js → requirementDiagram-MS252O5E.D5-Qo7vb.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.Bkc-HWYp.js → sankeyDiagram-XADWPNL6.8t65cesf.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.Dqn8Mlv2.js → sequenceDiagram-FGHM5R23.CaG07BdS.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.JikkoQUU.js → stateDiagram-FHFEXIEX.TKOweTB6.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CuqmyQc4.js +1 -0
- package/dist/docs/assets/chunks/{theme.b6HQ6zG_.js → theme.Dx-JhpTB.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BvpSXiBj.js → timeline-definition-GMOUNBTQ.fE53zQ2s.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CU7MVnZx.js → vennDiagram-DHZGUBPP.DJsZZaJg.js} +1 -1
- package/dist/docs/assets/chunks/{wardley-RL74JXVD.BKwC4ctG.js → wardley-RL74JXVD.844kyrjl.js} +1 -1
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.BfaF6Uhe.js → wardleyDiagram-NUSXRM2D.CMZ-Ru_t.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.Bg5dcpj4.js → xychartDiagram-5P7HB3ND.XXrhBc7a.js} +1 -1
- package/dist/docs/assets/{deployment.md.BJ8i7Q6p.js → deployment.md.UhnJIMr-.js} +2 -2
- package/dist/docs/assets/{deployment.md.BJ8i7Q6p.lean.js → deployment.md.UhnJIMr-.lean.js} +1 -1
- package/dist/docs/assets/{guides_jev.md.BNDm14Gy.js → guides_jev.md.CRcgmjDb.js} +2 -2
- package/dist/docs/assets/{guides_jev.md.BNDm14Gy.lean.js → guides_jev.md.CRcgmjDb.lean.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.DzGI777n.js → reference_agent-config.md.Cj5uBKp4.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.js → reference_extensions.md.pa2tN-e4.js} +4 -3
- package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.lean.js → reference_extensions.md.pa2tN-e4.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +35 -35
- package/dist/docs/deployment.html +37 -37
- package/dist/docs/deployment.md +4 -1
- package/dist/docs/evals.html +35 -35
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +35 -35
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/github.html +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 +35 -35
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +37 -37
- package/dist/docs/guides/jev.md +7 -0
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/opentelemetry.html +35 -35
- 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 +25 -2
- package/dist/docs/quickstart.html +35 -35
- package/dist/docs/reference/agent-config.html +37 -37
- package/dist/docs/reference/agent-config.md +1 -1
- 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 +39 -38
- package/dist/docs/reference/extensions.md +13 -0
- package/dist/docs/reference/hooks.html +35 -35
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +35 -35
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +35 -35
- package/dist/docs/reference/skills.html +35 -35
- package/dist/docs/reference/subagents.html +35 -35
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +35 -35
- package/dist/extensions/jev/extension.d.ts +3 -0
- package/dist/extensions/jev/extension.d.ts.map +1 -1
- package/dist/extensions/jev/extension.js +10 -1
- package/dist/extensions/jev/lib/evaluate.d.ts +4 -0
- package/dist/extensions/jev/lib/evaluate.d.ts.map +1 -1
- package/dist/extensions/jev/lib/evaluate.js +6 -2
- package/dist/extensions.d.ts +4 -2
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +5 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +19 -5
- package/dist/internal/discovery/agent-config.d.ts +6 -5
- package/dist/internal/discovery/agent-config.d.ts.map +1 -1
- package/dist/internal/discovery/agent-config.js +29 -28
- package/dist/internal/discovery/agent.js +1 -1
- package/dist/internal/discovery/extensions.d.ts.map +1 -1
- package/dist/internal/discovery/extensions.js +12 -0
- package/dist/internal/hosting.d.ts +8 -0
- package/dist/internal/hosting.d.ts.map +1 -1
- package/dist/internal/hosting.js +24 -0
- package/dist/types.d.ts +18 -2
- package/dist/types.d.ts.map +1 -1
- package/docs/deployment.md +4 -1
- package/docs/guides/jev.md +7 -0
- package/docs/reference/agent-config.md +1 -1
- package/docs/reference/extensions.md +13 -0
- package/package.json +1 -9
- package/dist/docs/assets/chunks/@localSearchIndexroot.D5L-b34G.js +0 -1
- package/dist/docs/assets/chunks/channel.BbOGaJQP.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Db58HCb1.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Db58HCb1.js +0 -1
- package/dist/docs/assets/chunks/clone.Co4MBflG.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CMsKhrW0.js +0 -1
- package/src/artifacts.ts +0 -68
- package/src/bin/agent-serve.ts +0 -1854
- package/src/channels/bitbucket/api.ts +0 -891
- package/src/channels/bitbucket/binding.ts +0 -417
- package/src/channels/bitbucket/bitbucket-channel.ts +0 -162
- package/src/channels/bitbucket/bitbucket-webhook.ts +0 -519
- package/src/channels/bitbucket/checks.ts +0 -146
- package/src/channels/bitbucket/cursor-account.ts +0 -106
- package/src/channels/bitbucket/defaults.ts +0 -100
- package/src/channels/bitbucket/events.ts +0 -74
- package/src/channels/bitbucket/index.ts +0 -51
- package/src/channels/bitbucket/replay.ts +0 -421
- package/src/channels/bitbucket/state.ts +0 -59
- package/src/channels/bitbucket/types.ts +0 -261
- package/src/channels/change-monitors/change-monitors-channel.ts +0 -63
- package/src/channels/change-monitors/index.ts +0 -8
- package/src/channels/change-monitors/types.ts +0 -42
- package/src/channels/checks.ts +0 -185
- package/src/channels/deployments/deployments-channel.ts +0 -224
- package/src/channels/deployments/index.ts +0 -25
- package/src/channels/deployments/types.ts +0 -92
- package/src/channels/github/api.ts +0 -526
- package/src/channels/github/auth.ts +0 -293
- package/src/channels/github/binding.ts +0 -233
- package/src/channels/github/checks.ts +0 -145
- package/src/channels/github/cursor-account.ts +0 -303
- package/src/channels/github/defaults.ts +0 -168
- package/src/channels/github/events.ts +0 -67
- package/src/channels/github/forward.ts +0 -359
- package/src/channels/github/github-channel.ts +0 -2334
- package/src/channels/github/index.ts +0 -54
- package/src/channels/github/progress.ts +0 -365
- package/src/channels/github/replay.ts +0 -372
- package/src/channels/github/state.ts +0 -124
- package/src/channels/github/types.ts +0 -590
- package/src/channels/gitlab/api.ts +0 -329
- package/src/channels/gitlab/binding.ts +0 -231
- package/src/channels/gitlab/checks.ts +0 -228
- package/src/channels/gitlab/cursor-account.ts +0 -105
- package/src/channels/gitlab/defaults.ts +0 -80
- package/src/channels/gitlab/events.ts +0 -37
- package/src/channels/gitlab/gitlab-channel.ts +0 -160
- package/src/channels/gitlab/gitlab-webhook.ts +0 -509
- package/src/channels/gitlab/index.ts +0 -44
- package/src/channels/gitlab/replay.ts +0 -328
- package/src/channels/gitlab/state.ts +0 -55
- package/src/channels/gitlab/types.ts +0 -247
- package/src/channels/issues/index.ts +0 -9
- package/src/channels/issues/issues-channel.ts +0 -45
- package/src/channels/issues/types.ts +0 -38
- package/src/channels/origin/api.ts +0 -507
- package/src/channels/origin/binding.ts +0 -114
- package/src/channels/origin/checks.ts +0 -250
- package/src/channels/origin/cursor-account.ts +0 -58
- package/src/channels/origin/defaults.ts +0 -140
- package/src/channels/origin/events.ts +0 -35
- package/src/channels/origin/index.ts +0 -35
- package/src/channels/origin/origin-channel.ts +0 -815
- package/src/channels/origin/origin-webhook.ts +0 -296
- package/src/channels/origin/reactions.ts +0 -72
- package/src/channels/origin/state.ts +0 -54
- package/src/channels/origin/types.ts +0 -295
- package/src/channels/slack/agentic-delivery.ts +0 -634
- package/src/channels/slack/agentic-posted.ts +0 -135
- package/src/channels/slack/agentic-signals.ts +0 -231
- package/src/channels/slack/api.ts +0 -761
- package/src/channels/slack/approvals.ts +0 -279
- package/src/channels/slack/assistant.ts +0 -76
- package/src/channels/slack/attachments.ts +0 -596
- package/src/channels/slack/auth.ts +0 -127
- package/src/channels/slack/blocks.ts +0 -131
- package/src/channels/slack/bot-mentions.ts +0 -318
- package/src/channels/slack/channel-watch.ts +0 -314
- package/src/channels/slack/cli-project.ts +0 -249
- package/src/channels/slack/code-fences.ts +0 -171
- package/src/channels/slack/constants.ts +0 -38
- package/src/channels/slack/credentials.ts +0 -88
- package/src/channels/slack/defaults.ts +0 -714
- package/src/channels/slack/dispatch.ts +0 -1060
- package/src/channels/slack/doctor.ts +0 -338
- package/src/channels/slack/eval-directive.ts +0 -306
- package/src/channels/slack/event-id-dedupe.ts +0 -30
- package/src/channels/slack/external-policy.ts +0 -75
- package/src/channels/slack/footer.ts +0 -106
- package/src/channels/slack/inbound.ts +0 -416
- package/src/channels/slack/index.ts +0 -53
- package/src/channels/slack/init.ts +0 -169
- package/src/channels/slack/interactive.ts +0 -406
- package/src/channels/slack/links.ts +0 -23
- package/src/channels/slack/live-delivery.ts +0 -489
- package/src/channels/slack/log.ts +0 -70
- package/src/channels/slack/manifest.ts +0 -240
- package/src/channels/slack/message-body.ts +0 -82
- package/src/channels/slack/nudge-carrier.ts +0 -224
- package/src/channels/slack/nudge-store.ts +0 -334
- package/src/channels/slack/paint-start.ts +0 -93
- package/src/channels/slack/placeholder.ts +0 -358
- package/src/channels/slack/pr-ref.ts +0 -74
- package/src/channels/slack/progress-delivery.ts +0 -138
- package/src/channels/slack/reasoning-card.ts +0 -125
- package/src/channels/slack/reasoning-chip.ts +0 -41
- package/src/channels/slack/recording-sink.ts +0 -167
- package/src/channels/slack/redact.ts +0 -6
- package/src/channels/slack/reply-options.ts +0 -279
- package/src/channels/slack/setup.ts +0 -125
- package/src/channels/slack/slack-channel.ts +0 -744
- package/src/channels/slack/socket-mode.ts +0 -140
- package/src/channels/slack/stop.ts +0 -25
- package/src/channels/slack/stream.ts +0 -66
- package/src/channels/slack/thread-context.ts +0 -485
- package/src/channels/slack/tool-approval-events.ts +0 -233
- package/src/channels/slack/tool-cards.ts +0 -198
- package/src/channels/slack/tool-chip.ts +0 -34
- package/src/channels/slack/types.ts +0 -787
- package/src/channels/slack/upload.ts +0 -137
- package/src/channels.ts +0 -543
- package/src/connections.ts +0 -153
- package/src/dashboard-session-url.ts +0 -30
- package/src/evals/assertions.ts +0 -688
- package/src/evals/expect.ts +0 -250
- package/src/evals/judge.ts +0 -329
- package/src/evals/loaders.ts +0 -111
- package/src/evals/matchers.ts +0 -223
- package/src/evals/reporters.ts +0 -257
- package/src/evals/results.ts +0 -130
- package/src/evals/run-facts.ts +0 -306
- package/src/evals.ts +0 -709
- package/src/extensions/cursor-cloud-agents/extension.ts +0 -131
- package/src/extensions/cursor-cloud-agents/lib/backend.ts +0 -386
- package/src/extensions/cursor-cloud-agents/lib/channels.ts +0 -11
- package/src/extensions/cursor-cloud-agents/lib/fleet.ts +0 -98
- package/src/extensions/cursor-cloud-agents/lib/inputs.ts +0 -5
- package/src/extensions/cursor-cloud-agents/lib/repos.ts +0 -80
- package/src/extensions/cursor-cloud-agents/lib/transcript.ts +0 -19
- package/src/extensions/cursor-cloud-agents/skills/handoff.md +0 -37
- package/src/extensions/cursor-cloud-agents/tools/cancel.ts +0 -21
- package/src/extensions/cursor-cloud-agents/tools/dump.ts +0 -47
- package/src/extensions/cursor-cloud-agents/tools/get.ts +0 -18
- package/src/extensions/cursor-cloud-agents/tools/launch.ts +0 -62
- package/src/extensions/cursor-cloud-agents/tools/list.ts +0 -31
- package/src/extensions/cursor-cloud-agents/tools/reply.ts +0 -36
- package/src/extensions/cursor-grokbot-agents/extension.ts +0 -132
- package/src/extensions/cursor-grokbot-agents/lib/agents.ts +0 -42
- package/src/extensions/cursor-grokbot-agents/lib/backend.ts +0 -208
- package/src/extensions/cursor-grokbot-agents/lib/contacts.ts +0 -74
- package/src/extensions/cursor-grokbot-agents/lib/conversation.ts +0 -260
- package/src/extensions/cursor-grokbot-agents/lib/inputs.ts +0 -21
- package/src/extensions/cursor-grokbot-agents/lib/lock.ts +0 -26
- package/src/extensions/cursor-grokbot-agents/skills/consult.md +0 -40
- package/src/extensions/cursor-grokbot-agents/tools/ask.ts +0 -32
- package/src/extensions/cursor-grokbot-agents/tools/check.ts +0 -25
- package/src/extensions/cursor-grokbot-agents/tools/interrupt.ts +0 -17
- package/src/extensions/cursor-grokbot-agents/tools/list.ts +0 -26
- package/src/extensions/improve/extension.ts +0 -69
- package/src/extensions/improve/skills/yourself.ts +0 -50
- package/src/extensions/jev/extension.ts +0 -95
- package/src/extensions/jev/lib/evaluate.ts +0 -266
- package/src/extensions/jev/skills/gated-write.md +0 -25
- package/src/extensions/jev/skills/questions.md +0 -33
- package/src/extensions/jev/tools/evaluate.ts +0 -82
- package/src/extensions/slack-communication/evals/harness.ts +0 -705
- package/src/extensions/slack-communication/evals/slack-communication.eval.ts +0 -830
- package/src/extensions/slack-communication/evals/slack-placeholder.eval.ts +0 -172
- package/src/extensions/slack-communication/extension.ts +0 -44
- package/src/extensions/slack-communication/skills/slack-voice.ts +0 -56
- package/src/extensions/slack-communication/tools/delete-message.ts +0 -33
- package/src/extensions/slack-communication/tools/edit-message.ts +0 -42
- package/src/extensions/slack-communication/tools/post-card.ts +0 -28
- package/src/extensions/slack-communication/tools/post-file.ts +0 -82
- package/src/extensions/slack-communication/tools/post-update.ts +0 -40
- package/src/extensions/slack-communication/tools/react.ts +0 -30
- package/src/extensions/slack-communication/tools/set-status.ts +0 -21
- package/src/extensions.ts +0 -179
- package/src/files-backends/agent-store-presigned-url.ts +0 -11
- package/src/files-backends/cursor-hosted.ts +0 -1212
- package/src/files-backends/local-fs.ts +0 -163
- package/src/files.ts +0 -293
- package/src/filesystem.ts +0 -2005
- package/src/hooks.ts +0 -30
- package/src/index.ts +0 -259
- package/src/internal/advertise-tools.ts +0 -370
- package/src/internal/approval-gate.ts +0 -103
- package/src/internal/artifacts-store.ts +0 -836
- package/src/internal/as-of.ts +0 -257
- package/src/internal/auth.ts +0 -46
- package/src/internal/authored-alias-hooks.ts +0 -138
- package/src/internal/authored-loaders.ts +0 -188
- package/src/internal/bounded-int.ts +0 -24
- package/src/internal/bounded.ts +0 -25
- package/src/internal/brand.ts +0 -28
- package/src/internal/browser-origin-guard.ts +0 -67
- package/src/internal/builtin-tools/artifacts.ts +0 -62
- package/src/internal/builtin-tools/index.ts +0 -53
- package/src/internal/builtin-tools/reminders.ts +0 -145
- package/src/internal/channel-dispatch.ts +0 -129
- package/src/internal/channel-route-dispatch.ts +0 -58
- package/src/internal/channel-state.ts +0 -83
- package/src/internal/chat-client.ts +0 -594
- package/src/internal/cli-ax.ts +0 -2318
- package/src/internal/cli-bitbucket.ts +0 -438
- package/src/internal/cli-convert-automation.ts +0 -335
- package/src/internal/cli-cursor.ts +0 -282
- package/src/internal/cli-deploy.ts +0 -2519
- package/src/internal/cli-docs.ts +0 -192
- package/src/internal/cli-github.ts +0 -806
- package/src/internal/cli-gitlab.ts +0 -452
- package/src/internal/cli-images.ts +0 -672
- package/src/internal/cli-manifest.ts +0 -56
- package/src/internal/cli-mcp-oauth.ts +0 -396
- package/src/internal/cli-mcp.ts +0 -808
- package/src/internal/cli-skills.ts +0 -98
- package/src/internal/cli-slack-manual.ts +0 -418
- package/src/internal/cli-slack.ts +0 -874
- package/src/internal/cloud-merge.ts +0 -51
- package/src/internal/cloud-turn-cost.ts +0 -159
- package/src/internal/connection-env.ts +0 -106
- package/src/internal/continuation-channel.ts +0 -233
- package/src/internal/continuation-identity.ts +0 -935
- package/src/internal/conversation-mirror.ts +0 -423
- package/src/internal/convert-automation/convert-workflow.ts +0 -1377
- package/src/internal/convert-automation/slug.ts +0 -29
- package/src/internal/convert-automation/types.ts +0 -212
- package/src/internal/cron.ts +0 -76
- package/src/internal/cursor/account-mcp.ts +0 -692
- package/src/internal/cursor/backend-client.ts +0 -984
- package/src/internal/cursor/bound-secret-file.ts +0 -101
- package/src/internal/cursor/credentials.ts +0 -560
- package/src/internal/cursor/cursor-api-transport.ts +0 -65
- package/src/internal/cursor/github-credentials.ts +0 -228
- package/src/internal/cursor/hosted-bound-secrets.ts +0 -71
- package/src/internal/cursor/hosted-deployment-secrets.ts +0 -100
- package/src/internal/cursor/hosted-store-secrets.ts +0 -152
- package/src/internal/cursor/session-token.ts +0 -111
- package/src/internal/cursor/store-api-client.ts +0 -323
- package/src/internal/cursor-account-mcp-auth.ts +0 -303
- package/src/internal/cursor-agent-template.ts +0 -50
- package/src/internal/cursor-deployment-relay.ts +0 -315
- package/src/internal/cursor-event-relay.ts +0 -675
- package/src/internal/cursor-relay-core.ts +0 -563
- package/src/internal/deferred-channel-session.ts +0 -61
- package/src/internal/deploy-client.ts +0 -1574
- package/src/internal/deploy-manifest.ts +0 -361
- package/src/internal/deploy-source.ts +0 -144
- package/src/internal/describe-error.ts +0 -32
- package/src/internal/dev-mode.ts +0 -20
- package/src/internal/discovery/agent-config.ts +0 -288
- package/src/internal/discovery/agent.ts +0 -381
- package/src/internal/discovery/channels.ts +0 -100
- package/src/internal/discovery/connections.ts +0 -516
- package/src/internal/discovery/context.ts +0 -38
- package/src/internal/discovery/cursor-plugin.ts +0 -628
- package/src/internal/discovery/extension-overlay.ts +0 -247
- package/src/internal/discovery/extensions.ts +0 -490
- package/src/internal/discovery/fs.ts +0 -103
- package/src/internal/discovery/hooks.ts +0 -63
- package/src/internal/discovery/info.ts +0 -174
- package/src/internal/discovery/instructions.ts +0 -98
- package/src/internal/discovery/modules.ts +0 -107
- package/src/internal/discovery/names.ts +0 -45
- package/src/internal/discovery/project.ts +0 -319
- package/src/internal/discovery/reminders.ts +0 -65
- package/src/internal/discovery/runtime.ts +0 -158
- package/src/internal/discovery/schedules.ts +0 -120
- package/src/internal/discovery/seed-files.ts +0 -34
- package/src/internal/discovery/services.ts +0 -151
- package/src/internal/discovery/skills.ts +0 -174
- package/src/internal/discovery/subagent.ts +0 -138
- package/src/internal/discovery/tools.ts +0 -170
- package/src/internal/discovery.ts +0 -27
- package/src/internal/distribution.ts +0 -126
- package/src/internal/docs-site.ts +0 -248
- package/src/internal/duration.ts +0 -37
- package/src/internal/env-file.ts +0 -83
- package/src/internal/eval-judge-model.ts +0 -142
- package/src/internal/eval-run-store.ts +0 -585
- package/src/internal/eval-runner.ts +0 -823
- package/src/internal/evals-client.ts +0 -475
- package/src/internal/event-log.ts +0 -342
- package/src/internal/event-mapper.ts +0 -811
- package/src/internal/expected-delivery-failure.ts +0 -34
- package/src/internal/factory-resource-channel.ts +0 -103
- package/src/internal/filesystem/errors.ts +0 -207
- package/src/internal/filesystem/format.ts +0 -253
- package/src/internal/filesystem/merge.ts +0 -192
- package/src/internal/filesystem/nearest.ts +0 -112
- package/src/internal/filesystem/scratch.ts +0 -239
- package/src/internal/filesystem/sdk-schemas.ts +0 -204
- package/src/internal/filesystem/tools.ts +0 -804
- package/src/internal/filesystem/walk.ts +0 -366
- package/src/internal/fixtures/units-server.ts +0 -52
- package/src/internal/framework-file-storage.ts +0 -357
- package/src/internal/framework-storage-selection.ts +0 -156
- package/src/internal/frontmatter.ts +0 -108
- package/src/internal/github-fanout.ts +0 -144
- package/src/internal/guest-network.ts +0 -391
- package/src/internal/handleAgentServeTrigger.ts +0 -286
- package/src/internal/host-files.ts +0 -341
- package/src/internal/host-kv.ts +0 -81
- package/src/internal/host-otel.ts +0 -231
- package/src/internal/host-platforms.ts +0 -170
- package/src/internal/hosted-admission-adapter.ts +0 -47
- package/src/internal/hosted-admission-context.ts +0 -37
- package/src/internal/hosted-catch-protocol.ts +0 -112
- package/src/internal/hosted-catch.ts +0 -179
- package/src/internal/hosted-delivery-protocol.ts +0 -824
- package/src/internal/hosted-delivery.ts +0 -1410
- package/src/internal/hosted-execution-diag.ts +0 -291
- package/src/internal/hosted-execution-flush.ts +0 -136
- package/src/internal/hosted-execution-latency.ts +0 -301
- package/src/internal/hosted-managed-automation.ts +0 -116
- package/src/internal/hosting.ts +0 -114
- package/src/internal/http-channel-define.ts +0 -25
- package/src/internal/http-channel.ts +0 -669
- package/src/internal/http-control-plane-session.ts +0 -110
- package/src/internal/ids.ts +0 -39
- package/src/internal/incoming-headers-to-fetch.ts +0 -45
- package/src/internal/init-interview.ts +0 -360
- package/src/internal/init-project.ts +0 -711
- package/src/internal/init-scaffold.ts +0 -182
- package/src/internal/inline-stdio-define-stub.ts +0 -4
- package/src/internal/inline-stdio-mcp.ts +0 -230
- package/src/internal/install-cursor-skills.ts +0 -604
- package/src/internal/is-record.ts +0 -3
- package/src/internal/json-schema.ts +0 -95
- package/src/internal/legacy-command-guard.ts +0 -66
- package/src/internal/listen-port.ts +0 -85
- package/src/internal/local-control-plane.ts +0 -442
- package/src/internal/local-env.ts +0 -59
- package/src/internal/local-ingress.ts +0 -90
- package/src/internal/log-ring.ts +0 -59
- package/src/internal/logs-client.ts +0 -477
- package/src/internal/map-pool.ts +0 -39
- package/src/internal/mcp-endpoint.ts +0 -747
- package/src/internal/mcp-host.ts +0 -509
- package/src/internal/mcp-oauth-on-demand.ts +0 -337
- package/src/internal/mcp-oauth-persist.ts +0 -118
- package/src/internal/mcp-oauth.ts +0 -549
- package/src/internal/net.ts +0 -29
- package/src/internal/open-browser.ts +0 -41
- package/src/internal/otel/attrs.ts +0 -16
- package/src/internal/otel/collector.ts +0 -937
- package/src/internal/otel/config.ts +0 -287
- package/src/internal/otel/http.ts +0 -122
- package/src/internal/otel/mcp.ts +0 -56
- package/src/internal/otel/propagation.ts +0 -17
- package/src/internal/otel/runtime.ts +0 -441
- package/src/internal/package-inline-stdio.ts +0 -114
- package/src/internal/peer-connections.ts +0 -96
- package/src/internal/platform-schedule-sync.ts +0 -75
- package/src/internal/platform-timers.ts +0 -365
- package/src/internal/playground/static.ts +0 -278
- package/src/internal/playground/toolchain.ts +0 -270
- package/src/internal/playground-proxy.ts +0 -564
- package/src/internal/process-memory-telemetry.ts +0 -334
- package/src/internal/project-layout.ts +0 -31
- package/src/internal/prompt-context.ts +0 -116
- package/src/internal/reminder-control-plane-protocol.ts +0 -482
- package/src/internal/reminder-runner.ts +0 -1559
- package/src/internal/reminder-schedule.ts +0 -104
- package/src/internal/reminder-store.ts +0 -176
- package/src/internal/request-error-status.ts +0 -95
- package/src/internal/request-headers.ts +0 -21
- package/src/internal/resolve-prod-target.ts +0 -334
- package/src/internal/resolved-connections.ts +0 -190
- package/src/internal/router.ts +0 -143
- package/src/internal/run-client.ts +0 -354
- package/src/internal/runtime-dispatch-runner.ts +0 -50
- package/src/internal/sanitize-mcp-tool-name.ts +0 -31
- package/src/internal/schedule-runner.ts +0 -154
- package/src/internal/scm/pr-url.ts +0 -245
- package/src/internal/sdk-runner.ts +0 -959
- package/src/internal/serve-restart.ts +0 -113
- package/src/internal/server.ts +0 -3147
- package/src/internal/session-cost.ts +0 -208
- package/src/internal/session-engine.ts +0 -5622
- package/src/internal/session-links.ts +0 -84
- package/src/internal/session-run-log.ts +0 -535
- package/src/internal/session-store.ts +0 -307
- package/src/internal/session-urls.ts +0 -32
- package/src/internal/sessions-client.ts +0 -239
- package/src/internal/skill-catalog.ts +0 -66
- package/src/internal/skills-sync.ts +0 -55
- package/src/internal/slack-provision-client.ts +0 -544
- package/src/internal/slack-thread-key.ts +0 -11
- package/src/internal/sleep.ts +0 -3
- package/src/internal/start-log-store.ts +0 -164
- package/src/internal/steering.ts +0 -17
- package/src/internal/storage-coordinator.ts +0 -800
- package/src/internal/storage-roles.ts +0 -86
- package/src/internal/storage.ts +0 -1
- package/src/internal/store-api-protocol.ts +0 -205
- package/src/internal/store-mirror.ts +0 -73
- package/src/internal/stream-progress.ts +0 -294
- package/src/internal/terminal-style.ts +0 -133
- package/src/internal/testing/factory-resource-fixtures.ts +0 -84
- package/src/internal/testing/scm-continuation-fixtures.ts +0 -285
- package/src/internal/tool-catalog.ts +0 -104
- package/src/internal/tool-policy.ts +0 -222
- package/src/internal/tool-result.ts +0 -50
- package/src/internal/trajectory.ts +0 -418
- package/src/internal/turn-cost.ts +0 -136
- package/src/internal/turn-governor.ts +0 -145
- package/src/internal/turn-lease-store.ts +0 -144
- package/src/internal/turn-outbox.ts +0 -77
- package/src/internal/update-check.ts +0 -517
- package/src/internal/v2-hosting.ts +0 -52
- package/src/internal/workspace-sync.ts +0 -114
- package/src/internal/workspace.ts +0 -505
- package/src/kv/memory-kv.ts +0 -94
- package/src/kv.ts +0 -18
- package/src/memory.ts +0 -487
- package/src/otel-public.ts +0 -24
- package/src/otel.ts +0 -320
- package/src/prompt.ts +0 -80
- package/src/reminders.ts +0 -65
- package/src/schedules.ts +0 -31
- package/src/skills.ts +0 -27
- package/src/storage-backends/cursor-hosted-v2.ts +0 -204
- package/src/storage-backends/cursor-hosted.ts +0 -388
- package/src/storage-backends/file-kv.ts +0 -276
- package/src/storage-protocol.ts +0 -261
- package/src/storage.ts +0 -408
- package/src/tools.ts +0 -166
- package/src/types.ts +0 -3776
- /package/dist/docs/assets/{reference_agent-config.md.DzGI777n.lean.js → reference_agent-config.md.Cj5uBKp4.lean.js} +0 -0
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified entry for dispatching agent-serve triggers from an external ingress
|
|
3
|
-
* (e.g. the Cursor backend GitHub webhook or Origin cursor-internal tap).
|
|
4
|
-
* Mirrors Automations' `handleAutomationTrigger`.
|
|
5
|
-
*
|
|
6
|
-
* Callers must authenticate the delivery before invoking this (the backend
|
|
7
|
-
* verifies GitHub HMAC at `/github_webhook` and Origin v1ed at the
|
|
8
|
-
* cursor-internal app). This fan-out does not re-check signatures — same
|
|
9
|
-
* trust model as Bugbot after `verifyGithubRequest`.
|
|
10
|
-
*
|
|
11
|
-
* Each agent's `onPullRequest` / `onComment` / … hooks decide whether to run.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
dispatchGitHubWebhook,
|
|
16
|
-
getGitHubChannelOptions,
|
|
17
|
-
} from "../channels/github/github-channel.js";
|
|
18
|
-
import type { GitHubChannelOptions } from "../channels/github/types.js";
|
|
19
|
-
import {
|
|
20
|
-
dispatchOriginWebhook,
|
|
21
|
-
getOriginChannelOptions,
|
|
22
|
-
originIngressExtractPayload,
|
|
23
|
-
parseOriginWebhookEnvelope,
|
|
24
|
-
} from "../channels/origin/origin-channel.js";
|
|
25
|
-
import type { OriginChannelOptions } from "../channels/origin/types.js";
|
|
26
|
-
import type { ChannelHandlerArgs } from "../types.js";
|
|
27
|
-
import { bindLocalIngressSend, type RouteLocalIngressContinuation } from "./local-ingress.js";
|
|
28
|
-
|
|
29
|
-
export interface AgentServeGitHubTriggerTarget {
|
|
30
|
-
/** Agent mount slug (empty string in single-agent mode). */
|
|
31
|
-
slug: string;
|
|
32
|
-
/** Options from the agent's `githubChannel({ ... })` definition. */
|
|
33
|
-
options: GitHubChannelOptions;
|
|
34
|
-
/** Per-agent channel handler args (`send`, `waitUntil`, `host`, …). */
|
|
35
|
-
args: ChannelHandlerArgs;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface AgentServeGitHubTriggerEvent {
|
|
39
|
-
type: "github";
|
|
40
|
-
/** Raw webhook body (signature already verified by the caller). */
|
|
41
|
-
bodyText: string;
|
|
42
|
-
eventName: string | null;
|
|
43
|
-
deliveryId?: string;
|
|
44
|
-
targets: AgentServeGitHubTriggerTarget[];
|
|
45
|
-
/** Local CP ingest. Defaults to {@link routeLocalIngressContinuation}. */
|
|
46
|
-
routeContinuation?: RouteLocalIngressContinuation;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface AgentServeOriginTriggerTarget {
|
|
50
|
-
slug: string;
|
|
51
|
-
options: OriginChannelOptions;
|
|
52
|
-
args: ChannelHandlerArgs;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface AgentServeOriginTriggerEvent {
|
|
56
|
-
type: "origin";
|
|
57
|
-
/** Origin envelope JSON (signature already verified by the caller). */
|
|
58
|
-
bodyText: string;
|
|
59
|
-
targets: AgentServeOriginTriggerTarget[];
|
|
60
|
-
/** Local CP ingest. Defaults to {@link routeLocalIngressContinuation}. */
|
|
61
|
-
routeContinuation?: RouteLocalIngressContinuation;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export type AgentServeTriggerEvent = AgentServeGitHubTriggerEvent | AgentServeOriginTriggerEvent;
|
|
65
|
-
|
|
66
|
-
export interface AgentServeTriggerTargetResult {
|
|
67
|
-
slug: string;
|
|
68
|
-
status: number;
|
|
69
|
-
body: unknown;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface AgentServeTriggerResult {
|
|
73
|
-
ok: boolean;
|
|
74
|
-
event: string | null;
|
|
75
|
-
targets: AgentServeTriggerTargetResult[];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Build fan-out targets from mounted agent projects that export a github
|
|
80
|
-
* channel created via {@link githubChannel}.
|
|
81
|
-
*/
|
|
82
|
-
export function collectGitHubTriggerTargets(input: {
|
|
83
|
-
mounts: Array<{
|
|
84
|
-
slug: string;
|
|
85
|
-
channels: Array<{ id: string; definition: object }>;
|
|
86
|
-
buildHandlerArgs: (channelId: string) => ChannelHandlerArgs;
|
|
87
|
-
}>;
|
|
88
|
-
}): AgentServeGitHubTriggerTarget[] {
|
|
89
|
-
const targets: AgentServeGitHubTriggerTarget[] = [];
|
|
90
|
-
for (const mount of input.mounts) {
|
|
91
|
-
for (const channel of mount.channels) {
|
|
92
|
-
const options = getGitHubChannelOptions(channel.definition);
|
|
93
|
-
if (options === undefined) {
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
targets.push({
|
|
97
|
-
slug: mount.slug,
|
|
98
|
-
options,
|
|
99
|
-
args: mount.buildHandlerArgs(channel.id),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return targets;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Build fan-out targets from mounted agent projects that export an origin
|
|
108
|
-
* channel created via {@link originChannel}.
|
|
109
|
-
*/
|
|
110
|
-
export function collectOriginTriggerTargets(input: {
|
|
111
|
-
mounts: Array<{
|
|
112
|
-
slug: string;
|
|
113
|
-
channels: Array<{ id: string; definition: object }>;
|
|
114
|
-
buildHandlerArgs: (channelId: string) => ChannelHandlerArgs;
|
|
115
|
-
}>;
|
|
116
|
-
}): AgentServeOriginTriggerTarget[] {
|
|
117
|
-
const targets: AgentServeOriginTriggerTarget[] = [];
|
|
118
|
-
for (const mount of input.mounts) {
|
|
119
|
-
for (const channel of mount.channels) {
|
|
120
|
-
const options = getOriginChannelOptions(channel.definition);
|
|
121
|
-
if (options === undefined) {
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
targets.push({
|
|
125
|
-
slug: mount.slug,
|
|
126
|
-
options,
|
|
127
|
-
args: mount.buildHandlerArgs(channel.id),
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return targets;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Dispatch an agent-serve trigger. GitHub and Origin webhook fan-out.
|
|
136
|
-
*/
|
|
137
|
-
export async function handleAgentServeTrigger(
|
|
138
|
-
event: AgentServeTriggerEvent,
|
|
139
|
-
): Promise<AgentServeTriggerResult> {
|
|
140
|
-
switch (event.type) {
|
|
141
|
-
case "github":
|
|
142
|
-
return handleAgentServeGitHubTrigger(event);
|
|
143
|
-
case "origin":
|
|
144
|
-
return handleAgentServeOriginTrigger(event);
|
|
145
|
-
default: {
|
|
146
|
-
const _: never = event;
|
|
147
|
-
throw new Error(`handleAgentServeTrigger: unknown event type: ${String(_)}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async function handleAgentServeGitHubTrigger(
|
|
153
|
-
event: AgentServeGitHubTriggerEvent,
|
|
154
|
-
): Promise<AgentServeTriggerResult> {
|
|
155
|
-
if (event.eventName === "ping") {
|
|
156
|
-
return {
|
|
157
|
-
ok: true,
|
|
158
|
-
event: "ping",
|
|
159
|
-
targets: [],
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
let payload: unknown;
|
|
164
|
-
try {
|
|
165
|
-
payload = JSON.parse(event.bodyText) as unknown;
|
|
166
|
-
} catch {
|
|
167
|
-
return {
|
|
168
|
-
ok: false,
|
|
169
|
-
event: event.eventName,
|
|
170
|
-
targets: [
|
|
171
|
-
{
|
|
172
|
-
slug: "",
|
|
173
|
-
status: 400,
|
|
174
|
-
body: { ok: false, error: "invalid_json" },
|
|
175
|
-
},
|
|
176
|
-
],
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const targets: AgentServeTriggerTargetResult[] = [];
|
|
181
|
-
for (const target of event.targets) {
|
|
182
|
-
const args =
|
|
183
|
-
event.eventName === null
|
|
184
|
-
? target.args
|
|
185
|
-
: bindLocalIngressSend(target.args, {
|
|
186
|
-
identity: target.options.continuation,
|
|
187
|
-
kind: "github",
|
|
188
|
-
eventType: event.eventName,
|
|
189
|
-
payload,
|
|
190
|
-
...(event.routeContinuation === undefined
|
|
191
|
-
? {}
|
|
192
|
-
: { routeContinuation: event.routeContinuation }),
|
|
193
|
-
});
|
|
194
|
-
const response = await dispatchGitHubWebhook({
|
|
195
|
-
options: target.options,
|
|
196
|
-
eventName: event.eventName,
|
|
197
|
-
payload,
|
|
198
|
-
deliveryId: event.deliveryId,
|
|
199
|
-
args,
|
|
200
|
-
});
|
|
201
|
-
targets.push(await triggerTargetResult(target.slug, response));
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return {
|
|
205
|
-
ok: true,
|
|
206
|
-
event: event.eventName,
|
|
207
|
-
targets,
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
async function handleAgentServeOriginTrigger(
|
|
212
|
-
event: AgentServeOriginTriggerEvent,
|
|
213
|
-
): Promise<AgentServeTriggerResult> {
|
|
214
|
-
let payload: unknown;
|
|
215
|
-
try {
|
|
216
|
-
payload = JSON.parse(event.bodyText) as unknown;
|
|
217
|
-
} catch {
|
|
218
|
-
return {
|
|
219
|
-
ok: false,
|
|
220
|
-
event: null,
|
|
221
|
-
targets: [
|
|
222
|
-
{
|
|
223
|
-
slug: "",
|
|
224
|
-
status: 400,
|
|
225
|
-
body: { ok: false, error: "invalid_json" },
|
|
226
|
-
},
|
|
227
|
-
],
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const envelope = parseOriginWebhookEnvelope(payload);
|
|
232
|
-
if (envelope === null) {
|
|
233
|
-
return {
|
|
234
|
-
ok: false,
|
|
235
|
-
event: null,
|
|
236
|
-
targets: [
|
|
237
|
-
{
|
|
238
|
-
slug: "",
|
|
239
|
-
status: 400,
|
|
240
|
-
body: { ok: false, error: "invalid_origin_payload" },
|
|
241
|
-
},
|
|
242
|
-
],
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const targets: AgentServeTriggerTargetResult[] = [];
|
|
247
|
-
for (const target of event.targets) {
|
|
248
|
-
const response = await dispatchOriginWebhook({
|
|
249
|
-
options: target.options,
|
|
250
|
-
envelope,
|
|
251
|
-
args: bindLocalIngressSend(target.args, {
|
|
252
|
-
identity: target.options.continuation,
|
|
253
|
-
kind: "origin",
|
|
254
|
-
eventType: envelope.event.type,
|
|
255
|
-
payload: originIngressExtractPayload(envelope),
|
|
256
|
-
...(event.routeContinuation === undefined
|
|
257
|
-
? {}
|
|
258
|
-
: { routeContinuation: event.routeContinuation }),
|
|
259
|
-
}),
|
|
260
|
-
});
|
|
261
|
-
targets.push(await triggerTargetResult(target.slug, response));
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return {
|
|
265
|
-
ok: true,
|
|
266
|
-
event: envelope.event.type,
|
|
267
|
-
targets,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
async function triggerTargetResult(
|
|
272
|
-
slug: string,
|
|
273
|
-
response: Response,
|
|
274
|
-
): Promise<AgentServeTriggerTargetResult> {
|
|
275
|
-
let body: unknown;
|
|
276
|
-
try {
|
|
277
|
-
body = await response.json();
|
|
278
|
-
} catch {
|
|
279
|
-
body = { ok: false, error: "invalid_response_json" };
|
|
280
|
-
}
|
|
281
|
-
return {
|
|
282
|
-
slug,
|
|
283
|
-
status: response.status,
|
|
284
|
-
body,
|
|
285
|
-
};
|
|
286
|
-
}
|
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Author-facing durable file storage for {@link HostContext.files}.
|
|
3
|
-
*
|
|
4
|
-
* On Cursor-managed hosting the bytes live in the deployment's durable
|
|
5
|
-
* store; otherwise they land under `--state-root/files` on local disk, which
|
|
6
|
-
* is what makes `host.files` work self-hosted with no storage service at all.
|
|
7
|
-
*
|
|
8
|
-
* Everything that decides *which* bytes an author may reach lives here rather
|
|
9
|
-
* than in the sink: scope selection, path validation, and key minting through
|
|
10
|
-
* {@link fileKeys}. A sink only ever sees a fully-qualified opaque key, so an
|
|
11
|
-
* authored sink — including one a customer wrote against their own Dropbox —
|
|
12
|
-
* cannot be steered into another deployment's or another session's files.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { join, normalize, sep } from "node:path";
|
|
16
|
-
import {
|
|
17
|
-
FilePathRejectedError,
|
|
18
|
-
FileSessionRequiredError,
|
|
19
|
-
type FileSink,
|
|
20
|
-
type FileSinkEntry,
|
|
21
|
-
FileTooLargeError,
|
|
22
|
-
fileKeys,
|
|
23
|
-
} from "../files.js";
|
|
24
|
-
import {
|
|
25
|
-
cursorHostedFiles,
|
|
26
|
-
isCursorHostedFilesAvailable,
|
|
27
|
-
} from "../files-backends/cursor-hosted.js";
|
|
28
|
-
import { localFiles } from "../files-backends/local-fs.js";
|
|
29
|
-
import type {
|
|
30
|
-
HostFileEntry,
|
|
31
|
-
HostFileStat,
|
|
32
|
-
HostFilesApi,
|
|
33
|
-
HostFilesCapabilities,
|
|
34
|
-
HostFilesScope,
|
|
35
|
-
} from "../types.js";
|
|
36
|
-
|
|
37
|
-
export interface CreateHostFilesApiOptions {
|
|
38
|
-
agentName: string;
|
|
39
|
-
/** Local disk root for the default sink. Required unless `sink` is supplied. */
|
|
40
|
-
stateRoot?: string;
|
|
41
|
-
/** Explicit sink override (tests). Omitted → hosted store or local disk. */
|
|
42
|
-
sink?: FileSink;
|
|
43
|
-
/** Session bound for `scope: "session"` calls; prefer {@link HostFilesApi.forSession}. */
|
|
44
|
-
sessionId?: string;
|
|
45
|
-
/** Environment consulted when choosing the default sink (tests). */
|
|
46
|
-
env?: NodeJS.ProcessEnv;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** Build the host file API for one agent process. */
|
|
50
|
-
export function createHostFilesApi(options: CreateHostFilesApiOptions): HostFilesApi {
|
|
51
|
-
const sink = options.sink ?? createDefaultSink(options);
|
|
52
|
-
return createBoundHostFilesApi({
|
|
53
|
-
agentName: options.agentName,
|
|
54
|
-
sink,
|
|
55
|
-
...(options.sessionId === undefined ? {} : { sessionId: options.sessionId }),
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Pick the default sink.
|
|
61
|
-
*
|
|
62
|
-
* On Cursor-managed hosting the durable store is the only correct answer —
|
|
63
|
-
* falling back to pod-local disk there would accept writes that vanish with
|
|
64
|
-
* the pod, which is the failure this surface exists to remove. Off hosting,
|
|
65
|
-
* local disk keeps `serve --dev`, replay, fixtures, and evals working with no
|
|
66
|
-
* storage service. This is the gate all six hosted agents write by hand in
|
|
67
|
-
* their `agent/storage.ts`; resolving it here means authors do not repeat it.
|
|
68
|
-
*/
|
|
69
|
-
function createDefaultSink(options: CreateHostFilesApiOptions): FileSink {
|
|
70
|
-
if (isCursorHostedFilesAvailable(options.env ?? process.env)) {
|
|
71
|
-
return cursorHostedFiles();
|
|
72
|
-
}
|
|
73
|
-
if (options.stateRoot === undefined) {
|
|
74
|
-
throw new Error(
|
|
75
|
-
"createHostFilesApi needs a stateRoot for the default local-disk sink, or an explicit sink",
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
return localFiles({
|
|
79
|
-
filesRoot: join(options.stateRoot, "files"),
|
|
80
|
-
stripKeyPrefix: localKeyPrefix(options.agentName),
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** On-disk layout drops the framework key prefix so paths stay navigable. */
|
|
85
|
-
function localKeyPrefix(agentName: string): string {
|
|
86
|
-
return fileKeys.deploymentPrefix(agentName).replace(/deployment\/$/, "");
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface BoundState {
|
|
90
|
-
agentName: string;
|
|
91
|
-
sink: FileSink;
|
|
92
|
-
sessionId?: string;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function createBoundHostFilesApi(state: BoundState): HostFilesApi {
|
|
96
|
-
const sinkCaps = state.sink.capabilities ?? {};
|
|
97
|
-
const capabilities: HostFilesCapabilities = {
|
|
98
|
-
conflictDetection: sinkCaps.etags === true,
|
|
99
|
-
materialized:
|
|
100
|
-
sinkCaps.materialized === true && typeof state.sink.materializedPath === "function",
|
|
101
|
-
...(sinkCaps.maxBytes === undefined ? {} : { maxBytes: sinkCaps.maxBytes }),
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const keyFor = (path: string, scope: HostFilesScope | undefined): string =>
|
|
105
|
-
mintKey(state, path, scope);
|
|
106
|
-
|
|
107
|
-
const api: HostFilesApi = {
|
|
108
|
-
capabilities,
|
|
109
|
-
|
|
110
|
-
forSession(sessionId: string): HostFilesApi {
|
|
111
|
-
const trimmed = sessionId.trim();
|
|
112
|
-
if (trimmed === "") {
|
|
113
|
-
throw new FileSessionRequiredError("host.files.forSession requires a non-empty session id");
|
|
114
|
-
}
|
|
115
|
-
return createBoundHostFilesApi({ ...state, sessionId: trimmed });
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
async read(path, options): Promise<string | undefined> {
|
|
119
|
-
const bytes = await api.readBytes(path, options);
|
|
120
|
-
return bytes === undefined
|
|
121
|
-
? undefined
|
|
122
|
-
: Buffer.from(bytes).toString(options?.encoding ?? "utf8");
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
async readBytes(path, options): Promise<Uint8Array | undefined> {
|
|
126
|
-
const found = await state.sink.get(keyFor(path, options?.scope));
|
|
127
|
-
if (found === undefined) {
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
return found instanceof Uint8Array ? found : found.body;
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
async write(path, data, options): Promise<void> {
|
|
134
|
-
const key = keyFor(path, options?.scope);
|
|
135
|
-
const body = typeof data === "string" ? Buffer.from(data, "utf8") : Buffer.from(data);
|
|
136
|
-
const maxBytes = capabilities.maxBytes;
|
|
137
|
-
if (maxBytes !== undefined && body.byteLength > maxBytes) {
|
|
138
|
-
throw new FileTooLargeError(key, body.byteLength, maxBytes);
|
|
139
|
-
}
|
|
140
|
-
await state.sink.put(
|
|
141
|
-
key,
|
|
142
|
-
body,
|
|
143
|
-
options?.ifMatch === undefined ? undefined : { ifMatch: options.ifMatch },
|
|
144
|
-
);
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
async remove(path, options): Promise<void> {
|
|
148
|
-
await state.sink.delete(keyFor(path, options?.scope));
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
async exists(path, options): Promise<boolean> {
|
|
152
|
-
return (await api.stat(path, options)) !== undefined;
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
async stat(path, options): Promise<HostFileStat | undefined> {
|
|
156
|
-
const key = keyFor(path, options?.scope);
|
|
157
|
-
const entry = await statKey(state.sink, key);
|
|
158
|
-
if (entry === undefined) {
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
return {
|
|
162
|
-
size: entry.size,
|
|
163
|
-
...(entry.mtimeMs === undefined ? {} : { mtimeMs: entry.mtimeMs }),
|
|
164
|
-
...(entry.etag === undefined ? {} : { etag: entry.etag }),
|
|
165
|
-
};
|
|
166
|
-
},
|
|
167
|
-
|
|
168
|
-
async list(prefix, options): Promise<HostFileEntry[]> {
|
|
169
|
-
const scopePrefix = mintPrefix(state, options?.scope);
|
|
170
|
-
const rel = prefix === undefined ? "" : normalizeRelPath(prefix, true);
|
|
171
|
-
const entries = await state.sink.list(`${scopePrefix}${rel}`);
|
|
172
|
-
const out: HostFileEntry[] = [];
|
|
173
|
-
for (const entry of entries) {
|
|
174
|
-
if (!entry.key.startsWith(scopePrefix)) {
|
|
175
|
-
// A sink that widens the prefix must not leak keys from another
|
|
176
|
-
// scope through a listing.
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
out.push({
|
|
180
|
-
path: entry.key.slice(scopePrefix.length),
|
|
181
|
-
size: entry.size,
|
|
182
|
-
...(entry.mtimeMs === undefined ? {} : { mtimeMs: entry.mtimeMs }),
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
return out.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
186
|
-
},
|
|
187
|
-
|
|
188
|
-
materializedPath(path, options): string | undefined {
|
|
189
|
-
if (!capabilities.materialized) {
|
|
190
|
-
return undefined;
|
|
191
|
-
}
|
|
192
|
-
return state.sink.materializedPath?.(keyFor(path, options?.scope));
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
return api;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async function statKey(sink: FileSink, key: string): Promise<FileSinkEntry | undefined> {
|
|
199
|
-
if (typeof sink.stat === "function") {
|
|
200
|
-
return await sink.stat(key);
|
|
201
|
-
}
|
|
202
|
-
const entries = await sink.list(key);
|
|
203
|
-
return entries.find(entry => entry.key === key);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// ============================================================================
|
|
207
|
-
// Key minting
|
|
208
|
-
// ============================================================================
|
|
209
|
-
|
|
210
|
-
function mintKey(state: BoundState, path: string, scope: HostFilesScope | undefined): string {
|
|
211
|
-
const rel = normalizeRelPath(path, false);
|
|
212
|
-
const resolved = resolveScope(state, scope);
|
|
213
|
-
if (resolved.kind === "session") {
|
|
214
|
-
return fileKeys.session(state.agentName, resolved.sessionId, rel);
|
|
215
|
-
}
|
|
216
|
-
return resolved.partition === undefined
|
|
217
|
-
? fileKeys.deployment(state.agentName, rel)
|
|
218
|
-
: fileKeys.deploymentPartition(state.agentName, resolved.partition, rel);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function mintPrefix(state: BoundState, scope: HostFilesScope | undefined): string {
|
|
222
|
-
const resolved = resolveScope(state, scope);
|
|
223
|
-
if (resolved.kind === "session") {
|
|
224
|
-
return fileKeys.sessionPrefix(state.agentName, resolved.sessionId);
|
|
225
|
-
}
|
|
226
|
-
const base = fileKeys.deploymentPrefix(state.agentName);
|
|
227
|
-
return resolved.partition === undefined ? base : `${base}${resolved.partition}/`;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
type ResolvedScope =
|
|
231
|
-
| { kind: "session"; sessionId: string }
|
|
232
|
-
| { kind: "deployment"; partition?: string };
|
|
233
|
-
|
|
234
|
-
function resolveScope(state: BoundState, scope: HostFilesScope | undefined): ResolvedScope {
|
|
235
|
-
if (scope === "deployment") {
|
|
236
|
-
return { kind: "deployment" };
|
|
237
|
-
}
|
|
238
|
-
if (scope !== undefined && typeof scope === "object") {
|
|
239
|
-
if (scope.kind === "deployment") {
|
|
240
|
-
return scope.partition === undefined
|
|
241
|
-
? { kind: "deployment" }
|
|
242
|
-
: { kind: "deployment", partition: segment(scope.partition) };
|
|
243
|
-
}
|
|
244
|
-
const explicit = scope.sessionId ?? state.sessionId;
|
|
245
|
-
return { kind: "session", sessionId: requireSession(explicit) };
|
|
246
|
-
}
|
|
247
|
-
// Default and explicit `"session"` both bind to the caller's own session, so
|
|
248
|
-
// a relative path can never be re-read as another session's.
|
|
249
|
-
return { kind: "session", sessionId: requireSession(state.sessionId) };
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function requireSession(sessionId: string | undefined): string {
|
|
253
|
-
if (sessionId === undefined || sessionId.trim() === "") {
|
|
254
|
-
throw new FileSessionRequiredError(
|
|
255
|
-
"host.files needs a session in scope: call forSession(sessionId), pass { scope: { kind: 'session', sessionId } }, or use { scope: 'deployment' }",
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
return segment(sessionId);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Normalize an author path into key-relative form. Rejects traversal, NUL,
|
|
263
|
-
* backslashes, trailing slashes, and the `.cursor*` prefix the Agent Store
|
|
264
|
-
* reserves for Cursor-managed content — refusing here turns an opaque failure
|
|
265
|
-
* deep in a sink (or a 400 from the hosted API, which accepts each path in
|
|
266
|
-
* exactly one spelling) into one the author can act on, and keeps the rule
|
|
267
|
-
* identical across sinks.
|
|
268
|
-
*/
|
|
269
|
-
function normalizeRelPath(path: string, allowEmpty: boolean): string {
|
|
270
|
-
if (typeof path !== "string") {
|
|
271
|
-
throw new FilePathRejectedError("host.files path must be a string");
|
|
272
|
-
}
|
|
273
|
-
const trimmed = path.trim().replace(/^\/+/, "");
|
|
274
|
-
if (trimmed === "") {
|
|
275
|
-
if (allowEmpty) {
|
|
276
|
-
return "";
|
|
277
|
-
}
|
|
278
|
-
throw new FilePathRejectedError("host.files path must be non-empty");
|
|
279
|
-
}
|
|
280
|
-
if (trimmed.includes("\0")) {
|
|
281
|
-
throw new FilePathRejectedError(`host.files path is not allowed: ${path}`);
|
|
282
|
-
}
|
|
283
|
-
// A backslash is a separator on Windows and a literal on POSIX, so a key
|
|
284
|
-
// minted from one would name different objects on different hosts — and the
|
|
285
|
-
// hosted API refuses it. Same rule as `segment()` below.
|
|
286
|
-
if (trimmed.includes("\\")) {
|
|
287
|
-
throw new FilePathRejectedError(`host.files path is not allowed: ${path}`);
|
|
288
|
-
}
|
|
289
|
-
// On an object path, a trailing slash would mint a key ending in "/" — an
|
|
290
|
-
// empty "directory marker" object, never what an author writing a file
|
|
291
|
-
// meant, and refused by the hosted API. A listing prefix (`allowEmpty`) is
|
|
292
|
-
// a different thing: there a trailing slash legitimately scopes to a
|
|
293
|
-
// directory's contents.
|
|
294
|
-
if (!allowEmpty && trimmed.endsWith("/")) {
|
|
295
|
-
throw new FilePathRejectedError(`host.files path is not allowed: ${path}`);
|
|
296
|
-
}
|
|
297
|
-
const normalized = normalize(trimmed).split(sep).join("/");
|
|
298
|
-
if (
|
|
299
|
-
normalized === ".." ||
|
|
300
|
-
normalized === "." ||
|
|
301
|
-
normalized.startsWith("../") ||
|
|
302
|
-
normalized.includes("/../") ||
|
|
303
|
-
normalized.endsWith("/..")
|
|
304
|
-
) {
|
|
305
|
-
throw new FilePathRejectedError(`host.files path is not allowed: ${path}`);
|
|
306
|
-
}
|
|
307
|
-
for (const part of normalized.split("/")) {
|
|
308
|
-
if (isReservedSegment(part)) {
|
|
309
|
-
throw new FilePathRejectedError(
|
|
310
|
-
`host.files path segment "${part}" is reserved for Cursor-managed content: ${path}`,
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return normalized;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/** One key segment (session id, partition): no separators, no traversal. */
|
|
318
|
-
function segment(value: string): string {
|
|
319
|
-
const trimmed = value.trim();
|
|
320
|
-
if (
|
|
321
|
-
trimmed === "" ||
|
|
322
|
-
trimmed === "." ||
|
|
323
|
-
trimmed === ".." ||
|
|
324
|
-
trimmed.includes("/") ||
|
|
325
|
-
trimmed.includes("\\") ||
|
|
326
|
-
trimmed.includes("\0")
|
|
327
|
-
) {
|
|
328
|
-
throw new FilePathRejectedError(`host.files key segment is not allowed: ${value}`);
|
|
329
|
-
}
|
|
330
|
-
if (isReservedSegment(trimmed)) {
|
|
331
|
-
throw new FilePathRejectedError(
|
|
332
|
-
`host.files key segment "${trimmed}" is reserved for Cursor-managed content`,
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
return trimmed;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/** Mirrors the server's reserved-prefix rule (`AGENT_STORE_RESERVED_CURSOR_PATH_PREFIX`). */
|
|
339
|
-
function isReservedSegment(value: string): boolean {
|
|
340
|
-
return value.toLowerCase().startsWith(".cursor");
|
|
341
|
-
}
|
package/src/internal/host-kv.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Author-facing durable JSON KV for {@link HostContext.kv}.
|
|
3
|
-
*
|
|
4
|
-
* When `defineStorage` is authored and exposes `get`, values live in that
|
|
5
|
-
* sink under {@link storageKeys.kv}. Otherwise they land as one JSON file
|
|
6
|
-
* per key under `--state-root/kv` (local dogfood / no durable plug-in).
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { randomUUID } from "node:crypto";
|
|
10
|
-
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
11
|
-
import { join } from "node:path";
|
|
12
|
-
import { storageKeys } from "../storage.js";
|
|
13
|
-
import type { HostKvApi, JsonValue } from "../types.js";
|
|
14
|
-
import type { AuthorKvStore } from "./storage-roles.js";
|
|
15
|
-
|
|
16
|
-
export interface CreateHostKvApiOptions {
|
|
17
|
-
agentName: string;
|
|
18
|
-
stateRoot: string;
|
|
19
|
-
/**
|
|
20
|
-
* Author KV backend. Narrowed to {@link AuthorKvStore} so this path cannot
|
|
21
|
-
* reach framework session state, which is headed somewhere else entirely.
|
|
22
|
-
*/
|
|
23
|
-
storage?: AuthorKvStore;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Build the host KV API for one agent process. */
|
|
27
|
-
export function createHostKvApi(options: CreateHostKvApiOptions): HostKvApi {
|
|
28
|
-
const storage = options.storage;
|
|
29
|
-
if (storage?.supportsAuthorKv === true) {
|
|
30
|
-
return {
|
|
31
|
-
get: key => storage.kvGet(normalizeAuthorKey(key)),
|
|
32
|
-
put: (key, value) => storage.kvPut(normalizeAuthorKey(key), value),
|
|
33
|
-
delete: key => storage.kvDelete(normalizeAuthorKey(key)),
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
return createFilesystemKvApi({
|
|
37
|
-
agentName: options.agentName,
|
|
38
|
-
stateRoot: options.stateRoot,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function createFilesystemKvApi(options: { agentName: string; stateRoot: string }): HostKvApi {
|
|
43
|
-
const dir = join(options.stateRoot, "kv");
|
|
44
|
-
const filePath = (authorKey: string): string =>
|
|
45
|
-
join(dir, `${encodeURIComponent(storageKeys.kv(options.agentName, authorKey))}.json`);
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
async get(key): Promise<JsonValue | undefined> {
|
|
49
|
-
const authorKey = normalizeAuthorKey(key);
|
|
50
|
-
try {
|
|
51
|
-
return JSON.parse(await readFile(filePath(authorKey), "utf8")) as JsonValue;
|
|
52
|
-
} catch (error) {
|
|
53
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
throw error;
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
async put(key, value): Promise<void> {
|
|
61
|
-
const authorKey = normalizeAuthorKey(key);
|
|
62
|
-
await mkdir(dir, { recursive: true });
|
|
63
|
-
const target = filePath(authorKey);
|
|
64
|
-
const tmp = join(dir, `.tmp-${randomUUID()}`);
|
|
65
|
-
await writeFile(tmp, JSON.stringify(value), "utf8");
|
|
66
|
-
await rename(tmp, target);
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
async delete(key): Promise<void> {
|
|
70
|
-
const authorKey = normalizeAuthorKey(key);
|
|
71
|
-
await rm(filePath(authorKey), { force: true });
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function normalizeAuthorKey(key: string): string {
|
|
77
|
-
if (typeof key !== "string" || key.trim() === "") {
|
|
78
|
-
throw new Error("host.kv key must be a non-empty string");
|
|
79
|
-
}
|
|
80
|
-
return key;
|
|
81
|
-
}
|