@cursor/july 0.1.100 → 0.1.102
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 +27 -0
- package/dist/bin/agent-serve.js +3 -2
- package/dist/channels/deployments/deployments-channel.d.ts +41 -5
- package/dist/channels/deployments/deployments-channel.d.ts.map +1 -1
- package/dist/channels/deployments/deployments-channel.js +88 -8
- package/dist/channels/deployments/types.d.ts +4 -3
- package/dist/channels/deployments/types.d.ts.map +1 -1
- package/dist/channels/origin/defaults.d.ts +43 -0
- package/dist/channels/origin/defaults.d.ts.map +1 -0
- package/dist/channels/origin/defaults.js +111 -0
- package/dist/channels/origin/index.d.ts +2 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +2 -0
- package/dist/channels/origin/origin-channel.d.ts +2 -1
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +24 -3
- package/dist/channels/origin/state.d.ts +32 -0
- package/dist/channels/origin/state.d.ts.map +1 -0
- package/dist/channels/origin/state.js +23 -0
- package/dist/channels/origin/types.d.ts +23 -1
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/api.d.ts +1 -1
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +5 -2
- package/dist/channels/slack/assistant.d.ts +1 -1
- package/dist/channels/slack/assistant.d.ts.map +1 -1
- package/dist/channels/slack/code-fences.d.ts +17 -0
- package/dist/channels/slack/code-fences.d.ts.map +1 -0
- package/dist/channels/slack/code-fences.js +168 -0
- package/dist/channels/slack/dispatch.d.ts +3 -2
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +28 -8
- package/dist/channels/slack/inbound.d.ts +8 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +28 -0
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +11 -4
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +2 -1
- package/dist/connections.d.ts +18 -2
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +18 -2
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.DZ1e0Ycq.js → app.CLA03RCz.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.FAqdWIXo.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.l8omwc6D.js → VPLocalSearchBox.ifxv-cJV.js} +1 -1
- package/dist/docs/assets/chunks/{theme.JVcD6gel.js → theme.DWCwM6p-.js} +2 -2
- package/dist/docs/assets/concepts.md.rPzW2HZN.js +1 -0
- package/dist/docs/assets/guides_cloud-agents.md.DumwWXba.js +9 -0
- package/dist/docs/assets/guides_cloud-agents.md.DumwWXba.lean.js +1 -0
- package/dist/docs/assets/{guides_cloud-runtime.md.CkYbjnAX.js → guides_cloud-runtime.md.BRirbRAN.js} +1 -1
- package/dist/docs/assets/index.md.Kiht7ell.js +5 -0
- package/dist/docs/assets/{index.md.Bb4k8kUm.lean.js → index.md.Kiht7ell.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BiGoBAk2.js → reference_connections.md.Di6jJAXF.js} +12 -2
- package/dist/docs/assets/{reference_connections.md.BiGoBAk2.lean.js → reference_connections.md.Di6jJAXF.lean.js} +1 -1
- package/dist/docs/assets/reference_extensions.md.9WQMZe1l.js +56 -0
- package/dist/docs/assets/reference_extensions.md.9WQMZe1l.lean.js +1 -0
- package/dist/docs/assets/{reference_http-api.md.BEJx9XVj.js → reference_http-api.md.oySXBO8o.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md.Bv4KOtlB.js → reference_project-layout.md.CA6QP6Lw.js} +2 -2
- package/dist/docs/assets/{reference_project-layout.md.Bv4KOtlB.lean.js → reference_project-layout.md.CA6QP6Lw.lean.js} +1 -1
- package/dist/docs/assets/{reference_skills.md.BFW9retM.js → reference_skills.md.l2ezAcaN.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.CvAHsdSp.js → reference_tools.md.B1up2r9W.js} +1 -1
- package/dist/docs/assets/skills_framework-map.md.DDa4MeEW.js +1 -0
- package/dist/docs/assets/{skills_framework-map.md.BTi817yv.lean.js → skills_framework-map.md.DDa4MeEW.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/concepts.md +3 -3
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-agents.html +35 -0
- package/dist/docs/guides/cloud-agents.md +93 -0
- package/dist/docs/guides/cloud-runtime.html +6 -6
- package/dist/docs/guides/cloud-runtime.md +2 -0
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +4 -4
- package/dist/docs/guides/opentelemetry.html +5 -5
- package/dist/docs/guides/slack.html +4 -4
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +5 -1
- package/dist/docs/llms-full.txt +353 -5
- package/dist/docs/llms.txt +2 -0
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +5 -5
- package/dist/docs/reference/cli.html +4 -4
- package/dist/docs/reference/connections.html +16 -6
- package/dist/docs/reference/connections.md +31 -0
- package/dist/docs/reference/extensions.html +82 -0
- package/dist/docs/reference/extensions.md +200 -0
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +1 -1
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +6 -6
- package/dist/docs/reference/project-layout.md +3 -0
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +6 -6
- package/dist/docs/reference/skills.md +2 -0
- package/dist/docs/reference/subagents.html +5 -5
- package/dist/docs/reference/tools.html +6 -6
- package/dist/docs/reference/tools.md +2 -0
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/skills/ab.html +4 -4
- package/dist/docs/skills/create-agent.html +4 -4
- package/dist/docs/skills/debug.html +4 -4
- package/dist/docs/skills/evals.html +4 -4
- package/dist/docs/skills/framework-map.html +5 -5
- package/dist/docs/skills/framework-map.md +1 -0
- package/dist/docs/skills/github.html +4 -4
- package/dist/docs/skills/hillclimb.html +4 -4
- package/dist/docs/skills/index.html +4 -4
- package/dist/docs/skills/mcp-auth.html +4 -4
- package/dist/docs/skills/otel.html +4 -4
- package/dist/docs/skills/setup-slack.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +4 -4
- package/dist/docs/templates/code-wiki.html +4 -4
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +4 -4
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/extensions/cursor-cloud-agents/extension.d.ts +57 -0
- package/dist/extensions/cursor-cloud-agents/extension.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/extension.js +66 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +78 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +286 -0
- package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts +25 -0
- package/dist/extensions/cursor-cloud-agents/lib/fleet.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +85 -0
- package/dist/extensions/cursor-cloud-agents/lib/inputs.d.ts +5 -0
- package/dist/extensions/cursor-cloud-agents/lib/inputs.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/inputs.js +4 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts +15 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +55 -0
- package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts +8 -0
- package/dist/extensions/cursor-cloud-agents/lib/transcript.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +15 -0
- package/dist/extensions/cursor-cloud-agents/skills/handoff.md +41 -0
- package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/cancel.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/cancel.js +26 -0
- package/dist/extensions/cursor-cloud-agents/tools/dump.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/dump.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/dump.js +54 -0
- package/dist/extensions/cursor-cloud-agents/tools/get.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/get.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/get.js +25 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +59 -0
- package/dist/extensions/cursor-cloud-agents/tools/list.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/list.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/list.js +36 -0
- package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts +4 -0
- package/dist/extensions/cursor-cloud-agents/tools/reply.d.ts.map +1 -0
- package/dist/extensions/cursor-cloud-agents/tools/reply.js +35 -0
- package/dist/extensions.d.ts +73 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +112 -0
- package/dist/files-backends/cursor-hosted.d.ts +0 -8
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +1 -11
- package/dist/files.d.ts +5 -1
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +22 -18
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/internal/advertise-tools.d.ts +4 -1
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +20 -1
- package/dist/internal/as-of.d.ts +18 -0
- package/dist/internal/as-of.d.ts.map +1 -1
- package/dist/internal/as-of.js +131 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +64 -19
- package/dist/internal/continuation-identity.d.ts.map +1 -1
- package/dist/internal/continuation-identity.js +3 -1
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +13 -15
- package/dist/internal/cursor/backend-client.d.ts +8 -1
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +25 -9
- package/dist/internal/cursor/hosted-deployment-secrets.d.ts +16 -0
- package/dist/internal/cursor/hosted-deployment-secrets.d.ts.map +1 -0
- package/dist/internal/cursor/hosted-deployment-secrets.js +61 -0
- package/dist/internal/cursor/hosted-store-secrets.d.ts +11 -0
- package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -1
- package/dist/internal/cursor/hosted-store-secrets.js +15 -0
- package/dist/internal/cursor-deployment-relay.d.ts +15 -1
- package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
- package/dist/internal/cursor-deployment-relay.js +46 -7
- package/dist/internal/deploy-client.d.ts +23 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +54 -12
- package/dist/internal/discovery/ab.d.ts +9 -0
- package/dist/internal/discovery/ab.d.ts.map +1 -0
- package/dist/internal/discovery/ab.js +101 -0
- package/dist/internal/discovery/agent-config.d.ts +35 -0
- package/dist/internal/discovery/agent-config.d.ts.map +1 -0
- package/dist/internal/discovery/agent-config.js +173 -0
- package/dist/internal/discovery/agent.d.ts +11 -0
- package/dist/internal/discovery/agent.d.ts.map +1 -0
- package/dist/internal/discovery/agent.js +306 -0
- package/dist/internal/discovery/channels.d.ts +10 -0
- package/dist/internal/discovery/channels.d.ts.map +1 -0
- package/dist/internal/discovery/channels.js +97 -0
- package/dist/internal/discovery/connections.d.ts +17 -0
- package/dist/internal/discovery/connections.d.ts.map +1 -0
- package/dist/internal/discovery/connections.js +436 -0
- package/dist/internal/discovery/context.d.ts +20 -0
- package/dist/internal/discovery/context.d.ts.map +1 -0
- package/dist/internal/discovery/context.js +30 -0
- package/dist/internal/discovery/cursor-plugin.d.ts +25 -0
- package/dist/internal/discovery/cursor-plugin.d.ts.map +1 -0
- package/dist/internal/discovery/cursor-plugin.js +570 -0
- package/dist/internal/discovery/extensions.d.ts +19 -0
- package/dist/internal/discovery/extensions.d.ts.map +1 -0
- package/dist/internal/discovery/extensions.js +238 -0
- package/dist/internal/discovery/fs.d.ts +15 -0
- package/dist/internal/discovery/fs.d.ts.map +1 -0
- package/dist/internal/discovery/fs.js +115 -0
- package/dist/internal/discovery/hooks.d.ts +7 -0
- package/dist/internal/discovery/hooks.d.ts.map +1 -0
- package/dist/internal/discovery/hooks.js +48 -0
- package/dist/internal/discovery/info.d.ts +6 -0
- package/dist/internal/discovery/info.d.ts.map +1 -0
- package/dist/internal/discovery/info.js +141 -0
- package/dist/internal/discovery/instructions.d.ts +7 -0
- package/dist/internal/discovery/instructions.d.ts.map +1 -0
- package/dist/internal/discovery/instructions.js +95 -0
- package/dist/internal/discovery/modules.d.ts +20 -0
- package/dist/internal/discovery/modules.d.ts.map +1 -0
- package/dist/internal/discovery/modules.js +101 -0
- package/dist/internal/discovery/names.d.ts +12 -0
- package/dist/internal/discovery/names.d.ts.map +1 -0
- package/dist/internal/discovery/names.js +36 -0
- package/dist/internal/discovery/project.d.ts +53 -0
- package/dist/internal/discovery/project.d.ts.map +1 -0
- package/dist/internal/discovery/project.js +239 -0
- package/dist/internal/discovery/runtime.d.ts +34 -0
- package/dist/internal/discovery/runtime.d.ts.map +1 -0
- package/dist/internal/discovery/runtime.js +98 -0
- package/dist/internal/discovery/schedules.d.ts +7 -0
- package/dist/internal/discovery/schedules.d.ts.map +1 -0
- package/dist/internal/discovery/schedules.js +97 -0
- package/dist/internal/discovery/seed-files.d.ts +7 -0
- package/dist/internal/discovery/seed-files.d.ts.map +1 -0
- package/dist/internal/discovery/seed-files.js +41 -0
- package/dist/internal/discovery/services.d.ts +17 -0
- package/dist/internal/discovery/services.d.ts.map +1 -0
- package/dist/internal/discovery/services.js +104 -0
- package/dist/internal/discovery/skills.d.ts +16 -0
- package/dist/internal/discovery/skills.d.ts.map +1 -0
- package/dist/internal/discovery/skills.js +151 -0
- package/dist/internal/discovery/subagent.d.ts +13 -0
- package/dist/internal/discovery/subagent.d.ts.map +1 -0
- package/dist/internal/discovery/subagent.js +19 -0
- package/dist/internal/discovery/tools.d.ts +18 -0
- package/dist/internal/discovery/tools.d.ts.map +1 -0
- package/dist/internal/discovery/tools.js +159 -0
- package/dist/internal/discovery.d.ts +8 -62
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +8 -2210
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +5 -0
- package/dist/internal/framework-file-storage.d.ts +3 -3
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +38 -9
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +8 -7
- package/dist/internal/frontmatter.d.ts +11 -3
- package/dist/internal/frontmatter.d.ts.map +1 -1
- package/dist/internal/frontmatter.js +29 -3
- package/dist/internal/hosted-delivery.d.ts +3 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +19 -32
- package/dist/internal/hosted-execution-diag.d.ts +5 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
- package/dist/internal/hosted-execution-diag.js +5 -0
- package/dist/internal/hosted-execution-flush.d.ts +46 -0
- package/dist/internal/hosted-execution-flush.d.ts.map +1 -0
- package/dist/internal/hosted-execution-flush.js +81 -0
- package/dist/internal/mcp-endpoint.js +1 -0
- package/dist/internal/mcp-host.d.ts +2 -1
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +66 -29
- package/dist/internal/otel/collector.d.ts +13 -0
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +84 -17
- package/dist/internal/otel/http.d.ts.map +1 -1
- package/dist/internal/otel/http.js +2 -10
- package/dist/internal/otel/mcp.d.ts +16 -0
- package/dist/internal/otel/mcp.d.ts.map +1 -0
- package/dist/internal/otel/mcp.js +68 -0
- package/dist/internal/otel/propagation.d.ts +6 -0
- package/dist/internal/otel/propagation.d.ts.map +1 -0
- package/dist/internal/otel/propagation.js +14 -0
- package/dist/internal/otel/runtime.d.ts.map +1 -1
- package/dist/internal/otel/runtime.js +2 -0
- package/dist/internal/review-comments.d.ts +1 -1
- package/dist/internal/review-comments.d.ts.map +1 -1
- package/dist/internal/review-comments.js +4 -4
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +79 -104
- package/dist/internal/session-engine.d.ts +14 -7
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +113 -66
- package/dist/internal/session-run-log.d.ts +3 -1
- package/dist/internal/session-run-log.d.ts.map +1 -1
- package/dist/internal/session-run-log.js +14 -14
- package/dist/internal/start-log-store.d.ts +60 -0
- package/dist/internal/start-log-store.d.ts.map +1 -0
- package/dist/internal/start-log-store.js +149 -0
- package/dist/internal/storage-coordinator.d.ts +4 -1
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +15 -13
- package/dist/internal/tool-catalog.d.ts.map +1 -1
- package/dist/internal/tool-catalog.js +9 -6
- package/dist/internal/tool-policy.d.ts +8 -0
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +19 -7
- package/dist/internal/turn-cost.d.ts +14 -0
- package/dist/internal/turn-cost.d.ts.map +1 -1
- package/dist/internal/turn-cost.js +41 -9
- package/dist/internal/v2-hosting.d.ts +22 -0
- package/dist/internal/v2-hosting.d.ts.map +1 -0
- package/dist/internal/v2-hosting.js +23 -0
- package/dist/otel.d.ts +16 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/otel.js +26 -0
- package/dist/playground/assets/index-B6C9S9nG.css +1 -0
- package/dist/playground/assets/{index-DVs98vPL.js → index-ZqNoT8Ie.js} +45 -45
- package/dist/playground/index.html +2 -2
- package/dist/storage-protocol.d.ts +47 -22
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +90 -54
- package/dist/storage.d.ts +2 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/tools.d.ts +9 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +9 -0
- package/dist/types.d.ts +154 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +29 -1
- package/docs/README.md +5 -1
- package/docs/concepts.md +3 -3
- package/docs/guides/cloud-agents.md +98 -0
- package/docs/guides/cloud-runtime.md +2 -0
- package/docs/reference/connections.md +31 -0
- package/docs/reference/extensions.md +205 -0
- package/docs/reference/http-api.md +1 -1
- package/docs/reference/project-layout.md +3 -0
- package/docs/reference/skills.md +2 -0
- package/docs/reference/tools.md +2 -0
- package/package.json +18 -4
- package/skills/framework-map/SKILL.md +1 -0
- package/src/bin/agent-serve.ts +11 -2
- package/src/channels/deployments/deployments-channel.ts +117 -8
- package/src/channels/deployments/types.ts +4 -3
- package/src/channels/origin/defaults.ts +143 -0
- package/src/channels/origin/index.ts +2 -0
- package/src/channels/origin/origin-channel.ts +37 -1
- package/src/channels/origin/state.ts +54 -0
- package/src/channels/origin/types.ts +24 -0
- package/src/channels/slack/api.ts +6 -3
- package/src/channels/slack/assistant.ts +1 -1
- package/src/channels/slack/code-fences.ts +183 -0
- package/src/channels/slack/dispatch.ts +27 -2
- package/src/channels/slack/inbound.ts +37 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/live-delivery.ts +16 -13
- package/src/channels/slack/manifest.ts +2 -1
- package/src/connections.ts +18 -1
- package/src/extensions/cursor-cloud-agents/extension.ts +120 -0
- package/src/extensions/cursor-cloud-agents/lib/backend.ts +395 -0
- package/src/extensions/cursor-cloud-agents/lib/fleet.ts +109 -0
- package/src/extensions/cursor-cloud-agents/lib/inputs.ts +5 -0
- package/src/extensions/cursor-cloud-agents/lib/repos.ts +81 -0
- package/src/extensions/cursor-cloud-agents/lib/transcript.ts +23 -0
- package/src/extensions/cursor-cloud-agents/skills/handoff.md +41 -0
- package/src/extensions/cursor-cloud-agents/tools/cancel.ts +19 -0
- package/src/extensions/cursor-cloud-agents/tools/dump.ts +51 -0
- package/src/extensions/cursor-cloud-agents/tools/get.ts +18 -0
- package/src/extensions/cursor-cloud-agents/tools/launch.ts +64 -0
- package/src/extensions/cursor-cloud-agents/tools/list.ts +31 -0
- package/src/extensions/cursor-cloud-agents/tools/reply.ts +34 -0
- package/src/extensions.ts +141 -0
- package/src/files-backends/cursor-hosted.ts +1 -17
- package/src/files.ts +43 -34
- package/src/index.ts +11 -0
- package/src/internal/advertise-tools.ts +37 -12
- package/src/internal/as-of.ts +163 -0
- package/src/internal/cli-deploy.ts +86 -23
- package/src/internal/continuation-identity.ts +3 -1
- package/src/internal/conversation-mirror.ts +23 -18
- package/src/internal/cursor/backend-client.ts +32 -10
- package/src/internal/cursor/hosted-deployment-secrets.ts +72 -0
- package/src/internal/cursor/hosted-store-secrets.ts +27 -0
- package/src/internal/cursor-deployment-relay.ts +65 -8
- package/src/internal/deploy-client.ts +73 -18
- package/src/internal/discovery/ab.ts +111 -0
- package/src/internal/discovery/agent-config.ts +222 -0
- package/src/internal/discovery/agent.ts +360 -0
- package/src/internal/discovery/channels.ts +103 -0
- package/src/internal/discovery/connections.ts +540 -0
- package/src/internal/discovery/context.ts +46 -0
- package/src/internal/discovery/cursor-plugin.ts +708 -0
- package/src/internal/discovery/extensions.ts +348 -0
- package/src/internal/discovery/fs.ts +108 -0
- package/src/internal/discovery/hooks.ts +45 -0
- package/src/internal/discovery/info.ts +179 -0
- package/src/internal/discovery/instructions.ts +113 -0
- package/src/internal/discovery/modules.ts +107 -0
- package/src/internal/discovery/names.ts +44 -0
- package/src/internal/discovery/project.ts +270 -0
- package/src/internal/discovery/runtime.ts +159 -0
- package/src/internal/discovery/schedules.ts +94 -0
- package/src/internal/discovery/seed-files.ts +37 -0
- package/src/internal/discovery/services.ts +124 -0
- package/src/internal/discovery/skills.ts +176 -0
- package/src/internal/discovery/subagent.ts +29 -0
- package/src/internal/discovery/tools.ts +182 -0
- package/src/internal/discovery.ts +20 -2724
- package/src/internal/distribution.ts +5 -0
- package/src/internal/framework-file-storage.ts +43 -9
- package/src/internal/framework-storage-selection.ts +9 -9
- package/src/internal/frontmatter.ts +36 -3
- package/src/internal/hosted-delivery.ts +38 -63
- package/src/internal/hosted-execution-diag.ts +6 -0
- package/src/internal/hosted-execution-flush.ts +142 -0
- package/src/internal/mcp-endpoint.ts +1 -0
- package/src/internal/mcp-host.ts +116 -37
- package/src/internal/otel/collector.ts +125 -25
- package/src/internal/otel/http.ts +2 -12
- package/src/internal/otel/mcp.ts +69 -0
- package/src/internal/otel/propagation.ts +17 -0
- package/src/internal/otel/runtime.ts +2 -0
- package/src/internal/review-comments.ts +5 -2
- package/src/internal/server.ts +81 -100
- package/src/internal/session-engine.ts +152 -39
- package/src/internal/session-run-log.ts +18 -16
- package/src/internal/start-log-store.ts +174 -0
- package/src/internal/storage-coordinator.ts +19 -16
- package/src/internal/tool-catalog.ts +9 -6
- package/src/internal/tool-policy.ts +39 -9
- package/src/internal/turn-cost.ts +47 -4
- package/src/internal/v2-hosting.ts +38 -0
- package/src/otel.ts +38 -0
- package/src/storage-protocol.ts +126 -79
- package/src/storage.ts +5 -0
- package/src/tools.ts +18 -0
- package/src/types.ts +213 -14
- package/dist/docs/assets/chunks/@localSearchIndexroot.j70vvPL4.js +0 -1
- package/dist/docs/assets/concepts.md.lwAgBIMI.js +0 -1
- package/dist/docs/assets/index.md.Bb4k8kUm.js +0 -5
- package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +0 -1
- package/dist/playground/assets/index-BszoQDc6.css +0 -1
- /package/dist/docs/assets/{concepts.md.lwAgBIMI.lean.js → concepts.md.rPzW2HZN.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.CkYbjnAX.lean.js → guides_cloud-runtime.md.BRirbRAN.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.BEJx9XVj.lean.js → reference_http-api.md.oySXBO8o.lean.js} +0 -0
- /package/dist/docs/assets/{reference_skills.md.BFW9retM.lean.js → reference_skills.md.l2ezAcaN.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.CvAHsdSp.lean.js → reference_tools.md.B1up2r9W.lean.js} +0 -0
|
@@ -138,6 +138,43 @@ export function parseAppMentionEvent(
|
|
|
138
138
|
return delegation === undefined ? message : { ...message, delegation };
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
export interface SlackAppHomeOpened {
|
|
142
|
+
channelId: string;
|
|
143
|
+
tab: string;
|
|
144
|
+
userId?: string;
|
|
145
|
+
teamId?: string;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Slack fires this when a user opens the app Home or Messages tab. */
|
|
149
|
+
export function parseAppHomeOpened(body: unknown): SlackAppHomeOpened | null {
|
|
150
|
+
const root = asRecord(body);
|
|
151
|
+
if (root === null || root.type !== "event_callback") {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
const event = asRecord(root.event);
|
|
155
|
+
if (event === null || event.type !== "app_home_opened") {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const channelId = asString(event.channel);
|
|
159
|
+
const tab = asString(event.tab);
|
|
160
|
+
if (
|
|
161
|
+
channelId === undefined ||
|
|
162
|
+
channelId === "" ||
|
|
163
|
+
tab === undefined ||
|
|
164
|
+
tab === ""
|
|
165
|
+
) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const userId = asString(event.user);
|
|
169
|
+
const teamId = asString(root.team_id) ?? asString(event.team_id);
|
|
170
|
+
return {
|
|
171
|
+
channelId,
|
|
172
|
+
tab,
|
|
173
|
+
userId: userId === undefined || userId === "" ? undefined : userId,
|
|
174
|
+
teamId: teamId === undefined || teamId === "" ? undefined : teamId,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
141
178
|
export interface SlackAssistantThreadStarted {
|
|
142
179
|
channelId: string;
|
|
143
180
|
threadTs: string;
|
|
@@ -21,6 +21,7 @@ export * from "./auth.js";
|
|
|
21
21
|
export * from "./blocks.js";
|
|
22
22
|
export * from "./bot-mentions.js";
|
|
23
23
|
export * from "./channel-watch.js";
|
|
24
|
+
export * from "./code-fences.js";
|
|
24
25
|
export * from "./constants.js";
|
|
25
26
|
export * from "./credentials.js";
|
|
26
27
|
export * from "./defaults.js";
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
startChatStream,
|
|
23
23
|
stopChatStream,
|
|
24
24
|
} from "./api.js";
|
|
25
|
+
import { highlightCodeFences } from "./code-fences.js";
|
|
25
26
|
import { SLACK_MARKDOWN_TEXT_MAX_LEN } from "./constants.js";
|
|
26
27
|
import type { SlackLog } from "./log.js";
|
|
27
28
|
import {
|
|
@@ -117,7 +118,7 @@ export function createStreamDeliveryStrategy(
|
|
|
117
118
|
const openingText = markdown_text ?? "";
|
|
118
119
|
const opening: StreamChunk[] = [];
|
|
119
120
|
if (openingText !== "") {
|
|
120
|
-
opening.push(markdownChunk(openingText));
|
|
121
|
+
opening.push(markdownChunk(highlightCodeFences(openingText)));
|
|
121
122
|
}
|
|
122
123
|
opening.push(...(chunks ?? []));
|
|
123
124
|
if (opening.length === 0) {
|
|
@@ -181,16 +182,24 @@ export function createStreamDeliveryStrategy(
|
|
|
181
182
|
return opened ? activeStreamTs(args.channel) : null;
|
|
182
183
|
};
|
|
183
184
|
|
|
185
|
+
/**
|
|
186
|
+
* What to append for the new cumulative text, as Slack should see it: the
|
|
187
|
+
* block text on both sides goes through the same fence rewrite, so the
|
|
188
|
+
* delta lines up with what the stream already holds.
|
|
189
|
+
*/
|
|
190
|
+
const streamDelta = (channel: SlackChannel, text: string): string =>
|
|
191
|
+
computeStreamAppend(
|
|
192
|
+
highlightCodeFences(channel.state.streamBlockText ?? ""),
|
|
193
|
+
highlightCodeFences(text)
|
|
194
|
+
);
|
|
195
|
+
|
|
184
196
|
const stopWithSuffix = async (args: {
|
|
185
197
|
channel: SlackChannel;
|
|
186
198
|
channelId: string;
|
|
187
199
|
ts: string;
|
|
188
200
|
text: string;
|
|
189
201
|
}): Promise<{ ok: boolean; error?: string }> => {
|
|
190
|
-
const appendText =
|
|
191
|
-
args.channel.state.streamBlockText,
|
|
192
|
-
args.text
|
|
193
|
-
);
|
|
202
|
+
const appendText = streamDelta(args.channel, args.text);
|
|
194
203
|
const stopped = await stopChatStream({
|
|
195
204
|
botToken,
|
|
196
205
|
channel: args.channelId,
|
|
@@ -299,10 +308,7 @@ export function createStreamDeliveryStrategy(
|
|
|
299
308
|
if (ts === null) {
|
|
300
309
|
return;
|
|
301
310
|
}
|
|
302
|
-
const appendText =
|
|
303
|
-
channel.state.streamBlockText,
|
|
304
|
-
text
|
|
305
|
-
);
|
|
311
|
+
const appendText = streamDelta(channel, text);
|
|
306
312
|
if (appendText === "") {
|
|
307
313
|
return;
|
|
308
314
|
}
|
|
@@ -374,10 +380,7 @@ export function createStreamDeliveryStrategy(
|
|
|
374
380
|
return { delivered: false };
|
|
375
381
|
}
|
|
376
382
|
// Measured before the stop attempt mutates stream state.
|
|
377
|
-
const remainder =
|
|
378
|
-
channel.state.streamBlockText,
|
|
379
|
-
text
|
|
380
|
-
);
|
|
383
|
+
const remainder = streamDelta(channel, text);
|
|
381
384
|
const stopped =
|
|
382
385
|
channel.state.streamFull === true
|
|
383
386
|
? { ok: false, error: "msg_too_long" }
|
|
@@ -84,7 +84,8 @@ const BOT_SCOPES = [
|
|
|
84
84
|
const BOT_EVENTS = [
|
|
85
85
|
"app_mention",
|
|
86
86
|
"message.im",
|
|
87
|
-
|
|
87
|
+
// agent_view DMs: Slack no longer fires assistant_thread_started.
|
|
88
|
+
"app_home_opened",
|
|
88
89
|
] as const;
|
|
89
90
|
|
|
90
91
|
/** Slack's display_information.description bound. */
|
package/src/connections.ts
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* are available to the agent (SDK `mcpServers`), host (`ctx.host.mcp`),
|
|
9
9
|
* and channel/schedule handlers. Pass `advertiseTools: true` for named
|
|
10
10
|
* tools on local turns. Pass `effects: "read"` with `advertiseTools` to
|
|
11
|
-
* advertise only tools the server classifies as reads.
|
|
11
|
+
* advertise only tools the server classifies as reads. Pass `tools` as
|
|
12
|
+
* a name list to keep a subset, same shape as `defineAgent({ tools })`.
|
|
13
|
+
* Pass `disallowedTools` to drop names. Files under
|
|
12
14
|
* `host-connections/` stay off the model.
|
|
13
15
|
*
|
|
14
16
|
* ```ts
|
|
@@ -42,6 +44,20 @@
|
|
|
42
44
|
* advertiseTools: true,
|
|
43
45
|
* effects: "read",
|
|
44
46
|
* });
|
|
47
|
+
*
|
|
48
|
+
* // named subset: advertise and call only these tools
|
|
49
|
+
* export default defineConnection({
|
|
50
|
+
* url: "https://mcp.example.com/inventory",
|
|
51
|
+
* advertiseTools: true,
|
|
52
|
+
* tools: ["search_skus", "get_stock"],
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* // drop a few tools from a large server
|
|
56
|
+
* export default defineConnection({
|
|
57
|
+
* url: "https://mcp.example.com/inventory",
|
|
58
|
+
* advertiseTools: true,
|
|
59
|
+
* disallowedTools: ["place_order", "delete_sku"],
|
|
60
|
+
* });
|
|
45
61
|
* ```
|
|
46
62
|
*
|
|
47
63
|
* A **Cursor account MCP connection** exposes the MCP connectors the operator
|
|
@@ -129,6 +145,7 @@ export {
|
|
|
129
145
|
isInlineStdioConnection,
|
|
130
146
|
isToolEffect,
|
|
131
147
|
normalizeConnectionEffects,
|
|
148
|
+
normalizeConnectionTools,
|
|
132
149
|
normalizeCursorAccountServers,
|
|
133
150
|
} from "./types.js";
|
|
134
151
|
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor cloud agents as an extension. Mount it and the agent can hand
|
|
3
|
+
* coding work to Cursor cloud agents and steer a fleet of them:
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* // agent/extensions/cloud.ts
|
|
7
|
+
* import cursorCloudAgents from "@cursor/july/extensions/cursor-cloud-agents";
|
|
8
|
+
*
|
|
9
|
+
* export default cursorCloudAgents({
|
|
10
|
+
* cloud: { repos: [{ url: "https://github.com/acme/api" }], autoCreatePR: true },
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Contributes `cloud__launch`, `cloud__get`, `cloud__dump`, `cloud__reply`,
|
|
15
|
+
* `cloud__cancel`, `cloud__list` and the `cloud__handoff` skill (the
|
|
16
|
+
* namespace is the mount filename), the action vocabulary Sand's CloudAgent
|
|
17
|
+
* tool uses, over the same backend calls: launches through the v1 Cloud
|
|
18
|
+
* Agents API, everything else through the BackgroundComposerService RPCs,
|
|
19
|
+
* all under the serve host's Cursor API key (`CURSOR_API_KEY`, key file, or
|
|
20
|
+
* `login`). Each launched agent stays bound to the principal that launched
|
|
21
|
+
* it, and launches go to the configured repositories. The tools run on the
|
|
22
|
+
* serve host, so they need the local runtime.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { z } from "zod";
|
|
26
|
+
import { defineExtension } from "../../extensions.js";
|
|
27
|
+
import type {
|
|
28
|
+
AgentCloudOptions,
|
|
29
|
+
Extension,
|
|
30
|
+
ModelSetting,
|
|
31
|
+
} from "../../types.js";
|
|
32
|
+
|
|
33
|
+
/** Mount options; every field is optional. */
|
|
34
|
+
export interface CursorCloudAgentsOptions {
|
|
35
|
+
/**
|
|
36
|
+
* Launch defaults: target `repos`, `env`, `autoCreatePR`, ... in the same
|
|
37
|
+
* vocabulary as `defineAgent({ cloud })`. Configured `repos` are also the
|
|
38
|
+
* allowlist for a launch's own `repo` / `prUrl`; model-chosen targets are
|
|
39
|
+
* refused when no allowlist is configured. With none configured,
|
|
40
|
+
* `needsApproval` defaults to true so prompt-only launches park first.
|
|
41
|
+
*/
|
|
42
|
+
cloud?: AgentCloudOptions;
|
|
43
|
+
/** Model for launched agents. The account default when omitted. */
|
|
44
|
+
model?: ModelSetting;
|
|
45
|
+
/**
|
|
46
|
+
* Park launches and follow-ups for a human approval. Defaults to `true`
|
|
47
|
+
* when no `cloud.repos` are configured (prompt-only launches still use
|
|
48
|
+
* the host key); `false` once repositories are configured. Pass an
|
|
49
|
+
* explicit boolean to override. Model-chosen `repo` / `prUrl` still
|
|
50
|
+
* require the allowlist regardless of this flag.
|
|
51
|
+
*/
|
|
52
|
+
needsApproval?: boolean;
|
|
53
|
+
/** Cursor API key. Defaults to the serve host's own key. */
|
|
54
|
+
apiKey?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** {@link CursorCloudAgentsOptions} with defaults applied. */
|
|
58
|
+
export interface CursorCloudAgentsConfig {
|
|
59
|
+
cloud: AgentCloudOptions;
|
|
60
|
+
model?: ModelSetting;
|
|
61
|
+
needsApproval: boolean;
|
|
62
|
+
apiKey?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const repo = z.object({
|
|
66
|
+
url: z.string().url(),
|
|
67
|
+
startingRef: z.string().optional(),
|
|
68
|
+
prUrl: z.string().url().optional(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const cloud: z.ZodType<AgentCloudOptions> = z.object({
|
|
72
|
+
env: z
|
|
73
|
+
.discriminatedUnion("type", [
|
|
74
|
+
z.object({ type: z.literal("cloud"), name: z.string().optional() }),
|
|
75
|
+
z.object({ type: z.literal("pool"), name: z.string().optional() }),
|
|
76
|
+
z.object({ type: z.literal("machine"), name: z.string().optional() }),
|
|
77
|
+
])
|
|
78
|
+
.optional(),
|
|
79
|
+
repos: z.array(repo).optional(),
|
|
80
|
+
workOnCurrentBranch: z.boolean().optional(),
|
|
81
|
+
autoCreatePR: z.boolean().optional(),
|
|
82
|
+
skipReviewerRequest: z.boolean().optional(),
|
|
83
|
+
envVars: z.record(z.string()).optional(),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const model: z.ZodType<ModelSetting> = z.union([
|
|
87
|
+
z.string().min(1),
|
|
88
|
+
z.object({
|
|
89
|
+
id: z.string().min(1),
|
|
90
|
+
params: z.array(z.object({ id: z.string(), value: z.string() })).optional(),
|
|
91
|
+
}),
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
const config: z.ZodType<
|
|
95
|
+
CursorCloudAgentsConfig,
|
|
96
|
+
z.ZodTypeDef,
|
|
97
|
+
CursorCloudAgentsOptions | undefined
|
|
98
|
+
> = z
|
|
99
|
+
.object({
|
|
100
|
+
cloud: cloud.default({}),
|
|
101
|
+
model: model.optional(),
|
|
102
|
+
needsApproval: z.boolean().optional(),
|
|
103
|
+
apiKey: z.string().optional(),
|
|
104
|
+
})
|
|
105
|
+
.default({})
|
|
106
|
+
.transform((options) => ({
|
|
107
|
+
...options,
|
|
108
|
+
needsApproval: options.needsApproval ?? options.cloud.repos === undefined,
|
|
109
|
+
}));
|
|
110
|
+
|
|
111
|
+
const cursorCloudAgents: Extension<
|
|
112
|
+
CursorCloudAgentsConfig,
|
|
113
|
+
CursorCloudAgentsOptions | undefined
|
|
114
|
+
> = defineExtension({
|
|
115
|
+
root: import.meta.dirname,
|
|
116
|
+
description: "Launch, steer, and monitor Cursor cloud agents.",
|
|
117
|
+
config,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export default cursorCloudAgents;
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Cursor backend as the tools use it: launches go through the public
|
|
3
|
+
* v1 Cloud Agents API (the only surface that takes per-launch `envVars`),
|
|
4
|
+
* everything about an existing agent goes through the same
|
|
5
|
+
* `aiserver.v1.BackgroundComposerService` RPCs Sand's CloudAgent tool
|
|
6
|
+
* calls, so follow-ups queue, runs pause, and the full conversation is
|
|
7
|
+
* readable. Both authenticate with the host's Cursor API key; the RPCs
|
|
8
|
+
* exchange it for a session token the way the dashboard client does.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { CursorBackendClient } from "../../../internal/cursor/backend-client.js";
|
|
14
|
+
import {
|
|
15
|
+
cursorBackendUrl,
|
|
16
|
+
cursorExternalApiUrl,
|
|
17
|
+
cursorWebsiteUrl,
|
|
18
|
+
resolveApiKeySync,
|
|
19
|
+
SIGN_IN_HINT,
|
|
20
|
+
} from "../../../internal/cursor/credentials.js";
|
|
21
|
+
import { toModelSelection } from "../../../internal/sdk-runner.js";
|
|
22
|
+
import type { AgentCloudOptions, ModelSetting } from "../../../types.js";
|
|
23
|
+
import extension from "../extension.js";
|
|
24
|
+
|
|
25
|
+
const SERVICE = "BackgroundComposerService";
|
|
26
|
+
/** Launches and follow-ups from this extension carry the SDK source, like the v1 API. */
|
|
27
|
+
const SOURCE = "BACKGROUND_COMPOSER_SOURCE_SDK";
|
|
28
|
+
const RPC_TIMEOUT_MS = 60_000;
|
|
29
|
+
// The create call returns once the initial run exists, which can wait on a VM.
|
|
30
|
+
const LAUNCH_TIMEOUT_MS = 300_000;
|
|
31
|
+
|
|
32
|
+
export class CloudAgentsApiError extends Error {
|
|
33
|
+
constructor(
|
|
34
|
+
message: string,
|
|
35
|
+
readonly status?: number
|
|
36
|
+
) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = "CloudAgentsApiError";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type CloudAgentStatus =
|
|
43
|
+
| "creating"
|
|
44
|
+
| "running"
|
|
45
|
+
| "finished"
|
|
46
|
+
| "error"
|
|
47
|
+
| "expired"
|
|
48
|
+
| "unknown";
|
|
49
|
+
|
|
50
|
+
// Type aliases, not interfaces: these flow into tool results.
|
|
51
|
+
export type CloudAgentInfo = {
|
|
52
|
+
agentId: string;
|
|
53
|
+
name: string;
|
|
54
|
+
status: CloudAgentStatus;
|
|
55
|
+
archived: boolean;
|
|
56
|
+
url: string;
|
|
57
|
+
branch?: string;
|
|
58
|
+
prUrl?: string;
|
|
59
|
+
summary?: string;
|
|
60
|
+
error?: string;
|
|
61
|
+
changes?: { filesChanged: number; linesAdded: number; linesRemoved: number };
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export type CloudAgentToolCall = {
|
|
65
|
+
name: string;
|
|
66
|
+
args: unknown;
|
|
67
|
+
content?: string;
|
|
68
|
+
error?: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type CloudAgentMessage = {
|
|
72
|
+
role: "user" | "assistant";
|
|
73
|
+
text?: string;
|
|
74
|
+
thinking?: string;
|
|
75
|
+
toolCalls?: CloudAgentToolCall[];
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type CloudAgentLaunch = {
|
|
79
|
+
agentId: string;
|
|
80
|
+
runId: string;
|
|
81
|
+
status: string;
|
|
82
|
+
url: string;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export type LaunchRequest = {
|
|
86
|
+
prompt: string;
|
|
87
|
+
name?: string;
|
|
88
|
+
cloud: AgentCloudOptions;
|
|
89
|
+
model?: ModelSetting;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Proto-JSON response schemas (camelCase; default-valued fields are omitted)
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
const composerSchema = z.object({
|
|
97
|
+
bcId: z.string(),
|
|
98
|
+
name: z.string().optional(),
|
|
99
|
+
status: z.string().optional(),
|
|
100
|
+
isArchived: z.boolean().optional(),
|
|
101
|
+
branchName: z.string().optional(),
|
|
102
|
+
prUrl: z.string().optional(),
|
|
103
|
+
linesAdded: z.number().optional(),
|
|
104
|
+
linesRemoved: z.number().optional(),
|
|
105
|
+
filesChanged: z.number().optional(),
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const errorDetailsSchema = z.object({
|
|
109
|
+
details: z
|
|
110
|
+
.object({ title: z.string().optional(), detail: z.string().optional() })
|
|
111
|
+
.optional(),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const infoResponseSchema = z.object({
|
|
115
|
+
composer: z.object({
|
|
116
|
+
composer: composerSchema,
|
|
117
|
+
summary: z.string().optional(),
|
|
118
|
+
startError: errorDetailsSchema.optional(),
|
|
119
|
+
permanentError: errorDetailsSchema.optional(),
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const toolResultSchema = z.object({
|
|
124
|
+
toolName: z.string().optional(),
|
|
125
|
+
args: z.string().optional(),
|
|
126
|
+
rawArgs: z.string().optional(),
|
|
127
|
+
content: z.string().optional(),
|
|
128
|
+
error: z
|
|
129
|
+
.object({ clientVisibleErrorMessage: z.string().optional() })
|
|
130
|
+
.optional(),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const conversationResponseSchema = z.object({
|
|
134
|
+
conversation: z
|
|
135
|
+
.array(
|
|
136
|
+
z.object({
|
|
137
|
+
type: z.string().optional(),
|
|
138
|
+
text: z.string().optional(),
|
|
139
|
+
thinking: z.object({ text: z.string().optional() }).optional(),
|
|
140
|
+
toolResults: z.array(toolResultSchema).optional(),
|
|
141
|
+
})
|
|
142
|
+
)
|
|
143
|
+
.optional(),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const followupResponseSchema = z.object({ runId: z.string().optional() });
|
|
147
|
+
|
|
148
|
+
const launchResponseSchema = z.object({
|
|
149
|
+
agent: z.object({ id: z.string(), url: z.string().optional() }),
|
|
150
|
+
run: z.object({ id: z.string(), status: z.string() }),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
export class CloudAgentsBackend {
|
|
156
|
+
private readonly rpcClient: CursorBackendClient;
|
|
157
|
+
|
|
158
|
+
constructor(
|
|
159
|
+
private readonly apiKey: () => string,
|
|
160
|
+
private readonly fetchImpl: typeof fetch = fetch
|
|
161
|
+
) {
|
|
162
|
+
// The key is read per call: the host can sign in after the mount.
|
|
163
|
+
this.rpcClient = new CursorBackendClient({
|
|
164
|
+
backendUrl: cursorBackendUrl(),
|
|
165
|
+
apiKey: "",
|
|
166
|
+
getApiKey: apiKey,
|
|
167
|
+
fetchImpl,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** `POST /v1/agents`: create the agent and start its first run in one call. */
|
|
172
|
+
async launch(request: LaunchRequest): Promise<CloudAgentLaunch> {
|
|
173
|
+
const { cloud } = request;
|
|
174
|
+
const body = {
|
|
175
|
+
prompt: { text: request.prompt },
|
|
176
|
+
name: request.name,
|
|
177
|
+
model:
|
|
178
|
+
request.model === undefined
|
|
179
|
+
? undefined
|
|
180
|
+
: toModelSelection(request.model),
|
|
181
|
+
env: cloud.env,
|
|
182
|
+
envVars: cloud.envVars,
|
|
183
|
+
repos: cloud.repos,
|
|
184
|
+
workOnCurrentBranch: cloud.workOnCurrentBranch,
|
|
185
|
+
autoCreatePR: cloud.autoCreatePR,
|
|
186
|
+
skipReviewerRequest: cloud.skipReviewerRequest,
|
|
187
|
+
};
|
|
188
|
+
let response: Response;
|
|
189
|
+
try {
|
|
190
|
+
response = await this.fetchImpl(`${cursorExternalApiUrl()}/v1/agents`, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
headers: {
|
|
193
|
+
"content-type": "application/json",
|
|
194
|
+
authorization: `Bearer ${this.apiKey()}`,
|
|
195
|
+
"x-ghost-mode": "true",
|
|
196
|
+
"x-cursor-client-type": "agent-serve",
|
|
197
|
+
"x-request-id": randomUUID(),
|
|
198
|
+
},
|
|
199
|
+
body: JSON.stringify(body),
|
|
200
|
+
signal: AbortSignal.timeout(LAUNCH_TIMEOUT_MS),
|
|
201
|
+
});
|
|
202
|
+
} catch (error) {
|
|
203
|
+
throw new CloudAgentsApiError(
|
|
204
|
+
`Cloud agent launch failed: ${error instanceof Error ? error.message : String(error)}`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
const text = await response.text();
|
|
208
|
+
if (!response.ok) {
|
|
209
|
+
throw new CloudAgentsApiError(
|
|
210
|
+
`Cloud agent launch failed (${response.status}): ${apiErrorMessage(text)}`,
|
|
211
|
+
response.status
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
const parsed = launchResponseSchema.parse(JSON.parse(text));
|
|
215
|
+
return {
|
|
216
|
+
agentId: parsed.agent.id,
|
|
217
|
+
runId: parsed.run.id,
|
|
218
|
+
status: parsed.run.status.toLowerCase(),
|
|
219
|
+
url: parsed.agent.url ?? agentUrl(parsed.agent.id),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async info(agentId: string): Promise<CloudAgentInfo> {
|
|
224
|
+
const { composer } = infoResponseSchema.parse(
|
|
225
|
+
await this.rpcClient.serviceRpc(
|
|
226
|
+
SERVICE,
|
|
227
|
+
"GetBackgroundComposerInfo",
|
|
228
|
+
{ bcId: agentId },
|
|
229
|
+
RPC_TIMEOUT_MS
|
|
230
|
+
)
|
|
231
|
+
);
|
|
232
|
+
const { composer: summary } = composer;
|
|
233
|
+
const failure = composer.permanentError ?? composer.startError;
|
|
234
|
+
return {
|
|
235
|
+
agentId: summary.bcId,
|
|
236
|
+
name: summary.name ?? "",
|
|
237
|
+
status: statusOf(summary.status),
|
|
238
|
+
archived: summary.isArchived === true,
|
|
239
|
+
url: agentUrl(summary.bcId),
|
|
240
|
+
branch: emptyToUndefined(summary.branchName),
|
|
241
|
+
prUrl: emptyToUndefined(summary.prUrl),
|
|
242
|
+
summary: emptyToUndefined(composer.summary),
|
|
243
|
+
error: failureMessage(failure),
|
|
244
|
+
changes:
|
|
245
|
+
summary.filesChanged === undefined
|
|
246
|
+
? undefined
|
|
247
|
+
: {
|
|
248
|
+
filesChanged: summary.filesChanged,
|
|
249
|
+
linesAdded: summary.linesAdded ?? 0,
|
|
250
|
+
linesRemoved: summary.linesRemoved ?? 0,
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async conversation(agentId: string): Promise<CloudAgentMessage[]> {
|
|
256
|
+
const { conversation } = conversationResponseSchema.parse(
|
|
257
|
+
await this.rpcClient.serviceRpc(
|
|
258
|
+
SERVICE,
|
|
259
|
+
"GetBackgroundComposerConversation",
|
|
260
|
+
{ bcId: agentId },
|
|
261
|
+
RPC_TIMEOUT_MS
|
|
262
|
+
)
|
|
263
|
+
);
|
|
264
|
+
return (conversation ?? []).map((message) => {
|
|
265
|
+
const toolCalls = (message.toolResults ?? []).map((result) => ({
|
|
266
|
+
name: result.toolName ?? "",
|
|
267
|
+
args: parseArgs(result.args ?? result.rawArgs),
|
|
268
|
+
content: result.content,
|
|
269
|
+
error: result.error?.clientVisibleErrorMessage,
|
|
270
|
+
}));
|
|
271
|
+
return {
|
|
272
|
+
role: message.type === "MESSAGE_TYPE_HUMAN" ? "user" : "assistant",
|
|
273
|
+
text: emptyToUndefined(message.text),
|
|
274
|
+
thinking: emptyToUndefined(message.thinking?.text),
|
|
275
|
+
toolCalls: toolCalls.length === 0 ? undefined : toolCalls,
|
|
276
|
+
};
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Queue a follow-up behind the current run, or with `interrupt` cancel the
|
|
282
|
+
* in-flight step and run it now; the backend's `synchronous` switch.
|
|
283
|
+
*/
|
|
284
|
+
async followUp(
|
|
285
|
+
agentId: string,
|
|
286
|
+
prompt: string,
|
|
287
|
+
interrupt: boolean
|
|
288
|
+
): Promise<{ runId: string | undefined }> {
|
|
289
|
+
const { runId } = followupResponseSchema.parse(
|
|
290
|
+
await this.rpcClient.serviceRpc(
|
|
291
|
+
SERVICE,
|
|
292
|
+
"AddAsyncFollowupBackgroundComposer",
|
|
293
|
+
{
|
|
294
|
+
bcId: agentId,
|
|
295
|
+
synchronous: interrupt,
|
|
296
|
+
followupSource: SOURCE,
|
|
297
|
+
followupMessage: {
|
|
298
|
+
text: prompt,
|
|
299
|
+
type: "MESSAGE_TYPE_HUMAN",
|
|
300
|
+
bubbleId: randomUUID(),
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
RPC_TIMEOUT_MS
|
|
304
|
+
)
|
|
305
|
+
);
|
|
306
|
+
return { runId };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async pause(agentId: string): Promise<void> {
|
|
310
|
+
await this.rpcClient.serviceRpc(
|
|
311
|
+
SERVICE,
|
|
312
|
+
"PauseBackgroundComposer",
|
|
313
|
+
{ bcId: agentId, source: SOURCE },
|
|
314
|
+
RPC_TIMEOUT_MS
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let backend: CloudAgentsBackend | undefined;
|
|
320
|
+
|
|
321
|
+
/** The process-wide backend for this mount, built on first use. */
|
|
322
|
+
export function cloudAgentsBackend(): CloudAgentsBackend {
|
|
323
|
+
backend ??= new CloudAgentsBackend(apiKey);
|
|
324
|
+
return backend;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export function apiKey(): string {
|
|
328
|
+
const key = resolveApiKeySync({ apiKey: extension.config.apiKey });
|
|
329
|
+
if (key === undefined) {
|
|
330
|
+
throw new Error(`Cloud agents need a Cursor API key. ${SIGN_IN_HINT}`);
|
|
331
|
+
}
|
|
332
|
+
return key.apiKey;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export function agentUrl(agentId: string): string {
|
|
336
|
+
return `${cursorWebsiteUrl()}/agents/${agentId}`;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function statusOf(status: string | undefined): CloudAgentStatus {
|
|
340
|
+
switch (status) {
|
|
341
|
+
case "BACKGROUND_COMPOSER_STATUS_CREATING":
|
|
342
|
+
return "creating";
|
|
343
|
+
case "BACKGROUND_COMPOSER_STATUS_RUNNING":
|
|
344
|
+
return "running";
|
|
345
|
+
case "BACKGROUND_COMPOSER_STATUS_FINISHED":
|
|
346
|
+
return "finished";
|
|
347
|
+
case "BACKGROUND_COMPOSER_STATUS_ERROR":
|
|
348
|
+
return "error";
|
|
349
|
+
case "BACKGROUND_COMPOSER_STATUS_EXPIRED":
|
|
350
|
+
return "expired";
|
|
351
|
+
default:
|
|
352
|
+
return "unknown";
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function failureMessage(
|
|
357
|
+
failure: z.infer<typeof errorDetailsSchema> | undefined
|
|
358
|
+
): string | undefined {
|
|
359
|
+
const parts = [failure?.details?.title, failure?.details?.detail].filter(
|
|
360
|
+
(part): part is string => part !== undefined && part !== ""
|
|
361
|
+
);
|
|
362
|
+
return parts.length === 0 ? undefined : parts.join(": ");
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function parseArgs(args: string | undefined): unknown {
|
|
366
|
+
if (args === undefined || args === "") {
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
return JSON.parse(args) as unknown;
|
|
371
|
+
} catch {
|
|
372
|
+
return args;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function emptyToUndefined(value: string | undefined): string | undefined {
|
|
377
|
+
return value === undefined || value === "" ? undefined : value;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function apiErrorMessage(text: string): string {
|
|
381
|
+
try {
|
|
382
|
+
const parsed = JSON.parse(text) as {
|
|
383
|
+
error?: { code?: string; message?: string };
|
|
384
|
+
code?: string;
|
|
385
|
+
message?: string;
|
|
386
|
+
};
|
|
387
|
+
const code = parsed.error?.code ?? parsed.code;
|
|
388
|
+
const message = parsed.error?.message ?? parsed.message;
|
|
389
|
+
return (
|
|
390
|
+
[code, message].filter((part) => part !== undefined).join(": ") || text
|
|
391
|
+
);
|
|
392
|
+
} catch {
|
|
393
|
+
return text;
|
|
394
|
+
}
|
|
395
|
+
}
|