@cursor/july 0.1.29 → 0.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +10 -5
- package/dist/bin/agent-serve.js +4 -4
- package/dist/channels/github/index.d.ts +1 -1
- package/dist/channels/github/index.js +1 -1
- package/dist/channels/slack/bot-mentions.d.ts +1 -1
- package/dist/channels/slack/bot-mentions.d.ts.map +1 -1
- package/dist/channels/slack/bot-mentions.js +1 -1
- package/dist/channels/slack/eval-directive.js +1 -1
- package/dist/channels/slack/external-policy.d.ts +1 -1
- package/dist/channels/slack/external-policy.js +1 -1
- package/dist/channels/slack/log.d.ts +1 -1
- package/dist/channels/slack/log.js +1 -1
- package/dist/channels/slack/setup.js +1 -1
- package/dist/channels/slack/socket-mode.js +1 -1
- package/dist/docs/404.html +3 -3
- package/dist/docs/ab.html +11 -11
- package/dist/docs/assets/{ab.md.BMCZ6Hd7.js → ab.md.DAQoJ-up.js} +6 -6
- package/dist/docs/assets/{ab.md.BMCZ6Hd7.lean.js → ab.md.DAQoJ-up.lean.js} +1 -1
- package/dist/docs/assets/{app.QdunVQKg.js → app.DigB_9cQ.js} +1 -1
- package/dist/docs/assets/building-with-agents.md.CnHqvYDd.js +13 -0
- package/dist/docs/assets/{building-with-agents.md.CJCtZCyi.lean.js → building-with-agents.md.CnHqvYDd.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CnFFl07y.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.B6EpUXYf.js → VPLocalSearchBox.BCMX25Bv.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BOTJVqh7.js → theme.BDDWeELx.js} +2 -2
- package/dist/docs/assets/concepts.md.DFaQEFkA.js +4 -0
- package/dist/docs/assets/concepts.md.DFaQEFkA.lean.js +1 -0
- package/dist/docs/assets/deployment.md.9MYBuKM1.js +55 -0
- package/dist/docs/assets/deployment.md.9MYBuKM1.lean.js +1 -0
- package/dist/docs/assets/{evals.md.DYOjkRCX.js → evals.md.BIUoVZ6X.js} +13 -13
- package/dist/docs/assets/evals.md.BIUoVZ6X.lean.js +1 -0
- package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.js → example-agents_approval-buddy.md.BhEfleVx.js} +4 -4
- package/dist/docs/assets/{example-agents_approval-buddy.md.DFGBYLcc.lean.js → example-agents_approval-buddy.md.BhEfleVx.lean.js} +1 -1
- package/dist/docs/assets/example-agents_benny.md.2Et1qa8f.js +7 -0
- package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.js → example-agents_bugbot.md.ByUexi5i.js} +5 -5
- package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.js → example-agents_codebase-wiki.md.B4y-7ZVW.js} +6 -6
- package/dist/docs/assets/{example-agents_codebase-wiki.md.DC6sgwn0.lean.js → example-agents_codebase-wiki.md.B4y-7ZVW.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.js → example-agents_codeowners-review.md.D6ay4nvf.js} +6 -6
- package/dist/docs/assets/{example-agents_codeowners-review.md.Ku_tG2RY.lean.js → example-agents_codeowners-review.md.D6ay4nvf.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.js → example-agents_concierge.md.lL8rhYlj.js} +7 -7
- package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.js → example-agents_fsd.md.DfNKQTHz.js} +5 -5
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.js +2 -0
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.lean.js +1 -0
- package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.js → example-agents_knowledge-base.md.CzyZ2DCr.js} +5 -5
- package/dist/docs/assets/{example-agents_knowledge-base.md.BPJiVueF.lean.js → example-agents_knowledge-base.md.CzyZ2DCr.lean.js} +1 -1
- package/dist/docs/assets/example-agents_oncall.md.wFFXXEyW.js +10 -0
- package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.js → example-agents_security-reviewer.md.Dkf1gyo6.js} +8 -8
- package/dist/docs/assets/example-agents_slack-agent.md.DvgvT4nn.js +5 -0
- package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.js +24 -0
- package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.lean.js +1 -0
- package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.js → guides_agent-to-agent.md.Bmbxy-FA.js} +4 -4
- package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.js +9 -0
- package/dist/docs/assets/{guides_github.md.DOOCpqsW.js → guides_github.md.R2QlpR75.js} +5 -5
- package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.js → guides_human-in-the-loop.md.BWvT7UqY.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.Dd8EgSem.js → guides_mcp-oauth.md.C7G7IykG.js} +5 -5
- package/dist/docs/assets/guides_mcp-oauth.md.C7G7IykG.lean.js +1 -0
- package/dist/docs/assets/guides_slack.md.zriQpU_9.js +47 -0
- package/dist/docs/assets/guides_slack.md.zriQpU_9.lean.js +1 -0
- package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.js → guides_webhooks.md.DiAwSR42.js} +1 -1
- package/dist/docs/assets/{hillclimbing.md.DHNast08.js → hillclimbing.md.D9Y1_bYh.js} +1 -1
- package/dist/docs/assets/index.md.CZqbBJPB.js +20 -0
- package/dist/docs/assets/index.md.CZqbBJPB.lean.js +1 -0
- package/dist/docs/assets/{quickstart.md.BU6Iwi_9.js → quickstart.md.TnEXYgYW.js} +12 -12
- package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.js → reference_agent-config.md.kuN6-OxK.js} +1 -1
- package/dist/docs/assets/reference_cli.md.sD-IUWjg.js +73 -0
- package/dist/docs/assets/{reference_cli.md.ccoKOoXt.lean.js → reference_cli.md.sD-IUWjg.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.B9Q3TOve.js → reference_connections.md.DGqAsFXb.js} +3 -3
- package/dist/docs/assets/reference_http-api.md.CfVM_ICa.js +11 -0
- package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.js → reference_project-layout.md.D8E6ZmHJ.js} +4 -4
- package/dist/docs/assets/{reference_project-layout.md.Bd_CKtNS.lean.js → reference_project-layout.md.D8E6ZmHJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.js → reference_schedules.md.gmfYzf_I.js} +1 -1
- package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.js → reference_sessions.md.C_ouF_uf.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.BRSDnTbN.js → reference_tools.md.BswAQM41.js} +3 -3
- package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.js → scaffolding-agents.md.Bsr9Pwzu.js} +1 -1
- package/dist/docs/assets/{scaffolding-agents.md.C3pTrmoE.lean.js → scaffolding-agents.md.Bsr9Pwzu.lean.js} +1 -1
- package/dist/docs/assets/{storage.md.DRTdnFvd.js → storage.md.xZoiGM58.js} +3 -3
- package/dist/docs/assets/storage.md.xZoiGM58.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.B5RVX_tL.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.CmQkmnzC.lean.js → troubleshooting.md.B5RVX_tL.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +12 -12
- package/dist/docs/concepts.html +6 -6
- package/dist/docs/deployment.html +32 -32
- package/dist/docs/evals.html +19 -19
- package/dist/docs/example-agents/approval-buddy.html +9 -9
- package/dist/docs/example-agents/benny.html +11 -11
- package/dist/docs/example-agents/bugbot.html +10 -10
- package/dist/docs/example-agents/codebase-wiki.html +11 -11
- package/dist/docs/example-agents/codeowners-review.html +11 -11
- package/dist/docs/example-agents/concierge.html +12 -12
- package/dist/docs/example-agents/fsd.html +10 -10
- package/dist/docs/example-agents/index.html +7 -7
- package/dist/docs/example-agents/knowledge-base.html +10 -10
- package/dist/docs/example-agents/oncall.html +10 -10
- package/dist/docs/example-agents/security-reviewer.html +13 -13
- package/dist/docs/example-agents/slack-agent.html +10 -10
- package/dist/docs/example-agents/weather-agent.html +16 -16
- package/dist/docs/guides/agent-to-agent.html +9 -9
- package/dist/docs/guides/cloud-runtime.html +7 -7
- package/dist/docs/guides/github.html +10 -10
- package/dist/docs/guides/human-in-the-loop.html +7 -7
- package/dist/docs/guides/mcp-oauth.html +11 -11
- package/dist/docs/guides/slack.html +22 -17
- package/dist/docs/guides/webhooks.html +7 -7
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +7 -7
- package/dist/docs/index.html +9 -9
- package/dist/docs/quickstart.html +17 -17
- package/dist/docs/reference/agent-config.html +7 -7
- package/dist/docs/reference/channels.html +5 -5
- package/dist/docs/reference/cli.html +56 -48
- package/dist/docs/reference/connections.html +9 -9
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +7 -7
- package/dist/docs/reference/instructions.html +5 -5
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/project-layout.html +9 -9
- package/dist/docs/reference/prompt.html +5 -5
- package/dist/docs/reference/schedules.html +7 -7
- package/dist/docs/reference/sessions.html +8 -8
- package/dist/docs/reference/skills.html +5 -5
- package/dist/docs/reference/subagents.html +5 -5
- package/dist/docs/reference/tools.html +9 -9
- package/dist/docs/scaffolding-agents.html +6 -6
- package/dist/docs/storage.html +9 -9
- package/dist/docs/troubleshooting.html +6 -6
- package/dist/evals/reporters.d.ts +1 -1
- package/dist/evals/reporters.js +1 -1
- package/dist/evals.d.ts +2 -2
- package/dist/files-backends/agent-store-presigned-url.d.ts +100 -0
- package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -0
- package/dist/files-backends/agent-store-presigned-url.js +347 -0
- package/dist/files-backends/cursor-hosted.d.ts +87 -0
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -0
- package/dist/files-backends/cursor-hosted.js +540 -0
- package/dist/files-backends/local-fs.d.ts +33 -0
- package/dist/files-backends/local-fs.d.ts.map +1 -0
- package/dist/files-backends/local-fs.js +199 -0
- package/dist/files.d.ts +139 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +89 -0
- package/dist/internal/ab-collector.js +2 -2
- package/dist/internal/ab-fold.js +1 -1
- package/dist/internal/cli-ax.d.ts +2 -2
- package/dist/internal/cli-ax.js +2 -2
- package/dist/internal/cli-deploy.d.ts +1 -1
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +7 -2
- package/dist/internal/cli-docs.d.ts +1 -1
- package/dist/internal/cli-docs.js +1 -1
- package/dist/internal/cli-github.js +13 -13
- package/dist/internal/cli-mcp-oauth.d.ts +1 -1
- package/dist/internal/cli-mcp-oauth.js +2 -2
- package/dist/internal/cli-mcp.d.ts +3 -3
- package/dist/internal/cli-mcp.js +4 -4
- package/dist/internal/cli-skills.js +1 -1
- package/dist/internal/cloud-turn-cost.d.ts +9 -1
- package/dist/internal/cloud-turn-cost.d.ts.map +1 -1
- package/dist/internal/cloud-turn-cost.js +14 -4
- package/dist/internal/cursor/account-mcp.js +5 -5
- package/dist/internal/cursor/backend-client.js +1 -1
- package/dist/internal/cursor/github-credentials.js +3 -3
- package/dist/internal/cursor-account-mcp-auth.d.ts +1 -1
- package/dist/internal/cursor-account-mcp-auth.js +1 -1
- package/dist/internal/cursor-event-relay.js +1 -1
- package/dist/internal/cursor-relay-core.d.ts +1 -1
- package/dist/internal/cursor-relay-core.d.ts.map +1 -1
- package/dist/internal/cursor-slack-relay.js +1 -1
- package/dist/internal/deploy-client.d.ts +6 -1
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +3 -2
- package/dist/internal/deploy-source.d.ts +2 -2
- package/dist/internal/deploy-source.js +2 -2
- package/dist/internal/discovery.js +2 -2
- package/dist/internal/distribution.d.ts +5 -5
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +6 -6
- package/dist/internal/docs-site.js +5 -5
- package/dist/internal/eval-run-store.js +8 -8
- package/dist/internal/evals-client.d.ts +1 -1
- package/dist/internal/evals-client.js +1 -1
- package/dist/internal/github-fanout.js +2 -2
- package/dist/internal/host-files.d.ts +29 -0
- package/dist/internal/host-files.d.ts.map +1 -0
- package/dist/internal/host-files.js +283 -0
- package/dist/internal/host-platforms.js +5 -5
- package/dist/internal/hosting.d.ts +1 -1
- package/dist/internal/hosting.js +1 -1
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +26 -0
- package/dist/internal/install-cursor-skills.d.ts +1 -1
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +33 -4
- package/dist/internal/local-control-plane.js +2 -2
- package/dist/internal/logs-client.d.ts +2 -2
- package/dist/internal/logs-client.js +2 -2
- package/dist/internal/mcp-endpoint.js +1 -1
- package/dist/internal/mcp-oauth.js +2 -2
- package/dist/internal/platform-schedule-sync.js +2 -2
- package/dist/internal/playground/toolchain.js +6 -6
- package/dist/internal/reminder-runner.js +13 -13
- package/dist/internal/resolved-connections.js +6 -6
- package/dist/internal/schedule-runner.js +1 -1
- package/dist/internal/sdk-runner.js +5 -5
- package/dist/internal/server.js +16 -16
- package/dist/internal/session-cost.d.ts +3 -2
- package/dist/internal/session-cost.d.ts.map +1 -1
- package/dist/internal/session-cost.js +7 -6
- package/dist/internal/session-engine.d.ts +31 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +119 -31
- package/dist/internal/slack-provision-client.js +1 -1
- package/dist/internal/storage-coordinator.js +7 -7
- package/dist/internal/trajectory.js +2 -2
- package/dist/internal/turn-cost.d.ts +27 -0
- package/dist/internal/turn-cost.d.ts.map +1 -0
- package/dist/internal/turn-cost.js +83 -0
- package/dist/internal/update-check.d.ts +3 -3
- package/dist/internal/update-check.d.ts.map +1 -1
- package/dist/internal/update-check.js +5 -5
- package/dist/memory.d.ts +1 -1
- package/dist/memory.js +1 -1
- package/dist/playground/assets/index-50PKeJlG.css +1 -0
- package/dist/playground/assets/index-C0f2Wl1q.js +85 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +1 -1
- package/dist/types.d.ts +120 -16
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +23 -23
- package/docs/ab.md +12 -12
- package/docs/building-with-agents.md +9 -9
- package/docs/concepts.md +11 -11
- package/docs/deployment.md +55 -43
- package/docs/evals.md +20 -20
- package/docs/example-agents/approval-buddy.md +9 -9
- package/docs/example-agents/benny.md +13 -13
- package/docs/example-agents/bugbot.md +6 -6
- package/docs/example-agents/codebase-wiki.md +8 -8
- package/docs/example-agents/codeowners-review.md +8 -8
- package/docs/example-agents/concierge.md +10 -10
- package/docs/example-agents/fsd.md +7 -7
- package/docs/example-agents/index.md +8 -8
- package/docs/example-agents/knowledge-base.md +9 -9
- package/docs/example-agents/oncall.md +7 -7
- package/docs/example-agents/security-reviewer.md +12 -12
- package/docs/example-agents/slack-agent.md +10 -10
- package/docs/example-agents/weather-agent.md +30 -26
- package/docs/guides/agent-to-agent.md +4 -4
- package/docs/guides/cloud-runtime.md +3 -3
- package/docs/guides/github.md +6 -6
- package/docs/guides/human-in-the-loop.md +1 -1
- package/docs/guides/mcp-oauth.md +9 -9
- package/docs/guides/slack.md +94 -21
- package/docs/guides/webhooks.md +1 -1
- package/docs/hillclimbing.md +3 -3
- package/docs/quickstart.md +18 -18
- package/docs/reference/agent-config.md +1 -1
- package/docs/reference/cli.md +110 -79
- package/docs/reference/connections.md +3 -3
- package/docs/reference/http-api.md +2 -2
- package/docs/reference/project-layout.md +7 -7
- package/docs/reference/schedules.md +1 -1
- package/docs/reference/sessions.md +7 -7
- package/docs/reference/tools.md +3 -3
- package/docs/scaffolding-agents.md +2 -2
- package/docs/storage.md +5 -5
- package/docs/troubleshooting.md +11 -10
- package/package.json +3 -1
- package/skills/ab/SKILL.md +5 -5
- package/skills/create-agent/SKILL.md +17 -17
- package/skills/debug/SKILL.md +10 -10
- package/skills/evals/SKILL.md +13 -13
- package/skills/framework-map/SKILL.md +3 -3
- package/skills/github/SKILL.md +11 -11
- package/skills/hillclimb/SKILL.md +9 -9
- package/skills/mcp-auth/SKILL.md +11 -11
- package/skills/setup-slack/SKILL.md +28 -28
- package/src/bin/agent-serve.ts +4 -4
- package/src/channels/github/index.ts +1 -1
- package/src/channels/slack/bot-mentions.ts +1 -1
- package/src/channels/slack/eval-directive.ts +1 -1
- package/src/channels/slack/external-policy.ts +1 -1
- package/src/channels/slack/log.ts +1 -1
- package/src/channels/slack/setup.ts +1 -1
- package/src/channels/slack/socket-mode.ts +1 -1
- package/src/evals/reporters.ts +1 -1
- package/src/evals.ts +2 -2
- package/src/files-backends/agent-store-presigned-url.ts +402 -0
- package/src/files-backends/cursor-hosted.ts +698 -0
- package/src/files-backends/local-fs.ts +178 -0
- package/src/files.ts +195 -0
- package/src/internal/ab-collector.ts +2 -2
- package/src/internal/ab-fold.ts +1 -1
- package/src/internal/cli-ax.ts +2 -2
- package/src/internal/cli-deploy.ts +7 -2
- package/src/internal/cli-docs.ts +1 -1
- package/src/internal/cli-github.ts +13 -13
- package/src/internal/cli-mcp-oauth.ts +2 -2
- package/src/internal/cli-mcp.ts +4 -4
- package/src/internal/cli-skills.ts +1 -1
- package/src/internal/cloud-turn-cost.ts +20 -4
- package/src/internal/cursor/account-mcp.ts +5 -5
- package/src/internal/cursor/backend-client.ts +1 -1
- package/src/internal/cursor/github-credentials.ts +3 -3
- package/src/internal/cursor-account-mcp-auth.ts +1 -1
- package/src/internal/cursor-event-relay.ts +1 -1
- package/src/internal/cursor-relay-core.ts +1 -1
- package/src/internal/cursor-slack-relay.ts +1 -1
- package/src/internal/deploy-client.ts +8 -2
- package/src/internal/deploy-source.ts +2 -2
- package/src/internal/discovery.ts +2 -2
- package/src/internal/distribution.ts +6 -6
- package/src/internal/docs-site.ts +5 -5
- package/src/internal/eval-run-store.ts +8 -8
- package/src/internal/evals-client.ts +1 -1
- package/src/internal/github-fanout.ts +2 -2
- package/src/internal/host-files.ts +372 -0
- package/src/internal/host-platforms.ts +5 -5
- package/src/internal/hosting.ts +1 -1
- package/src/internal/http-channel.ts +30 -0
- package/src/internal/install-cursor-skills.ts +31 -3
- package/src/internal/local-control-plane.ts +2 -2
- package/src/internal/logs-client.ts +2 -2
- package/src/internal/mcp-endpoint.ts +1 -1
- package/src/internal/mcp-oauth.ts +2 -2
- package/src/internal/platform-schedule-sync.ts +2 -2
- package/src/internal/playground/toolchain.ts +6 -6
- package/src/internal/reminder-runner.ts +13 -13
- package/src/internal/resolved-connections.ts +6 -6
- package/src/internal/schedule-runner.ts +1 -1
- package/src/internal/sdk-runner.ts +5 -5
- package/src/internal/server.ts +16 -16
- package/src/internal/session-cost.ts +7 -6
- package/src/internal/session-engine.ts +141 -28
- package/src/internal/slack-provision-client.ts +1 -1
- package/src/internal/storage-coordinator.ts +7 -7
- package/src/internal/trajectory.ts +2 -2
- package/src/internal/turn-cost.ts +110 -0
- package/src/internal/update-check.ts +6 -6
- package/src/memory.ts +1 -1
- package/src/storage.ts +1 -1
- package/src/types.ts +148 -16
- package/dist/docs/assets/building-with-agents.md.CJCtZCyi.js +0 -13
- package/dist/docs/assets/chunks/@localSearchIndexroot.DGe61XHA.js +0 -1
- package/dist/docs/assets/concepts.md.Cfb9b-k1.js +0 -4
- package/dist/docs/assets/concepts.md.Cfb9b-k1.lean.js +0 -1
- package/dist/docs/assets/deployment.md.TecHo0_2.js +0 -55
- package/dist/docs/assets/deployment.md.TecHo0_2.lean.js +0 -1
- package/dist/docs/assets/evals.md.DYOjkRCX.lean.js +0 -1
- package/dist/docs/assets/example-agents_benny.md.B0gjhI-p.js +0 -7
- package/dist/docs/assets/example-agents_index.md.D2PEVSXl.js +0 -2
- package/dist/docs/assets/example-agents_index.md.D2PEVSXl.lean.js +0 -1
- package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.js +0 -10
- package/dist/docs/assets/example-agents_slack-agent.md.buLbgvBf.js +0 -5
- package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.js +0 -24
- package/dist/docs/assets/example-agents_weather-agent.md.C9Qv-W0o.lean.js +0 -1
- package/dist/docs/assets/guides_cloud-runtime.md.gVzabdQL.js +0 -9
- package/dist/docs/assets/guides_mcp-oauth.md.Dd8EgSem.lean.js +0 -1
- package/dist/docs/assets/guides_slack.md.CjmJSvZS.js +0 -42
- package/dist/docs/assets/guides_slack.md.CjmJSvZS.lean.js +0 -1
- package/dist/docs/assets/index.md.CH_s5uZe.js +0 -20
- package/dist/docs/assets/index.md.CH_s5uZe.lean.js +0 -1
- package/dist/docs/assets/reference_cli.md.ccoKOoXt.js +0 -65
- package/dist/docs/assets/reference_http-api.md.BncLd3PZ.js +0 -11
- package/dist/docs/assets/storage.md.DRTdnFvd.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.CmQkmnzC.js +0 -1
- package/dist/internal/model-pricing.d.ts +0 -49
- package/dist/internal/model-pricing.d.ts.map +0 -1
- package/dist/internal/model-pricing.js +0 -377
- package/dist/playground/assets/index-CquRB-l0.js +0 -85
- package/dist/playground/assets/index-Dj0bWpkn.css +0 -1
- package/src/internal/model-pricing.ts +0 -426
- /package/dist/docs/assets/{example-agents_benny.md.B0gjhI-p.lean.js → example-agents_benny.md.2Et1qa8f.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_bugbot.md.DelIdhxB.lean.js → example-agents_bugbot.md.ByUexi5i.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_concierge.md.4rQTSMXt.lean.js → example-agents_concierge.md.lL8rhYlj.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_fsd.md.CzgUrDfi.lean.js → example-agents_fsd.md.DfNKQTHz.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_oncall.md.BG_sUMly.lean.js → example-agents_oncall.md.wFFXXEyW.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_security-reviewer.md.Dhj_m7_B.lean.js → example-agents_security-reviewer.md.Dkf1gyo6.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_slack-agent.md.buLbgvBf.lean.js → example-agents_slack-agent.md.DvgvT4nn.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.Bpzgq2Pq.lean.js → guides_agent-to-agent.md.Bmbxy-FA.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.gVzabdQL.lean.js → guides_cloud-runtime.md.BZ2GA7Es.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.DOOCpqsW.lean.js → guides_github.md.R2QlpR75.lean.js} +0 -0
- /package/dist/docs/assets/{guides_human-in-the-loop.md.DlUqsp1S.lean.js → guides_human-in-the-loop.md.BWvT7UqY.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.wSOYas3X.lean.js → guides_webhooks.md.DiAwSR42.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.DHNast08.lean.js → hillclimbing.md.D9Y1_bYh.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.BU6Iwi_9.lean.js → quickstart.md.TnEXYgYW.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.DrW2JUM8.lean.js → reference_agent-config.md.kuN6-OxK.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.B9Q3TOve.lean.js → reference_connections.md.DGqAsFXb.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.BncLd3PZ.lean.js → reference_http-api.md.CfVM_ICa.lean.js} +0 -0
- /package/dist/docs/assets/{reference_schedules.md.w_F2mXB6.lean.js → reference_schedules.md.gmfYzf_I.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.DLd6mvbv.lean.js → reference_sessions.md.C_ouF_uf.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.BRSDnTbN.lean.js → reference_tools.md.BswAQM41.lean.js} +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local-disk file sink: one file per key under a directory you own.
|
|
3
|
+
*
|
|
4
|
+
* The default off Cursor-managed hosting. Paths are real, so the harness can
|
|
5
|
+
* open a file with its ordinary tools — that is why this reports
|
|
6
|
+
* `materialized` — and there are no etags, so `conflictDetection` is honestly
|
|
7
|
+
* false and concurrent writers are last-writer-wins.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { randomUUID } from "node:crypto";
|
|
11
|
+
import {
|
|
12
|
+
mkdir,
|
|
13
|
+
readdir,
|
|
14
|
+
readFile,
|
|
15
|
+
rename,
|
|
16
|
+
rm,
|
|
17
|
+
stat,
|
|
18
|
+
writeFile,
|
|
19
|
+
} from "node:fs/promises";
|
|
20
|
+
import { join, relative, resolve, sep } from "node:path";
|
|
21
|
+
import {
|
|
22
|
+
FilePathRejectedError,
|
|
23
|
+
type FileSink,
|
|
24
|
+
type FileSinkBody,
|
|
25
|
+
type FileSinkEntry,
|
|
26
|
+
} from "../files.js";
|
|
27
|
+
|
|
28
|
+
export interface LocalFilesOptions {
|
|
29
|
+
/** Directory the sink owns. */
|
|
30
|
+
filesRoot: string;
|
|
31
|
+
/**
|
|
32
|
+
* Prefix trimmed off each key before building the on-disk path, so the tree
|
|
33
|
+
* reads `deployment/notes.md` instead of repeating the framework key root.
|
|
34
|
+
*
|
|
35
|
+
* Framework-supplied. Authors should omit it: the value has to match the
|
|
36
|
+
* internal key scheme exactly, and a near-miss would silently nest files
|
|
37
|
+
* under a redundant path instead of failing. Omitted, keys are stored
|
|
38
|
+
* verbatim, which is always correct and lets two agents share one root.
|
|
39
|
+
*/
|
|
40
|
+
stripKeyPrefix?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Default sink: one file per key under the state root, written atomically.
|
|
45
|
+
*
|
|
46
|
+
* Reports `materialized` because the paths are real — that is what lets the
|
|
47
|
+
* harness read a file with its ordinary tools — and reports no `etags`, so
|
|
48
|
+
* `host.files.capabilities.conflictDetection` is honestly false and concurrent
|
|
49
|
+
* writers are last-writer-wins.
|
|
50
|
+
*/
|
|
51
|
+
export function localFiles(options: LocalFilesOptions): FileSink {
|
|
52
|
+
const root = resolve(options.filesRoot);
|
|
53
|
+
|
|
54
|
+
const stripPrefix = options.stripKeyPrefix ?? "";
|
|
55
|
+
const pathForKey = (key: string): string => {
|
|
56
|
+
const rel =
|
|
57
|
+
stripPrefix !== "" && key.startsWith(stripPrefix)
|
|
58
|
+
? key.slice(stripPrefix.length)
|
|
59
|
+
: key;
|
|
60
|
+
const candidate = resolve(root, rel);
|
|
61
|
+
const within = relative(root, candidate);
|
|
62
|
+
if (within === "" || within === ".." || within.startsWith(`..${sep}`)) {
|
|
63
|
+
throw new FilePathRejectedError(
|
|
64
|
+
`host.files key does not resolve under the state root: ${key}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return candidate;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const entryFor = async (
|
|
71
|
+
key: string,
|
|
72
|
+
absPath: string
|
|
73
|
+
): Promise<FileSinkEntry | undefined> => {
|
|
74
|
+
try {
|
|
75
|
+
const info = await stat(absPath);
|
|
76
|
+
if (!info.isFile()) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
return { key, size: info.size, mtimeMs: info.mtimeMs };
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
capabilities: { materialized: true },
|
|
90
|
+
|
|
91
|
+
materializedPath: (key) => pathForKey(key),
|
|
92
|
+
|
|
93
|
+
async put(key, body): Promise<void> {
|
|
94
|
+
const target = pathForKey(key);
|
|
95
|
+
await mkdir(join(target, ".."), { recursive: true });
|
|
96
|
+
// Same-directory temp + rename: a reader either sees the previous value
|
|
97
|
+
// or the whole new one, never a half-written file.
|
|
98
|
+
const tmp = join(target, "..", `.tmp-${randomUUID()}`);
|
|
99
|
+
try {
|
|
100
|
+
await writeFile(tmp, body);
|
|
101
|
+
await rename(tmp, target);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
await rm(tmp, { force: true });
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
async get(key): Promise<FileSinkBody | undefined> {
|
|
109
|
+
try {
|
|
110
|
+
return { body: new Uint8Array(await readFile(pathForKey(key))) };
|
|
111
|
+
} catch (error) {
|
|
112
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
113
|
+
if (code === "ENOENT" || code === "EISDIR") {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
async delete(key): Promise<void> {
|
|
121
|
+
await rm(pathForKey(key), { force: true });
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
async stat(key): Promise<FileSinkEntry | undefined> {
|
|
125
|
+
return await entryFor(key, pathForKey(key));
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
async list(prefix): Promise<FileSinkEntry[]> {
|
|
129
|
+
// Walk the deepest existing directory at or above the prefix, then keep
|
|
130
|
+
// the keys that actually start with it — `prefix` is a key prefix, not a
|
|
131
|
+
// directory, so `notes/sum` must match `notes/summary.md`.
|
|
132
|
+
const prefixPath = pathForKey(prefix);
|
|
133
|
+
const searchRoot = (await isDirectory(prefixPath))
|
|
134
|
+
? prefixPath
|
|
135
|
+
: join(prefixPath, "..");
|
|
136
|
+
const out: FileSinkEntry[] = [];
|
|
137
|
+
for await (const absPath of walkFiles(searchRoot)) {
|
|
138
|
+
const key = `${stripPrefix}${relative(root, absPath).split(sep).join("/")}`;
|
|
139
|
+
if (!key.startsWith(prefix)) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const entry = await entryFor(key, absPath);
|
|
143
|
+
if (entry !== undefined) {
|
|
144
|
+
out.push(entry);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return out.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function isDirectory(absPath: string): Promise<boolean> {
|
|
153
|
+
try {
|
|
154
|
+
return (await stat(absPath)).isDirectory();
|
|
155
|
+
} catch {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function* walkFiles(dir: string): AsyncGenerator<string> {
|
|
161
|
+
let entries: Awaited<ReturnType<typeof readdir>>;
|
|
162
|
+
try {
|
|
163
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
164
|
+
} catch (error) {
|
|
165
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
for (const entry of entries) {
|
|
171
|
+
const abs = join(dir, entry.name);
|
|
172
|
+
if (entry.isDirectory()) {
|
|
173
|
+
yield* walkFiles(abs);
|
|
174
|
+
} else if (entry.isFile() && !entry.name.startsWith(".tmp-")) {
|
|
175
|
+
yield abs;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
package/src/files.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The internal sink contract behind `ctx.host.files` — durable, file-shaped
|
|
3
|
+
* state that must outlive the engine process.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately **not a filesystem**: no file descriptors, no seeking, no
|
|
6
|
+
* rename, no directories as first-class objects, and no POSIX errno contract
|
|
7
|
+
* — a sink that is an HTTP API can implement all of it. The framework
|
|
8
|
+
* **mints every key** from a stable, versioned scheme (see {@link fileKeys});
|
|
9
|
+
* sinks see opaque strings and never learn which deployment or session a key
|
|
10
|
+
* belongs to, which is what keeps one deployment's files unreachable from
|
|
11
|
+
* another's.
|
|
12
|
+
*
|
|
13
|
+
* Internal for now: the authored plug-in surface (`agent/files.ts` with a
|
|
14
|
+
* `defineFiles`, mirroring `defineStorage`) is deliberately deferred so this
|
|
15
|
+
* ships as exactly the hosted connector plus the local default. When it
|
|
16
|
+
* lands, {@link FileSink} is the contract authored sinks implement.
|
|
17
|
+
*
|
|
18
|
+
* Delivery semantics differ from {@link import("./storage.js").defineStorage}
|
|
19
|
+
* on purpose. Storage is a fire-and-forget mirror of framework state, so a
|
|
20
|
+
* throwing `put` is logged and dropped. Files are author data the next turn
|
|
21
|
+
* may depend on, so {@link HostFilesApi} writes are **awaited and surface
|
|
22
|
+
* their failure** — an author who writes evidence and then delegates has to
|
|
23
|
+
* know the write did not land.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { STORAGE_KEY_ROOT } from "./storage.js";
|
|
27
|
+
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Sink interface
|
|
30
|
+
// ============================================================================
|
|
31
|
+
|
|
32
|
+
/** One entry returned by {@link FileSink.list}. */
|
|
33
|
+
export interface FileSinkEntry {
|
|
34
|
+
/** Framework-minted key, as passed to {@link FileSink.put}. */
|
|
35
|
+
key: string;
|
|
36
|
+
size: number;
|
|
37
|
+
/** Last-modified epoch ms, when the sink tracks one. */
|
|
38
|
+
mtimeMs?: number;
|
|
39
|
+
/** Opaque version tag; required for `ifMatch` to be usable. */
|
|
40
|
+
etag?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** One stored value plus the version it was read at. */
|
|
44
|
+
export interface FileSinkBody {
|
|
45
|
+
body: Uint8Array;
|
|
46
|
+
etag?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Outcome of {@link FileSink.put}. */
|
|
50
|
+
export interface FileSinkPutResult {
|
|
51
|
+
/** Version tag after the write, when the sink issues one. */
|
|
52
|
+
etag?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* What a sink can do beyond the four required calls. Absent flags are false,
|
|
57
|
+
* so the narrowest possible sink — four functions over an HTTP API — is valid
|
|
58
|
+
* and the framework degrades visibly rather than assuming.
|
|
59
|
+
*/
|
|
60
|
+
export interface FileSinkCapabilities {
|
|
61
|
+
/**
|
|
62
|
+
* `put` honors `ifMatch` and rejects a stale write. Required for
|
|
63
|
+
* {@link HostFilesApi} to report `conflictDetection`.
|
|
64
|
+
*/
|
|
65
|
+
etags?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* The sink keeps a local copy at {@link FileSink.materializedPath} that the
|
|
68
|
+
* harness can read with ordinary file tools.
|
|
69
|
+
*/
|
|
70
|
+
materialized?: boolean;
|
|
71
|
+
/** Largest value the sink accepts, in bytes. */
|
|
72
|
+
maxBytes?: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The pluggable file store. Keys are framework-minted opaque strings; a sink
|
|
77
|
+
* may treat them as flat keys or split on `/` to build a hierarchy.
|
|
78
|
+
*/
|
|
79
|
+
export interface FileSink {
|
|
80
|
+
/**
|
|
81
|
+
* Write or replace one value. When `ifMatch` is set and the sink reports
|
|
82
|
+
* {@link FileSinkCapabilities.etags}, the write must fail unless the stored
|
|
83
|
+
* version matches — throw {@link FileConflictError} to say so precisely.
|
|
84
|
+
* `ifMatch: null` means "must not already exist".
|
|
85
|
+
*/
|
|
86
|
+
put(
|
|
87
|
+
key: string,
|
|
88
|
+
body: Uint8Array,
|
|
89
|
+
options?: { ifMatch?: string | null }
|
|
90
|
+
): Promise<FileSinkPutResult | void>;
|
|
91
|
+
/** Read one value. Miss → `undefined`. */
|
|
92
|
+
get(key: string): Promise<FileSinkBody | Uint8Array | undefined>;
|
|
93
|
+
/** Remove one key. No-op when missing. */
|
|
94
|
+
delete(key: string): Promise<void>;
|
|
95
|
+
/** Entries whose key starts with `prefix`, in key order. */
|
|
96
|
+
list(prefix: string): Promise<FileSinkEntry[]>;
|
|
97
|
+
/** Per-key metadata without transferring the body. Optional; `list` is the fallback. */
|
|
98
|
+
stat?(key: string): Promise<FileSinkEntry | undefined>;
|
|
99
|
+
/**
|
|
100
|
+
* Absolute path of the sink's local copy of `key`, or `undefined` when it
|
|
101
|
+
* keeps none. Only consulted when
|
|
102
|
+
* {@link FileSinkCapabilities.materialized} is set.
|
|
103
|
+
*/
|
|
104
|
+
materializedPath?(key: string): string | undefined;
|
|
105
|
+
capabilities?: FileSinkCapabilities;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// Key scheme
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The framework-owned file key scheme, a stable versioned contract under
|
|
114
|
+
* {@link STORAGE_KEY_ROOT}. Sinks may treat these as opaque, or route on
|
|
115
|
+
* prefixes.
|
|
116
|
+
*
|
|
117
|
+
* | Key | Holds |
|
|
118
|
+
* | --- | --- |
|
|
119
|
+
* | `agentkit/v1/{agent}/files/deployment/{path}` | Deployment-scoped file, shared by every session and surviving redeploys |
|
|
120
|
+
* | `agentkit/v1/{agent}/files/deployment/{partition}/{path}` | Deployment-scoped file under an author partition (a PR, a customer, a branch) |
|
|
121
|
+
* | `agentkit/v1/{agent}/files/sessions/{sessionId}/{path}` | Session-scoped file |
|
|
122
|
+
*
|
|
123
|
+
* Scoping lives here, above the sink, so a sink cannot be handed a key for a
|
|
124
|
+
* deployment or session other than its own.
|
|
125
|
+
*/
|
|
126
|
+
export const fileKeys = {
|
|
127
|
+
deployment: (agent: string, path: string): string =>
|
|
128
|
+
`${STORAGE_KEY_ROOT}/${agent}/files/deployment/${path}`,
|
|
129
|
+
deploymentPartition: (
|
|
130
|
+
agent: string,
|
|
131
|
+
partition: string,
|
|
132
|
+
path: string
|
|
133
|
+
): string =>
|
|
134
|
+
`${STORAGE_KEY_ROOT}/${agent}/files/deployment/${partition}/${path}`,
|
|
135
|
+
session: (agent: string, sessionId: string, path: string): string =>
|
|
136
|
+
`${STORAGE_KEY_ROOT}/${agent}/files/sessions/${sessionId}/${path}`,
|
|
137
|
+
deploymentPrefix: (agent: string): string =>
|
|
138
|
+
`${STORAGE_KEY_ROOT}/${agent}/files/deployment/`,
|
|
139
|
+
sessionPrefix: (agent: string, sessionId: string): string =>
|
|
140
|
+
`${STORAGE_KEY_ROOT}/${agent}/files/sessions/${sessionId}/`,
|
|
141
|
+
} as const;
|
|
142
|
+
|
|
143
|
+
/** Errors raised by the file surface. Thrown by sinks and by the framework. */
|
|
144
|
+
export class FileConflictError extends Error {
|
|
145
|
+
constructor(
|
|
146
|
+
readonly key: string,
|
|
147
|
+
options?: { cause?: unknown; storedEtag?: string }
|
|
148
|
+
) {
|
|
149
|
+
super(
|
|
150
|
+
`host.files write for "${key}" lost a race with another writer${
|
|
151
|
+
options?.storedEtag === undefined
|
|
152
|
+
? ""
|
|
153
|
+
: ` (stored version ${options.storedEtag})`
|
|
154
|
+
}`
|
|
155
|
+
);
|
|
156
|
+
this.name = "FileConflictError";
|
|
157
|
+
if (options?.cause !== undefined) {
|
|
158
|
+
this.cause = options.cause;
|
|
159
|
+
}
|
|
160
|
+
if (options?.storedEtag !== undefined) {
|
|
161
|
+
this.storedEtag = options.storedEtag;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
storedEtag?: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** A path the framework refuses to mint a key for. */
|
|
168
|
+
export class FilePathRejectedError extends Error {
|
|
169
|
+
constructor(message: string) {
|
|
170
|
+
super(message);
|
|
171
|
+
this.name = "FilePathRejectedError";
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** A session-scoped call with no session in scope. */
|
|
176
|
+
export class FileSessionRequiredError extends Error {
|
|
177
|
+
constructor(message: string) {
|
|
178
|
+
super(message);
|
|
179
|
+
this.name = "FileSessionRequiredError";
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** A value larger than the sink accepts. */
|
|
184
|
+
export class FileTooLargeError extends Error {
|
|
185
|
+
constructor(
|
|
186
|
+
readonly key: string,
|
|
187
|
+
readonly size: number,
|
|
188
|
+
readonly maxBytes: number
|
|
189
|
+
) {
|
|
190
|
+
super(
|
|
191
|
+
`host.files value for "${key}" is ${size} bytes, over the sink's ${maxBytes}-byte limit`
|
|
192
|
+
);
|
|
193
|
+
this.name = "FileTooLargeError";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -147,7 +147,7 @@ export class ABCollector {
|
|
|
147
147
|
},
|
|
148
148
|
(key, error) => {
|
|
149
149
|
this.logger(
|
|
150
|
-
`[
|
|
150
|
+
`[agent-sdk] ab "${experiment.name}" derive.${key} threw: ${describeError(error)}`
|
|
151
151
|
);
|
|
152
152
|
}
|
|
153
153
|
);
|
|
@@ -174,7 +174,7 @@ export class ABCollector {
|
|
|
174
174
|
await def.onSample(sample);
|
|
175
175
|
} catch (error) {
|
|
176
176
|
this.logger(
|
|
177
|
-
`[
|
|
177
|
+
`[agent-sdk] ab "${experiment.name}" onSample threw: ${describeError(error)}`
|
|
178
178
|
);
|
|
179
179
|
}
|
|
180
180
|
this.persistSample?.(sample);
|
package/src/internal/ab-fold.ts
CHANGED
|
@@ -161,7 +161,7 @@ export async function applyABDerive(
|
|
|
161
161
|
ctx,
|
|
162
162
|
(key, error) => {
|
|
163
163
|
logger(
|
|
164
|
-
`[
|
|
164
|
+
`[agent-sdk] ab "${experiment.name}" derive.${key} threw: ${describeError(error)}`
|
|
165
165
|
);
|
|
166
166
|
}
|
|
167
167
|
);
|
package/src/internal/cli-ax.ts
CHANGED
|
@@ -1863,8 +1863,8 @@ const COST_FETCH_CONCURRENCY = 4;
|
|
|
1863
1863
|
* With a session id: per-turn token usage + estimated cost for that session.
|
|
1864
1864
|
* Without one: one row per session (all sessions on the target) plus a
|
|
1865
1865
|
* total row. `--json` prints the underlying report(s); text is the default.
|
|
1866
|
-
* Costs are
|
|
1867
|
-
* (
|
|
1866
|
+
* Costs are recorded on `turn.completed` via `POST /v1/models/estimate-cost`
|
|
1867
|
+
* (billed usage when available). Turns persisted before cost tracking simply
|
|
1868
1868
|
* count as unpriced.
|
|
1869
1869
|
*/
|
|
1870
1870
|
export async function cmdCost(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `
|
|
2
|
+
* `agent-sdk deploy | deployments | deployment | stop | rotate-token |
|
|
3
3
|
* rotate-pod-credential | secrets set|list|unset` — Heroku-style deploys
|
|
4
4
|
* onto Cursor's managed agent-serve hosting.
|
|
5
5
|
*
|
|
@@ -554,7 +554,7 @@ async function deployOne(
|
|
|
554
554
|
const { dir, slug } = target;
|
|
555
555
|
|
|
556
556
|
// Fill --repo/--ref/--path from the local git checkout when omitted so
|
|
557
|
-
// `
|
|
557
|
+
// `agent-sdk deploy` inside an agent directory is enough. Only probe git
|
|
558
558
|
// for real agent projects (avoids ambient monorepo remotes when someone
|
|
559
559
|
// deploys a bare --slug). Explicit flags always win.
|
|
560
560
|
const isAgent = await isAgentProjectDir(dir);
|
|
@@ -968,6 +968,11 @@ export async function cmdDeploymentStatus(
|
|
|
968
968
|
) {
|
|
969
969
|
lines.push(` service account: ${detail.serviceAccountId}`);
|
|
970
970
|
}
|
|
971
|
+
if (detail.agentStoreSourceId !== undefined) {
|
|
972
|
+
// The durable file store's address: GET /v0/agent-serve-files/<id> lists
|
|
973
|
+
// it, and the pod sees it as AGENT_SERVE_STORE_SOURCE_ID.
|
|
974
|
+
lines.push(` file store: ${detail.agentStoreSourceId}`);
|
|
975
|
+
}
|
|
971
976
|
if (
|
|
972
977
|
detail.egressAllowedDomains !== undefined &&
|
|
973
978
|
detail.egressAllowedDomains.length > 0
|
package/src/internal/cli-docs.ts
CHANGED
|
@@ -196,7 +196,7 @@ async function cmdGithubForward(options: GithubCliOptions): Promise<number> {
|
|
|
196
196
|
);
|
|
197
197
|
return 1;
|
|
198
198
|
}
|
|
199
|
-
process.stderr.write(`[
|
|
199
|
+
process.stderr.write(`[agent-sdk] inferred --repo ${repo}\n`);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
const secret = options.secret ?? process.env.GITHUB_WEBHOOK_SECRET;
|
|
@@ -219,30 +219,30 @@ async function cmdGithubForward(options: GithubCliOptions): Promise<number> {
|
|
|
219
219
|
});
|
|
220
220
|
|
|
221
221
|
process.stderr.write(
|
|
222
|
-
`[
|
|
222
|
+
`[agent-sdk] forwarding ${org !== undefined ? `org ${org}` : `repo ${repo}`} to ${targets.length} channel${targets.length === 1 ? "" : "s"}:\n`
|
|
223
223
|
);
|
|
224
224
|
for (const target of targets) {
|
|
225
225
|
process.stderr.write(
|
|
226
|
-
`[
|
|
226
|
+
`[agent-sdk] → ${targetLabel(target)} ${target.url} (${target.events.join(", ")})\n`
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
if (fanout) {
|
|
230
230
|
process.stderr.write(
|
|
231
|
-
`[
|
|
231
|
+
`[agent-sdk] fan-out proxy on ${forwardUrl} (union events: ${events.join(", ")})\n`
|
|
232
232
|
);
|
|
233
233
|
}
|
|
234
234
|
if (secret === undefined || secret === "") {
|
|
235
235
|
process.stderr.write(
|
|
236
|
-
"[
|
|
236
|
+
"[agent-sdk] no signing secret — deliveries are unsigned. A `serve --dev` github channel accepts them; set GITHUB_WEBHOOK_SECRET on both sides to verify signatures (required for a non-dev target).\n"
|
|
237
237
|
);
|
|
238
238
|
}
|
|
239
239
|
const envToken = detectGitHubEnvTokenOverride();
|
|
240
240
|
if (envToken !== undefined) {
|
|
241
241
|
process.stderr.write(
|
|
242
|
-
`[
|
|
242
|
+
`[agent-sdk] warning: ${githubEnvTokenHint(envToken)}\n`
|
|
243
243
|
);
|
|
244
244
|
}
|
|
245
|
-
process.stderr.write(`[
|
|
245
|
+
process.stderr.write(`[agent-sdk] running: gh ${redact(args)}\n`);
|
|
246
246
|
|
|
247
247
|
try {
|
|
248
248
|
return await spawnGh(args);
|
|
@@ -318,7 +318,7 @@ async function cmdGithubReplay(options: GithubCliOptions): Promise<number> {
|
|
|
318
318
|
);
|
|
319
319
|
if (unsupported.length > 0) {
|
|
320
320
|
process.stderr.write(
|
|
321
|
-
`[
|
|
321
|
+
`[agent-sdk] cannot synthesize (skipped): ${unsupported.join(", ")}\n`
|
|
322
322
|
);
|
|
323
323
|
}
|
|
324
324
|
if (eventsToReplay.length === 0) {
|
|
@@ -364,7 +364,7 @@ async function cmdGithubReplay(options: GithubCliOptions): Promise<number> {
|
|
|
364
364
|
check,
|
|
365
365
|
});
|
|
366
366
|
if ("error" in result) {
|
|
367
|
-
process.stderr.write(`[
|
|
367
|
+
process.stderr.write(`[agent-sdk] skipping ${event}: ${result.error}\n`);
|
|
368
368
|
continue;
|
|
369
369
|
}
|
|
370
370
|
synthesized.push(result);
|
|
@@ -376,7 +376,7 @@ async function cmdGithubReplay(options: GithubCliOptions): Promise<number> {
|
|
|
376
376
|
|
|
377
377
|
const secret = options.secret ?? process.env.GITHUB_WEBHOOK_SECRET;
|
|
378
378
|
process.stderr.write(
|
|
379
|
-
`[
|
|
379
|
+
`[agent-sdk] replaying ${ref.label} (${synthesized
|
|
380
380
|
.map((s) => s.eventName)
|
|
381
381
|
.join(
|
|
382
382
|
", "
|
|
@@ -399,7 +399,7 @@ async function cmdGithubReplay(options: GithubCliOptions): Promise<number> {
|
|
|
399
399
|
|
|
400
400
|
if (options.out !== undefined) {
|
|
401
401
|
const file = await writeReplayFixture(options.out, event);
|
|
402
|
-
process.stderr.write(`[
|
|
402
|
+
process.stderr.write(`[agent-sdk] wrote ${file}\n`);
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
const label = eventLabel(event);
|
|
@@ -434,7 +434,7 @@ async function cmdGithubReplay(options: GithubCliOptions): Promise<number> {
|
|
|
434
434
|
`${delivery.label} ${delivery.status || "ERR"}${delivery.ok ? "" : " (rejected)"}`
|
|
435
435
|
)
|
|
436
436
|
.join(", ") || "(no matching channel)";
|
|
437
|
-
process.stderr.write(`[
|
|
437
|
+
process.stderr.write(`[agent-sdk] ${label} → ${summary}\n`);
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
|
|
@@ -745,7 +745,7 @@ async function ensureWebhookExtension(
|
|
|
745
745
|
};
|
|
746
746
|
}
|
|
747
747
|
process.stderr.write(
|
|
748
|
-
`[
|
|
748
|
+
`[agent-sdk] installing ${GITHUB_WEBHOOK_EXTENSION}@${GITHUB_WEBHOOK_EXTENSION_PIN}…\n`
|
|
749
749
|
);
|
|
750
750
|
if (
|
|
751
751
|
(await tryExec({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `
|
|
2
|
+
* `agent-sdk mcp oauth <connection> [--store]`.
|
|
3
3
|
*
|
|
4
4
|
* Host MCP OAuth for `defineConnection({ url, oauth: true })` (local tokens,
|
|
5
5
|
* optionally stored as deployment secrets), and service-account connector
|
|
@@ -109,7 +109,7 @@ export async function cmdMcpOauth(
|
|
|
109
109
|
},
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
-
const client = new Client({ name: "
|
|
112
|
+
const client = new Client({ name: "agent-sdk-mcp-oauth", version: "0.1.0" });
|
|
113
113
|
const url = new URL(transport.url);
|
|
114
114
|
const requestInit =
|
|
115
115
|
transport.headers === undefined
|
package/src/internal/cli-mcp.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `
|
|
2
|
+
* `agent-sdk mcp` — stdio ↔ streamable-HTTP proxy for an agent's MCP endpoint.
|
|
3
3
|
*
|
|
4
4
|
* Every served agent is an MCP server at `<base>/v1/mcp` (hosted deployments
|
|
5
5
|
* run in single mode, so the endpoint sits directly on the engine base URL).
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
* - `--url <baseUrl>` — a running server (local `serve` mount or self-hosted
|
|
16
16
|
* base URL), with optional `--bearer-token`.
|
|
17
17
|
*
|
|
18
|
-
* `
|
|
18
|
+
* `agent-sdk mcp install` writes the matching entry into `~/.cursor/mcp.json`
|
|
19
19
|
* so the agent shows up as an MCP server in Cursor:
|
|
20
20
|
*
|
|
21
21
|
* { "mcpServers": { "weather-agent": {
|
|
22
|
-
* "command": "
|
|
22
|
+
* "command": "agent-sdk",
|
|
23
23
|
* "args": ["mcp", "--prod", "--slug", "weather-agent"] } } }
|
|
24
24
|
*
|
|
25
25
|
* stdout is reserved for the MCP wire in serve mode; all logging goes to
|
|
@@ -620,7 +620,7 @@ export async function cmdMcpInstall(options: McpCliOptions): Promise<number> {
|
|
|
620
620
|
* engineAccess server-side, so the entry never carries a pod hostname or a
|
|
621
621
|
* short-lived port token — only the durable, stable gateway URL.
|
|
622
622
|
*
|
|
623
|
-
* Auth: this headless/CLI entry sends the `
|
|
623
|
+
* Auth: this headless/CLI entry sends the `agent-sdk login` API key as a
|
|
624
624
|
* bearer against the user-API-key gateway surface. That key is written to
|
|
625
625
|
* `mcp.json` in plain text (flagged below); a signed-in Cursor client
|
|
626
626
|
* (Glass) can instead use the session gateway surface with no header at all
|
|
@@ -60,7 +60,7 @@ export async function cmdInstallSkills(
|
|
|
60
60
|
return 0;
|
|
61
61
|
}
|
|
62
62
|
const action = plan.firstInstall ? "install" : "update";
|
|
63
|
-
out(`Would ${action} ${plan.leaves.length}
|
|
63
|
+
out(`Would ${action} ${plan.leaves.length} Agent SDK ${noun}\n`);
|
|
64
64
|
out(previewBlock(plan));
|
|
65
65
|
return 0;
|
|
66
66
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Recover token usage /
|
|
2
|
+
* Recover token usage / billed cost for cloud turns that finished without
|
|
3
3
|
* either field on `turn.completed`.
|
|
4
4
|
*
|
|
5
5
|
* Cloud `run.wait()` often drops streamed usage after SSE reconnect, and
|
|
@@ -14,15 +14,17 @@ import type {
|
|
|
14
14
|
TurnCost,
|
|
15
15
|
TurnUsage,
|
|
16
16
|
} from "../types.js";
|
|
17
|
-
import {
|
|
17
|
+
import { modelSettingId, turnCostFromCents } from "./turn-cost.js";
|
|
18
18
|
|
|
19
19
|
export interface CloudRunUsage {
|
|
20
20
|
runId: string;
|
|
21
21
|
usage: TurnUsage;
|
|
22
|
+
cost?: { rawCostCents: number; chargedCents: number };
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export interface CloudAgentUsage {
|
|
25
26
|
usage: TurnUsage;
|
|
27
|
+
cost?: { rawCostCents: number; chargedCents: number };
|
|
26
28
|
runs: CloudRunUsage[];
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -100,7 +102,7 @@ export function applyCloudUsageToEvents(
|
|
|
100
102
|
if (index !== undefined) {
|
|
101
103
|
patches.set(index, {
|
|
102
104
|
usage: billed.usage,
|
|
103
|
-
cost:
|
|
105
|
+
cost: turnCostFromBilled(model, billed.cost),
|
|
104
106
|
});
|
|
105
107
|
}
|
|
106
108
|
} else if (
|
|
@@ -115,7 +117,7 @@ export function applyCloudUsageToEvents(
|
|
|
115
117
|
}
|
|
116
118
|
patches.set(index, {
|
|
117
119
|
usage: run.usage,
|
|
118
|
-
cost:
|
|
120
|
+
cost: turnCostFromBilled(model, run.cost),
|
|
119
121
|
});
|
|
120
122
|
}
|
|
121
123
|
} else {
|
|
@@ -138,6 +140,20 @@ export function applyCloudUsageToEvents(
|
|
|
138
140
|
});
|
|
139
141
|
}
|
|
140
142
|
|
|
143
|
+
function turnCostFromBilled(
|
|
144
|
+
model: ModelSetting,
|
|
145
|
+
cost: { rawCostCents: number; chargedCents: number } | undefined
|
|
146
|
+
): TurnCost | undefined {
|
|
147
|
+
if (cost === undefined) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
return turnCostFromCents({
|
|
151
|
+
model: modelSettingId(model),
|
|
152
|
+
cost,
|
|
153
|
+
source: "usage",
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
export function mapSdkTokenUsage(usage: {
|
|
142
158
|
inputTokens: number;
|
|
143
159
|
outputTokens: number;
|