@cursor/july 0.1.95 → 0.1.97
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 +3 -4
- package/README.md +3 -2
- package/dist/bin/agent-serve.js +14 -3
- package/dist/channels/deployments/types.d.ts +1 -1
- package/dist/channels/deployments/types.d.ts.map +1 -1
- package/dist/channels/deployments/types.js +1 -0
- package/dist/channels/origin/api.d.ts +72 -15
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +185 -28
- package/dist/channels/origin/binding.d.ts +13 -2
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +41 -25
- package/dist/channels/origin/checks.d.ts +6 -6
- package/dist/channels/origin/checks.js +6 -6
- package/dist/channels/origin/cursor-account.d.ts +5 -3
- package/dist/channels/origin/cursor-account.d.ts.map +1 -1
- package/dist/channels/origin/cursor-account.js +5 -3
- package/dist/channels/origin/index.d.ts +1 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +1 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +3 -0
- package/dist/channels/origin/reactions.d.ts +56 -0
- package/dist/channels/origin/reactions.d.ts.map +1 -0
- package/dist/channels/origin/reactions.js +67 -0
- package/dist/channels/origin/types.d.ts +11 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/api.d.ts +9 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +36 -5
- package/dist/channels/slack/approvals.d.ts +16 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -1
- package/dist/channels/slack/approvals.js +86 -0
- package/dist/channels/slack/cli-project.d.ts +19 -0
- package/dist/channels/slack/cli-project.d.ts.map +1 -0
- package/dist/channels/slack/cli-project.js +234 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +110 -81
- package/dist/channels/slack/dispatch.d.ts +7 -1
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +47 -23
- 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 +32 -0
- package/dist/channels/slack/init.d.ts +3 -2
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +5 -5
- package/dist/channels/slack/interactive.d.ts +2 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +15 -4
- package/dist/channels/slack/live-delivery.d.ts +26 -29
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +172 -73
- package/dist/channels/slack/manifest.d.ts +1 -1
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +6 -2
- package/dist/channels/slack/nudge-carrier.d.ts +2 -0
- package/dist/channels/slack/nudge-carrier.d.ts.map +1 -1
- package/dist/channels/slack/nudge-carrier.js +48 -1
- package/dist/channels/slack/setup.d.ts +1 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +10 -6
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +3 -2
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +91 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.BBj0klBO.js → app.B3rWNYE1.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.CUEXpL78.js → VPLocalSearchBox.C1lhqJJR.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DabmQnia.js → theme.B40_SXuv.js} +2 -2
- package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
- package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
- package/dist/docs/assets/{index.md.BoHaMdeZ.lean.js → index.md.CVeRUOeZ.lean.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.BsMOxDvh.js → reference_cli.md.RyZf5OTE.js} +10 -6
- package/dist/docs/assets/{reference_cli.md.BsMOxDvh.lean.js → reference_cli.md.RyZf5OTE.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
- package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.5zOAbV86.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.B84gw9Ii.js} +1 -1
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.js +2 -0
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/deployment.md +5 -4
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- 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 +8 -8
- package/dist/docs/guides/mcp-oauth.md +26 -8
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +17 -33
- package/dist/docs/guides/slack.md +92 -201
- 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 +7 -3
- package/dist/docs/llms-full.txt +398 -653
- package/dist/docs/llms.txt +3 -2
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/agent-config.md +2 -2
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +14 -10
- package/dist/docs/reference/cli.md +39 -16
- package/dist/docs/reference/connections.html +9 -8
- package/dist/docs/reference/connections.md +6 -3
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +2 -1
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +5 -5
- package/dist/docs/reference/sessions.md +4 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +6 -6
- package/dist/docs/reference/tools.md +9 -2
- package/dist/docs/scaffolding-agents.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 +28 -0
- package/dist/docs/templates/agents-md.md +105 -0
- package/dist/docs/templates/code-wiki.html +28 -0
- package/dist/docs/templates/code-wiki.md +91 -0
- package/dist/docs/templates/demo.html +5 -5
- 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 +5 -5
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/evals/run-facts.d.ts.map +1 -1
- package/dist/evals/run-facts.js +27 -0
- package/dist/files-backends/cursor-hosted.d.ts +26 -4
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +32 -4
- package/dist/internal/advertise-tools.d.ts +2 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +30 -10
- package/dist/internal/approval-gate.d.ts +12 -13
- package/dist/internal/approval-gate.d.ts.map +1 -1
- package/dist/internal/approval-gate.js +16 -21
- package/dist/internal/bounded.d.ts +7 -0
- package/dist/internal/bounded.d.ts.map +1 -0
- package/dist/internal/bounded.js +32 -0
- package/dist/internal/chat-client.js +10 -0
- package/dist/internal/cli-deploy.d.ts +5 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +57 -18
- package/dist/internal/cli-mcp-oauth.js +8 -18
- package/dist/internal/cli-slack-manual.d.ts +24 -2
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +251 -20
- package/dist/internal/cli-slack.d.ts +9 -2
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +29 -82
- package/dist/internal/conversation-mirror.d.ts +11 -8
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +116 -55
- package/dist/internal/cursor/account-mcp.d.ts +1 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +17 -0
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +22 -48
- package/dist/internal/cursor/session-token.d.ts +45 -0
- package/dist/internal/cursor/session-token.d.ts.map +1 -0
- package/dist/internal/cursor/session-token.js +99 -0
- package/dist/internal/cursor-agent-template.d.ts +1 -1
- package/dist/internal/cursor-agent-template.d.ts.map +1 -1
- package/dist/internal/cursor-agent-template.js +2 -0
- package/dist/internal/deploy-client.d.ts +17 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +31 -10
- package/dist/internal/env-file.d.ts +19 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +90 -0
- package/dist/internal/framework-file-storage.d.ts +61 -0
- package/dist/internal/framework-file-storage.d.ts.map +1 -0
- package/dist/internal/framework-file-storage.js +210 -0
- package/dist/internal/framework-storage-selection.d.ts +11 -5
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +38 -11
- package/dist/internal/hosted-delivery-protocol.d.ts +7 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +7 -0
- package/dist/internal/hosted-delivery.d.ts +13 -0
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +64 -19
- package/dist/internal/hosted-execution-diag.d.ts +48 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
- package/dist/internal/hosted-execution-diag.js +150 -0
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +81 -1
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +4 -0
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +1 -3
- package/dist/internal/logs-client.d.ts +5 -0
- package/dist/internal/logs-client.d.ts.map +1 -1
- package/dist/internal/logs-client.js +5 -0
- package/dist/internal/managed-delivery.d.ts +80 -0
- package/dist/internal/managed-delivery.d.ts.map +1 -0
- package/dist/internal/managed-delivery.js +86 -0
- package/dist/internal/mcp-endpoint.js +2 -3
- package/dist/internal/mcp-host.d.ts +10 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +57 -8
- package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
- package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-on-demand.js +287 -0
- package/dist/internal/mcp-oauth-persist.d.ts +42 -0
- package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-persist.js +92 -0
- package/dist/internal/mcp-oauth.d.ts +1 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -1
- package/dist/internal/mcp-oauth.js +10 -2
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +22 -9
- package/dist/internal/runtime-dispatch-runner.d.ts +5 -1
- package/dist/internal/runtime-dispatch-runner.d.ts.map +1 -1
- package/dist/internal/runtime-dispatch-runner.js +7 -0
- package/dist/internal/sdk-runner.d.ts +11 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +39 -8
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +49 -21
- package/dist/internal/session-engine.d.ts +101 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +577 -46
- package/dist/internal/sessions-client.d.ts +9 -7
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +3 -1
- package/dist/internal/steering.d.ts +15 -0
- package/dist/internal/steering.d.ts.map +1 -0
- package/dist/internal/steering.js +18 -0
- package/dist/internal/storage-coordinator.d.ts +7 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +28 -5
- package/dist/internal/storage-roles.d.ts +5 -0
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +10 -0
- package/dist/internal/tool-policy.d.ts +9 -1
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +13 -0
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +10 -0
- package/dist/internal/turn-outbox.d.ts +24 -0
- package/dist/internal/turn-outbox.d.ts.map +1 -0
- package/dist/internal/turn-outbox.js +80 -0
- package/dist/playground/assets/{index-CZA1uEWA.js → index-DrkI6y5O.js} +51 -51
- package/dist/playground/assets/index-DzNGwm7q.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +9 -6
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +16 -3
- package/dist/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/types.d.ts +65 -8
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +7 -3
- package/docs/deployment.md +5 -4
- package/docs/guides/mcp-oauth.md +26 -8
- package/docs/guides/slack.md +93 -202
- package/docs/reference/agent-config.md +2 -2
- package/docs/reference/cli.md +39 -16
- package/docs/reference/connections.md +6 -3
- package/docs/reference/http-api.md +2 -1
- package/docs/reference/sessions.md +4 -2
- package/docs/reference/tools.md +9 -2
- package/docs/templates/agents-md.md +110 -0
- package/docs/templates/code-wiki.md +96 -0
- package/docs/troubleshooting.md +2 -2
- package/package.json +2 -2
- package/skills/ab/SKILL.md +13 -97
- package/skills/create-agent/SKILL.md +124 -223
- package/skills/debug/SKILL.md +34 -68
- package/skills/evals/SKILL.md +55 -180
- package/skills/framework-map/SKILL.md +83 -145
- package/skills/github/SKILL.md +53 -111
- package/skills/hillclimb/SKILL.md +40 -163
- package/skills/mcp-auth/SKILL.md +51 -107
- package/skills/otel/SKILL.md +22 -68
- package/skills/setup-slack/SKILL.md +91 -212
- package/src/bin/agent-serve.ts +13 -1
- package/src/channels/deployments/types.ts +1 -0
- package/src/channels/origin/api.ts +264 -33
- package/src/channels/origin/binding.ts +57 -28
- package/src/channels/origin/checks.ts +6 -6
- package/src/channels/origin/cursor-account.ts +5 -3
- package/src/channels/origin/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +4 -0
- package/src/channels/origin/reactions.ts +82 -0
- package/src/channels/origin/types.ts +11 -0
- package/src/channels/slack/api.ts +41 -5
- package/src/channels/slack/approvals.ts +105 -0
- package/src/channels/slack/cli-project.ts +267 -0
- package/src/channels/slack/defaults.ts +122 -93
- package/src/channels/slack/dispatch.ts +56 -22
- package/src/channels/slack/inbound.ts +43 -0
- package/src/channels/slack/init.ts +10 -5
- package/src/channels/slack/interactive.ts +35 -9
- package/src/channels/slack/live-delivery.ts +235 -114
- package/src/channels/slack/manifest.ts +6 -2
- package/src/channels/slack/nudge-carrier.ts +48 -1
- package/src/channels/slack/setup.ts +10 -6
- package/src/channels/slack/slack-channel.ts +3 -0
- package/src/channels/slack/tool-approval-events.ts +93 -0
- package/src/evals/run-facts.ts +32 -0
- package/src/files-backends/cursor-hosted.ts +40 -7
- package/src/internal/advertise-tools.ts +49 -12
- package/src/internal/approval-gate.ts +20 -29
- package/src/internal/bounded.ts +28 -0
- package/src/internal/chat-client.ts +19 -0
- package/src/internal/cli-deploy.ts +91 -9
- package/src/internal/cli-mcp-oauth.ts +7 -21
- package/src/internal/cli-slack-manual.ts +350 -18
- package/src/internal/cli-slack.ts +40 -84
- package/src/internal/conversation-mirror.ts +145 -69
- package/src/internal/cursor/account-mcp.ts +21 -0
- package/src/internal/cursor/backend-client.ts +34 -58
- package/src/internal/cursor/session-token.ts +115 -0
- package/src/internal/cursor-agent-template.ts +2 -0
- package/src/internal/deploy-client.ts +43 -0
- package/src/internal/env-file.ts +84 -0
- package/src/internal/framework-file-storage.ts +228 -0
- package/src/internal/framework-storage-selection.ts +51 -11
- package/src/internal/hosted-delivery-protocol.ts +7 -0
- package/src/internal/hosted-delivery.ts +107 -24
- package/src/internal/hosted-execution-diag.ts +207 -0
- package/src/internal/http-channel.ts +99 -0
- package/src/internal/init-project.ts +4 -0
- package/src/internal/install-cursor-skills.ts +1 -4
- package/src/internal/logs-client.ts +5 -0
- package/src/internal/managed-delivery.ts +125 -0
- package/src/internal/mcp-endpoint.ts +13 -4
- package/src/internal/mcp-host.ts +77 -11
- package/src/internal/mcp-oauth-on-demand.ts +352 -0
- package/src/internal/mcp-oauth-persist.ts +127 -0
- package/src/internal/mcp-oauth.ts +17 -1
- package/src/internal/otel/collector.ts +30 -0
- package/src/internal/runtime-dispatch-runner.ts +10 -0
- package/src/internal/sdk-runner.ts +56 -8
- package/src/internal/server.ts +61 -9
- package/src/internal/session-engine.ts +723 -60
- package/src/internal/sessions-client.ts +17 -8
- package/src/internal/steering.ts +17 -0
- package/src/internal/storage-coordinator.ts +38 -8
- package/src/internal/storage-roles.ts +7 -0
- package/src/internal/stream-progress.ts +19 -0
- package/src/internal/tool-policy.ts +18 -0
- package/src/internal/trajectory.ts +10 -0
- package/src/internal/turn-outbox.ts +85 -0
- package/src/storage-backends/cursor-hosted.ts +22 -8
- package/src/storage.ts +12 -0
- package/src/types.ts +70 -9
- package/templates/agents-md/README.md +39 -0
- package/templates/agents-md/agent/agent.ts +8 -0
- package/templates/agents-md/agent/channels/github.ts +10 -0
- package/templates/agents-md/agent/channels/queue.ts +28 -0
- package/templates/agents-md/agent/channels/slack.ts +9 -0
- package/templates/agents-md/agent/instructions.md +39 -0
- package/templates/agents-md/agent/lib/collect.ts +439 -0
- package/templates/agents-md/agent/lib/config.ts +8 -0
- package/templates/agents-md/agent/lib/paths.ts +51 -0
- package/templates/agents-md/agent/schedules/weekly.ts +17 -0
- package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
- package/templates/agents-md/evals/agents.eval.ts +135 -0
- package/templates/agents-md/evals/evals.config.ts +5 -0
- package/templates/agents-md/init.json +38 -0
- package/templates/agents-md/package.json +18 -0
- package/templates/agents-md/tsconfig.json +12 -0
- package/templates/code-wiki/README.md +34 -0
- package/templates/code-wiki/agent/agent.ts +8 -0
- package/templates/code-wiki/agent/channels/github.ts +144 -0
- package/templates/code-wiki/agent/instructions.md +39 -0
- package/templates/code-wiki/agent/lib/repos.ts +5 -0
- package/templates/code-wiki/agent/lib/wiki.ts +22 -0
- package/templates/code-wiki/agent/tools/apply_wiki.ts +219 -0
- package/templates/code-wiki/evals/evals.config.ts +5 -0
- package/templates/code-wiki/evals/wiki.eval.ts +132 -0
- package/templates/code-wiki/init.json +25 -0
- package/templates/code-wiki/package.json +18 -0
- package/templates/code-wiki/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.oqPawjiD.js +0 -1
- package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
- package/dist/docs/assets/index.md.BoHaMdeZ.js +0 -5
- package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
- package/dist/docs/design/agsh.md +0 -406
- package/dist/internal/deployment-scm-event-stream.d.ts +0 -116
- package/dist/internal/deployment-scm-event-stream.d.ts.map +0 -1
- package/dist/internal/deployment-scm-event-stream.js +0 -474
- package/dist/playground/assets/index-CF7hUDnQ.css +0 -1
- package/docs/design/agsh.md +0 -406
- package/src/internal/deployment-scm-event-stream.ts +0 -593
- /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.5zOAbV86.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.B84gw9Ii.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
|
@@ -21,8 +21,11 @@
|
|
|
21
21
|
import type { ChannelEventHandlers } from "../../types.js";
|
|
22
22
|
import { postMessage, setThreadStatus, updateMessage } from "./api.js";
|
|
23
23
|
import {
|
|
24
|
+
authThreadStatus,
|
|
24
25
|
buildApprovalBlocks,
|
|
26
|
+
buildAuthBlocks,
|
|
25
27
|
buildResolvedApprovalBlocks,
|
|
28
|
+
buildResolvedAuthBlocks,
|
|
26
29
|
} from "./approvals.js";
|
|
27
30
|
import { SLACK_DEFAULT_LOADING_MESSAGES } from "./constants.js";
|
|
28
31
|
import { defaultSlackLog, type SlackLog } from "./log.js";
|
|
@@ -132,5 +135,95 @@ export function buildToolApprovalEvents(
|
|
|
132
135
|
decision: event.data.decision,
|
|
133
136
|
});
|
|
134
137
|
},
|
|
138
|
+
|
|
139
|
+
async "action.auth_requested"(event, channel, ctx) {
|
|
140
|
+
const log = getLog();
|
|
141
|
+
const state = channel.state;
|
|
142
|
+
if (state.channelId === null || state.threadTs === null) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const blocks = buildAuthBlocks({
|
|
146
|
+
sessionId: ctx.session.id,
|
|
147
|
+
callId: event.data.callId,
|
|
148
|
+
toolName: event.data.toolName,
|
|
149
|
+
connection: event.data.connection,
|
|
150
|
+
authUrl: event.data.authUrl,
|
|
151
|
+
});
|
|
152
|
+
try {
|
|
153
|
+
const posted = await postMessage({
|
|
154
|
+
botToken,
|
|
155
|
+
channel: state.channelId,
|
|
156
|
+
threadTs: state.threadTs,
|
|
157
|
+
text: `Authorization required for \`${event.data.connection}\``,
|
|
158
|
+
blocks,
|
|
159
|
+
});
|
|
160
|
+
channel.state.approvalMessageByCallId = {
|
|
161
|
+
...(state.approvalMessageByCallId ?? {}),
|
|
162
|
+
[event.data.callId]: posted.ts,
|
|
163
|
+
};
|
|
164
|
+
await setThreadStatus({
|
|
165
|
+
botToken,
|
|
166
|
+
channelId: state.channelId,
|
|
167
|
+
threadTs: state.threadTs,
|
|
168
|
+
status: authThreadStatus(event.data.connection),
|
|
169
|
+
loadingMessages: [
|
|
170
|
+
authThreadStatus(event.data.connection),
|
|
171
|
+
...SLACK_DEFAULT_LOADING_MESSAGES,
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
log.info("auth card posted", {
|
|
175
|
+
call_id: event.data.callId,
|
|
176
|
+
connection: event.data.connection,
|
|
177
|
+
message_ts: posted.ts,
|
|
178
|
+
});
|
|
179
|
+
} catch (error) {
|
|
180
|
+
log.warn("auth card post failed", {
|
|
181
|
+
call_id: event.data.callId,
|
|
182
|
+
error: error instanceof Error ? error.message : String(error),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
async "action.auth_resolved"(event, channel) {
|
|
188
|
+
const log = getLog();
|
|
189
|
+
const state = channel.state;
|
|
190
|
+
const messageTs = state.approvalMessageByCallId?.[event.data.callId];
|
|
191
|
+
if (
|
|
192
|
+
state.channelId !== null &&
|
|
193
|
+
messageTs !== undefined &&
|
|
194
|
+
messageTs !== ""
|
|
195
|
+
) {
|
|
196
|
+
const blocks = buildResolvedAuthBlocks({
|
|
197
|
+
connection: event.data.connection,
|
|
198
|
+
decision: event.data.decision,
|
|
199
|
+
byUserId: event.data.by,
|
|
200
|
+
});
|
|
201
|
+
const verb =
|
|
202
|
+
event.data.decision === "approve" ? "Connected" : "Cancelled";
|
|
203
|
+
await updateMessage({
|
|
204
|
+
botToken,
|
|
205
|
+
channel: state.channelId,
|
|
206
|
+
ts: messageTs,
|
|
207
|
+
text: `${verb} — ${event.data.connection}`,
|
|
208
|
+
blocks,
|
|
209
|
+
});
|
|
210
|
+
const next = { ...(state.approvalMessageByCallId ?? {}) };
|
|
211
|
+
delete next[event.data.callId];
|
|
212
|
+
channel.state.approvalMessageByCallId = next;
|
|
213
|
+
}
|
|
214
|
+
if (state.channelId !== null && state.threadTs !== null) {
|
|
215
|
+
await setThreadStatus({
|
|
216
|
+
botToken,
|
|
217
|
+
channelId: state.channelId,
|
|
218
|
+
threadTs: state.threadTs,
|
|
219
|
+
status: "Working…",
|
|
220
|
+
loadingMessages: [...SLACK_DEFAULT_LOADING_MESSAGES],
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
log.info("auth resolved in slack", {
|
|
224
|
+
call_id: event.data.callId,
|
|
225
|
+
decision: event.data.decision,
|
|
226
|
+
});
|
|
227
|
+
},
|
|
135
228
|
};
|
|
136
229
|
}
|
package/src/evals/run-facts.ts
CHANGED
|
@@ -182,6 +182,38 @@ export function deriveRunFacts(events: readonly SessionEvent[]): EvalRunFacts {
|
|
|
182
182
|
}
|
|
183
183
|
break;
|
|
184
184
|
}
|
|
185
|
+
case "action.auth_requested": {
|
|
186
|
+
const request: EvalInputRequestFact = {
|
|
187
|
+
callId: event.data.callId,
|
|
188
|
+
toolName: event.data.toolName,
|
|
189
|
+
args: {
|
|
190
|
+
connection: event.data.connection,
|
|
191
|
+
authUrl: event.data.authUrl,
|
|
192
|
+
},
|
|
193
|
+
resolved: false,
|
|
194
|
+
};
|
|
195
|
+
inputRequests.push(request);
|
|
196
|
+
inputRequestsByCallId.set(event.data.callId, request);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case "action.auth_resolved": {
|
|
200
|
+
const request = inputRequestsByCallId.get(event.data.callId);
|
|
201
|
+
if (request !== undefined) {
|
|
202
|
+
request.resolved = true;
|
|
203
|
+
request.decision = event.data.decision;
|
|
204
|
+
}
|
|
205
|
+
const fact = ensureCall(
|
|
206
|
+
event.data.callId,
|
|
207
|
+
event.data.toolName,
|
|
208
|
+
event.turnId,
|
|
209
|
+
event.data.parentCallId
|
|
210
|
+
);
|
|
211
|
+
fact.approvalDecision = event.data.decision;
|
|
212
|
+
if (event.data.decision === "deny") {
|
|
213
|
+
fact.status = "rejected";
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
185
217
|
case "subagent.called": {
|
|
186
218
|
const existing = subagentsByCallId.get(event.data.callId);
|
|
187
219
|
if (existing === undefined) {
|
|
@@ -71,6 +71,19 @@ const AGENT_SERVE_FILES_PATH = "/v0/agent-serve-files";
|
|
|
71
71
|
export const AGENT_SERVE_STORE_SOURCE_ID_ENV_VAR =
|
|
72
72
|
"AGENT_SERVE_STORE_SOURCE_ID";
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* The deployment's **framework-level** file store, distinct from the
|
|
76
|
+
* user-level store above. The user store carries author-facing bytes
|
|
77
|
+
* (`ctx.host.files`, skills, memory, artifacts) and is browsable and
|
|
78
|
+
* mountable; the framework store carries engine-owned session state —
|
|
79
|
+
* session records, event transcripts, continuation index, and the SDK
|
|
80
|
+
* conversation mirror — and is never exposed to authors or models.
|
|
81
|
+
* Provisioned by the v2 deploy pipeline alongside the user store; v1
|
|
82
|
+
* deployments have only the user store.
|
|
83
|
+
*/
|
|
84
|
+
export const AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID_ENV_VAR =
|
|
85
|
+
"AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID";
|
|
86
|
+
|
|
74
87
|
/** Cap on the per-process etag cache; a miss costs a lookup, not correctness. */
|
|
75
88
|
const MAX_REMEMBERED_ETAGS = 1_000;
|
|
76
89
|
|
|
@@ -101,6 +114,20 @@ export function isCursorHostedFilesAvailable(
|
|
|
101
114
|
return sourceId !== undefined && sourceId !== "";
|
|
102
115
|
}
|
|
103
116
|
|
|
117
|
+
/**
|
|
118
|
+
* The framework-level store's source id, or `undefined` when the deployment
|
|
119
|
+
* has none (v1, self-hosted, or a v2 deploy predating framework-store
|
|
120
|
+
* provisioning). Same detection posture as
|
|
121
|
+
* {@link isCursorHostedFilesAvailable}: keyed on the id alone — a missing
|
|
122
|
+
* credential must fail loudly at use, not silently deselect the store.
|
|
123
|
+
*/
|
|
124
|
+
export function cursorFrameworkStoreSourceId(
|
|
125
|
+
env: NodeJS.ProcessEnv = process.env
|
|
126
|
+
): string | undefined {
|
|
127
|
+
const sourceId = env[AGENT_SERVE_FRAMEWORK_STORE_SOURCE_ID_ENV_VAR]?.trim();
|
|
128
|
+
return sourceId === undefined || sourceId === "" ? undefined : sourceId;
|
|
129
|
+
}
|
|
130
|
+
|
|
104
131
|
/**
|
|
105
132
|
* Local `serve`/`run` with a personal `CURSOR_API_KEY` can address
|
|
106
133
|
* `/v0/agent-serve-files/user`. Hosted deployments have a store source id
|
|
@@ -125,12 +152,15 @@ export function isCursorUserStoreFilesAvailable(
|
|
|
125
152
|
export interface CursorHostedFilesOptions {
|
|
126
153
|
/** Control-plane base URL (default: `CURSOR_API_BASE_URL`, else api.cursor.com). */
|
|
127
154
|
baseUrl?: string;
|
|
155
|
+
/** Bearer credential (default: `CURSOR_API_KEY`). */
|
|
156
|
+
apiKey?: string;
|
|
128
157
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* file after serve start.
|
|
158
|
+
* Lazy credential, re-resolved on every call and preferred over
|
|
159
|
+
* {@link apiKey} — hosted freeze snapshots listen unsigned and bind the
|
|
160
|
+
* key file after serve start. Kept separate so `apiKey` stays a plain
|
|
161
|
+
* string.
|
|
132
162
|
*/
|
|
133
|
-
|
|
163
|
+
resolveApiKey?: () => string | undefined;
|
|
134
164
|
/** File store to address (default: `AGENT_SERVE_STORE_SOURCE_ID`). */
|
|
135
165
|
storeSourceId?: string;
|
|
136
166
|
/** Test seam; defaults to global fetch. */
|
|
@@ -253,7 +283,11 @@ export function cursorHostedFiles(
|
|
|
253
283
|
}
|
|
254
284
|
out.push(toEntry(file, file.path));
|
|
255
285
|
}
|
|
256
|
-
|
|
286
|
+
// The FileSink contract promises key order, and transcript-chunk
|
|
287
|
+
// consumers depend on it (chunk keys are zero-padded so key order
|
|
288
|
+
// is append order). The server happens to scan in order today; do
|
|
289
|
+
// not let that be the only thing holding the contract.
|
|
290
|
+
return out.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
|
|
257
291
|
}
|
|
258
292
|
// The unscoped listing was truncated (`complete: false`) and has no
|
|
259
293
|
// continuation to follow. `list()` promises the whole scope, so rather
|
|
@@ -626,8 +660,7 @@ function resolveStoreSourceId(options: CursorHostedFilesOptions): string {
|
|
|
626
660
|
}
|
|
627
661
|
|
|
628
662
|
function resolveApiKey(options: CursorHostedFilesOptions): string {
|
|
629
|
-
const configured =
|
|
630
|
-
typeof options.apiKey === "function" ? options.apiKey() : options.apiKey;
|
|
663
|
+
const configured = options.resolveApiKey?.() ?? options.apiKey;
|
|
631
664
|
const key = (configured ?? process.env.CURSOR_API_KEY)?.trim();
|
|
632
665
|
if (key === undefined || key === "") {
|
|
633
666
|
throw new Error(
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
* `defineConnection({ effects })` filters the listing before names are
|
|
28
28
|
* assigned: only tools whose MCP annotations classify as an intended
|
|
29
29
|
* effect are advertised. Unclassified tools are omitted, not guessed.
|
|
30
|
+
* Tools whose `annotations.title` is `do-not-call` are dropped as well
|
|
31
|
+
* (vendor host-UI / MCP Apps helpers that still carry `readOnlyHint`).
|
|
30
32
|
*/
|
|
31
33
|
|
|
32
34
|
import type {
|
|
@@ -116,26 +118,49 @@ export async function resolveAdvertisedTools(args: {
|
|
|
116
118
|
return [];
|
|
117
119
|
}
|
|
118
120
|
const sourceFor = args.sourceFor ?? sourceForConnection;
|
|
121
|
+
// Each connection's listing is a network round trip against a distinct
|
|
122
|
+
// server (auth callback, MCP initialize, tools/list), so they run
|
|
123
|
+
// concurrently; the fan-out is bounded by the agent's declared
|
|
124
|
+
// connections. Name assignment below stays in declaration order so
|
|
125
|
+
// collision suffixes do not depend on which server answered first.
|
|
126
|
+
type Listing =
|
|
127
|
+
| {
|
|
128
|
+
connection: DiscoveredConnection;
|
|
129
|
+
ok: true;
|
|
130
|
+
source: AdvertisedToolSource;
|
|
131
|
+
listed: HostMcpToolInfo[];
|
|
132
|
+
}
|
|
133
|
+
| { connection: DiscoveredConnection; ok: false; error: unknown };
|
|
134
|
+
const listings = await Promise.all(
|
|
135
|
+
advertising.map(async (connection): Promise<Listing> => {
|
|
136
|
+
try {
|
|
137
|
+
const source = await sourceFor(connection, args.session, args.hostMcp);
|
|
138
|
+
const listed = await source.listTools();
|
|
139
|
+
return { connection, ok: true, source, listed };
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return { connection, ok: false, error };
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
);
|
|
119
145
|
const claimed = new Set(args.agent.tools.map((tool) => tool.name));
|
|
120
146
|
const resolved: DiscoveredTool[] = [];
|
|
121
|
-
for (const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
try {
|
|
125
|
-
source = await sourceFor(connection, args.session, args.hostMcp);
|
|
126
|
-
listed = await source.listTools();
|
|
127
|
-
} catch (error) {
|
|
147
|
+
for (const listing of listings) {
|
|
148
|
+
const { connection } = listing;
|
|
149
|
+
if (!listing.ok) {
|
|
128
150
|
if (args.onConnectionError !== undefined) {
|
|
129
|
-
args.onConnectionError(connection.name, error);
|
|
151
|
+
args.onConnectionError(connection.name, listing.error);
|
|
130
152
|
continue;
|
|
131
153
|
}
|
|
132
154
|
throw new Error(
|
|
133
|
-
`Failed to list tools on advertised connection "${connection.name}": ${describeError(error)}`,
|
|
134
|
-
{ cause: error }
|
|
155
|
+
`Failed to list tools on advertised connection "${connection.name}": ${describeError(listing.error)}`,
|
|
156
|
+
{ cause: listing.error }
|
|
135
157
|
);
|
|
136
158
|
}
|
|
137
|
-
const
|
|
138
|
-
|
|
159
|
+
const { source, listed } = listing;
|
|
160
|
+
const intended = listed.filter(
|
|
161
|
+
(info) =>
|
|
162
|
+
!isDoNotCallTool(info.annotations) &&
|
|
163
|
+
matchesIntendedEffects(info.annotations, connection.effects)
|
|
139
164
|
);
|
|
140
165
|
const exposed = exposeListedTools(intended, claimed);
|
|
141
166
|
for (const { info, exposedName } of exposed) {
|
|
@@ -232,6 +257,18 @@ function exposeListedTools(
|
|
|
232
257
|
}));
|
|
233
258
|
}
|
|
234
259
|
|
|
260
|
+
/**
|
|
261
|
+
* Vendors (Datadog MCP Apps) stamp host-UI-only helpers with this title.
|
|
262
|
+
* They still look like reads (`readOnlyHint: true`), so the effects
|
|
263
|
+
* filter would keep them. The model and agsh should not see them; the
|
|
264
|
+
* raw MCP listing stays intact for the host.
|
|
265
|
+
*/
|
|
266
|
+
const DO_NOT_CALL_TITLE = "do-not-call";
|
|
267
|
+
|
|
268
|
+
function isDoNotCallTool(annotations: McpToolAnnotations | undefined): boolean {
|
|
269
|
+
return annotations?.title?.trim() === DO_NOT_CALL_TITLE;
|
|
270
|
+
}
|
|
271
|
+
|
|
235
272
|
function matchesIntendedEffects(
|
|
236
273
|
annotations: McpToolAnnotations | undefined,
|
|
237
274
|
effects: readonly ToolEffect[] | undefined
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* In-memory gate for human-in-the-loop
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* {@link ApprovalGate.resolve}.
|
|
2
|
+
* In-memory gate for human-in-the-loop parks. The session engine parks
|
|
3
|
+
* inside a server-tool `execute` by awaiting {@link ApprovalGate.wait};
|
|
4
|
+
* HTTP (or the playground) unblocks via {@link ApprovalGate.resolve}.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
* durability of the *list* across
|
|
9
|
-
* in-flight SDK tool callback is gone,
|
|
10
|
-
* the host treats the
|
|
6
|
+
* Used for `needsApproval` and MCP on-demand auth. Pending rows are also
|
|
7
|
+
* mirrored onto {@link SessionRecord} for durability of the *list* across
|
|
8
|
+
* reloads. After a process restart the in-flight SDK tool callback is gone,
|
|
9
|
+
* so resolve returns false and the host treats the park as interrupted.
|
|
11
10
|
*/
|
|
12
11
|
|
|
13
12
|
import type { ApprovalDecision, PendingApproval } from "../types.js";
|
|
@@ -21,33 +20,25 @@ export interface ApprovalResolution {
|
|
|
21
20
|
by?: string;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
interface Waiter {
|
|
25
|
-
meta:
|
|
23
|
+
interface Waiter<T> {
|
|
24
|
+
meta: T;
|
|
26
25
|
resolve: (resolution: ApprovalResolution) => void;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
export class ApprovalGate {
|
|
30
|
-
private readonly waiters = new Map<string, Waiter
|
|
28
|
+
export class ApprovalGate<T extends { callId: string } = PendingApproval> {
|
|
29
|
+
private readonly waiters = new Map<string, Waiter<T>>();
|
|
31
30
|
|
|
32
|
-
wait(
|
|
33
|
-
|
|
34
|
-
): Promise<ApprovalResolution> {
|
|
35
|
-
const key = approvalKey(meta.sessionId, meta.callId);
|
|
31
|
+
wait(sessionId: string, meta: T): Promise<ApprovalResolution> {
|
|
32
|
+
const key = approvalKey(sessionId, meta.callId);
|
|
36
33
|
const existing = this.waiters.get(key);
|
|
37
34
|
if (existing !== undefined) {
|
|
38
35
|
throw new Error(
|
|
39
|
-
`Approval already pending for session ${
|
|
36
|
+
`Approval already pending for session ${sessionId} call ${meta.callId}`
|
|
40
37
|
);
|
|
41
38
|
}
|
|
42
39
|
return new Promise<ApprovalResolution>((resolveDecision) => {
|
|
43
40
|
this.waiters.set(key, {
|
|
44
|
-
meta
|
|
45
|
-
callId: meta.callId,
|
|
46
|
-
turnId: meta.turnId,
|
|
47
|
-
toolName: meta.toolName,
|
|
48
|
-
args: meta.args,
|
|
49
|
-
requestedAt: meta.requestedAt,
|
|
50
|
-
},
|
|
41
|
+
meta,
|
|
51
42
|
resolve: resolveDecision,
|
|
52
43
|
});
|
|
53
44
|
});
|
|
@@ -69,11 +60,11 @@ export class ApprovalGate {
|
|
|
69
60
|
return false;
|
|
70
61
|
}
|
|
71
62
|
this.waiters.delete(key);
|
|
63
|
+
const by =
|
|
64
|
+
resolvedBy === undefined || resolvedBy === "" ? undefined : resolvedBy;
|
|
72
65
|
waiter.resolve({
|
|
73
66
|
decision,
|
|
74
|
-
|
|
75
|
-
? {}
|
|
76
|
-
: { by: resolvedBy }),
|
|
67
|
+
by,
|
|
77
68
|
});
|
|
78
69
|
return true;
|
|
79
70
|
}
|
|
@@ -82,9 +73,9 @@ export class ApprovalGate {
|
|
|
82
73
|
return this.waiters.has(approvalKey(sessionId, callId));
|
|
83
74
|
}
|
|
84
75
|
|
|
85
|
-
list(sessionId: string):
|
|
76
|
+
list(sessionId: string): T[] {
|
|
86
77
|
const prefix = `${sessionId}\0`;
|
|
87
|
-
const out:
|
|
78
|
+
const out: T[] = [];
|
|
88
79
|
for (const [key, waiter] of this.waiters) {
|
|
89
80
|
if (key.startsWith(prefix)) {
|
|
90
81
|
out.push(waiter.meta);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded-concurrency map, in input order. Local rather than
|
|
3
|
+
* `@anysphere/utils`: this published package cannot depend on monorepo
|
|
4
|
+
* internals.
|
|
5
|
+
*/
|
|
6
|
+
export async function mapBounded<T, R>(
|
|
7
|
+
items: readonly T[],
|
|
8
|
+
max: number,
|
|
9
|
+
run: (item: T) => Promise<R>
|
|
10
|
+
): Promise<R[]> {
|
|
11
|
+
const out = new Array<R>(items.length);
|
|
12
|
+
let nextIndex = 0;
|
|
13
|
+
const workers = Array.from(
|
|
14
|
+
{ length: Math.min(max, items.length) },
|
|
15
|
+
async () => {
|
|
16
|
+
for (;;) {
|
|
17
|
+
const index = nextIndex;
|
|
18
|
+
nextIndex += 1;
|
|
19
|
+
if (index >= items.length) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
out[index] = await run(items[index] as T);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
await Promise.all(workers);
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
@@ -483,6 +483,25 @@ async function streamTurn(args: StreamTurnArgs): Promise<number> {
|
|
|
483
483
|
);
|
|
484
484
|
continue;
|
|
485
485
|
}
|
|
486
|
+
if (event.type === "action.auth_requested") {
|
|
487
|
+
closeAssistant();
|
|
488
|
+
write(
|
|
489
|
+
` ${c.yellow("⏸")} ${c.bold(event.data.connection)} ${c.dim(
|
|
490
|
+
"awaiting MCP authorization"
|
|
491
|
+
)}\n`
|
|
492
|
+
);
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
if (event.type === "action.auth_resolved") {
|
|
496
|
+
const mark =
|
|
497
|
+
event.data.decision === "approve" ? c.green("✓") : c.red("✗");
|
|
498
|
+
write(
|
|
499
|
+
` ${mark} ${c.bold(event.data.connection)} ${c.dim(
|
|
500
|
+
event.data.decision === "approve" ? "connected" : "denied"
|
|
501
|
+
)}\n`
|
|
502
|
+
);
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
486
505
|
if (event.type === "action.result") {
|
|
487
506
|
if (
|
|
488
507
|
event.data.toolName === "task" &&
|
|
@@ -49,6 +49,8 @@ import {
|
|
|
49
49
|
import { type GitRunner, inferDeployGitSource } from "./deploy-source.js";
|
|
50
50
|
import {
|
|
51
51
|
type ChildAgentDir,
|
|
52
|
+
formatDiagnostics,
|
|
53
|
+
hasErrorDiagnostics,
|
|
52
54
|
isAgentProjectDir,
|
|
53
55
|
listChildAgentDirs,
|
|
54
56
|
loadAgentProject,
|
|
@@ -110,6 +112,11 @@ export interface DeployCliOptions {
|
|
|
110
112
|
cursorEventsRepos?: string[];
|
|
111
113
|
/** deploy `--allow-domain <domain>` (repeatable; unioned with the manifest). */
|
|
112
114
|
allowDomains?: string[];
|
|
115
|
+
/**
|
|
116
|
+
* deploy `--multi-tenant`: add a release to an existing Cursor-managed
|
|
117
|
+
* (multi-tenant) product. Cannot create a new multi-tenant application.
|
|
118
|
+
*/
|
|
119
|
+
multiTenant?: boolean;
|
|
113
120
|
/** Test seams. */
|
|
114
121
|
fetchImpl?: typeof fetch;
|
|
115
122
|
/** Inject the connector-auth browser opener (tests; also forces interactive). */
|
|
@@ -309,7 +316,9 @@ export async function cmdDeploy(options: DeployCliOptions): Promise<number> {
|
|
|
309
316
|
manifests.push(await readDeployManifest(target.dir));
|
|
310
317
|
}
|
|
311
318
|
if (manifests.every((manifest) => manifest.architecture === "v2")) {
|
|
312
|
-
return deployAgentsdkApplication(ctx, options, targets
|
|
319
|
+
return deployAgentsdkApplication(ctx, options, targets, {
|
|
320
|
+
hasScmChannels: manifests.some((manifest) => manifest.hasScmChannels),
|
|
321
|
+
});
|
|
313
322
|
}
|
|
314
323
|
if (
|
|
315
324
|
!ctx.json &&
|
|
@@ -720,9 +729,18 @@ async function deployOne(
|
|
|
720
729
|
gitRef,
|
|
721
730
|
agentPath,
|
|
722
731
|
repositories: options.cursorEventsRepos,
|
|
732
|
+
hasScmChannels: manifest.hasScmChannels,
|
|
733
|
+
multiTenant: options.multiTenant === true,
|
|
723
734
|
});
|
|
724
735
|
}
|
|
725
736
|
|
|
737
|
+
if (options.multiTenant === true) {
|
|
738
|
+
ctx.err(
|
|
739
|
+
"--multi-tenant is only valid for architecture: v2 deploys (Cursor-managed products).\n"
|
|
740
|
+
);
|
|
741
|
+
return 1;
|
|
742
|
+
}
|
|
743
|
+
|
|
726
744
|
// Today's only source shape: the control plane builds from a git ref.
|
|
727
745
|
// See DeploySource for the artifact seam.
|
|
728
746
|
const source: DeploySource = {
|
|
@@ -802,11 +820,9 @@ async function deployOne(
|
|
|
802
820
|
}
|
|
803
821
|
|
|
804
822
|
if (detail.status !== "running") {
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
: `: ${sanitizeCustomerError(detail.lastError)}`;
|
|
809
|
-
ctx.err(`Deployment ${slug} ended ${detail.status}${errorDetail}\n`);
|
|
823
|
+
ctx.err(
|
|
824
|
+
`Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`
|
|
825
|
+
);
|
|
810
826
|
return 1;
|
|
811
827
|
}
|
|
812
828
|
const deployedPublicRoutes = detail.publicRoutePaths ?? [];
|
|
@@ -843,7 +859,8 @@ async function deployOne(
|
|
|
843
859
|
async function deployAgentsdkApplication(
|
|
844
860
|
ctx: DeployCliContext,
|
|
845
861
|
options: DeployCliOptions,
|
|
846
|
-
targets: readonly DeployTarget[]
|
|
862
|
+
targets: readonly DeployTarget[],
|
|
863
|
+
declarations: { hasScmChannels: boolean }
|
|
847
864
|
): Promise<number> {
|
|
848
865
|
const parentDir = resolve(options.dir ?? ".");
|
|
849
866
|
const slug = slugFromDirectoryName(basename(parentDir));
|
|
@@ -924,6 +941,8 @@ async function deployAgentsdkApplication(
|
|
|
924
941
|
agentPath: undefined,
|
|
925
942
|
components,
|
|
926
943
|
repositories: options.cursorEventsRepos,
|
|
944
|
+
hasScmChannels: declarations.hasScmChannels,
|
|
945
|
+
multiTenant: options.multiTenant === true,
|
|
927
946
|
});
|
|
928
947
|
}
|
|
929
948
|
|
|
@@ -942,6 +961,10 @@ async function deployOneAgentsdk(
|
|
|
942
961
|
agentPath: string | undefined;
|
|
943
962
|
components?: AgentkitDeployComponent[];
|
|
944
963
|
repositories: string[] | undefined;
|
|
964
|
+
/** Any component declares a GitHub/Origin channel. */
|
|
965
|
+
hasScmChannels: boolean;
|
|
966
|
+
/** Redeploy an existing Cursor-managed product. */
|
|
967
|
+
multiTenant: boolean;
|
|
945
968
|
}
|
|
946
969
|
): Promise<number> {
|
|
947
970
|
const { slug } = args;
|
|
@@ -951,6 +974,9 @@ async function deployOneAgentsdk(
|
|
|
951
974
|
: ` components: ${args.components
|
|
952
975
|
.map((component) => component.componentKey)
|
|
953
976
|
.join(", ")}\n`;
|
|
977
|
+
if (args.multiTenant && !ctx.json) {
|
|
978
|
+
ctx.err(" multi-tenant: existing product\n");
|
|
979
|
+
}
|
|
954
980
|
let accepted: AgentkitDeployAccepted;
|
|
955
981
|
try {
|
|
956
982
|
accepted = await ctx.client.deployAgentkit({
|
|
@@ -961,6 +987,7 @@ async function deployOneAgentsdk(
|
|
|
961
987
|
agentPath: args.agentPath,
|
|
962
988
|
components: args.components,
|
|
963
989
|
repositories: args.repositories,
|
|
990
|
+
...(args.multiTenant ? { multiTenant: true } : {}),
|
|
964
991
|
});
|
|
965
992
|
} catch (error) {
|
|
966
993
|
return renderApiError(error, ctx.err);
|
|
@@ -1002,7 +1029,9 @@ async function deployOneAgentsdk(
|
|
|
1002
1029
|
}
|
|
1003
1030
|
|
|
1004
1031
|
if (detail.status !== "running") {
|
|
1005
|
-
ctx.err(
|
|
1032
|
+
ctx.err(
|
|
1033
|
+
`Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`
|
|
1034
|
+
);
|
|
1006
1035
|
return 1;
|
|
1007
1036
|
}
|
|
1008
1037
|
ctx.out(
|
|
@@ -1015,8 +1044,19 @@ async function deployOneAgentsdk(
|
|
|
1015
1044
|
? ""
|
|
1016
1045
|
: ` components: ${args.components
|
|
1017
1046
|
.map((component) => component.componentKey)
|
|
1018
|
-
.join(", ")}\n`)
|
|
1047
|
+
.join(", ")}\n`) +
|
|
1048
|
+
(detail.repositories === undefined || !args.hasScmChannels
|
|
1049
|
+
? ""
|
|
1050
|
+
: ` watching: ${detail.repositories.length === 0 ? "(nothing)" : detail.repositories.join(", ")}\n`)
|
|
1019
1051
|
);
|
|
1052
|
+
// An agent with GitHub/Origin channels bound to no repository scope gets
|
|
1053
|
+
// no deliveries at all, which is otherwise invisible in this output.
|
|
1054
|
+
if (args.hasScmChannels && detail.repositories?.length === 0) {
|
|
1055
|
+
ctx.err(
|
|
1056
|
+
`warning: ${slug} watches no repositories, so its GitHub/Origin channels receive no events.\n` +
|
|
1057
|
+
` Redeploy with --cursor-events-repo <owner>/<name> to set the scope.\n`
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1020
1060
|
return 0;
|
|
1021
1061
|
}
|
|
1022
1062
|
|
|
@@ -1126,6 +1166,11 @@ interface DeployManifest {
|
|
|
1126
1166
|
* (only `/v1/channels/…` subtrees can be public); surfaced as a warning.
|
|
1127
1167
|
*/
|
|
1128
1168
|
httpChannelPublicEndpoint: boolean;
|
|
1169
|
+
/**
|
|
1170
|
+
* The agent has GitHub/Origin channels, so it only receives deliveries
|
|
1171
|
+
* while the deployment is bound to at least one `owner/name` scope.
|
|
1172
|
+
*/
|
|
1173
|
+
hasScmChannels: boolean;
|
|
1129
1174
|
}
|
|
1130
1175
|
|
|
1131
1176
|
/**
|
|
@@ -1135,6 +1180,16 @@ interface DeployManifest {
|
|
|
1135
1180
|
*/
|
|
1136
1181
|
async function readDeployManifest(dir: string): Promise<DeployManifest> {
|
|
1137
1182
|
const project = await loadAgentProject(dir);
|
|
1183
|
+
// Fail here, before anything is dispatched: a project with error
|
|
1184
|
+
// diagnostics (e.g. agent/storage.ts on architecture v2) would only be
|
|
1185
|
+
// refused later by `serve` inside the hosted build, wasting a bake.
|
|
1186
|
+
if (hasErrorDiagnostics(project)) {
|
|
1187
|
+
throw new Error(
|
|
1188
|
+
`Refusing to deploy ${project.name} — it has errors:\n${formatDiagnostics(
|
|
1189
|
+
project.diagnostics.filter((d) => d.severity === "error")
|
|
1190
|
+
)}`
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1138
1193
|
return {
|
|
1139
1194
|
hosting: project.agent.hosting,
|
|
1140
1195
|
architecture: project.agent.architecture,
|
|
@@ -1151,6 +1206,10 @@ async function readDeployManifest(dir: string): Promise<DeployManifest> {
|
|
|
1151
1206
|
httpChannelPublicEndpoint: (project.httpChannel.auth ?? []).some(
|
|
1152
1207
|
isPublicEndpointPolicy
|
|
1153
1208
|
),
|
|
1209
|
+
hasScmChannels: project.channels.some((channel) => {
|
|
1210
|
+
const kind = channel.definition.meta?.kind;
|
|
1211
|
+
return kind === "github" || kind === "origin";
|
|
1212
|
+
}),
|
|
1154
1213
|
};
|
|
1155
1214
|
}
|
|
1156
1215
|
|
|
@@ -1926,9 +1985,32 @@ function aliasTokenBlock(aliasToken: string): string {
|
|
|
1926
1985
|
);
|
|
1927
1986
|
}
|
|
1928
1987
|
|
|
1988
|
+
/**
|
|
1989
|
+
* `: <reason>` suffix for a deploy that ended in a non-running state, or
|
|
1990
|
+
* empty when the control plane recorded no reason.
|
|
1991
|
+
*/
|
|
1992
|
+
function deployFailureDetail(lastError: string | null | undefined): string {
|
|
1993
|
+
if (
|
|
1994
|
+
lastError === null ||
|
|
1995
|
+
lastError === undefined ||
|
|
1996
|
+
lastError.trim() === ""
|
|
1997
|
+
) {
|
|
1998
|
+
return "";
|
|
1999
|
+
}
|
|
2000
|
+
return `: ${sanitizeCustomerError(lastError.trim())}`;
|
|
2001
|
+
}
|
|
2002
|
+
|
|
1929
2003
|
function renderApiError(error: unknown, err: (text: string) => void): number {
|
|
1930
2004
|
if (error instanceof DeployApiError) {
|
|
1931
2005
|
err(`${error.message}\n`);
|
|
2006
|
+
if (
|
|
2007
|
+
error.status === 409 &&
|
|
2008
|
+
error.message.includes("application multiTenant does not match")
|
|
2009
|
+
) {
|
|
2010
|
+
err(
|
|
2011
|
+
"This slug is a Cursor-managed (multi-tenant) product. Redeploy it with --multi-tenant.\n"
|
|
2012
|
+
);
|
|
2013
|
+
}
|
|
1932
2014
|
return 1;
|
|
1933
2015
|
}
|
|
1934
2016
|
throw error;
|