@cursor/bdk 0.2.3 → 0.2.5
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/README.md +76 -1154
- 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.94Iu5dyD.js} +4 -4
- package/dist/docs/assets/{building-with-agents.md.-fcjCmJU.js → building-with-agents.md.BPjPFxFg.js} +2 -2
- package/dist/docs/assets/{building-with-agents.md.-fcjCmJU.lean.js → building-with-agents.md.BPjPFxFg.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BITLoOQa.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.D49zVZqM.js → VPLocalSearchBox.DTKFDlBr.js} +1 -1
- package/dist/docs/assets/chunks/{arc.hmjb-sc4.js → arc.DuzwHEeg.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CxEI1KqM.js → architectureDiagram-Q4EWVU46.C6lyhLs0.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.DHHvBWoV.js → baseUniq.DUNEWlY8.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DnXW-3bu.js → blockDiagram-DXYQGD6D.CXOQGI0O.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.e-47O2jM.js → c4Diagram-AHTNJAMY.BYdPE-Oe.js} +1 -1
- package/dist/docs/assets/chunks/channel.B46uXH41.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.3ry4pYXB.js → chunk-4BX2VUAB.YIV9HeX0.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DGIZFRx6.js → chunk-4TB4RGXK.BG80DEOc.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.DKBnqg9U.js → chunk-55IACEB6.BDKJSZQc.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.BIU8Ue5k.js → chunk-EDXVE4YY.CtYnQqts.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.DP-TFhjI.js → chunk-FMBD7UC4.CityOth-.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.Ux0OYj5v.js → chunk-OYMX7WX6.CMD22CQX.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BzHMwYox.js → chunk-QZHKN3VN.WWpc3ND0.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.D4OGAsSP.js → chunk-YZCP3GAM.BMg-yhj3.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.0cmCFsSf.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.0cmCFsSf.js +1 -0
- package/dist/docs/assets/chunks/clone.1vTOFZT1.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Jq_7BUNx.js → cose-bilkent-S5V4N54A.Buu_LC5q.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.Di-skR2x.js → dagre-KV5264BT.DW7onj6E.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.DeREHIdH.js → diagram-5BDNPKRD.B3NxIbEV.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.C7Kcqxro.js → diagram-G4DWMVQ6.BJvN6Vkv.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BK3eohyo.js → diagram-MMDJMWI5.wfRWrexs.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.C6TyymXT.js → diagram-TYMM5635.7QtjSYio.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DYGG-gGx.js → erDiagram-SMLLAGMA.jxPgDH1t.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.C9nBcSV4.js → flowDiagram-DWJPFMVM.BhDWA-TO.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.wAg_ymsp.js → ganttDiagram-T4ZO3ILL.Ijq8iYKv.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.B87j9Oeg.js → gitGraphDiagram-UUTBAWPF.DXpfW4YG.js} +1 -1
- package/dist/docs/assets/chunks/{graph.CuFMj31w.js → graph.CoPlssRl.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.P_mLGumP.js → infoDiagram-42DDH7IO.eJuv_EOz.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DyuL_MsT.js → ishikawaDiagram-UXIWVN3A._OEzenCR.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CtP09IoJ.js → journeyDiagram-VCZTEJTY.CwlTjirB.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.BoeSYPZo.js → kanban-definition-6JOO6SKY.DSp_C8cZ.js} +1 -1
- package/dist/docs/assets/chunks/{layout.B0lMMtNo.js → layout.Bms9s7uB.js} +1 -1
- package/dist/docs/assets/chunks/{linear.HxRBiAFX.js → linear.BjnmB4je.js} +1 -1
- package/dist/docs/assets/chunks/{min.BGlFFHwS.js → min.CKkYlMsn.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.JyLBD9M8.js → mindmap-definition-QFDTVHPH.T2d0vJ7X.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DnSmNZF8.js → pieDiagram-DEJITSTG.DU0RoCvx.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CUCnbfCa.js → quadrantDiagram-34T5L4WZ.9QZjM-x0.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.py0IVUn5.js → requirementDiagram-MS252O5E.CZpylJMd.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.Bkc-HWYp.js → sankeyDiagram-XADWPNL6.CnFdfW95.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.Dqn8Mlv2.js → sequenceDiagram-FGHM5R23.-jC0PP1t.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.JikkoQUU.js → stateDiagram-FHFEXIEX.DG7yBRUU.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CbsZcOOu.js +1 -0
- package/dist/docs/assets/chunks/{theme.b6HQ6zG_.js → theme.B3O9koXV.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BvpSXiBj.js → timeline-definition-GMOUNBTQ.Bf9u4Ebb.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CU7MVnZx.js → vennDiagram-DHZGUBPP.BjhbbYE6.js} +1 -1
- package/dist/docs/assets/chunks/{wardley-RL74JXVD.BKwC4ctG.js → wardley-RL74JXVD.DEA21akR.js} +1 -1
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.BfaF6Uhe.js → wardleyDiagram-NUSXRM2D.8fRb4Nb5.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.Bg5dcpj4.js → xychartDiagram-5P7HB3ND.DoOP3zZM.js} +1 -1
- package/dist/docs/assets/{deployment.md.BJ8i7Q6p.js → deployment.md.BdqTiGdc.js} +5 -5
- package/dist/docs/assets/{deployment.md.BJ8i7Q6p.lean.js → deployment.md.BdqTiGdc.lean.js} +1 -1
- package/dist/docs/assets/{evals.md.CCAtNcuL.js → evals.md.LRCSn6Ik.js} +2 -2
- package/dist/docs/assets/{evals.md.CCAtNcuL.lean.js → evals.md.LRCSn6Ik.lean.js} +1 -1
- package/dist/docs/assets/{guides_agent-to-agent.md.CGkicXeB.js → guides_agent-to-agent.md.Cps5NiCV.js} +2 -2
- package/dist/docs/assets/{guides_agent-to-agent.md.CGkicXeB.lean.js → guides_agent-to-agent.md.Cps5NiCV.lean.js} +1 -1
- package/dist/docs/assets/{guides_bitbucket.md.Cb3LPKt3.js → guides_bitbucket.md.BB6fqD-M.js} +2 -2
- package/dist/docs/assets/{guides_bitbucket.md.Cb3LPKt3.lean.js → guides_bitbucket.md.BB6fqD-M.lean.js} +1 -1
- package/dist/docs/assets/{guides_cloud-agents.md.BuEkDCwo.js → guides_cloud-agents.md.CWJjS9No.js} +2 -2
- package/dist/docs/assets/{guides_cloud-agents.md.BuEkDCwo.lean.js → guides_cloud-agents.md.CWJjS9No.lean.js} +1 -1
- package/dist/docs/assets/{guides_convert-automation.md.Ci-Y2iD5.js → guides_convert-automation.md.DMEX9nF-.js} +3 -3
- package/dist/docs/assets/{guides_convert-automation.md.Ci-Y2iD5.lean.js → guides_convert-automation.md.DMEX9nF-.lean.js} +1 -1
- package/dist/docs/assets/{guides_github.md.Bq9kQU9B.js → guides_github.md.Cr1Xlf-m.js} +3 -3
- package/dist/docs/assets/{guides_github.md.Bq9kQU9B.lean.js → guides_github.md.Cr1Xlf-m.lean.js} +1 -1
- package/dist/docs/assets/{guides_gitlab.md.BM27P43u.js → guides_gitlab.md.CMpmFi4M.js} +2 -2
- package/dist/docs/assets/{guides_gitlab.md.BM27P43u.lean.js → guides_gitlab.md.CMpmFi4M.lean.js} +1 -1
- package/dist/docs/assets/{guides_grokbot-agents.md.yxVbSlKA.js → guides_grokbot-agents.md.tD1smFhU.js} +2 -2
- package/dist/docs/assets/{guides_grokbot-agents.md.yxVbSlKA.lean.js → guides_grokbot-agents.md.tD1smFhU.lean.js} +1 -1
- package/dist/docs/assets/{guides_hooks.md.BWoiNaMq.js → guides_hooks.md.5Ce3NXxZ.js} +2 -2
- package/dist/docs/assets/{guides_hooks.md.BWoiNaMq.lean.js → guides_hooks.md.5Ce3NXxZ.lean.js} +1 -1
- package/dist/docs/assets/{guides_improve.md.COtL-6ft.js → guides_improve.md.CRrYq22s.js} +2 -2
- package/dist/docs/assets/{guides_improve.md.COtL-6ft.lean.js → guides_improve.md.CRrYq22s.lean.js} +1 -1
- package/dist/docs/assets/{guides_jev.md.BNDm14Gy.js → guides_jev.md.D7XH4JH3.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.Cu6mhZ_3.js → guides_mcp-oauth.md.DR3zhC9r.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.Cu6mhZ_3.lean.js → guides_mcp-oauth.md.DR3zhC9r.lean.js} +1 -1
- package/dist/docs/assets/{guides_opentelemetry.md.DLlIB5rv.js → guides_opentelemetry.md.jcPNrQbH.js} +8 -6
- package/dist/docs/assets/{guides_opentelemetry.md.DLlIB5rv.lean.js → guides_opentelemetry.md.jcPNrQbH.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.diqqXTTm.js → guides_slack.md.Bn-WupSE.js} +8 -8
- package/dist/docs/assets/{guides_slack.md.diqqXTTm.lean.js → guides_slack.md.Bn-WupSE.lean.js} +1 -1
- package/dist/docs/assets/{guides_webhooks.md.D0furjw0.js → guides_webhooks.md.BBvAm_VF.js} +2 -2
- package/dist/docs/assets/{guides_webhooks.md.D0furjw0.lean.js → guides_webhooks.md.BBvAm_VF.lean.js} +1 -1
- package/dist/docs/assets/{hillclimbing.md.Biy0m-Qb.js → hillclimbing.md.Dxvd-0gT.js} +2 -2
- package/dist/docs/assets/{hillclimbing.md.Biy0m-Qb.lean.js → hillclimbing.md.Dxvd-0gT.lean.js} +1 -1
- package/dist/docs/assets/index.md.Dxxr7pFa.js +27 -0
- package/dist/docs/assets/{index.md.CVc_oOA3.lean.js → index.md.Dxxr7pFa.lean.js} +1 -1
- package/dist/docs/assets/{quickstart.md.CHpHPBUN.js → quickstart.md.BK5gjHM2.js} +2 -2
- package/dist/docs/assets/{quickstart.md.CHpHPBUN.lean.js → quickstart.md.BK5gjHM2.lean.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.DzGI777n.js → reference_agent-config.md.DrtLxWgR.js} +4 -4
- package/dist/docs/assets/{reference_agent-config.md.DzGI777n.lean.js → reference_agent-config.md.DrtLxWgR.lean.js} +1 -1
- package/dist/docs/assets/{reference_artifacts.md.CQfKq8F2.js → reference_artifacts.md.DLV9MZES.js} +2 -2
- package/dist/docs/assets/{reference_artifacts.md.CQfKq8F2.lean.js → reference_artifacts.md.DLV9MZES.lean.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.mbNtKCiR.js → reference_channels.md.LbNIJBwd.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.mbNtKCiR.lean.js → reference_channels.md.LbNIJBwd.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.DgeLTO18.js → reference_cli.md.BsgDqYPh.js} +4 -4
- package/dist/docs/assets/{reference_cli.md.DgeLTO18.lean.js → reference_cli.md.BsgDqYPh.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.COq--gAm.js → reference_connections.md.Bljpve-y.js} +4 -4
- package/dist/docs/assets/{reference_connections.md.COq--gAm.lean.js → reference_connections.md.Bljpve-y.lean.js} +1 -1
- package/dist/docs/assets/{reference_evals.md.CJm3uCUm.js → reference_evals.md.D5i8PuXJ.js} +2 -2
- package/dist/docs/assets/{reference_evals.md.CJm3uCUm.lean.js → reference_evals.md.D5i8PuXJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.js → reference_extensions.md.OUacPetl.js} +5 -4
- package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.lean.js → reference_extensions.md.OUacPetl.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.DbthhtIR.js → reference_hooks.md.C5LCJ1R3.js} +2 -2
- package/dist/docs/assets/{reference_hooks.md.DbthhtIR.lean.js → reference_hooks.md.C5LCJ1R3.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.BZOvhCqY.js → reference_http-api.md.DbFNOubV.js} +1 -1
- package/dist/docs/assets/{reference_instructions.md.Bdwscs4G.js → reference_instructions.md.DrcHZXig.js} +2 -2
- package/dist/docs/assets/{reference_instructions.md.Bdwscs4G.lean.js → reference_instructions.md.DrcHZXig.lean.js} +1 -1
- package/dist/docs/assets/reference_playground.md.1hx0gcIu.js +1 -0
- package/dist/docs/assets/{reference_playground.md.BdQzRJc2.lean.js → reference_playground.md.1hx0gcIu.lean.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md.CpLQ9j4K.js → reference_project-layout.md.C2JMRh7p.js} +2 -2
- package/dist/docs/assets/{reference_prompt.md.BQZB4eaV.js → reference_prompt.md.DqPh71XN.js} +3 -3
- package/dist/docs/assets/{reference_prompt.md.BQZB4eaV.lean.js → reference_prompt.md.DqPh71XN.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.BVU5EFbz.js → reference_schedules.md.BuJ8fgMa.js} +2 -2
- package/dist/docs/assets/{reference_schedules.md.BVU5EFbz.lean.js → reference_schedules.md.BuJ8fgMa.lean.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.CM5zo3w4.js +1 -0
- package/dist/docs/assets/{reference_sessions.md.DeRUItHD.lean.js → reference_sessions.md.CM5zo3w4.lean.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.Cy00QMKS.js → reference_skills.md.C0guGcH0.js} +4 -4
- package/dist/docs/assets/{reference_skills.md.Cy00QMKS.lean.js → reference_skills.md.C0guGcH0.lean.js} +1 -1
- package/dist/docs/assets/{reference_subagents.md.B8oyeXOI.js → reference_subagents.md.gmPt5J-M.js} +2 -2
- package/dist/docs/assets/{reference_subagents.md.B8oyeXOI.lean.js → reference_subagents.md.gmPt5J-M.lean.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.hg2Wi5Bq.js → reference_tools.md.v3SXVSs_.js} +2 -2
- package/dist/docs/assets/{reference_tools.md.hg2Wi5Bq.lean.js → reference_tools.md.v3SXVSs_.lean.js} +1 -1
- package/dist/docs/assets/{templates_agentic-owners.md.BykUiZ8j.js → templates_agentic-owners.md.vtjfwxbf.js} +2 -2
- package/dist/docs/assets/{templates_agentic-owners.md.BykUiZ8j.lean.js → templates_agentic-owners.md.vtjfwxbf.lean.js} +1 -1
- package/dist/docs/assets/templates_grokbot-agents.md.2sydjFiO.js +5 -0
- package/dist/docs/assets/templates_grokbot-agents.md.2sydjFiO.lean.js +1 -0
- package/dist/docs/assets/{templates_security-reviewer.md.DXMmKl_o.js → templates_security-reviewer.md.CX9l9bcg.js} +2 -2
- package/dist/docs/assets/{templates_security-reviewer.md.DXMmKl_o.lean.js → templates_security-reviewer.md.CX9l9bcg.lean.js} +1 -1
- package/dist/docs/assets/{templates_thermo-quality-review.md.Dg1p1MsG.js → templates_thermo-quality-review.md.95qmTmr1.js} +2 -2
- package/dist/docs/assets/{templates_thermo-quality-review.md.Dg1p1MsG.lean.js → templates_thermo-quality-review.md.95qmTmr1.lean.js} +1 -1
- package/dist/docs/assets/{templates_thermo-review.md.Dlylkowj.js → templates_thermo-review.md.DQh6Q0C-.js} +2 -2
- package/dist/docs/assets/{templates_thermo-review.md.Dlylkowj.lean.js → templates_thermo-review.md.DQh6Q0C-.lean.js} +1 -1
- package/dist/docs/assets/{templates_triage.md.CvJyx81N.js → templates_triage.md.BFlQhWXf.js} +3 -3
- package/dist/docs/assets/{templates_triage.md.CvJyx81N.lean.js → templates_triage.md.BFlQhWXf.lean.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.Bscj6ODe.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.Cw5PKa3t.lean.js → troubleshooting.md.Bscj6ODe.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +36 -36
- package/dist/docs/building-with-agents.md +0 -3
- package/dist/docs/deployment.html +39 -39
- package/dist/docs/deployment.md +6 -10
- package/dist/docs/evals.html +36 -36
- package/dist/docs/evals.md +0 -3
- package/dist/docs/guides/agent-to-agent.html +36 -36
- package/dist/docs/guides/agent-to-agent.md +0 -3
- package/dist/docs/guides/bitbucket.html +36 -36
- package/dist/docs/guides/bitbucket.md +0 -3
- package/dist/docs/guides/cloud-agents.html +36 -36
- package/dist/docs/guides/cloud-agents.md +0 -4
- package/dist/docs/guides/convert-automation.html +37 -37
- package/dist/docs/guides/convert-automation.md +2 -5
- package/dist/docs/guides/github.html +37 -37
- package/dist/docs/guides/github.md +1 -4
- package/dist/docs/guides/gitlab.html +36 -36
- package/dist/docs/guides/gitlab.md +0 -3
- package/dist/docs/guides/grokbot-agents.html +37 -37
- package/dist/docs/guides/grokbot-agents.md +1 -4
- package/dist/docs/guides/hooks.html +36 -36
- package/dist/docs/guides/hooks.md +0 -3
- package/dist/docs/guides/improve.html +36 -36
- package/dist/docs/guides/improve.md +0 -3
- package/dist/docs/guides/jev.html +37 -37
- package/dist/docs/guides/jev.md +7 -3
- package/dist/docs/guides/mcp-oauth.html +37 -37
- package/dist/docs/guides/mcp-oauth.md +1 -4
- package/dist/docs/guides/opentelemetry.html +42 -40
- package/dist/docs/guides/opentelemetry.md +4 -5
- package/dist/docs/guides/slack.html +43 -43
- package/dist/docs/guides/slack.md +14 -24
- package/dist/docs/guides/webhooks.html +36 -36
- package/dist/docs/guides/webhooks.md +0 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +36 -36
- package/dist/docs/hillclimbing.md +0 -3
- package/dist/docs/index.html +38 -38
- package/dist/docs/index.md +9 -16
- package/dist/docs/llms-full.txt +156 -220
- package/dist/docs/llms.txt +1 -0
- package/dist/docs/quickstart.html +36 -36
- package/dist/docs/quickstart.md +2 -7
- package/dist/docs/reference/agent-config.html +38 -38
- package/dist/docs/reference/agent-config.md +4 -7
- package/dist/docs/reference/artifacts.html +36 -36
- package/dist/docs/reference/artifacts.md +0 -3
- package/dist/docs/reference/channels.html +37 -37
- package/dist/docs/reference/channels.md +1 -6
- package/dist/docs/reference/cli.html +38 -38
- package/dist/docs/reference/cli.md +7 -14
- package/dist/docs/reference/connections.html +38 -38
- package/dist/docs/reference/connections.md +7 -10
- package/dist/docs/reference/evals.html +36 -36
- package/dist/docs/reference/evals.md +0 -3
- package/dist/docs/reference/extensions.html +40 -39
- package/dist/docs/reference/extensions.md +15 -5
- package/dist/docs/reference/hooks.html +36 -36
- package/dist/docs/reference/hooks.md +0 -3
- package/dist/docs/reference/http-api.html +37 -37
- package/dist/docs/reference/http-api.md +1 -1
- package/dist/docs/reference/instructions.html +36 -36
- package/dist/docs/reference/instructions.md +0 -3
- package/dist/docs/reference/playground.html +36 -36
- package/dist/docs/reference/playground.md +0 -3
- package/dist/docs/reference/project-layout.html +37 -37
- package/dist/docs/reference/project-layout.md +2 -2
- package/dist/docs/reference/prompt.html +37 -37
- package/dist/docs/reference/prompt.md +0 -3
- package/dist/docs/reference/schedules.html +36 -36
- package/dist/docs/reference/schedules.md +0 -3
- package/dist/docs/reference/sessions.html +36 -36
- package/dist/docs/reference/sessions.md +0 -3
- package/dist/docs/reference/skills.html +38 -38
- package/dist/docs/reference/skills.md +0 -3
- package/dist/docs/reference/subagents.html +36 -36
- package/dist/docs/reference/subagents.md +0 -3
- package/dist/docs/reference/tools.html +36 -36
- package/dist/docs/reference/tools.md +1 -5
- package/dist/docs/templates/agentic-owners.html +36 -36
- package/dist/docs/templates/agentic-owners.md +0 -3
- package/dist/docs/templates/grokbot-agents.html +64 -0
- package/dist/docs/templates/grokbot-agents.md +55 -0
- package/dist/docs/templates/security-reviewer.html +37 -37
- package/dist/docs/templates/security-reviewer.md +0 -3
- package/dist/docs/templates/thermo-quality-review.html +36 -36
- package/dist/docs/templates/thermo-quality-review.md +3 -6
- package/dist/docs/templates/thermo-review.html +36 -36
- package/dist/docs/templates/thermo-review.md +3 -5
- package/dist/docs/templates/triage.html +37 -37
- package/dist/docs/templates/triage.md +2 -3
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/docs/troubleshooting.md +3 -7
- 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/README.md +9 -16
- package/docs/building-with-agents.md +0 -3
- package/docs/deployment.md +6 -10
- package/docs/evals.md +0 -3
- package/docs/guides/agent-to-agent.md +0 -3
- package/docs/guides/bitbucket.md +0 -3
- package/docs/guides/cloud-agents.md +0 -4
- package/docs/guides/convert-automation.md +2 -5
- package/docs/guides/github.md +1 -4
- package/docs/guides/gitlab.md +0 -3
- package/docs/guides/grokbot-agents.md +1 -4
- package/docs/guides/hooks.md +0 -3
- package/docs/guides/improve.md +0 -3
- package/docs/guides/jev.md +7 -3
- package/docs/guides/mcp-oauth.md +1 -4
- package/docs/guides/opentelemetry.md +4 -5
- package/docs/guides/slack.md +14 -24
- package/docs/guides/webhooks.md +0 -3
- package/docs/hillclimbing.md +0 -3
- package/docs/quickstart.md +2 -7
- package/docs/reference/agent-config.md +4 -7
- package/docs/reference/artifacts.md +0 -3
- package/docs/reference/channels.md +1 -6
- package/docs/reference/cli.md +7 -14
- package/docs/reference/connections.md +7 -10
- package/docs/reference/evals.md +0 -3
- package/docs/reference/extensions.md +15 -5
- package/docs/reference/hooks.md +0 -3
- package/docs/reference/http-api.md +1 -1
- package/docs/reference/instructions.md +0 -3
- package/docs/reference/playground.md +0 -3
- package/docs/reference/project-layout.md +2 -2
- package/docs/reference/prompt.md +0 -3
- package/docs/reference/schedules.md +0 -3
- package/docs/reference/sessions.md +0 -3
- package/docs/reference/skills.md +0 -3
- package/docs/reference/subagents.md +0 -3
- package/docs/reference/tools.md +1 -5
- package/docs/templates/agentic-owners.md +0 -3
- package/docs/templates/grokbot-agents.md +60 -0
- package/docs/templates/security-reviewer.md +0 -3
- package/docs/templates/thermo-quality-review.md +3 -6
- package/docs/templates/thermo-review.md +3 -5
- package/docs/templates/triage.md +2 -3
- package/docs/troubleshooting.md +3 -7
- package/package.json +2 -10
- package/templates/agentic-owners/README.md +0 -3
- package/templates/agents-md/README.md +4 -3
- package/templates/code-wiki/README.md +0 -3
- package/templates/demo/README.md +0 -3
- package/templates/grokbot-agents/README.md +4 -6
- package/templates/security-help/README.md +12 -6
- package/templates/security-reviewer/README.md +0 -3
- package/templates/thermo-quality-review/README.md +0 -3
- package/templates/thermo-review/README.md +0 -3
- package/templates/triage/README.md +0 -3
- package/templates/triage/overlays/jira/README.md +0 -3
- package/templates/triage/overlays/linear/README.md +0 -3
- 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/dist/docs/assets/index.md.CVc_oOA3.js +0 -27
- package/dist/docs/assets/reference_playground.md.BdQzRJc2.js +0 -1
- package/dist/docs/assets/reference_sessions.md.DeRUItHD.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Cw5PKa3t.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/{guides_jev.md.BNDm14Gy.lean.js → guides_jev.md.D7XH4JH3.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.BZOvhCqY.lean.js → reference_http-api.md.DbFNOubV.lean.js} +0 -0
- /package/dist/docs/assets/{reference_project-layout.md.CpLQ9j4K.lean.js → reference_project-layout.md.C2JMRh7p.lean.js} +0 -0
|
@@ -1,836 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Durable artifact rows and payloads behind `ctx.artifacts`
|
|
3
|
-
* ({@link ArtifactsApi}).
|
|
4
|
-
*
|
|
5
|
-
* On Cursor-managed hosting rows and file payloads live on the deployment's
|
|
6
|
-
* Agent Store (the same store behind `ctx.host.files`, so they survive
|
|
7
|
-
* deploys and are visible on cloud VMs under the store mount); otherwise
|
|
8
|
-
* they land under `--state-root/artifacts` on local disk.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
12
|
-
import { mkdir, readdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
13
|
-
import { join } from "node:path";
|
|
14
|
-
import { resolveArtifactsMax } from "../artifacts.js";
|
|
15
|
-
import { agentStoreKeys, type FileSink } from "../files.js";
|
|
16
|
-
import {
|
|
17
|
-
cursorHostedFiles,
|
|
18
|
-
isCursorHostedFilesAvailable,
|
|
19
|
-
} from "../files-backends/cursor-hosted.js";
|
|
20
|
-
import type {
|
|
21
|
-
ArtifactListFilter,
|
|
22
|
-
ArtifactPage,
|
|
23
|
-
ArtifactPageOptions,
|
|
24
|
-
ArtifactRecord,
|
|
25
|
-
ArtifactsConfig,
|
|
26
|
-
ArtifactTagInput,
|
|
27
|
-
JsonValue,
|
|
28
|
-
} from "../types.js";
|
|
29
|
-
import { mapBounded } from "./bounded.js";
|
|
30
|
-
|
|
31
|
-
/** Default {@link ArtifactPageOptions.limit}; also `GET /v1/artifacts`. */
|
|
32
|
-
export const ARTIFACTS_PAGE_DEFAULT_LIMIT = 200;
|
|
33
|
-
/** Ceiling for {@link ArtifactPageOptions.limit}; larger asks clamp. */
|
|
34
|
-
export const ARTIFACTS_PAGE_MAX_LIMIT = 1_000;
|
|
35
|
-
/**
|
|
36
|
-
* Rows examined per `page()` call, floor. Filters live in row bodies, so a
|
|
37
|
-
* sparse filter must hydrate rows just to reject them; this stops one call
|
|
38
|
-
* from scanning an arbitrarily large store, returning a short (possibly
|
|
39
|
-
* empty) page with a `nextCursor` instead. `Math.max(limit, …)` keeps a
|
|
40
|
-
* full unfiltered page satisfiable in one call.
|
|
41
|
-
*/
|
|
42
|
-
const ARTIFACTS_PAGE_SCAN_MIN = 250;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Row-body hydration fan-out cap. `list()` fetches one object per row; on
|
|
46
|
-
* the Agent Store each fetch is a control-plane request, and an unbounded
|
|
47
|
-
* `Promise.all` over ~1k rows is a fleet-visible read burst (the 2026-09-18
|
|
48
|
-
* Agent Store read storm was this exact fan-out, run once per insert by the
|
|
49
|
-
* pre-metadata eviction path).
|
|
50
|
-
*/
|
|
51
|
-
const ROW_HYDRATION_CONCURRENCY = 8;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Rows hydrated per round trip when the row store batches
|
|
55
|
-
* ({@link ArtifactRowStore.getMany}). Matches the hosted sink's presign
|
|
56
|
-
* batch, so one page-scan slice is one control-plane request instead of one
|
|
57
|
-
* per row.
|
|
58
|
-
*/
|
|
59
|
-
const ARTIFACTS_SCAN_BATCH_ROWS = 100;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Most rows one eviction pass may delete. Bounds the tag-latency cost of
|
|
63
|
-
* draining a store that sits far past the retention cap (see
|
|
64
|
-
* {@link ArtifactsStore.evictPastCap}): at ~0.7s per Agent Store delete and
|
|
65
|
-
* {@link ROW_HYDRATION_CONCURRENCY}-way batching, a full pass stays under
|
|
66
|
-
* ~10s while a backlog drains across the inserts that keep arriving.
|
|
67
|
-
*/
|
|
68
|
-
const ARTIFACTS_EVICT_MAX_PER_PASS = 64;
|
|
69
|
-
|
|
70
|
-
/** One row's identity + modification metadata, without its body. */
|
|
71
|
-
interface ArtifactRowMeta {
|
|
72
|
-
id: string;
|
|
73
|
-
/** Last-modified epoch ms, when the backing store tracks one. */
|
|
74
|
-
mtimeMs?: number;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
interface ArtifactRowStore {
|
|
78
|
-
get(id: string): Promise<ArtifactRecord | undefined>;
|
|
79
|
-
/**
|
|
80
|
-
* Batched {@link get}, index-aligned with `ids`; a miss is `undefined`.
|
|
81
|
-
* Optional — the paged scan falls back to bounded per-id gets. The sink
|
|
82
|
-
* row store implements it over `FileSink.getMany` so a page walk spends
|
|
83
|
-
* one control-plane call per 100 rows instead of one per row.
|
|
84
|
-
*/
|
|
85
|
-
getMany?(ids: readonly string[]): Promise<Array<ArtifactRecord | undefined>>;
|
|
86
|
-
put(record: ArtifactRecord): Promise<void>;
|
|
87
|
-
delete(id: string): Promise<void>;
|
|
88
|
-
list(): Promise<ArtifactRecord[]>;
|
|
89
|
-
/**
|
|
90
|
-
* Row ids + modification metadata without hydrating bodies — the
|
|
91
|
-
* per-insert cap check and (when mtimes are tracked) the eviction order.
|
|
92
|
-
*/
|
|
93
|
-
listMeta(): Promise<ArtifactRowMeta[]>;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** File/blob payload bytes, keyed by artifact id (metadata lives on the row). */
|
|
97
|
-
interface ArtifactContentStore {
|
|
98
|
-
get(id: string): Promise<Uint8Array | undefined>;
|
|
99
|
-
put(id: string, body: Uint8Array): Promise<void>;
|
|
100
|
-
delete(id: string): Promise<void>;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export interface CreateArtifactsStoreOptions {
|
|
104
|
-
stateRoot: string;
|
|
105
|
-
agentName: string;
|
|
106
|
-
/** `agent/artifacts.ts` config, when authored. */
|
|
107
|
-
config?: ArtifactsConfig;
|
|
108
|
-
/** Explicit sink override (tests). Omitted → hosted store or local disk. */
|
|
109
|
-
sink?: FileSink;
|
|
110
|
-
/**
|
|
111
|
-
* Whether `tag` enforces {@link ArtifactsConfig.max} by listing and
|
|
112
|
-
* deleting. Default true. Hosted architecture v2 passes false: the
|
|
113
|
-
* installation store is allowed to grow, and a tag must not list the prefix.
|
|
114
|
-
*/
|
|
115
|
-
enforceCap?: () => boolean;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** Kind used by freeform tags when no kinds are declared. */
|
|
119
|
-
export const ARTIFACT_DEFAULT_KIND = "artifact";
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Upsert + list semantics over one {@link ArtifactRowStore}: kind/schema
|
|
123
|
-
* validation, deterministic ids for keyed tags, and `max` eviction.
|
|
124
|
-
* Architecture v1 and self-hosted v2 evict. Hosted architecture v2 sets
|
|
125
|
-
* {@link CreateArtifactsStoreOptions.enforceCap} false and does not list
|
|
126
|
-
* or delete on tag. The engine wraps this into the per-context
|
|
127
|
-
* {@link ArtifactsApi} facades and
|
|
128
|
-
* owns the `artifact.tagged` event append.
|
|
129
|
-
*/
|
|
130
|
-
export class ArtifactsStore {
|
|
131
|
-
private readonly rows: ArtifactRowStore;
|
|
132
|
-
private readonly content: ArtifactContentStore;
|
|
133
|
-
private readonly config: ArtifactsConfig | undefined;
|
|
134
|
-
private readonly max: number;
|
|
135
|
-
private readonly enforceCap: () => boolean;
|
|
136
|
-
/** Serializes tags so read-modify-write upserts and eviction don't race. */
|
|
137
|
-
private tagChain: Promise<unknown> = Promise.resolve();
|
|
138
|
-
|
|
139
|
-
constructor(options: CreateArtifactsStoreOptions) {
|
|
140
|
-
const sink = options.sink ?? (isCursorHostedFilesAvailable() ? cursorHostedFiles() : undefined);
|
|
141
|
-
if (sink === undefined) {
|
|
142
|
-
this.rows = createFilesystemRowStore(options.stateRoot);
|
|
143
|
-
this.content = createFilesystemContentStore(options.stateRoot);
|
|
144
|
-
} else {
|
|
145
|
-
this.rows = createSinkRowStore(sink, options.agentName);
|
|
146
|
-
this.content = createSinkContentStore(sink, options.agentName);
|
|
147
|
-
}
|
|
148
|
-
this.config = options.config;
|
|
149
|
-
this.max = resolveArtifactsMax(options.config);
|
|
150
|
-
this.enforceCap = options.enforceCap ?? (() => true);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
tag(input: ArtifactTagInput): Promise<ArtifactRecord> {
|
|
154
|
-
const result = this.tagChain.then(() => this.tagSerialized(input));
|
|
155
|
-
this.tagChain = result.catch(() => {});
|
|
156
|
-
return result;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
private async tagSerialized(input: ArtifactTagInput): Promise<ArtifactRecord> {
|
|
160
|
-
const { kind, data } = this.resolveKindAndData(input);
|
|
161
|
-
const id = input.key === undefined ? `art_${randomUUID()}` : artifactIdForKey(input.key);
|
|
162
|
-
// Fresh random ids can't collide; only keyed tags upsert.
|
|
163
|
-
const existing = input.key === undefined ? undefined : await this.rows.get(id);
|
|
164
|
-
const now = new Date().toISOString();
|
|
165
|
-
const record: ArtifactRecord = {
|
|
166
|
-
id,
|
|
167
|
-
kind,
|
|
168
|
-
key: input.key,
|
|
169
|
-
title: input.title,
|
|
170
|
-
data,
|
|
171
|
-
sessionId: input.sessionId,
|
|
172
|
-
turnId: input.turnId,
|
|
173
|
-
source: input.source ?? "host",
|
|
174
|
-
createdAt: existing?.createdAt ?? now,
|
|
175
|
-
updatedAt: now,
|
|
176
|
-
};
|
|
177
|
-
if (input.contents !== undefined) {
|
|
178
|
-
const body =
|
|
179
|
-
typeof input.contents === "string" ? Buffer.from(input.contents, "utf8") : input.contents;
|
|
180
|
-
await this.content.put(id, body);
|
|
181
|
-
record.content = {
|
|
182
|
-
size: body.byteLength,
|
|
183
|
-
contentType: input.contentType,
|
|
184
|
-
};
|
|
185
|
-
} else if (existing?.content !== undefined) {
|
|
186
|
-
if (existing.sessionId === record.sessionId) {
|
|
187
|
-
record.content = existing.content;
|
|
188
|
-
} else {
|
|
189
|
-
// Keys are deployment-global: rebinding a keyed row to another
|
|
190
|
-
// session must not carry the prior session's payload with it.
|
|
191
|
-
await this.content.delete(id);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
await this.rows.put(record);
|
|
195
|
-
if (existing === undefined && this.enforceCap()) {
|
|
196
|
-
await this.evictPastCap();
|
|
197
|
-
}
|
|
198
|
-
return record;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
get(id: string): Promise<ArtifactRecord | undefined> {
|
|
202
|
-
return this.rows.get(id);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** Payload bytes for one artifact; undefined when it carries none. */
|
|
206
|
-
getContent(id: string): Promise<Uint8Array | undefined> {
|
|
207
|
-
return this.content.get(id);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Newest page only (default limit, no cursor) — the bounded
|
|
212
|
-
* {@link ArtifactsApi.list} contract. Walk the full set via
|
|
213
|
-
* {@link ArtifactsStore.page}.
|
|
214
|
-
*/
|
|
215
|
-
async list(filter?: ArtifactListFilter): Promise<ArtifactRecord[]> {
|
|
216
|
-
const page = await this.page(filter);
|
|
217
|
-
return page.records;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Bounded cursor pagination, newest-updated first. On a store whose
|
|
222
|
-
* listing tracks mtimes (the hosted Agent Store), a page hydrates only
|
|
223
|
-
* the rows it examines — roughly `limit` bodies, never the whole store.
|
|
224
|
-
* Row-body order is the listing's mtime order (upserts rewrite the row,
|
|
225
|
-
* so mtime tracks `updatedAt`; same argument as eviction). The
|
|
226
|
-
* filesystem store hydrates everything (cheap local reads) and orders
|
|
227
|
-
* exactly by `updatedAt`.
|
|
228
|
-
*
|
|
229
|
-
* `matches` is a host-side *visibility* predicate composed with the
|
|
230
|
-
* public filter — the engine passes session-ownership through it. Its
|
|
231
|
-
* presence forces the exact hydrated lane: the metadata lane's cursor
|
|
232
|
-
* and its short-page continuation are derived from every row in the
|
|
233
|
-
* store, and handing them to a caller who may not see every row is a
|
|
234
|
-
* side channel (existence, count within the scan budget, boundary
|
|
235
|
-
* mtimes and cohort depths of hidden rows) that the pre-pagination
|
|
236
|
-
* filtered list never had. The exact lane's cursor names only a record
|
|
237
|
-
* the caller received, and continues only while more *visible* records
|
|
238
|
-
* remain — at the pre-pagination cost (hydrate all rows, bounded).
|
|
239
|
-
*/
|
|
240
|
-
async page(
|
|
241
|
-
options?: ArtifactPageOptions & {
|
|
242
|
-
matches?: (record: ArtifactRecord) => boolean;
|
|
243
|
-
},
|
|
244
|
-
): Promise<ArtifactPage> {
|
|
245
|
-
const limit = Math.min(
|
|
246
|
-
Math.max(options?.limit ?? ARTIFACTS_PAGE_DEFAULT_LIMIT, 1),
|
|
247
|
-
ARTIFACTS_PAGE_MAX_LIMIT,
|
|
248
|
-
);
|
|
249
|
-
const cursor =
|
|
250
|
-
options?.cursor === undefined ? undefined : decodeArtifactPageCursor(options.cursor);
|
|
251
|
-
const matches = (record: ArtifactRecord): boolean =>
|
|
252
|
-
(options?.kind === undefined || record.kind === options.kind) &&
|
|
253
|
-
(options?.sessionId === undefined || record.sessionId === options.sessionId) &&
|
|
254
|
-
(options?.matches === undefined || options.matches(record));
|
|
255
|
-
|
|
256
|
-
if (options?.matches === undefined) {
|
|
257
|
-
const metas = await this.rows.listMeta();
|
|
258
|
-
if (metas.some(meta => meta.mtimeMs !== undefined)) {
|
|
259
|
-
return this.pageFromMetadata(
|
|
260
|
-
metas,
|
|
261
|
-
limit,
|
|
262
|
-
cursor,
|
|
263
|
-
matches,
|
|
264
|
-
options?.kind !== undefined || options?.sessionId !== undefined,
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return this.pageFromRecords(limit, cursor, matches);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Metadata-ordered page: sort metas newest first, resume after the
|
|
273
|
-
* cursor, hydrate in bounded batches until the page fills, the scan
|
|
274
|
-
* budget runs out, or the metas do. The cursor marks the last *examined*
|
|
275
|
-
* meta, so a budget-limited call still makes progress.
|
|
276
|
-
*/
|
|
277
|
-
private async pageFromMetadata(
|
|
278
|
-
metas: ArtifactRowMeta[],
|
|
279
|
-
limit: number,
|
|
280
|
-
cursor: ArtifactPageCursor | undefined,
|
|
281
|
-
matches: (record: ArtifactRecord) => boolean,
|
|
282
|
-
filtered: boolean,
|
|
283
|
-
): Promise<ArtifactPage> {
|
|
284
|
-
const newestFirst = metas.sort((a, b) => byOldestModified(b, a));
|
|
285
|
-
let start = 0;
|
|
286
|
-
if (cursor !== undefined && cursor.kind === "mtime") {
|
|
287
|
-
// Resume after (boundary stamp, rows of that cohort already
|
|
288
|
-
// examined). Same-stamp rows sit contiguously in the sort, so the
|
|
289
|
-
// pair names an exact position without identifying any row.
|
|
290
|
-
start = newestFirst.findIndex(meta => (meta.mtimeMs ?? 0) <= cursor.m);
|
|
291
|
-
if (start === -1) {
|
|
292
|
-
return { records: [] };
|
|
293
|
-
}
|
|
294
|
-
let skipped = 0;
|
|
295
|
-
while (
|
|
296
|
-
start < newestFirst.length &&
|
|
297
|
-
(newestFirst[start]?.mtimeMs ?? 0) === cursor.m &&
|
|
298
|
-
skipped < cursor.s
|
|
299
|
-
) {
|
|
300
|
-
start += 1;
|
|
301
|
-
skipped += 1;
|
|
302
|
-
}
|
|
303
|
-
if (start >= newestFirst.length) {
|
|
304
|
-
return { records: [] };
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
// A cursor of the other kind means the store's listing gained mtimes
|
|
308
|
-
// between pages (a mode flip, not caller error): restart from the top
|
|
309
|
-
// rather than fail the walk.
|
|
310
|
-
const budget = Math.max(limit, ARTIFACTS_PAGE_SCAN_MIN);
|
|
311
|
-
const records: ArtifactRecord[] = [];
|
|
312
|
-
let examined = 0;
|
|
313
|
-
let lastExamined = start - 1;
|
|
314
|
-
// A batched row store hydrates a bigger slice per round trip (one
|
|
315
|
-
// control-plane call on the hosted sink); without one, keep the slice at
|
|
316
|
-
// the per-row fan-out bound so concurrency stays capped. An unfiltered
|
|
317
|
-
// page needs exactly the rows it returns — every hydrated row matches —
|
|
318
|
-
// so cap its slice at the remaining page instead of over-hydrating a
|
|
319
|
-
// full batch for a small `limit`.
|
|
320
|
-
const scanBatchSize =
|
|
321
|
-
this.rows.getMany !== undefined ? ARTIFACTS_SCAN_BATCH_ROWS : ROW_HYDRATION_CONCURRENCY;
|
|
322
|
-
scan: while (
|
|
323
|
-
lastExamined + 1 < newestFirst.length &&
|
|
324
|
-
records.length < limit &&
|
|
325
|
-
examined < budget
|
|
326
|
-
) {
|
|
327
|
-
const from = lastExamined + 1;
|
|
328
|
-
const sliceCap = filtered ? scanBatchSize : Math.min(scanBatchSize, limit - records.length);
|
|
329
|
-
const batch = newestFirst.slice(from, from + Math.min(sliceCap, budget - examined));
|
|
330
|
-
const bodies =
|
|
331
|
-
this.rows.getMany !== undefined
|
|
332
|
-
? await this.rows.getMany(batch.map(meta => meta.id))
|
|
333
|
-
: await mapBounded(batch, ROW_HYDRATION_CONCURRENCY, meta => this.rows.get(meta.id));
|
|
334
|
-
for (let i = 0; i < batch.length; i += 1) {
|
|
335
|
-
lastExamined = from + i;
|
|
336
|
-
examined += 1;
|
|
337
|
-
const record = bodies[i];
|
|
338
|
-
if (record !== undefined && matches(record)) {
|
|
339
|
-
records.push(record);
|
|
340
|
-
if (records.length === limit) {
|
|
341
|
-
break scan;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
if (lastExamined >= newestFirst.length - 1) {
|
|
347
|
-
return { records };
|
|
348
|
-
}
|
|
349
|
-
const boundary = (newestFirst[lastExamined] as ArtifactRowMeta).mtimeMs ?? 0;
|
|
350
|
-
// How deep into the boundary's same-stamp cohort the scan got —
|
|
351
|
-
// cohorts are contiguous, so count back from the last examined row.
|
|
352
|
-
let cohortExamined = 0;
|
|
353
|
-
for (let i = lastExamined; i >= 0 && (newestFirst[i]?.mtimeMs ?? 0) === boundary; i -= 1) {
|
|
354
|
-
cohortExamined += 1;
|
|
355
|
-
}
|
|
356
|
-
return {
|
|
357
|
-
records,
|
|
358
|
-
nextCursor: encodeArtifactPageCursor({
|
|
359
|
-
v: 1,
|
|
360
|
-
kind: "mtime",
|
|
361
|
-
m: boundary,
|
|
362
|
-
s: cohortExamined,
|
|
363
|
-
}),
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Hydrate-everything page: exact `updatedAt` order, cursor = the last
|
|
369
|
-
* *returned* record's position. Serves stores without listing mtimes
|
|
370
|
-
* (the local filesystem store) and every visibility-filtered walk — see
|
|
371
|
-
* {@link ArtifactsStore.page} for why filtered callers must not receive
|
|
372
|
-
* metadata-lane cursors.
|
|
373
|
-
*/
|
|
374
|
-
private async pageFromRecords(
|
|
375
|
-
limit: number,
|
|
376
|
-
cursor: ArtifactPageCursor | undefined,
|
|
377
|
-
matches: (record: ArtifactRecord) => boolean,
|
|
378
|
-
): Promise<ArtifactPage> {
|
|
379
|
-
const records = (await this.rows.list()).filter(matches).sort(byNewestUpdated);
|
|
380
|
-
let start = 0;
|
|
381
|
-
if (cursor !== undefined && cursor.kind === "updated") {
|
|
382
|
-
const position = {
|
|
383
|
-
updatedAt: cursor.u,
|
|
384
|
-
createdAt: cursor.c,
|
|
385
|
-
id: cursor.id,
|
|
386
|
-
} as ArtifactRecord;
|
|
387
|
-
start = records.findIndex(record => byNewestUpdated(record, position) > 0);
|
|
388
|
-
if (start === -1) {
|
|
389
|
-
return { records: [] };
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
const page = records.slice(start, start + limit);
|
|
393
|
-
const last = page[page.length - 1];
|
|
394
|
-
if (last === undefined || start + page.length >= records.length) {
|
|
395
|
-
return { records: page };
|
|
396
|
-
}
|
|
397
|
-
return {
|
|
398
|
-
records: page,
|
|
399
|
-
nextCursor: encodeArtifactPageCursor({
|
|
400
|
-
v: 1,
|
|
401
|
-
kind: "updated",
|
|
402
|
-
u: last.updatedAt,
|
|
403
|
-
c: last.createdAt,
|
|
404
|
-
id: last.id,
|
|
405
|
-
}),
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* Resolve the effective kind (freeform when no kinds are declared) and
|
|
411
|
-
* the payload to persist. Like tool input schemas
|
|
412
|
-
* (`validateToolInput`), zod schemas validate *and* transform: the
|
|
413
|
-
* parsed output — defaults and coercions applied — is what gets stored.
|
|
414
|
-
*/
|
|
415
|
-
private resolveKindAndData(input: ArtifactTagInput): {
|
|
416
|
-
kind: string;
|
|
417
|
-
data: JsonValue;
|
|
418
|
-
} {
|
|
419
|
-
const kind = input.kind ?? ARTIFACT_DEFAULT_KIND;
|
|
420
|
-
if (kind.trim() === "") {
|
|
421
|
-
throw new Error("artifacts.tag: kind must be a non-empty string");
|
|
422
|
-
}
|
|
423
|
-
const kinds = this.config?.kinds;
|
|
424
|
-
if (kinds === undefined || Object.keys(kinds).length === 0) {
|
|
425
|
-
return { kind, data: input.data };
|
|
426
|
-
}
|
|
427
|
-
const kindConfig = kinds[kind];
|
|
428
|
-
if (kindConfig === undefined) {
|
|
429
|
-
throw new Error(
|
|
430
|
-
`artifacts.tag: unknown kind ${JSON.stringify(kind)} (declared: ${Object.keys(kinds).join(", ")})`,
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
if (kindConfig.schema !== undefined) {
|
|
434
|
-
const parsed = kindConfig.schema.safeParse(input.data);
|
|
435
|
-
if (!parsed.success) {
|
|
436
|
-
throw new Error(
|
|
437
|
-
`artifacts.tag: data does not match the ${JSON.stringify(kind)} schema: ${parsed.error.message}`,
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
return { kind, data: parsed.data as JsonValue };
|
|
441
|
-
}
|
|
442
|
-
return { kind, data: input.data };
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Trim toward the retention cap from listing metadata alone. Past the
|
|
447
|
-
* cap this runs on every new-row insert, so it must not hydrate row
|
|
448
|
-
* bodies: on the Agent Store that is one read per row (~`max` reads per
|
|
449
|
-
* insert, forever, since eviction trims right back to the cap) — the
|
|
450
|
-
* 2026-09-18 read storm on the security-reviewer deployment. The store
|
|
451
|
-
* listing carries last-modified metadata, and a row is rewritten on
|
|
452
|
-
* every upsert, so listing mtime orders rows the same way their
|
|
453
|
-
* `updatedAt` does.
|
|
454
|
-
*
|
|
455
|
-
* Deletes are capped per pass: eviction runs inside `tag()`'s per-pod
|
|
456
|
-
* chain, so its wall time is tag latency for every queued caller. A
|
|
457
|
-
* store far past the cap (evictions failed during the 2026-09-19 read
|
|
458
|
-
* throttling and the backlog grew unchecked) must drain amortized
|
|
459
|
-
* across inserts, not wedge one insert deleting the whole backlog — on
|
|
460
|
-
* 2026-09-20 an uncapped pass held security-reviewer tags for hours and
|
|
461
|
-
* tripled review stage durations. Steady state (excess of 1) is
|
|
462
|
-
* unaffected.
|
|
463
|
-
*/
|
|
464
|
-
private async evictPastCap(): Promise<void> {
|
|
465
|
-
const metas = await this.rows.listMeta();
|
|
466
|
-
const excess = Math.min(metas.length - this.max, ARTIFACTS_EVICT_MAX_PER_PASS);
|
|
467
|
-
if (excess <= 0) {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
await mapBounded(
|
|
471
|
-
await this.oldestRowIds(metas, excess),
|
|
472
|
-
ROW_HYDRATION_CONCURRENCY,
|
|
473
|
-
async id => {
|
|
474
|
-
await this.rows.delete(id);
|
|
475
|
-
// Without the row body there is no `content` flag to consult;
|
|
476
|
-
// delete the payload unconditionally — absent ones are a no-op.
|
|
477
|
-
await this.content.delete(id);
|
|
478
|
-
},
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/** The `excess` oldest row ids, cheapest available ordering first. */
|
|
483
|
-
private async oldestRowIds(metas: ArtifactRowMeta[], excess: number): Promise<string[]> {
|
|
484
|
-
if (metas.some(meta => meta.mtimeMs !== undefined)) {
|
|
485
|
-
// A store that tracks mtimes must never regress to per-insert
|
|
486
|
-
// hydration. The rare entry missing one (anomalous on such a store)
|
|
487
|
-
// sorts oldest via the comparator's `?? 0` and gets evicted first —
|
|
488
|
-
// evicting an anomaly beats re-reading every row on every insert.
|
|
489
|
-
return metas
|
|
490
|
-
.sort(byOldestModified)
|
|
491
|
-
.slice(0, excess)
|
|
492
|
-
.map(meta => meta.id);
|
|
493
|
-
}
|
|
494
|
-
// A store that tracks no modification times at all (the local
|
|
495
|
-
// filesystem store, deliberately) leaves only the rows' own
|
|
496
|
-
// `updatedAt`: hydrate — bounded — and order exactly. Corrupt rows
|
|
497
|
-
// drop out of `list()`, so recompute the excess against the rows that
|
|
498
|
-
// actually parsed.
|
|
499
|
-
const records = await this.rows.list();
|
|
500
|
-
return records
|
|
501
|
-
.sort((a, b) => byNewestUpdated(b, a))
|
|
502
|
-
.slice(0, Math.min(excess, Math.max(0, records.length - this.max)))
|
|
503
|
-
.map(record => record.id);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/** A syntactically invalid {@link ArtifactPageOptions.cursor}. */
|
|
508
|
-
export class InvalidArtifactCursorError extends Error {
|
|
509
|
-
constructor() {
|
|
510
|
-
super("artifacts.page: invalid cursor");
|
|
511
|
-
this.name = "InvalidArtifactCursorError";
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* Resume position, opaque to callers (base64url JSON). Which kind a store
|
|
517
|
-
* mints follows which ordering source it paged from.
|
|
518
|
-
*
|
|
519
|
-
* `mtime` is purely positional — the boundary modification stamp plus how
|
|
520
|
-
* many rows of that same-stamp cohort were already examined. It must never
|
|
521
|
-
* carry a row id: the scan examines rows the caller's visibility predicate
|
|
522
|
-
* then rejects, so a cursor naming the last *examined* row would hand
|
|
523
|
-
* strict-auth callers other principals' artifact ids inside an unsigned
|
|
524
|
-
* token. `updated` names only the last *returned* record, which the caller
|
|
525
|
-
* already received.
|
|
526
|
-
*/
|
|
527
|
-
type ArtifactPageCursor =
|
|
528
|
-
| { v: 1; kind: "mtime"; m: number; s: number }
|
|
529
|
-
| { v: 1; kind: "updated"; u: string; c: string; id: string };
|
|
530
|
-
|
|
531
|
-
function encodeArtifactPageCursor(cursor: ArtifactPageCursor): string {
|
|
532
|
-
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
/** Throws {@link InvalidArtifactCursorError} on anything undecodable. */
|
|
536
|
-
function decodeArtifactPageCursor(raw: string): ArtifactPageCursor {
|
|
537
|
-
let value: unknown;
|
|
538
|
-
try {
|
|
539
|
-
value = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
|
|
540
|
-
} catch {
|
|
541
|
-
throw new InvalidArtifactCursorError();
|
|
542
|
-
}
|
|
543
|
-
if (typeof value !== "object" || value === null) {
|
|
544
|
-
throw new InvalidArtifactCursorError();
|
|
545
|
-
}
|
|
546
|
-
const cursor = value as Record<string, unknown>;
|
|
547
|
-
if (cursor.v !== 1) {
|
|
548
|
-
throw new InvalidArtifactCursorError();
|
|
549
|
-
}
|
|
550
|
-
if (
|
|
551
|
-
cursor.kind === "mtime" &&
|
|
552
|
-
typeof cursor.m === "number" &&
|
|
553
|
-
typeof cursor.s === "number" &&
|
|
554
|
-
Number.isInteger(cursor.s) &&
|
|
555
|
-
cursor.s >= 0
|
|
556
|
-
) {
|
|
557
|
-
return { v: 1, kind: "mtime", m: cursor.m, s: cursor.s };
|
|
558
|
-
}
|
|
559
|
-
if (
|
|
560
|
-
cursor.kind === "updated" &&
|
|
561
|
-
typeof cursor.u === "string" &&
|
|
562
|
-
typeof cursor.c === "string" &&
|
|
563
|
-
typeof cursor.id === "string"
|
|
564
|
-
) {
|
|
565
|
-
return { v: 1, kind: "updated", u: cursor.u, c: cursor.c, id: cursor.id };
|
|
566
|
-
}
|
|
567
|
-
throw new InvalidArtifactCursorError();
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/** Deterministic id for a keyed tag (same key ⇒ same id ⇒ upsert). */
|
|
571
|
-
export function artifactIdForKey(key: string): string {
|
|
572
|
-
if (key.trim() === "") {
|
|
573
|
-
throw new Error("artifacts.tag: key must be a non-empty string");
|
|
574
|
-
}
|
|
575
|
-
return `art_${createHash("sha256").update(key, "utf8").digest("hex").slice(0, 32)}`;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
* Oldest-modified first. Store mtimes can be coarse (S3 rounds to the
|
|
580
|
-
* second), so equal stamps tie-break by id — deterministic, and within a
|
|
581
|
-
* same-stamp cohort any victim is equally past the retention cap.
|
|
582
|
-
*/
|
|
583
|
-
function byOldestModified(a: ArtifactRowMeta, b: ArtifactRowMeta): number {
|
|
584
|
-
if (a.mtimeMs !== b.mtimeMs) {
|
|
585
|
-
return (a.mtimeMs ?? 0) - (b.mtimeMs ?? 0);
|
|
586
|
-
}
|
|
587
|
-
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
function byNewestUpdated(a: ArtifactRecord, b: ArtifactRecord): number {
|
|
591
|
-
if (a.updatedAt !== b.updatedAt) {
|
|
592
|
-
return a.updatedAt < b.updatedAt ? 1 : -1;
|
|
593
|
-
}
|
|
594
|
-
// Tie-break so eviction and listing stay deterministic.
|
|
595
|
-
if (a.createdAt !== b.createdAt) {
|
|
596
|
-
return a.createdAt < b.createdAt ? 1 : -1;
|
|
597
|
-
}
|
|
598
|
-
return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
function isArtifactRecord(value: JsonValue | undefined): value is ArtifactRecord & JsonValue {
|
|
602
|
-
if (
|
|
603
|
-
typeof value !== "object" ||
|
|
604
|
-
value === null ||
|
|
605
|
-
Array.isArray(value) ||
|
|
606
|
-
typeof value.id !== "string" ||
|
|
607
|
-
typeof value.kind !== "string" ||
|
|
608
|
-
(value.source !== "host" && value.source !== "model") ||
|
|
609
|
-
typeof value.createdAt !== "string" ||
|
|
610
|
-
typeof value.updatedAt !== "string" ||
|
|
611
|
-
!("data" in value)
|
|
612
|
-
) {
|
|
613
|
-
return false;
|
|
614
|
-
}
|
|
615
|
-
for (const field of ["key", "title", "sessionId", "turnId"] as const) {
|
|
616
|
-
if (value[field] !== undefined && typeof value[field] !== "string") {
|
|
617
|
-
return false;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
return true;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
function parseRecordBytes(bytes: Uint8Array | undefined): ArtifactRecord | undefined {
|
|
624
|
-
if (bytes === undefined) {
|
|
625
|
-
return undefined;
|
|
626
|
-
}
|
|
627
|
-
let value: JsonValue;
|
|
628
|
-
try {
|
|
629
|
-
value = JSON.parse(Buffer.from(bytes).toString("utf8")) as JsonValue;
|
|
630
|
-
} catch {
|
|
631
|
-
// A corrupt row must not poison list().
|
|
632
|
-
return undefined;
|
|
633
|
-
}
|
|
634
|
-
return isArtifactRecord(value) ? value : undefined;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function sinkBody(found: Awaited<ReturnType<FileSink["get"]>>): Uint8Array | undefined {
|
|
638
|
-
if (found === undefined) {
|
|
639
|
-
return undefined;
|
|
640
|
-
}
|
|
641
|
-
return found instanceof Uint8Array ? found : found.body;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
/** Rows as one JSON file each on the deployment's Agent Store. */
|
|
645
|
-
function createSinkRowStore(sink: FileSink, agentName: string): ArtifactRowStore {
|
|
646
|
-
const key = (id: string): string => agentStoreKeys.artifactRow(agentName, id);
|
|
647
|
-
return {
|
|
648
|
-
async get(id): Promise<ArtifactRecord | undefined> {
|
|
649
|
-
return parseRecordBytes(sinkBody(await sink.get(key(id))));
|
|
650
|
-
},
|
|
651
|
-
async put(record): Promise<void> {
|
|
652
|
-
await sink.put(key(record.id), Buffer.from(JSON.stringify(record), "utf8"));
|
|
653
|
-
},
|
|
654
|
-
async delete(id): Promise<void> {
|
|
655
|
-
await sink.delete(key(id));
|
|
656
|
-
},
|
|
657
|
-
async getMany(ids): Promise<Array<ArtifactRecord | undefined>> {
|
|
658
|
-
const keys = ids.map(id => key(id));
|
|
659
|
-
const bodies =
|
|
660
|
-
sink.getMany !== undefined
|
|
661
|
-
? await sink.getMany(keys)
|
|
662
|
-
: await mapBounded(keys, ROW_HYDRATION_CONCURRENCY, rowKey => sink.get(rowKey));
|
|
663
|
-
return bodies.map(body => parseRecordBytes(sinkBody(body)));
|
|
664
|
-
},
|
|
665
|
-
async list(): Promise<ArtifactRecord[]> {
|
|
666
|
-
const entries = await sink.list(agentStoreKeys.artifactRowPrefix(agentName));
|
|
667
|
-
const bodies =
|
|
668
|
-
sink.getMany !== undefined
|
|
669
|
-
? await sink.getMany(entries.map(entry => entry.key))
|
|
670
|
-
: await mapBounded(entries, ROW_HYDRATION_CONCURRENCY, entry => sink.get(entry.key));
|
|
671
|
-
const records: ArtifactRecord[] = [];
|
|
672
|
-
for (const body of bodies) {
|
|
673
|
-
const record = parseRecordBytes(sinkBody(body));
|
|
674
|
-
if (record !== undefined) {
|
|
675
|
-
records.push(record);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
return records;
|
|
679
|
-
},
|
|
680
|
-
async listMeta(): Promise<ArtifactRowMeta[]> {
|
|
681
|
-
const prefix = agentStoreKeys.artifactRowPrefix(agentName);
|
|
682
|
-
const metas: ArtifactRowMeta[] = [];
|
|
683
|
-
for (const entry of await sink.list(prefix)) {
|
|
684
|
-
const id = rowIdFromName(entry.key.slice(prefix.length));
|
|
685
|
-
if (id !== undefined) {
|
|
686
|
-
metas.push({ id, mtimeMs: entry.mtimeMs });
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
return metas;
|
|
690
|
-
},
|
|
691
|
-
};
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* Invert the row naming scheme (`encodeURIComponent(id) + ".json"`).
|
|
696
|
-
* Foreign keys under the prefix — no `.json` suffix, malformed escapes,
|
|
697
|
-
* non-canonical encodings — read as absent rather than throwing. The
|
|
698
|
-
* round-trip check matters for eviction: a name that decodes but does not
|
|
699
|
-
* re-encode to itself (`a+b.json`, `foo bar.json`) would count toward the
|
|
700
|
-
* cap yet be undeletable through `key(id)`, leaving a phantom victim that
|
|
701
|
-
* every subsequent insert re-selects and fails to remove.
|
|
702
|
-
*/
|
|
703
|
-
function rowIdFromName(name: string): string | undefined {
|
|
704
|
-
if (!name.endsWith(".json") || name.includes("/")) {
|
|
705
|
-
return undefined;
|
|
706
|
-
}
|
|
707
|
-
const encoded = name.slice(0, -".json".length);
|
|
708
|
-
try {
|
|
709
|
-
const id = decodeURIComponent(encoded);
|
|
710
|
-
return encodeURIComponent(id) === encoded ? id : undefined;
|
|
711
|
-
} catch {
|
|
712
|
-
return undefined;
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
function createSinkContentStore(sink: FileSink, agentName: string): ArtifactContentStore {
|
|
717
|
-
const key = (id: string): string => agentStoreKeys.artifactContent(agentName, id);
|
|
718
|
-
return {
|
|
719
|
-
async get(id): Promise<Uint8Array | undefined> {
|
|
720
|
-
return sinkBody(await sink.get(key(id)));
|
|
721
|
-
},
|
|
722
|
-
async put(id, body): Promise<void> {
|
|
723
|
-
await sink.put(key(id), body);
|
|
724
|
-
},
|
|
725
|
-
async delete(id): Promise<void> {
|
|
726
|
-
await sink.delete(key(id));
|
|
727
|
-
},
|
|
728
|
-
};
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
function createFilesystemRowStore(stateRoot: string): ArtifactRowStore {
|
|
732
|
-
const dir = join(stateRoot, "artifacts");
|
|
733
|
-
const filePath = (id: string): string => join(dir, `${encodeURIComponent(id)}.json`);
|
|
734
|
-
|
|
735
|
-
// Missing and corrupt rows both read as absent — a truncated/garbled
|
|
736
|
-
// file must not poison list() (and with it every insert's eviction).
|
|
737
|
-
const readRecord = async (path: string): Promise<ArtifactRecord | undefined> => {
|
|
738
|
-
try {
|
|
739
|
-
const value = JSON.parse(await readFile(path, "utf8")) as JsonValue;
|
|
740
|
-
return isArtifactRecord(value) ? value : undefined;
|
|
741
|
-
} catch (error) {
|
|
742
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT" || error instanceof SyntaxError) {
|
|
743
|
-
return undefined;
|
|
744
|
-
}
|
|
745
|
-
throw error;
|
|
746
|
-
}
|
|
747
|
-
};
|
|
748
|
-
|
|
749
|
-
return {
|
|
750
|
-
get(id): Promise<ArtifactRecord | undefined> {
|
|
751
|
-
return readRecord(filePath(id));
|
|
752
|
-
},
|
|
753
|
-
async put(record): Promise<void> {
|
|
754
|
-
await mkdir(dir, { recursive: true });
|
|
755
|
-
const tmp = join(dir, `.tmp-${randomUUID()}`);
|
|
756
|
-
await writeFile(tmp, JSON.stringify(record), "utf8");
|
|
757
|
-
await rename(tmp, filePath(record.id));
|
|
758
|
-
},
|
|
759
|
-
async delete(id): Promise<void> {
|
|
760
|
-
await rm(filePath(id), { force: true });
|
|
761
|
-
},
|
|
762
|
-
async list(): Promise<ArtifactRecord[]> {
|
|
763
|
-
let names: string[];
|
|
764
|
-
try {
|
|
765
|
-
names = await readdir(dir);
|
|
766
|
-
} catch (error) {
|
|
767
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
768
|
-
return [];
|
|
769
|
-
}
|
|
770
|
-
throw error;
|
|
771
|
-
}
|
|
772
|
-
const records: ArtifactRecord[] = [];
|
|
773
|
-
for (const name of names.sort()) {
|
|
774
|
-
if (name.startsWith(".") || !name.endsWith(".json")) {
|
|
775
|
-
continue;
|
|
776
|
-
}
|
|
777
|
-
const record = await readRecord(join(dir, name));
|
|
778
|
-
if (record !== undefined) {
|
|
779
|
-
records.push(record);
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
return records;
|
|
783
|
-
},
|
|
784
|
-
async listMeta(): Promise<ArtifactRowMeta[]> {
|
|
785
|
-
// No mtimes on purpose: local rows are cheap to hydrate, and the
|
|
786
|
-
// rows' own `updatedAt` orders eviction exactly, immune to coarse
|
|
787
|
-
// filesystem timestamp granularity.
|
|
788
|
-
let names: string[];
|
|
789
|
-
try {
|
|
790
|
-
names = await readdir(dir);
|
|
791
|
-
} catch (error) {
|
|
792
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
793
|
-
return [];
|
|
794
|
-
}
|
|
795
|
-
throw error;
|
|
796
|
-
}
|
|
797
|
-
const metas: ArtifactRowMeta[] = [];
|
|
798
|
-
for (const name of names) {
|
|
799
|
-
if (name.startsWith(".")) {
|
|
800
|
-
continue;
|
|
801
|
-
}
|
|
802
|
-
const id = rowIdFromName(name);
|
|
803
|
-
if (id !== undefined) {
|
|
804
|
-
metas.push({ id });
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
return metas;
|
|
808
|
-
},
|
|
809
|
-
};
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
function createFilesystemContentStore(stateRoot: string): ArtifactContentStore {
|
|
813
|
-
const dir = join(stateRoot, "artifacts", "content");
|
|
814
|
-
const filePath = (id: string): string => join(dir, encodeURIComponent(id));
|
|
815
|
-
return {
|
|
816
|
-
async get(id): Promise<Uint8Array | undefined> {
|
|
817
|
-
try {
|
|
818
|
-
return new Uint8Array(await readFile(filePath(id)));
|
|
819
|
-
} catch (error) {
|
|
820
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
821
|
-
return undefined;
|
|
822
|
-
}
|
|
823
|
-
throw error;
|
|
824
|
-
}
|
|
825
|
-
},
|
|
826
|
-
async put(id, body): Promise<void> {
|
|
827
|
-
await mkdir(dir, { recursive: true });
|
|
828
|
-
const tmp = join(dir, `.tmp-${randomUUID()}`);
|
|
829
|
-
await writeFile(tmp, body);
|
|
830
|
-
await rename(tmp, filePath(id));
|
|
831
|
-
},
|
|
832
|
-
async delete(id): Promise<void> {
|
|
833
|
-
await rm(filePath(id), { force: true });
|
|
834
|
-
},
|
|
835
|
-
};
|
|
836
|
-
}
|