@cursor/july 0.1.93 → 0.1.95
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 +8 -20
- package/README.md +4 -26
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +14 -2
- package/dist/channels/github/types.d.ts +18 -3
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +11 -3
- package/dist/channels/origin/origin-webhook.d.ts +11 -1
- package/dist/channels/origin/origin-webhook.d.ts.map +1 -1
- package/dist/channels/origin/origin-webhook.js +23 -3
- package/dist/channels/origin/types.d.ts +8 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/attachments.js +2 -2
- package/dist/channels/slack/dispatch.d.ts +0 -7
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +4 -7
- package/dist/channels/slack/eval-directive.d.ts +5 -12
- package/dist/channels/slack/eval-directive.d.ts.map +1 -1
- package/dist/channels/slack/eval-directive.js +8 -19
- package/dist/channels/slack/index.d.ts +0 -6
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +0 -6
- package/dist/channels/slack/pr-ref.d.ts +7 -1
- package/dist/channels/slack/pr-ref.d.ts.map +1 -1
- package/dist/channels/slack/pr-ref.js +42 -23
- package/dist/channels/slack/setup.d.ts +4 -4
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +8 -15
- package/dist/channels/slack/slack-channel.d.ts +6 -13
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +15 -101
- package/dist/channels/slack/types.d.ts +12 -79
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/types.js +1 -15
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +12 -0
- package/dist/connections.d.ts +18 -9
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +17 -8
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.CjWU-x0z.js → app.BBj0klBO.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.oqPawjiD.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.Cxy8ySFQ.js → VPLocalSearchBox.CUEXpL78.js} +1 -1
- package/dist/docs/assets/chunks/{theme.Dvq1Bktu.js → theme.DabmQnia.js} +2 -2
- package/dist/docs/assets/concepts.md.lwAgBIMI.js +1 -0
- package/dist/docs/assets/{deployment.md.DoLFAzfm.js → deployment.md.D9msOFOW.js} +3 -8
- package/dist/docs/assets/{deployment.md.DoLFAzfm.lean.js → deployment.md.D9msOFOW.lean.js} +1 -1
- package/dist/docs/assets/{guides_agent-to-agent.md.B3JIaAqz.js → guides_agent-to-agent.md.BDb0t1QV.js} +1 -1
- package/dist/docs/assets/guides_cloud-runtime.md.CkYbjnAX.js +9 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CkYbjnAX.lean.js +1 -0
- package/dist/docs/assets/{guides_convert-automation.md.Bboisykk.js → guides_convert-automation.md.B4sjlodG.js} +1 -1
- package/dist/docs/assets/{guides_github.md.DqJhuaN1.js → guides_github.md.Cnh2mL4a.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.CJvrXtkN.js → guides_mcp-oauth.md.DPYmBCbV.js} +7 -9
- package/dist/docs/assets/{guides_mcp-oauth.md.CJvrXtkN.lean.js → guides_mcp-oauth.md.DPYmBCbV.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.mqeNKs84.js → guides_slack.md.C32HsdKk.js} +5 -11
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +1 -0
- package/dist/docs/assets/index.md.BoHaMdeZ.js +5 -0
- package/dist/docs/assets/{index.md.B-lVR4wT.lean.js → index.md.BoHaMdeZ.lean.js} +1 -1
- package/dist/docs/assets/{quickstart.md.BrmfrrIr.js → quickstart.md.Nj_LjW_a.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.D9KESDsD.js → reference_cli.md.BsMOxDvh.js} +4 -3
- package/dist/docs/assets/{reference_cli.md.D9KESDsD.lean.js → reference_cli.md.BsMOxDvh.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.DB6SsN6U.js → reference_connections.md.BH8Oc0D0.js} +5 -5
- package/dist/docs/assets/{reference_connections.md.DB6SsN6U.lean.js → reference_connections.md.BH8Oc0D0.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BxN87gCw.js → reference_hooks.md.a8BJxMR5.js} +1 -1
- package/dist/docs/assets/reference_http-api.md.D89k1mdm.js +11 -0
- package/dist/docs/assets/reference_http-api.md.D89k1mdm.lean.js +1 -0
- package/dist/docs/assets/reference_project-layout.md.Bv4KOtlB.js +19 -0
- package/dist/docs/assets/{reference_subagents.md.Xoav0AII.js → reference_subagents.md.CfsIloPm.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.DuKvkYWG.js → reference_tools.md.BHeXn2id.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.DuKvkYWG.lean.js → reference_tools.md.BHeXn2id.lean.js} +1 -1
- package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.js → templates_agentic-owners.md.BZSH4N9z.js} +1 -1
- package/dist/docs/assets/{templates_demo.md.DhFcWN6j.js → templates_demo.md.BeQX9V3H.js} +1 -1
- package/dist/docs/assets/{templates_pr-autofixer.md.R4K_qytS.js → templates_pr-autofixer.md.x5zl6-GT.js} +2 -2
- package/dist/docs/assets/{templates_pr-autofixer.md.R4K_qytS.lean.js → templates_pr-autofixer.md.x5zl6-GT.lean.js} +1 -1
- package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.js +4 -0
- package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.lean.js +1 -0
- package/dist/docs/assets/{templates_security-reviewer.md.ByFyRta2.js → templates_security-reviewer.md.lshxbCLK.js} +2 -2
- package/dist/docs/assets/{templates_security-reviewer.md.ByFyRta2.lean.js → templates_security-reviewer.md.lshxbCLK.lean.js} +1 -1
- package/dist/docs/assets/{templates_triage.md.CVlpctKS.js → templates_triage.md.Co4UNzkZ.js} +3 -3
- package/dist/docs/assets/{templates_triage.md.CVlpctKS.lean.js → templates_triage.md.Co4UNzkZ.lean.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/concepts.md +1 -0
- package/dist/docs/deployment.html +7 -12
- package/dist/docs/deployment.md +1 -20
- package/dist/docs/design/agsh.md +406 -0
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +6 -6
- package/dist/docs/guides/agent-to-agent.md +2 -2
- package/dist/docs/guides/cloud-runtime.html +6 -6
- package/dist/docs/guides/cloud-runtime.md +1 -0
- package/dist/docs/guides/convert-automation.html +6 -6
- package/dist/docs/guides/convert-automation.md +1 -1
- package/dist/docs/guides/github.html +6 -6
- package/dist/docs/guides/github.md +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +11 -13
- package/dist/docs/guides/mcp-oauth.md +10 -18
- package/dist/docs/guides/opentelemetry.html +5 -5
- package/dist/docs/guides/slack.html +9 -15
- package/dist/docs/guides/slack.md +9 -46
- 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 +3 -29
- package/dist/docs/llms-full.txt +756 -2810
- package/dist/docs/llms.txt +3 -16
- package/dist/docs/quickstart.html +6 -6
- package/dist/docs/quickstart.md +2 -3
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +8 -7
- package/dist/docs/reference/cli.md +5 -2
- package/dist/docs/reference/connections.html +9 -9
- package/dist/docs/reference/connections.md +15 -11
- package/dist/docs/reference/hooks.html +6 -6
- package/dist/docs/reference/hooks.md +2 -3
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +8 -0
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +8 -6
- package/dist/docs/reference/project-layout.md +5 -1
- 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 +4 -4
- package/dist/docs/reference/subagents.html +6 -6
- package/dist/docs/reference/subagents.md +2 -2
- package/dist/docs/reference/tools.html +7 -7
- package/dist/docs/reference/tools.md +19 -3
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +7 -7
- package/dist/docs/templates/agentic-owners.md +1 -1
- package/dist/docs/templates/demo.html +6 -6
- package/dist/docs/templates/demo.md +3 -2
- package/dist/docs/templates/pr-autofixer.html +6 -6
- package/dist/docs/templates/pr-autofixer.md +8 -13
- package/dist/docs/templates/security-help.html +30 -0
- package/dist/docs/templates/security-help.md +65 -0
- package/dist/docs/templates/security-reviewer.html +6 -6
- package/dist/docs/templates/security-reviewer.md +1 -3
- package/dist/docs/templates/triage.html +7 -7
- package/dist/docs/templates/triage.md +2 -6
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/files-backends/cursor-hosted.d.ts +6 -2
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +2 -2
- package/dist/files.d.ts +2 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +5 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/advertise-tools.d.ts +11 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +47 -9
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +135 -6
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +7 -4
- package/dist/internal/conversation-mirror.d.ts +82 -0
- package/dist/internal/conversation-mirror.d.ts.map +1 -0
- package/dist/internal/conversation-mirror.js +251 -0
- package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -1
- package/dist/internal/convert-automation/convert-workflow.js +26 -15
- package/dist/internal/convert-automation/slug.d.ts +0 -2
- package/dist/internal/convert-automation/slug.d.ts.map +1 -1
- package/dist/internal/convert-automation/slug.js +0 -8
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +5 -1
- package/dist/internal/deferred-channel-session.d.ts +20 -0
- package/dist/internal/deferred-channel-session.d.ts.map +1 -0
- package/dist/internal/deferred-channel-session.js +62 -0
- package/dist/internal/deploy-client.d.ts +13 -1
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +11 -1
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +11 -5
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +110 -15
- package/dist/internal/framework-storage-selection.d.ts +32 -16
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +51 -17
- package/dist/internal/hosted-admission-context.d.ts +20 -0
- package/dist/internal/hosted-admission-context.d.ts.map +1 -0
- package/dist/internal/hosted-admission-context.js +31 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +5 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +33 -1
- package/dist/internal/hosted-delivery.d.ts +4 -2
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +97 -44
- package/dist/internal/hosted-managed-automation.d.ts +30 -0
- package/dist/internal/hosted-managed-automation.d.ts.map +1 -0
- package/dist/internal/hosted-managed-automation.js +58 -0
- package/dist/internal/mcp-endpoint.js +3 -3
- package/dist/internal/mcp-host.d.ts +8 -7
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +8 -7
- package/dist/internal/peer-connections.d.ts.map +1 -1
- package/dist/internal/peer-connections.js +5 -1
- package/dist/internal/playground/static.d.ts +0 -3
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +5 -7
- package/dist/internal/review-comments.d.ts.map +1 -1
- package/dist/internal/review-comments.js +10 -98
- package/dist/internal/scm/pr-url.d.ts +14 -0
- package/dist/internal/scm/pr-url.d.ts.map +1 -0
- package/dist/internal/scm/pr-url.js +65 -0
- package/dist/internal/sdk-runner.d.ts +14 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +41 -2
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +123 -174
- package/dist/internal/session-engine.d.ts +45 -10
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +217 -65
- package/dist/internal/tool-catalog.d.ts +31 -0
- package/dist/internal/tool-catalog.d.ts.map +1 -0
- package/dist/internal/tool-catalog.js +67 -0
- package/dist/playground/assets/index-CF7hUDnQ.css +1 -0
- package/dist/playground/assets/{index-D9MFzhNE.js → index-CZA1uEWA.js} +48 -48
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +7 -2
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +2 -2
- package/dist/types.d.ts +72 -23
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +19 -0
- package/docs/README.md +3 -29
- package/docs/concepts.md +1 -0
- package/docs/deployment.md +1 -20
- package/docs/design/agsh.md +406 -0
- package/docs/guides/agent-to-agent.md +2 -2
- package/docs/guides/cloud-runtime.md +1 -0
- package/docs/guides/convert-automation.md +1 -1
- package/docs/guides/github.md +4 -4
- package/docs/guides/mcp-oauth.md +10 -18
- package/docs/guides/slack.md +10 -47
- package/docs/quickstart.md +2 -3
- package/docs/reference/cli.md +5 -2
- package/docs/reference/connections.md +15 -11
- package/docs/reference/hooks.md +2 -3
- package/docs/reference/http-api.md +8 -0
- package/docs/reference/project-layout.md +5 -1
- package/docs/reference/subagents.md +2 -2
- package/docs/reference/tools.md +19 -3
- package/docs/templates/agentic-owners.md +1 -1
- package/docs/templates/demo.md +3 -2
- package/docs/templates/pr-autofixer.md +8 -13
- package/docs/templates/security-help.md +70 -0
- package/docs/templates/security-reviewer.md +1 -3
- package/docs/templates/triage.md +2 -6
- package/docs/troubleshooting.md +2 -2
- package/package.json +9 -2
- package/skills/create-agent/SKILL.md +6 -13
- package/skills/debug/SKILL.md +2 -4
- package/skills/evals/SKILL.md +1 -1
- package/skills/framework-map/SKILL.md +3 -2
- package/skills/mcp-auth/SKILL.md +10 -13
- package/skills/setup-slack/SKILL.md +21 -137
- package/src/channels/github/github-channel.ts +23 -8
- package/src/channels/github/types.ts +19 -2
- package/src/channels/origin/origin-channel.ts +13 -1
- package/src/channels/origin/origin-webhook.ts +27 -3
- package/src/channels/origin/types.ts +8 -0
- package/src/channels/slack/attachments.ts +2 -2
- package/src/channels/slack/dispatch.ts +2 -16
- package/src/channels/slack/eval-directive.ts +8 -27
- package/src/channels/slack/index.ts +0 -6
- package/src/channels/slack/pr-ref.ts +56 -25
- package/src/channels/slack/setup.ts +8 -15
- package/src/channels/slack/slack-channel.ts +14 -125
- package/src/channels/slack/types.ts +12 -96
- package/src/client.ts +23 -0
- package/src/connections.ts +20 -7
- package/src/files-backends/cursor-hosted.ts +9 -3
- package/src/files.ts +11 -0
- package/src/index.ts +2 -0
- package/src/internal/advertise-tools.ts +45 -7
- package/src/internal/cli-deploy.ts +171 -7
- package/src/internal/cli-mcp-oauth.ts +6 -4
- package/src/internal/conversation-mirror.ts +330 -0
- package/src/internal/convert-automation/convert-workflow.ts +29 -17
- package/src/internal/convert-automation/slug.ts +0 -9
- package/src/internal/cursor/account-mcp.ts +4 -1
- package/src/internal/deferred-channel-session.ts +61 -0
- package/src/internal/deploy-client.ts +24 -1
- package/src/internal/deploy-manifest.ts +10 -5
- package/src/internal/discovery.ts +129 -15
- package/src/internal/fixtures/units-server.ts +52 -0
- package/src/internal/framework-storage-selection.ts +61 -19
- package/src/internal/hosted-admission-context.ts +37 -0
- package/src/internal/hosted-delivery-protocol.ts +44 -1
- package/src/internal/hosted-delivery.ts +155 -68
- package/src/internal/hosted-managed-automation.ts +72 -0
- package/src/internal/mcp-endpoint.ts +3 -3
- package/src/internal/mcp-host.ts +8 -7
- package/src/internal/peer-connections.ts +4 -1
- package/src/internal/playground/static.ts +1 -3
- package/src/internal/resolved-connections.ts +8 -10
- package/src/internal/review-comments.ts +10 -113
- package/src/internal/scm/pr-url.ts +95 -0
- package/src/internal/sdk-runner.ts +57 -2
- package/src/internal/server.ts +161 -251
- package/src/internal/session-engine.ts +266 -69
- package/src/internal/tool-catalog.ts +106 -0
- package/src/storage-backends/cursor-hosted.ts +10 -3
- package/src/types.ts +90 -23
- package/templates/agentic-owners/README.md +1 -1
- package/templates/agentic-owners/agent/agent.ts +0 -10
- package/templates/agentic-owners/agent/channels/github.ts +5 -14
- package/templates/agentic-owners/agent/lib/config.ts +0 -8
- package/templates/agentic-owners/agent/lib/review.ts +2 -15
- package/templates/agentic-owners/agent/tools/record_review.ts +2 -4
- package/templates/demo/agent/agent.ts +0 -10
- package/templates/pr-autofixer/README.md +0 -2
- package/templates/pr-autofixer/agent/agent.ts +0 -11
- package/templates/pr-autofixer/agent/channels/slack.ts +1 -2
- package/templates/pr-autofixer/agent/lib/pr-state.ts +5 -17
- package/templates/pr-autofixer/agent/lib/repos.ts +0 -1
- package/templates/security-help/README.md +2 -2
- package/templates/security-help/agent/agent.ts +1 -2
- package/templates/security-help/agent/channels/slack.ts +0 -3
- package/templates/security-help/agent/instructions.md +9 -10
- package/templates/security-help/agent/skills/access-request.md +1 -1
- package/templates/security-help/agent/skills/faq.md +31 -0
- package/templates/security-help/agent/skills/security-playbooks.md +1 -1
- package/templates/security-help/package.json +1 -2
- package/templates/security-reviewer/agent/agent.ts +0 -10
- package/templates/triage/README.md +2 -1
- package/templates/triage/agent/agent.ts +0 -10
- package/templates/triage/agent/channels/queue.ts +1 -1
- package/templates/triage/agent/channels/webhook.ts +1 -3
- package/templates/triage/overlays/jira/agent/mcp-connections/tracker.ts +0 -1
- package/templates/triage/overlays/linear/agent/mcp-connections/tracker.ts +0 -1
- package/dist/channels/slack/cursor-account.d.ts +0 -87
- package/dist/channels/slack/cursor-account.d.ts.map +0 -1
- package/dist/channels/slack/cursor-account.js +0 -100
- package/dist/docs/assets/chunks/@localSearchIndexroot.ChpIC3Zy.js +0 -1
- package/dist/docs/assets/concepts.md.F6AiPorA.js +0 -1
- package/dist/docs/assets/example-agents_approval-buddy.md.DmezILPg.js +0 -10
- package/dist/docs/assets/example-agents_approval-buddy.md.DmezILPg.lean.js +0 -1
- package/dist/docs/assets/example-agents_benny.md.B0kwY7D_.js +0 -5
- package/dist/docs/assets/example-agents_benny.md.B0kwY7D_.lean.js +0 -1
- package/dist/docs/assets/example-agents_bugbot.md.BRGMi9O2.js +0 -11
- package/dist/docs/assets/example-agents_bugbot.md.BRGMi9O2.lean.js +0 -1
- package/dist/docs/assets/example-agents_codebase-wiki.md.BBNw9Ekr.js +0 -8
- package/dist/docs/assets/example-agents_codebase-wiki.md.BBNw9Ekr.lean.js +0 -1
- package/dist/docs/assets/example-agents_codeowners-review.md.Bfta-lBU.js +0 -8
- package/dist/docs/assets/example-agents_codeowners-review.md.Bfta-lBU.lean.js +0 -1
- package/dist/docs/assets/example-agents_concierge.md.BzB2b20R.js +0 -22
- package/dist/docs/assets/example-agents_concierge.md.BzB2b20R.lean.js +0 -1
- package/dist/docs/assets/example-agents_index.md.ChBp0AX6.js +0 -2
- package/dist/docs/assets/example-agents_index.md.ChBp0AX6.lean.js +0 -1
- package/dist/docs/assets/example-agents_knowledge-base.md.CrA85ig-.js +0 -11
- package/dist/docs/assets/example-agents_knowledge-base.md.CrA85ig-.lean.js +0 -1
- package/dist/docs/assets/example-agents_oncall.md.DK4XkYTd.js +0 -10
- package/dist/docs/assets/example-agents_oncall.md.DK4XkYTd.lean.js +0 -1
- package/dist/docs/assets/example-agents_security-reviewer.md.74pPpWYj.js +0 -19
- package/dist/docs/assets/example-agents_security-reviewer.md.74pPpWYj.lean.js +0 -1
- package/dist/docs/assets/example-agents_slack-agent.md.D7Kdj5BV.js +0 -5
- package/dist/docs/assets/example-agents_slack-agent.md.D7Kdj5BV.lean.js +0 -1
- package/dist/docs/assets/example-agents_weather-agent.md.CaGpmw3Y.js +0 -25
- package/dist/docs/assets/example-agents_weather-agent.md.CaGpmw3Y.lean.js +0 -1
- package/dist/docs/assets/guides_cloud-runtime.md.BnvjPiia.js +0 -9
- package/dist/docs/assets/guides_cloud-runtime.md.BnvjPiia.lean.js +0 -1
- package/dist/docs/assets/guides_slack.md.mqeNKs84.lean.js +0 -1
- package/dist/docs/assets/index.md.B-lVR4wT.js +0 -5
- package/dist/docs/assets/reference_http-api.md.C68BERYr.js +0 -11
- package/dist/docs/assets/reference_http-api.md.C68BERYr.lean.js +0 -1
- package/dist/docs/assets/reference_project-layout.md.WN9nwJht.js +0 -17
- package/dist/docs/assets/troubleshooting.md.vCWwvqcJ.js +0 -1
- package/dist/docs/example-agents/approval-buddy.html +0 -36
- package/dist/docs/example-agents/approval-buddy.md +0 -266
- package/dist/docs/example-agents/benny.html +0 -31
- package/dist/docs/example-agents/benny.md +0 -173
- package/dist/docs/example-agents/bugbot.html +0 -37
- package/dist/docs/example-agents/bugbot.md +0 -229
- package/dist/docs/example-agents/codebase-wiki.html +0 -34
- package/dist/docs/example-agents/codebase-wiki.md +0 -167
- package/dist/docs/example-agents/codeowners-review.html +0 -34
- package/dist/docs/example-agents/codeowners-review.md +0 -192
- package/dist/docs/example-agents/concierge.html +0 -48
- package/dist/docs/example-agents/concierge.md +0 -200
- package/dist/docs/example-agents/index.html +0 -28
- package/dist/docs/example-agents/index.md +0 -99
- package/dist/docs/example-agents/knowledge-base.html +0 -37
- package/dist/docs/example-agents/knowledge-base.md +0 -168
- package/dist/docs/example-agents/oncall.html +0 -36
- package/dist/docs/example-agents/oncall.md +0 -212
- package/dist/docs/example-agents/security-reviewer.html +0 -45
- package/dist/docs/example-agents/security-reviewer.md +0 -265
- package/dist/docs/example-agents/slack-agent.html +0 -31
- package/dist/docs/example-agents/slack-agent.md +0 -142
- package/dist/docs/example-agents/weather-agent.html +0 -51
- package/dist/docs/example-agents/weather-agent.md +0 -297
- package/dist/internal/cursor-slack-relay.d.ts +0 -96
- package/dist/internal/cursor-slack-relay.d.ts.map +0 -1
- package/dist/internal/cursor-slack-relay.js +0 -176
- package/dist/playground/assets/index-D9N7-q97.css +0 -1
- package/docs/example-agents/approval-buddy.md +0 -271
- package/docs/example-agents/benny.md +0 -178
- package/docs/example-agents/bugbot.md +0 -234
- package/docs/example-agents/codebase-wiki.md +0 -172
- package/docs/example-agents/codeowners-review.md +0 -197
- package/docs/example-agents/concierge.md +0 -205
- package/docs/example-agents/index.md +0 -104
- package/docs/example-agents/knowledge-base.md +0 -173
- package/docs/example-agents/oncall.md +0 -217
- package/docs/example-agents/security-reviewer.md +0 -270
- package/docs/example-agents/slack-agent.md +0 -147
- package/docs/example-agents/weather-agent.md +0 -302
- package/src/channels/slack/cursor-account.ts +0 -202
- package/src/internal/cursor-slack-relay.ts +0 -249
- package/templates/security-help/agent/knowledge/faq/approvals.md +0 -5
- package/templates/security-help/agent/knowledge/faq/channels.md +0 -6
- package/templates/security-help/agent/knowledge/faq/phishing.md +0 -10
- package/templates/security-help/agent/skills/security-first-pass.md +0 -15
- /package/dist/docs/assets/{concepts.md.F6AiPorA.lean.js → concepts.md.lwAgBIMI.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.B3JIaAqz.lean.js → guides_agent-to-agent.md.BDb0t1QV.lean.js} +0 -0
- /package/dist/docs/assets/{guides_convert-automation.md.Bboisykk.lean.js → guides_convert-automation.md.B4sjlodG.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.DqJhuaN1.lean.js → guides_github.md.Cnh2mL4a.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.BrmfrrIr.lean.js → quickstart.md.Nj_LjW_a.lean.js} +0 -0
- /package/dist/docs/assets/{reference_hooks.md.BxN87gCw.lean.js → reference_hooks.md.a8BJxMR5.lean.js} +0 -0
- /package/dist/docs/assets/{reference_project-layout.md.WN9nwJht.lean.js → reference_project-layout.md.Bv4KOtlB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_subagents.md.Xoav0AII.lean.js → reference_subagents.md.CfsIloPm.lean.js} +0 -0
- /package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.lean.js → templates_agentic-owners.md.BZSH4N9z.lean.js} +0 -0
- /package/dist/docs/assets/{templates_demo.md.DhFcWN6j.lean.js → templates_demo.md.BeQX9V3H.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.vCWwvqcJ.lean.js → troubleshooting.md.Ctv3T8C2.lean.js} +0 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable mirror for the SDK runner's conversation store.
|
|
3
|
+
*
|
|
4
|
+
* The Cursor SDK keeps each local conversation in SQLite under the engine's
|
|
5
|
+
* state root (`runner/index.db` + `runner/agents/agent-<hash>/store.db`).
|
|
6
|
+
* That disk dies with the pod: on architecture v2, session **records** and
|
|
7
|
+
* event chunks survive replacement through the control-plane storage mirror
|
|
8
|
+
* (framework-storage-selection.ts), but the conversation itself was never
|
|
9
|
+
* hydrated anywhere — a replacement pod resumed every thread as a fresh
|
|
10
|
+
* conversation.
|
|
11
|
+
*
|
|
12
|
+
* This module mirrors the conversation through the SDK's own store APIs —
|
|
13
|
+
* the agent document (which carries `sdkMetadata.blobEncryptionKey`, without
|
|
14
|
+
* which the checkpoint blobs cannot be decrypted) plus its content-addressed
|
|
15
|
+
* checkpoint blobs — into the deployment's shared file storage. On
|
|
16
|
+
* Cursor-managed hosting that is the Agent Store reached over
|
|
17
|
+
* `/v0/agent-serve-files` presigned URLs: the store is **not mounted** as a
|
|
18
|
+
* filesystem in the engine VM (the FUSE mount at
|
|
19
|
+
* {@link DEPLOYMENT_STORE_MOUNT_PATH} exists only on cloud-runtime VMs), so
|
|
20
|
+
* the mirror moves bytes through the {@link FileSink} contract instead.
|
|
21
|
+
*
|
|
22
|
+
* Going through the store APIs rather than copying `store.db` files sidesteps
|
|
23
|
+
* WAL consistency and the shared `index.db` (per-session raw copies would
|
|
24
|
+
* clobber other sessions' rows); checkpoint blobs are content-addressed, so
|
|
25
|
+
* repeat persists upload only what is new.
|
|
26
|
+
*
|
|
27
|
+
* Timing: the runner hydrates before `Agent.resume` (so a follow-up landing
|
|
28
|
+
* on a fresh pod — including a v2 hosted-execution delivery — finds the
|
|
29
|
+
* conversation before the turn runs) and persists after each local turn
|
|
30
|
+
* settles, **awaited**, because a hosted pod can be parked immediately after
|
|
31
|
+
* the execution reply.
|
|
32
|
+
*
|
|
33
|
+
* Run rows and run events are deliberately not mirrored: they are per-pod
|
|
34
|
+
* bookkeeping (turn numbers, stream offsets), and the durable session event
|
|
35
|
+
* stream already lives in the control-plane storage mirror.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import type { LocalAgentDocument, LocalAgentStore } from "@cursor/sdk";
|
|
39
|
+
import { agentStoreKeys, type FileSink } from "../files.js";
|
|
40
|
+
import {
|
|
41
|
+
cursorHostedFiles,
|
|
42
|
+
isCursorHostedFilesAvailable,
|
|
43
|
+
} from "../files-backends/cursor-hosted.js";
|
|
44
|
+
import type { AgentProject } from "../types.js";
|
|
45
|
+
import { resolveApiKeySync } from "./cursor/credentials.js";
|
|
46
|
+
import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
|
|
47
|
+
import { describeError } from "./describe-error.js";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Persist/restore one SDK conversation between a {@link LocalAgentStore} and
|
|
51
|
+
* durable file storage. Implemented by {@link createConversationMirror};
|
|
52
|
+
* consumed by the SDK runner.
|
|
53
|
+
*/
|
|
54
|
+
export interface ConversationMirror {
|
|
55
|
+
/**
|
|
56
|
+
* Restore `sdkAgentId`'s conversation into `store` when the store does not
|
|
57
|
+
* already hold it. Resolves `true` when a conversation was restored,
|
|
58
|
+
* `false` on a definitive miss (never persisted, or already local — the
|
|
59
|
+
* caller falls through to its fresh-conversation path). A sink **failure**
|
|
60
|
+
* propagates: an outage must fail the turn (retryable) rather than
|
|
61
|
+
* silently fork the thread onto a fresh conversation.
|
|
62
|
+
*/
|
|
63
|
+
hydrate(store: LocalAgentStore, sdkAgentId: string): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Mirror `sdkAgentId`'s conversation from `store` to the sink
|
|
66
|
+
* (last write wins). No-op until the conversation has a checkpoint.
|
|
67
|
+
*/
|
|
68
|
+
persist(store: LocalAgentStore, sdkAgentId: string): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Wire shape at {@link agentStoreKeys.conversationManifest}. */
|
|
72
|
+
interface ConversationManifestV1 {
|
|
73
|
+
v: 1;
|
|
74
|
+
/** The SDK agent document, verbatim apart from `activeRunId` (nulled). */
|
|
75
|
+
agent: LocalAgentDocument;
|
|
76
|
+
/** Checkpoint blob ids present under the conversation's blob prefix. */
|
|
77
|
+
blobIds: string[];
|
|
78
|
+
persistedAtMs: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface CreateConversationMirrorOptions {
|
|
82
|
+
sink: FileSink;
|
|
83
|
+
/** Agent name baked into every minted key. */
|
|
84
|
+
agentName: string;
|
|
85
|
+
logger?: (line: string) => void;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Build a {@link ConversationMirror} over a {@link FileSink}. */
|
|
89
|
+
export function createConversationMirror(
|
|
90
|
+
options: CreateConversationMirrorOptions
|
|
91
|
+
): ConversationMirror {
|
|
92
|
+
const { sink, agentName } = options;
|
|
93
|
+
const logger = options.logger ?? (() => {});
|
|
94
|
+
/** Blob ids known to be in the sink, per SDK agent id (upload dedupe). */
|
|
95
|
+
const mirrored = new Map<string, Set<string>>();
|
|
96
|
+
/**
|
|
97
|
+
* Per-conversation serialization so a persist cannot interleave with a
|
|
98
|
+
* hydrate (or another persist) for the same conversation.
|
|
99
|
+
*/
|
|
100
|
+
const chains = new Map<string, Promise<unknown>>();
|
|
101
|
+
|
|
102
|
+
function serialize<T>(sdkAgentId: string, run: () => Promise<T>): Promise<T> {
|
|
103
|
+
const previous = chains.get(sdkAgentId) ?? Promise.resolve();
|
|
104
|
+
const next = previous.then(run, run);
|
|
105
|
+
chains.set(
|
|
106
|
+
sdkAgentId,
|
|
107
|
+
next.catch(() => {})
|
|
108
|
+
);
|
|
109
|
+
return next;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function mirroredBlobIds(sdkAgentId: string): Promise<Set<string>> {
|
|
113
|
+
const cached = mirrored.get(sdkAgentId);
|
|
114
|
+
if (cached !== undefined) {
|
|
115
|
+
return cached;
|
|
116
|
+
}
|
|
117
|
+
// Seed from the previous manifest so a fresh pod does not re-upload the
|
|
118
|
+
// whole history on its first persist. A miss (or parse failure) seeds
|
|
119
|
+
// empty — re-uploading is wasteful, never wrong.
|
|
120
|
+
const seeded = new Set<string>();
|
|
121
|
+
try {
|
|
122
|
+
const manifest = await readManifest(sink, agentName, sdkAgentId);
|
|
123
|
+
for (const blobId of manifest?.blobIds ?? []) {
|
|
124
|
+
seeded.add(blobId);
|
|
125
|
+
}
|
|
126
|
+
} catch (error) {
|
|
127
|
+
logger(
|
|
128
|
+
`[agent-sdk] conversation mirror: could not read the prior manifest for ${sdkAgentId} (${describeError(error)}); re-uploading blobs`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
mirrored.set(sdkAgentId, seeded);
|
|
132
|
+
return seeded;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
persist(store, sdkAgentId): Promise<void> {
|
|
137
|
+
return serialize(sdkAgentId, async () => {
|
|
138
|
+
const document = await store.agents.get({ agentId: sdkAgentId });
|
|
139
|
+
if (document === null || document.latestCheckpoint == null) {
|
|
140
|
+
// Nothing restorable yet (no conversation, or no checkpoint).
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const uploaded = await mirroredBlobIds(sdkAgentId);
|
|
144
|
+
const blobIds = await listCheckpointBlobIds(store, sdkAgentId);
|
|
145
|
+
for (const blobId of blobIds) {
|
|
146
|
+
if (uploaded.has(blobId)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const bytes = await store.checkpoints.get({
|
|
150
|
+
agentId: sdkAgentId,
|
|
151
|
+
blobId,
|
|
152
|
+
});
|
|
153
|
+
if (bytes === null) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
await sink.put(
|
|
157
|
+
agentStoreKeys.conversationBlob(agentName, sdkAgentId, blobId),
|
|
158
|
+
bytes
|
|
159
|
+
);
|
|
160
|
+
// Content-addressed: once in the sink, never re-uploaded.
|
|
161
|
+
uploaded.add(blobId);
|
|
162
|
+
}
|
|
163
|
+
const manifest: ConversationManifestV1 = {
|
|
164
|
+
v: 1,
|
|
165
|
+
// The referenced run is pod-local bookkeeping and is not mirrored;
|
|
166
|
+
// a hydrated store must not point at a run row it does not hold.
|
|
167
|
+
agent: { ...document, activeRunId: null },
|
|
168
|
+
blobIds: blobIds.filter((blobId) => uploaded.has(blobId)),
|
|
169
|
+
persistedAtMs: Date.now(),
|
|
170
|
+
};
|
|
171
|
+
// Manifest last: it only ever references blobs already uploaded.
|
|
172
|
+
await sink.put(
|
|
173
|
+
agentStoreKeys.conversationManifest(agentName, sdkAgentId),
|
|
174
|
+
new TextEncoder().encode(JSON.stringify(manifest))
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
hydrate(store, sdkAgentId): Promise<boolean> {
|
|
180
|
+
return serialize(sdkAgentId, async () => {
|
|
181
|
+
const existing = await store.agents.get({ agentId: sdkAgentId });
|
|
182
|
+
if (existing !== null) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
const manifest = await readManifest(sink, agentName, sdkAgentId);
|
|
186
|
+
if (manifest === undefined) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
const rootBlobId = manifest.agent.latestCheckpoint?.rootBlobId;
|
|
190
|
+
const restored = new Set<string>();
|
|
191
|
+
for (const blobId of manifest.blobIds) {
|
|
192
|
+
const body = await sink.get(
|
|
193
|
+
agentStoreKeys.conversationBlob(agentName, sdkAgentId, blobId)
|
|
194
|
+
);
|
|
195
|
+
const bytes =
|
|
196
|
+
body === undefined
|
|
197
|
+
? undefined
|
|
198
|
+
: body instanceof Uint8Array
|
|
199
|
+
? body
|
|
200
|
+
: body.body;
|
|
201
|
+
if (bytes === undefined) {
|
|
202
|
+
// Definitive absence (never uploaded, or deleted). A missing
|
|
203
|
+
// root blob makes the conversation unrestorable — fall through
|
|
204
|
+
// to the caller's fresh-conversation path rather than creating
|
|
205
|
+
// an agent row whose checkpoint cannot load.
|
|
206
|
+
if (blobId === rootBlobId) {
|
|
207
|
+
logger(
|
|
208
|
+
`[agent-sdk] conversation mirror: the root checkpoint blob for ${sdkAgentId} is missing from the sink; treating the conversation as unrestorable`
|
|
209
|
+
);
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (
|
|
215
|
+
(await store.checkpoints.get({ agentId: sdkAgentId, blobId })) ===
|
|
216
|
+
null
|
|
217
|
+
) {
|
|
218
|
+
await store.checkpoints.create({
|
|
219
|
+
agentId: sdkAgentId,
|
|
220
|
+
blobId,
|
|
221
|
+
data: bytes,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
restored.add(blobId);
|
|
225
|
+
}
|
|
226
|
+
if (rootBlobId !== undefined && !restored.has(rootBlobId)) {
|
|
227
|
+
logger(
|
|
228
|
+
`[agent-sdk] conversation mirror: the manifest for ${sdkAgentId} does not list its root checkpoint blob; treating the conversation as unrestorable`
|
|
229
|
+
);
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
await store.agents.create({
|
|
233
|
+
agent: { ...manifest.agent, activeRunId: null },
|
|
234
|
+
});
|
|
235
|
+
mirrored.set(sdkAgentId, restored);
|
|
236
|
+
logger(
|
|
237
|
+
`[agent-sdk] conversation mirror: restored the conversation for ${sdkAgentId} (${restored.size} checkpoint blob(s))`
|
|
238
|
+
);
|
|
239
|
+
return true;
|
|
240
|
+
});
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async function readManifest(
|
|
246
|
+
sink: FileSink,
|
|
247
|
+
agentName: string,
|
|
248
|
+
sdkAgentId: string
|
|
249
|
+
): Promise<ConversationManifestV1 | undefined> {
|
|
250
|
+
const body = await sink.get(
|
|
251
|
+
agentStoreKeys.conversationManifest(agentName, sdkAgentId)
|
|
252
|
+
);
|
|
253
|
+
if (body === undefined) {
|
|
254
|
+
return undefined;
|
|
255
|
+
}
|
|
256
|
+
const bytes = body instanceof Uint8Array ? body : body.body;
|
|
257
|
+
const parsed: unknown = JSON.parse(new TextDecoder().decode(bytes));
|
|
258
|
+
if (
|
|
259
|
+
parsed === null ||
|
|
260
|
+
typeof parsed !== "object" ||
|
|
261
|
+
(parsed as { v?: unknown }).v !== 1
|
|
262
|
+
) {
|
|
263
|
+
throw new Error(
|
|
264
|
+
`conversation mirror: unsupported manifest for ${sdkAgentId}`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
const manifest = parsed as ConversationManifestV1;
|
|
268
|
+
if (
|
|
269
|
+
manifest.agent === null ||
|
|
270
|
+
typeof manifest.agent !== "object" ||
|
|
271
|
+
manifest.agent.agentId !== sdkAgentId ||
|
|
272
|
+
!Array.isArray(manifest.blobIds)
|
|
273
|
+
) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
`conversation mirror: malformed manifest for ${sdkAgentId}`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
return manifest;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function listCheckpointBlobIds(
|
|
282
|
+
store: LocalAgentStore,
|
|
283
|
+
sdkAgentId: string
|
|
284
|
+
): Promise<string[]> {
|
|
285
|
+
const blobIds: string[] = [];
|
|
286
|
+
let cursor: string | undefined;
|
|
287
|
+
do {
|
|
288
|
+
const page = await store.checkpoints.list({
|
|
289
|
+
filter: { agentIds: [sdkAgentId], cursor },
|
|
290
|
+
});
|
|
291
|
+
blobIds.push(...page.items);
|
|
292
|
+
cursor = page.nextCursor;
|
|
293
|
+
} while (cursor !== undefined);
|
|
294
|
+
return blobIds;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Whether (and over which sink) this serve process mirrors conversations.
|
|
299
|
+
*
|
|
300
|
+
* Selected for architecture-v2 agents on Cursor-managed hosting — the same
|
|
301
|
+
* generation signal as framework-storage-selection.ts, plus a provisioned
|
|
302
|
+
* deployment file store. Self-hosted v2 keeps everything on the state root
|
|
303
|
+
* (the operator owns the disk), and v1 keeps today's behavior while it runs.
|
|
304
|
+
*/
|
|
305
|
+
export function selectConversationMirror(input: {
|
|
306
|
+
project: AgentProject;
|
|
307
|
+
logger?: (line: string) => void;
|
|
308
|
+
env?: Record<string, string | undefined>;
|
|
309
|
+
}): ConversationMirror | undefined {
|
|
310
|
+
if (input.project.agent.architecture !== "v2") {
|
|
311
|
+
return undefined;
|
|
312
|
+
}
|
|
313
|
+
const env = input.env ?? process.env;
|
|
314
|
+
if (
|
|
315
|
+
env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined ||
|
|
316
|
+
!isCursorHostedFilesAvailable(env as NodeJS.ProcessEnv)
|
|
317
|
+
) {
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
return createConversationMirror({
|
|
321
|
+
sink: cursorHostedFiles({
|
|
322
|
+
// Full chain (env → key file → stored login): frozen engines listen
|
|
323
|
+
// unsigned and bind CURSOR_API_KEY_FILE at task time, after this sink
|
|
324
|
+
// is constructed.
|
|
325
|
+
apiKey: () => resolveApiKeySync()?.apiKey,
|
|
326
|
+
}),
|
|
327
|
+
agentName: input.project.name,
|
|
328
|
+
logger: input.logger,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
* clock — `exportedAt` comes from the caller.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { envPrefixFromName } from "../../channels/slack/credentials.js";
|
|
9
10
|
import { CLI_COMMAND_NAME, PACKAGE_NAME } from "../distribution.js";
|
|
10
11
|
import { MEMORY_TS } from "../init-scaffold.js";
|
|
11
|
-
import {
|
|
12
|
+
import { SlugRegistry, slugify } from "./slug.js";
|
|
12
13
|
import type {
|
|
13
14
|
ActionJson,
|
|
14
15
|
ConvertedFile,
|
|
@@ -998,11 +999,11 @@ function emitSlackChannel(
|
|
|
998
999
|
"The Slack trigger marked triggering messages with a completion reaction; agentsdk has no completion-reaction option, so that signal is lost unless agent/instructions.md tells the agent to add the reaction itself via Slack tools."
|
|
999
1000
|
);
|
|
1000
1001
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
`Slack channel-watch / reaction / channel-created triggers need a dedicated Socket Mode Slack app
|
|
1004
|
-
|
|
1005
|
-
|
|
1002
|
+
out.setupSteps.push(
|
|
1003
|
+
socketMode
|
|
1004
|
+
? `Slack channel-watch / reaction / channel-created triggers need a dedicated Socket Mode Slack app: run \`${CLI_COMMAND_NAME} slack create --channel-posts\`, then finish in the dashboard wizard.`
|
|
1005
|
+
: `Slack mentions need a dedicated Socket Mode Slack app: run \`${CLI_COMMAND_NAME} slack create\`, then finish in the dashboard wizard.`
|
|
1006
|
+
);
|
|
1006
1007
|
|
|
1007
1008
|
const header = [
|
|
1008
1009
|
`import { slackChannel } from "${PACKAGE_NAME}/channels/slack";`,
|
|
@@ -1069,26 +1070,37 @@ function emitSlackChannel(
|
|
|
1069
1070
|
}
|
|
1070
1071
|
body = [
|
|
1071
1072
|
"//",
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
"export default slackChannel({",
|
|
1075
|
-
...engagement,
|
|
1076
|
-
"});",
|
|
1073
|
+
`// Run \`${CLI_COMMAND_NAME} slack create --channel-posts\` for a dedicated Slack app.`,
|
|
1074
|
+
...slackChannelExport(automation.name, engagement),
|
|
1077
1075
|
];
|
|
1078
1076
|
} else {
|
|
1079
|
-
const agentName = pascalCase(automation.name, "ExportedAgent");
|
|
1080
1077
|
body = [
|
|
1081
1078
|
"//",
|
|
1082
|
-
`//
|
|
1083
|
-
|
|
1084
|
-
" cursorAccount: true,",
|
|
1085
|
-
` agentName: ${JSON.stringify(agentName)},`,
|
|
1086
|
-
"});",
|
|
1079
|
+
`// Run \`${CLI_COMMAND_NAME} slack create\` for a dedicated Slack app.`,
|
|
1080
|
+
...slackChannelExport(automation.name, []),
|
|
1087
1081
|
];
|
|
1088
1082
|
}
|
|
1089
1083
|
out.files.push({ path, contents: `${[...header, ...body].join("\n")}\n` });
|
|
1090
1084
|
}
|
|
1091
1085
|
|
|
1086
|
+
/**
|
|
1087
|
+
* `slack create` writes `<DIR>_SLACK_*` from the project directory. Convert
|
|
1088
|
+
* names that directory from the automation (`Nightly Triage` →
|
|
1089
|
+
* `nightly-triage` → `NIGHTLY_TRIAGE`). Emit the same prefix so minted
|
|
1090
|
+
* tokens bind.
|
|
1091
|
+
*/
|
|
1092
|
+
function slackChannelExport(name: string, optionLines: string[]): string[] {
|
|
1093
|
+
const prefix = envPrefixFromName(slugify(name, "automation"));
|
|
1094
|
+
const options = [
|
|
1095
|
+
...(prefix === "" ? [] : [` envPrefix: ${JSON.stringify(prefix)},`]),
|
|
1096
|
+
...optionLines,
|
|
1097
|
+
];
|
|
1098
|
+
if (options.length === 0) {
|
|
1099
|
+
return ["export default slackChannel();"];
|
|
1100
|
+
}
|
|
1101
|
+
return ["export default slackChannel({", ...options, "});"];
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1092
1104
|
function slackChannelList(
|
|
1093
1105
|
trigger: SlackChannelsTriggerJson | undefined
|
|
1094
1106
|
): string[] {
|
|
@@ -9,15 +9,6 @@ export function slugify(name: string, fallback: string): string {
|
|
|
9
9
|
return slug === "" ? fallback : slug;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
/** Single-token PascalCase (Slack cursorAccount agentName). */
|
|
13
|
-
export function pascalCase(name: string, fallback: string): string {
|
|
14
|
-
const words = name.split(/[^a-zA-Z0-9]+/).filter((word) => word !== "");
|
|
15
|
-
if (words.length === 0) {
|
|
16
|
-
return fallback;
|
|
17
|
-
}
|
|
18
|
-
return words.map((word) => word[0]?.toUpperCase() + word.slice(1)).join("");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
12
|
/** Dedupes slugs with numeric suffixes: `linear`, `linear-2`, `linear-3`, … */
|
|
22
13
|
export class SlugRegistry {
|
|
23
14
|
private readonly used = new Set<string>();
|
|
@@ -85,7 +85,10 @@ export function collectCursorAccountConnections(
|
|
|
85
85
|
const bySlug = new Map<string, CursorAccountConnectionRef[]>();
|
|
86
86
|
for (const { slug, project } of mounts) {
|
|
87
87
|
const refs: CursorAccountConnectionRef[] = [];
|
|
88
|
-
for (const connection of
|
|
88
|
+
for (const connection of [
|
|
89
|
+
...project.agent.connections,
|
|
90
|
+
...(project.agent.hostConnections ?? []),
|
|
91
|
+
]) {
|
|
89
92
|
if (!isCursorAccountTransport(connection.transport)) {
|
|
90
93
|
continue;
|
|
91
94
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ChannelSession } from "../types.js";
|
|
2
|
+
|
|
3
|
+
const deferredSessions = new WeakSet<ChannelSession>();
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Authored code touched a member of the deferred handle that needs the live
|
|
7
|
+
* session. This is deterministic (the session never exists during admission),
|
|
8
|
+
* so the admission route surfaces it as a non-retryable 422 rather than a
|
|
9
|
+
* retryable failure.
|
|
10
|
+
*/
|
|
11
|
+
export class DeferredChannelSessionError extends Error {
|
|
12
|
+
constructor(member: string) {
|
|
13
|
+
super(
|
|
14
|
+
`ChannelSession.${member} is not available on a send() captured ` +
|
|
15
|
+
"during hosted admission: the control plane allocates the session " +
|
|
16
|
+
"(and runs the turn) only after this delivery is acknowledged, so " +
|
|
17
|
+
"the handle cannot observe it yet. Move work that needs the live " +
|
|
18
|
+
"session into the session turn instead."
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function unavailable(member: string): never {
|
|
24
|
+
throw new DeferredChannelSessionError(member);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Inert `ChannelSession` returned by the hosted-admission `send` stub: every
|
|
29
|
+
* member fails loudly via {@link DeferredChannelSessionError}. Caveat: new
|
|
30
|
+
* OPTIONAL members added to `ChannelSession` slip through this factory
|
|
31
|
+
* silently (reads return `undefined`) until a throwing getter is added here.
|
|
32
|
+
*/
|
|
33
|
+
export function createDeferredChannelSession(): ChannelSession {
|
|
34
|
+
const session: ChannelSession = {
|
|
35
|
+
get id(): string {
|
|
36
|
+
return unavailable("id");
|
|
37
|
+
},
|
|
38
|
+
get continuationToken(): string | null {
|
|
39
|
+
return unavailable("continuationToken");
|
|
40
|
+
},
|
|
41
|
+
get isNew(): boolean {
|
|
42
|
+
return unavailable("isNew");
|
|
43
|
+
},
|
|
44
|
+
get coalesced(): boolean | undefined {
|
|
45
|
+
return unavailable("coalesced");
|
|
46
|
+
},
|
|
47
|
+
get info(): ChannelSession["info"] {
|
|
48
|
+
return unavailable("info");
|
|
49
|
+
},
|
|
50
|
+
getEventStream: async () => unavailable("getEventStream()"),
|
|
51
|
+
waitForCompletion: async () => unavailable("waitForCompletion()"),
|
|
52
|
+
setContinuationToken: async () => unavailable("setContinuationToken()"),
|
|
53
|
+
};
|
|
54
|
+
deferredSessions.add(session);
|
|
55
|
+
return session;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** True when `send()` returned a hosted-admission capture handle. */
|
|
59
|
+
export function isDeferredChannelSession(session: ChannelSession): boolean {
|
|
60
|
+
return deferredSessions.has(session);
|
|
61
|
+
}
|
|
@@ -224,6 +224,16 @@ export interface AgentkitDeployAccepted {
|
|
|
224
224
|
status: string;
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
/**
|
|
228
|
+
* One release component of a v2 multi-component deploy: a stable key (the
|
|
229
|
+
* child agent's slug) plus that agent's directory relative to the repo
|
|
230
|
+
* root.
|
|
231
|
+
*/
|
|
232
|
+
export interface AgentkitDeployComponent {
|
|
233
|
+
componentKey: string;
|
|
234
|
+
agentPath?: string;
|
|
235
|
+
}
|
|
236
|
+
|
|
227
237
|
/** Customer-visible v2 deploy status (`GET /internal/agentkit/deployments/:slug`). */
|
|
228
238
|
export type AgentkitCustomerStatus =
|
|
229
239
|
| "pending"
|
|
@@ -576,7 +586,9 @@ export class AgentServeDeployClient {
|
|
|
576
586
|
/**
|
|
577
587
|
* Create or redeploy onto the v2 control plane
|
|
578
588
|
* (`POST /internal/agentkit/deployments`). 202 means accepted; poll
|
|
579
|
-
* {@link getAgentkitDeploy} until a terminal status.
|
|
589
|
+
* {@link getAgentkitDeploy} until a terminal status. `components` deploys
|
|
590
|
+
* one application with several release components (one per agent
|
|
591
|
+
* directory); it is mutually exclusive with `agentPath`.
|
|
580
592
|
*/
|
|
581
593
|
async deployAgentkit(args: {
|
|
582
594
|
teamId: number;
|
|
@@ -584,12 +596,22 @@ export class AgentServeDeployClient {
|
|
|
584
596
|
gitRepoUrl: string;
|
|
585
597
|
gitRef?: string;
|
|
586
598
|
agentPath?: string;
|
|
599
|
+
components?: AgentkitDeployComponent[];
|
|
587
600
|
repositories?: string[];
|
|
588
601
|
}): Promise<AgentkitDeployAccepted> {
|
|
589
602
|
const slugError = validateDeploymentSlug(args.slug);
|
|
590
603
|
if (slugError !== undefined) {
|
|
591
604
|
throw new DeployApiError(slugError, 400);
|
|
592
605
|
}
|
|
606
|
+
for (const component of args.components ?? []) {
|
|
607
|
+
const keyError = validateDeploymentSlug(component.componentKey);
|
|
608
|
+
if (keyError !== undefined) {
|
|
609
|
+
throw new DeployApiError(
|
|
610
|
+
`Invalid component key ${JSON.stringify(component.componentKey)}: use lowercase letters, digits, '-' or '_' (max 64 chars)`,
|
|
611
|
+
400
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
593
615
|
const raw = await this.request({
|
|
594
616
|
method: "POST",
|
|
595
617
|
path: "/internal/agentkit/deployments",
|
|
@@ -599,6 +621,7 @@ export class AgentServeDeployClient {
|
|
|
599
621
|
gitRepoUrl: args.gitRepoUrl,
|
|
600
622
|
gitRef: args.gitRef,
|
|
601
623
|
agentPath: args.agentPath,
|
|
624
|
+
components: args.components,
|
|
602
625
|
repositories:
|
|
603
626
|
args.repositories !== undefined && args.repositories.length > 0
|
|
604
627
|
? args.repositories
|
|
@@ -168,12 +168,17 @@ export function buildAgentDeployManifest(
|
|
|
168
168
|
declarations: {
|
|
169
169
|
egressDomains: [...(project.agent.hosting?.egressDomains ?? [])],
|
|
170
170
|
publicRoutePaths,
|
|
171
|
+
// v2 ignores authored storage; deploy manifests describe
|
|
172
|
+
// Cursor-hosted deployments, where framework-storage-selection.ts
|
|
173
|
+
// injects the Cursor-hosted mirror.
|
|
171
174
|
frameworkStorage:
|
|
172
|
-
project.
|
|
173
|
-
? "
|
|
174
|
-
:
|
|
175
|
-
? "
|
|
176
|
-
:
|
|
175
|
+
project.agent.architecture === "v2"
|
|
176
|
+
? "cursor-hosted"
|
|
177
|
+
: project.storage === undefined
|
|
178
|
+
? "none"
|
|
179
|
+
: isCursorHostedStorage(project.storage)
|
|
180
|
+
? "cursor-hosted"
|
|
181
|
+
: "other",
|
|
177
182
|
...(project.agent.architecture === undefined
|
|
178
183
|
? {}
|
|
179
184
|
: { architecture: project.agent.architecture }),
|