@cursor/july 0.1.96 → 0.1.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +3 -2
- package/dist/bin/agent-serve.js +13 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +16 -0
- package/dist/channels/origin/api.d.ts +15 -4
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +19 -3
- package/dist/channels/origin/binding.d.ts +11 -0
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +41 -25
- 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 +2 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +40 -4
- 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/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 +142 -63
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +1 -1
- 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 +1 -1
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +4 -2
- package/dist/channels/slack/manifest.d.ts +1 -1
- package/dist/channels/slack/manifest.js +1 -1
- package/dist/channels/slack/progress-delivery.d.ts +28 -0
- package/dist/channels/slack/progress-delivery.d.ts.map +1 -0
- package/dist/channels/slack/progress-delivery.js +115 -0
- 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 +1 -0
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +91 -1
- package/dist/channels/slack/types.d.ts +9 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.jXleCmOc.js → app.BplEAZ3S.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.8LhyglIT.js → VPLocalSearchBox.CHXyv4wP.js} +1 -1
- package/dist/docs/assets/chunks/{theme.9ged-pr2.js → theme.BTcsZmjQ.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/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.js → reference_cli.md.DfoeyvL0.js} +9 -6
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.lean.js → reference_cli.md.DfoeyvL0.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.BEJx9XVj.js} +2 -2
- package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.CvAHsdSp.js} +10 -2
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.CvAHsdSp.lean.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/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/design/runtime-abstraction.md +1757 -0
- 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 +5 -3
- package/dist/docs/llms-full.txt +2065 -637
- 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 +13 -10
- package/dist/docs/reference/cli.md +32 -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 +7 -7
- package/dist/docs/reference/http-api.md +3 -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 +15 -7
- package/dist/docs/reference/tools.md +34 -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 +5 -5
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +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 +3 -2
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +3 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +15 -9
- 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/as-of.d.ts +19 -0
- package/dist/internal/as-of.d.ts.map +1 -0
- package/dist/internal/as-of.js +82 -0
- package/dist/internal/chat-client.js +10 -0
- package/dist/internal/cli-deploy.d.ts +6 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +149 -21
- 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/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-agent-template.d.ts +1 -1
- package/dist/internal/cursor-agent-template.d.ts.map +1 -1
- package/dist/internal/cursor-agent-template.js +1 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +5 -6
- 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 +11 -17
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +17 -40
- package/dist/internal/framework-storage-selection.d.ts +13 -11
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +37 -26
- package/dist/internal/hosted-admission-adapter.d.ts +28 -0
- package/dist/internal/hosted-admission-adapter.d.ts.map +1 -0
- package/dist/internal/hosted-admission-adapter.js +7 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +13 -1
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +8 -1
- package/dist/internal/hosted-delivery.d.ts +21 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +101 -34
- package/dist/internal/hosted-execution-diag.d.ts +59 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
- package/dist/internal/hosted-execution-diag.js +187 -0
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +85 -2
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +2 -0
- 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/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/null-kv-storage.d.ts +48 -0
- package/dist/internal/null-kv-storage.d.ts.map +1 -0
- package/dist/internal/null-kv-storage.js +58 -0
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +22 -9
- package/dist/internal/server.d.ts +6 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +123 -33
- package/dist/internal/session-engine.d.ts +88 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +538 -46
- package/dist/internal/session-run-log.d.ts +120 -0
- package/dist/internal/session-run-log.d.ts.map +1 -0
- package/dist/internal/session-run-log.js +359 -0
- 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/storage-coordinator.d.ts +13 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +37 -6
- 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 +29 -9
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +24 -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-D7rGZNjy.css +1 -0
- package/dist/playground/assets/index-jzNbJENa.js +69 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +1 -1
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +12 -0
- package/dist/storage-protocol.d.ts +8 -0
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +8 -0
- package/dist/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/tools.d.ts +12 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/types.d.ts +88 -7
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +5 -3
- package/docs/deployment.md +5 -4
- package/docs/design/runtime-abstraction.md +1757 -0
- 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 +32 -16
- package/docs/reference/connections.md +6 -3
- package/docs/reference/http-api.md +3 -1
- package/docs/reference/sessions.md +4 -2
- package/docs/reference/tools.md +34 -2
- package/docs/templates/agents-md.md +110 -0
- package/docs/troubleshooting.md +2 -2
- package/package.json +1 -1
- package/skills/create-agent/SKILL.md +2 -1
- package/skills/mcp-auth/SKILL.md +6 -3
- package/skills/setup-slack/SKILL.md +23 -13
- package/src/bin/agent-serve.ts +12 -1
- package/src/channels/github/github-channel.ts +17 -0
- package/src/channels/origin/api.ts +24 -5
- package/src/channels/origin/binding.ts +55 -26
- package/src/channels/origin/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +78 -10
- package/src/channels/origin/reactions.ts +82 -0
- package/src/channels/origin/types.ts +11 -0
- package/src/channels/slack/approvals.ts +105 -0
- package/src/channels/slack/cli-project.ts +267 -0
- package/src/channels/slack/defaults.ts +165 -74
- package/src/channels/slack/dispatch.ts +2 -0
- package/src/channels/slack/init.ts +10 -5
- package/src/channels/slack/interactive.ts +35 -9
- package/src/channels/slack/live-delivery.ts +5 -3
- package/src/channels/slack/manifest.ts +1 -1
- package/src/channels/slack/progress-delivery.ts +133 -0
- package/src/channels/slack/setup.ts +10 -6
- package/src/channels/slack/slack-channel.ts +1 -0
- package/src/channels/slack/tool-approval-events.ts +93 -0
- package/src/channels/slack/types.ts +9 -1
- package/src/evals/run-facts.ts +32 -0
- package/src/files-backends/cursor-hosted.ts +3 -2
- package/src/index.ts +4 -0
- package/src/internal/advertise-tools.ts +31 -10
- package/src/internal/approval-gate.ts +20 -29
- package/src/internal/as-of.ts +107 -0
- package/src/internal/chat-client.ts +19 -0
- package/src/internal/cli-deploy.ts +203 -13
- 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/cursor/account-mcp.ts +21 -0
- package/src/internal/cursor-agent-template.ts +1 -0
- package/src/internal/cursor-event-relay.ts +5 -6
- package/src/internal/deploy-client.ts +43 -0
- package/src/internal/env-file.ts +84 -0
- package/src/internal/framework-file-storage.ts +18 -46
- package/src/internal/framework-storage-selection.ts +41 -25
- package/src/internal/hosted-admission-adapter.ts +42 -0
- package/src/internal/hosted-delivery-protocol.ts +14 -2
- package/src/internal/hosted-delivery.ts +169 -44
- package/src/internal/hosted-execution-diag.ts +252 -0
- package/src/internal/http-channel.ts +107 -0
- package/src/internal/init-project.ts +2 -0
- package/src/internal/logs-client.ts +5 -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/null-kv-storage.ts +74 -0
- package/src/internal/otel/collector.ts +30 -0
- package/src/internal/server.ts +159 -11
- package/src/internal/session-engine.ts +691 -57
- package/src/internal/session-run-log.ts +584 -0
- package/src/internal/sessions-client.ts +17 -8
- package/src/internal/storage-coordinator.ts +49 -9
- package/src/internal/storage-roles.ts +7 -0
- package/src/internal/stream-progress.ts +19 -0
- package/src/internal/tool-policy.ts +49 -9
- package/src/internal/trajectory.ts +10 -0
- package/src/internal/turn-outbox.ts +85 -0
- package/src/storage-backends/cursor-hosted.ts +13 -1
- package/src/storage-protocol.ts +10 -0
- package/src/storage.ts +12 -0
- package/src/tools.ts +12 -2
- package/src/types.ts +93 -8
- 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/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.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.CI93Ltlb.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/playground/assets/index-B1DDvBeC.css +0 -1
- package/dist/playground/assets/index-Cx9CclK_.js +0 -88
- package/docs/design/agsh.md +0 -406
- /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.CI93Ltlb.lean.js → index.md.CVeRUOeZ.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.BEJx9XVj.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/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
|
@@ -67,8 +67,10 @@ message. Interrupted turns record `turn.failed` with
|
|
|
67
67
|
Slack `stop` / `@agent stop` does the same for that thread and clears
|
|
68
68
|
pending coalesced nudges.
|
|
69
69
|
|
|
70
|
-
Session-bound deterministic tool calls share the
|
|
71
|
-
|
|
70
|
+
Session-bound deterministic tool calls share the lock only for writes: a
|
|
71
|
+
write-effect call returns `409 session_busy` while a model turn is
|
|
72
|
+
running, a read-effect call runs alongside the turn (see
|
|
73
|
+
[Tools](./tools.md#call-a-tool-without-a-model-turn)).
|
|
72
74
|
|
|
73
75
|
## Which events can I stream?
|
|
74
76
|
|
package/docs/reference/tools.md
CHANGED
|
@@ -147,6 +147,31 @@ export default defineTool({
|
|
|
147
147
|
`dryRunResult` keeps the result shape stable. Without it, a stubbed write
|
|
148
148
|
returns `"Operation acknowledged."`. Traces mark the result as stubbed.
|
|
149
149
|
|
|
150
|
+
### Bound time arguments under `asOf`
|
|
151
|
+
|
|
152
|
+
Declare `timeArgs` with the input properties that carry time bounds. In a
|
|
153
|
+
session created with `asOf`, every named argument must be an absolute
|
|
154
|
+
ISO-8601 instant with a timezone, no later than the session's frozen
|
|
155
|
+
instant. A call that omits one, or supplies a relative or later value, is
|
|
156
|
+
refused with an error telling the model to retry with absolute bounds.
|
|
157
|
+
Sessions without `asOf` ignore the declaration.
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
export default defineTool({
|
|
161
|
+
description: "Query telemetry between two instants.",
|
|
162
|
+
inputSchema: z.object({ since: z.string(), until: z.string() }),
|
|
163
|
+
effect: "read",
|
|
164
|
+
timeArgs: ["since", "until"],
|
|
165
|
+
async execute({ since, until }) {
|
|
166
|
+
return queryTelemetry(since, until);
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Every name in `timeArgs` must exist in the input schema; a session with
|
|
172
|
+
`asOf` refuses to start otherwise, because a misspelled name would silently
|
|
173
|
+
check nothing.
|
|
174
|
+
|
|
150
175
|
## Define an agent tool
|
|
151
176
|
|
|
152
177
|
Set `execution: "agent"` and the tool materializes as a shell script
|
|
@@ -263,7 +288,14 @@ when the call returns. Pass a `sessionId` (a body field over
|
|
|
263
288
|
HTTP, `--session` on the CLI, `options.sessionId` programmatically) to
|
|
264
289
|
run inside an existing session instead: the tool sees that session's
|
|
265
290
|
workspace, and the call is recorded on the session's event stream.
|
|
266
|
-
|
|
291
|
+
While a model turn is running, a session-bound call is admitted by its
|
|
292
|
+
effect: a read-effect call (a declared `effect: "read"`, or an advertised
|
|
293
|
+
MCP tool whose server annotates it read-only) runs alongside the turn,
|
|
294
|
+
reading the workspace as the turn has left it, and is recorded under its
|
|
295
|
+
own per-call `turnId` so trajectories keep it apart from the turn's own
|
|
296
|
+
calls; a write-effect call — including an undeclared tool, which counts
|
|
297
|
+
as a write — returns `409 session_busy` until the turn finishes, because
|
|
298
|
+
a running turn owns the workspace. When the
|
|
267
299
|
session's harness cwd cannot be materialized, a read-effect call runs
|
|
268
300
|
in a scratch workspace instead and the outcome carries
|
|
269
301
|
`scratchWorkspace: true`; a write-effect call fails with
|
|
@@ -273,7 +305,7 @@ A session can also be addressed by its continuation token: an optional
|
|
|
273
305
|
`continuationToken` (`<channelId>:<key>`, as `/v1/sessions` lists it;
|
|
274
306
|
mutually exclusive with `sessionId`). A token that maps to a live
|
|
275
307
|
session behaves exactly like passing that session's id — same ownership
|
|
276
|
-
check, same
|
|
308
|
+
check, same busy semantics, same event recording. A token with no
|
|
277
309
|
session behind it runs the call scratch-bound with the token's channel
|
|
278
310
|
id and continuation key as the call's session identity, so a deployment
|
|
279
311
|
whose tools resolve state from the continuation key can serve it with
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Keep AGENTS.md current from last week's work"
|
|
3
|
+
description: "Scaffold the agent, pick a repo and Slack channels, dispatch the weekly job, and deploy."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Keep AGENTS.md current from last week's work
|
|
7
|
+
|
|
8
|
+
This agent runs every Monday at 09:00 UTC. It reads last week's merged
|
|
9
|
+
pull requests and the Slack channels you list. When a durable rule
|
|
10
|
+
showed up, `apply_agents` parks the write until a person approves it,
|
|
11
|
+
then opens a draft follow-up pull request against the default branch.
|
|
12
|
+
Chores and rules the file already states stay quiet.
|
|
13
|
+
|
|
14
|
+
This template is one model turn: read the week, then call
|
|
15
|
+
`apply_agents`.
|
|
16
|
+
|
|
17
|
+
Init once per app. Pass a different repo and channel list each time.
|
|
18
|
+
|
|
19
|
+
## Scaffold
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx @cursor/july init ./agents-md --template agents-md
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`init` asks which GitHub repo to watch and which Slack channels to
|
|
26
|
+
read. Pass `--var repos=acme/api --var slack=#eng-api,#api-private`
|
|
27
|
+
to skip the prompt. Use `--var slack=none` when Slack is out of
|
|
28
|
+
scope.
|
|
29
|
+
|
|
30
|
+
The answers land in `agent/lib/config.ts`. Edit that file when the
|
|
31
|
+
set changes.
|
|
32
|
+
|
|
33
|
+
## Connect GitHub and Slack
|
|
34
|
+
|
|
35
|
+
Connect GitHub in Cursor for that repository (Settings or
|
|
36
|
+
[cursor.com/dashboard](https://cursor.com/dashboard)). Sign the host
|
|
37
|
+
in:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cd agents-md
|
|
41
|
+
agent-sdk login
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`cursorAccount` mints a short-lived, repo-scoped credential with
|
|
45
|
+
`contents-write` so the agent can open the follow-up PR. See the
|
|
46
|
+
[GitHub guide](../guides/github.md).
|
|
47
|
+
|
|
48
|
+
Create the Slack app and invite the bot to each listed channel,
|
|
49
|
+
including private ones:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
agent-sdk slack create --dir .
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
See the [Slack guide](../guides/slack.md).
|
|
56
|
+
|
|
57
|
+
## First weekly run
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
agent-sdk dev
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Schedules never fire under `dev`. Dispatch the same path production
|
|
64
|
+
uses:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
curl -X POST http://127.0.0.1:3000/v1/dev/schedules/weekly
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The playground can run `/queue/run` too.
|
|
71
|
+
|
|
72
|
+
The host writes `week/prs.md`, `week/slack.md`, `week/window.txt`,
|
|
73
|
+
and `week/tree/**.txt` snapshots of the current `AGENTS.md` files,
|
|
74
|
+
then starts a model turn. The
|
|
75
|
+
model calls `apply_agents` once. A skip finishes. An update parks in
|
|
76
|
+
the playground until someone approves; then a draft PR opens against
|
|
77
|
+
the repository default branch. Later updates to the same base stack
|
|
78
|
+
on `agents-md/<base>`. Pull requests from those branches are ignored
|
|
79
|
+
so the follow-up cannot feed the next week.
|
|
80
|
+
|
|
81
|
+
Chat replies stay in the playground. `apply_agents` records a skip,
|
|
82
|
+
or parks the write. Approve there or with
|
|
83
|
+
`POST /v1/session/:id/approvals/:callId`.
|
|
84
|
+
|
|
85
|
+
## What to edit
|
|
86
|
+
|
|
87
|
+
- `agent/lib/config.ts`: repo and Slack channels
|
|
88
|
+
- `agent/instructions.md`: what counts as an update
|
|
89
|
+
- `evals/agents.eval.ts`: smoke cases
|
|
90
|
+
|
|
91
|
+
## Evals
|
|
92
|
+
|
|
93
|
+
Four smoke cases: a lint-only week, a billing rule that parks the
|
|
94
|
+
write, the same rule already in `AGENTS.md`, and an empty week.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
agent-sdk eval
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Eval sessions skip the GitHub write.
|
|
101
|
+
|
|
102
|
+
## Deploy
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
agent-sdk deploy
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Run it from the agent's git checkout. The command infers repository,
|
|
109
|
+
ref, path, and slug. Production fires the Monday cron. The deployment
|
|
110
|
+
uses the team's Cursor GitHub connection for the watched repo.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -42,7 +42,7 @@ not on `PATH`, use `npx @cursor/july`.
|
|
|
42
42
|
| What you see | What to do |
|
|
43
43
|
| --- | --- |
|
|
44
44
|
| `409` on a follow-up message | Refresh the `continuationToken` or confirm the session is a chat session. Task sessions do not accept follow-ups. |
|
|
45
|
-
| `409 session_busy` on `call --session` | Wait for the
|
|
45
|
+
| `409 session_busy` on `call --session` | The tool is a write (or declares no effect) and a model turn is running. Wait for the turn to finish, omit `--session` for a one-off call, or declare `effect: "read"` on a tool that only reads so it runs alongside turns. |
|
|
46
46
|
| `403` on stream or follow-up | Use the same auth identity that created the session. Off localhost, pass `--bearer-token` and send it on every request. |
|
|
47
47
|
| Works on localhost; blocked through a tunnel or LAN | Default auth allows only direct loopback callers. Share the host with `--bearer-token <secret>` (or authored `bearerAuth`). Use `--allow-anonymous` only on a trusted private network. |
|
|
48
48
|
| A channel route fails to compile with a schema type error | `GET` routes need a Zod `querySchema`. `POST` / `PUT` / `PATCH` need a Zod `bodySchema`. Use `z.object({})` or `z.unknown()` for open shapes. |
|
|
@@ -70,7 +70,7 @@ not on `PATH`, use `npx @cursor/july`.
|
|
|
70
70
|
| What you see | What to do |
|
|
71
71
|
| --- | --- |
|
|
72
72
|
| `must be defineConnection({ url, oauth: true })` | The connection file needs `oauth: true`, or you passed the wrong connection name to `agent-sdk mcp oauth`. |
|
|
73
|
-
| Local auth works; hosted calls unauthorized |
|
|
73
|
+
| Local auth works; hosted calls unauthorized | Finish Connect on the hosted engine, or run `agent-sdk mcp oauth <name> --store`. Confirm names with `agent-sdk secrets list <slug>`, then redeploy. |
|
|
74
74
|
| Model asks for `mcp_auth` or IDE MCP for a connector it already has | Attached MCP is behind meta-tools. Set `advertiseTools: true` for named tools on local turns, or call it from a host tool via `ctx.host.mcp`. |
|
|
75
75
|
|
|
76
76
|
See [Host MCP OAuth](./guides/mcp-oauth.md) and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor/july",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.99",
|
|
4
4
|
"description": "(early alpha) Filesystem-first framework for defining Cursor agents as markdown and TypeScript and serving them over channels with the Cursor SDK.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"repository": {
|
|
@@ -111,7 +111,8 @@ agent-sdk init ./<slug>
|
|
|
111
111
|
`subagents/<id>/` (needs `description`), `schedules/`, `hooks/`.
|
|
112
112
|
Slack: `agent-sdk slack create --dir ./<slug> --name "<Name>"`,
|
|
113
113
|
not a hand-written channel. Manual Slack app:
|
|
114
|
-
`agent-sdk slack init --manual
|
|
114
|
+
`agent-sdk slack init --manual` (Slack CLI, or paste at
|
|
115
|
+
api.slack.com).
|
|
115
116
|
4. `evals/evals.config.ts` with `maxConcurrency: 20` (required;
|
|
116
117
|
cap 200) plus `evals/**/*.eval.ts`. Assert `t.succeeded()` +
|
|
117
118
|
`t.calledTool(...)`. API: `skills/evals/SKILL.md`.
|
package/skills/mcp-auth/SKILL.md
CHANGED
|
@@ -30,8 +30,11 @@ can still call `ctx.host.mcp`.
|
|
|
30
30
|
3. **Allow egress** on hosted non-bootstrap hosts:
|
|
31
31
|
`hosting.egressDomains`.
|
|
32
32
|
4. **Authorize.** Local: `agent-sdk mcp oauth <name>`. Hosted:
|
|
33
|
-
|
|
34
|
-
`
|
|
33
|
+
finish Connect so the current process can retry, then
|
|
34
|
+
`agent-sdk mcp oauth <name> --store` and `agent-sdk deploy` so
|
|
35
|
+
the next pod gets `MCP_OAUTH_*`. `secrets list` shows the names.
|
|
36
|
+
Secrets are deployment-wide, not per caller. `cursorAccount: true`
|
|
37
|
+
stays on the Cursor backend.
|
|
35
38
|
|
|
36
39
|
```ts
|
|
37
40
|
// agent/mcp-connections/inventory.ts
|
|
@@ -75,7 +78,7 @@ the CLI config directory (`mcp-auth.json` or
|
|
|
75
78
|
| `must be defineConnection({ url, oauth: true })` | Wrong name or missing `oauth: true` |
|
|
76
79
|
| `Unknown MCP connection` | Filename must match the CLI arg |
|
|
77
80
|
| Callback hang | Free port 8787; finish the browser flow here |
|
|
78
|
-
| Hosted 401 | `secrets list`; `--store`; redeploy |
|
|
81
|
+
| Hosted 401 | `secrets list`; Connect or `--store`; redeploy |
|
|
79
82
|
| Model invents `mcp_auth` / IDE MCP | `advertiseTools: true` on local turns |
|
|
80
83
|
|
|
81
84
|
No raw tokens in git.
|
|
@@ -64,28 +64,38 @@ Local serve does not need a hosted engine. Next
|
|
|
64
64
|
|
|
65
65
|
## 2. Manual (`slack init --manual`)
|
|
66
66
|
|
|
67
|
-
Only when they own the app
|
|
67
|
+
Only when they own the app. Preferred: Slack CLI
|
|
68
|
+
(`~/.slack/bin/slack`). Paste at api.slack.com if the CLI is
|
|
69
|
+
missing. Never `slack deploy`; Agent SDK serve owns Socket Mode.
|
|
68
70
|
|
|
69
71
|
```bash
|
|
70
72
|
agent-sdk slack init --manual --dir . --name "My Agent"
|
|
73
|
+
# --slack-team T0123ABCD when several workspaces are logged in
|
|
74
|
+
# --no-install to scaffold only
|
|
71
75
|
```
|
|
72
76
|
|
|
73
77
|
Writes `agent/channels/slack.ts` (`envPrefix` from the directory),
|
|
74
|
-
manifests
|
|
75
|
-
`--channel-posts` subscribes `message.channels`
|
|
76
|
-
`message.groups`.
|
|
78
|
+
manifests, a `.slack/` project (`get-manifest` → those JSON files),
|
|
79
|
+
and `env.example`. `--channel-posts` subscribes `message.channels`
|
|
80
|
+
/ `message.groups`. If Slack CLI is logged in, this installs the
|
|
81
|
+
app. `--install` fails when that cannot run.
|
|
77
82
|
|
|
78
83
|
Human gates, one at a time. Stop after each.
|
|
79
84
|
|
|
80
|
-
1. **
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
1. **Install the app.** If `next` starts with "Ask the user to
|
|
86
|
+
install this Slack app", stop and prompt them. Slack CLI: they
|
|
87
|
+
run `slack login --no-prompt`, send `/slackauthticket <ticket>`,
|
|
88
|
+
then `slack login --ticket <ticket> --challenge <code>`, then
|
|
89
|
+
`slack app install --environment local --team <T> --force`.
|
|
90
|
+
Prod: `SLACK_ENV=deployed slack app install --environment
|
|
91
|
+
deployed --team <T> --force`. Fallback: Create New App → From a
|
|
92
|
+
manifest, start with `.slack/manifest.dev.json`.
|
|
93
|
+
2. **Tokens.** Slack CLI leaves xoxb / xapp in that process only.
|
|
94
|
+
Copy the bot token from the app's OAuth page. Mint an app-level
|
|
95
|
+
token with `connections:write`. Put both in `.env.local` using
|
|
96
|
+
`env.example` names. If Slack CLI wrote `SLACK_*` to `.env`,
|
|
97
|
+
copy those values to the prefixed keys.
|
|
98
|
+
3. **Doctor.**
|
|
89
99
|
|
|
90
100
|
## 3. Doctor and smoke
|
|
91
101
|
|
package/src/bin/agent-serve.ts
CHANGED
|
@@ -71,6 +71,7 @@ import {
|
|
|
71
71
|
isServeRestartWorker,
|
|
72
72
|
runEnterRestartSupervisor,
|
|
73
73
|
} from "../internal/serve-restart.js";
|
|
74
|
+
import { flushSessionRunFatal } from "../internal/session-run-log.js";
|
|
74
75
|
import { clearTerminal, stdoutPalette } from "../internal/terminal-style.js";
|
|
75
76
|
import { cmdUpdate, warnIfOutdated } from "../internal/update-check.js";
|
|
76
77
|
import type { AgentProject, AgentServeHandle } from "../types.js";
|
|
@@ -439,6 +440,8 @@ Options:
|
|
|
439
440
|
GITHUB_WEBHOOK_SECRET). github: --events overrides the
|
|
440
441
|
derived webhook event list.
|
|
441
442
|
--install github: install the cli/gh-webhook extension if missing.
|
|
443
|
+
slack init --manual: require Slack CLI app install.
|
|
444
|
+
--no-install slack init --manual: skip Slack CLI app install.
|
|
442
445
|
--action github replay: event action (e.g. opened, synchronize).
|
|
443
446
|
--conclusion github replay: CI conclusion (check_run/suite/status).
|
|
444
447
|
--comment github replay: comment body for comment events.
|
|
@@ -557,6 +560,7 @@ async function main(argv: string[]): Promise<number> {
|
|
|
557
560
|
secret: { type: "string" },
|
|
558
561
|
channel: { type: "string", multiple: true },
|
|
559
562
|
install: { type: "boolean", default: false },
|
|
563
|
+
"no-install": { type: "boolean", default: false },
|
|
560
564
|
action: { type: "string" },
|
|
561
565
|
conclusion: { type: "string" },
|
|
562
566
|
context: { type: "string" },
|
|
@@ -570,6 +574,8 @@ async function main(argv: string[]): Promise<number> {
|
|
|
570
574
|
all: { type: "boolean", default: false },
|
|
571
575
|
"cursor-events-repo": { type: "string", multiple: true },
|
|
572
576
|
"allow-domain": { type: "string", multiple: true },
|
|
577
|
+
// Hidden Anysphere-only flag; omitted from help.
|
|
578
|
+
"multi-tenant": { type: "boolean", default: false },
|
|
573
579
|
"from-argv": { type: "boolean", default: false },
|
|
574
580
|
strict: { type: "boolean", default: false },
|
|
575
581
|
junit: { type: "string" },
|
|
@@ -622,6 +628,8 @@ async function main(argv: string[]): Promise<number> {
|
|
|
622
628
|
icon: values.icon,
|
|
623
629
|
force: values.force,
|
|
624
630
|
manual: values.manual,
|
|
631
|
+
install: values.install,
|
|
632
|
+
noInstall: values["no-install"],
|
|
625
633
|
iconSource: positionals[0] === "icon" ? positionals[1] : undefined,
|
|
626
634
|
});
|
|
627
635
|
}
|
|
@@ -757,6 +765,7 @@ async function main(argv: string[]): Promise<number> {
|
|
|
757
765
|
...(values["allow-domain"] === undefined
|
|
758
766
|
? {}
|
|
759
767
|
: { allowDomains: values["allow-domain"] }),
|
|
768
|
+
multiTenant: values["multi-tenant"] === true,
|
|
760
769
|
});
|
|
761
770
|
}
|
|
762
771
|
|
|
@@ -1717,7 +1726,9 @@ function installTransportErrorGuards(): void {
|
|
|
1717
1726
|
process.stderr.write(
|
|
1718
1727
|
`[agent-sdk] uncaughtException: ${error.stack ?? error.message}\n`
|
|
1719
1728
|
);
|
|
1720
|
-
|
|
1729
|
+
void flushSessionRunFatal(error).finally(() => {
|
|
1730
|
+
process.exit(1);
|
|
1731
|
+
});
|
|
1721
1732
|
});
|
|
1722
1733
|
}
|
|
1723
1734
|
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from "../../internal/continuation-identity.js";
|
|
14
14
|
import { isDeferredChannelSession } from "../../internal/deferred-channel-session.js";
|
|
15
15
|
import { isDevMode } from "../../internal/dev-mode.js";
|
|
16
|
+
import { attachHostedAdmissionAdapter } from "../../internal/hosted-admission-adapter.js";
|
|
16
17
|
import { bindLocalIngressSend } from "../../internal/local-ingress.js";
|
|
17
18
|
import type {
|
|
18
19
|
AgentCloudOptions,
|
|
@@ -804,6 +805,22 @@ export function githubChannel(
|
|
|
804
805
|
],
|
|
805
806
|
});
|
|
806
807
|
githubChannelOptionsByDefinition.set(definition, channelOptions);
|
|
808
|
+
attachHostedAdmissionAdapter(definition, {
|
|
809
|
+
kind: GITHUB_CHANNEL_KIND,
|
|
810
|
+
prepareArgs: withPropagatingGitHubBackgroundErrors,
|
|
811
|
+
dispatch: ({ eventType, payload, deliveryId, args }) =>
|
|
812
|
+
dispatchGitHubWebhook({
|
|
813
|
+
options: channelOptions,
|
|
814
|
+
eventName: eventType,
|
|
815
|
+
payload,
|
|
816
|
+
deliveryId,
|
|
817
|
+
args,
|
|
818
|
+
}),
|
|
819
|
+
getOutcome: (response) => {
|
|
820
|
+
const outcome = getGitHubDispatchOutcome(response);
|
|
821
|
+
return outcome === "skip" || outcome === "task" ? outcome : undefined;
|
|
822
|
+
},
|
|
823
|
+
});
|
|
807
824
|
if (cursorCredentials !== undefined) {
|
|
808
825
|
registerGithubCursorAccountRuntime(definition, {
|
|
809
826
|
options,
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* from options first, then the environment: `ORIGIN_APP_ID` (or
|
|
10
10
|
* `AGENT_SERVE_ORIGIN_APP_ID`), `ORIGIN_APP_INSTALLATION_ID`,
|
|
11
11
|
* `ORIGIN_APP_PRIVATE_KEY` (PKCS8 PEM for the app's Ed25519 key; literal
|
|
12
|
-
* `\n` sequences are normalized),
|
|
13
|
-
*
|
|
12
|
+
* `\n` sequences are normalized), `ORIGIN_API_BASE_URL` for the public REST
|
|
13
|
+
* base, and `ORIGIN_RPC_BASE_URL` for the first-party ConnectRPC base.
|
|
14
14
|
*
|
|
15
15
|
* Hosted v2 forks configure none of that: their only credential is the
|
|
16
16
|
* deployment service account's `CURSOR_API_KEY`, exchanged for a Cursor
|
|
@@ -40,6 +40,15 @@ import {
|
|
|
40
40
|
*/
|
|
41
41
|
export const DEFAULT_ORIGIN_PUBLIC_API_BASE_URL = "https://api.cursor.com";
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Origin's first-party ConnectRPC host (`origin.v1.OriginService`). Separate
|
|
45
|
+
* deployment from {@link DEFAULT_ORIGIN_PUBLIC_API_BASE_URL}: a handful of
|
|
46
|
+
* workflow operations — comment reactions among them — have no
|
|
47
|
+
* `/v1/origin/...` REST binding yet and are only reachable as Connect unary
|
|
48
|
+
* JSON here.
|
|
49
|
+
*/
|
|
50
|
+
export const DEFAULT_ORIGIN_RPC_BASE_URL = "https://api.origin.cursor.com";
|
|
51
|
+
|
|
43
52
|
/** Fixed audience for Origin app JWTs (`APP_TOKEN_AUDIENCE` backend-side). */
|
|
44
53
|
const ORIGIN_APP_TOKEN_AUDIENCE = "origin-apps";
|
|
45
54
|
const APP_JWT_TTL_SECONDS = 5 * 60;
|
|
@@ -139,6 +148,12 @@ export function originPublicApiBaseUrl(
|
|
|
139
148
|
return fromEnv ?? DEFAULT_ORIGIN_PUBLIC_API_BASE_URL;
|
|
140
149
|
}
|
|
141
150
|
|
|
151
|
+
/** Origin ConnectRPC base. Trailing slashes are stripped for path joins. */
|
|
152
|
+
export function originRpcBaseUrl(env: NodeJS.ProcessEnv = process.env): string {
|
|
153
|
+
const fromEnv = envValue(env.ORIGIN_RPC_BASE_URL)?.replace(/\/+$/, "");
|
|
154
|
+
return fromEnv ?? DEFAULT_ORIGIN_RPC_BASE_URL;
|
|
155
|
+
}
|
|
156
|
+
|
|
142
157
|
function base64UrlJson(value: unknown): string {
|
|
143
158
|
return Buffer.from(JSON.stringify(value)).toString("base64url");
|
|
144
159
|
}
|
|
@@ -376,9 +391,10 @@ export interface OriginClientOptions {
|
|
|
376
391
|
token?: string | OriginTokenProvider;
|
|
377
392
|
/**
|
|
378
393
|
* App credentials to mint installation tokens from. Defaults to the
|
|
379
|
-
* environment ({@link resolveOriginAppCredentials}).
|
|
394
|
+
* environment ({@link resolveOriginAppCredentials}). Pass `false` to
|
|
395
|
+
* disable app credential lookup and force the Cursor-account exchange.
|
|
380
396
|
*/
|
|
381
|
-
credentials?: OriginAppCredentials;
|
|
397
|
+
credentials?: OriginAppCredentials | false;
|
|
382
398
|
/** Public Origin REST base. Defaults to `ORIGIN_API_BASE_URL` / prod. */
|
|
383
399
|
apiBaseUrl?: string;
|
|
384
400
|
/** Injectable fetch for tests. */
|
|
@@ -441,7 +457,10 @@ export function createOriginClient(
|
|
|
441
457
|
return await options.token();
|
|
442
458
|
}
|
|
443
459
|
if (tokenProvider === undefined) {
|
|
444
|
-
const credentials =
|
|
460
|
+
const credentials =
|
|
461
|
+
options.credentials === false
|
|
462
|
+
? undefined
|
|
463
|
+
: (options.credentials ?? resolveOriginAppCredentials());
|
|
445
464
|
const exchange = options.cursorAccountExchange ?? true;
|
|
446
465
|
const exchangeOptions =
|
|
447
466
|
exchange === false ? undefined : exchange === true ? {} : exchange;
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
createOriginClient,
|
|
14
14
|
type OriginApiMethod,
|
|
15
15
|
type OriginClient,
|
|
16
|
+
originRpcBaseUrl,
|
|
16
17
|
resolveOriginAppCredentialParts,
|
|
17
18
|
} from "./api.js";
|
|
18
19
|
import {
|
|
@@ -20,6 +21,10 @@ import {
|
|
|
20
21
|
type OriginCheck,
|
|
21
22
|
type OriginCheckCreateInput,
|
|
22
23
|
} from "./checks.js";
|
|
24
|
+
import {
|
|
25
|
+
type OriginCommentReactionInput,
|
|
26
|
+
setOriginCommentReaction,
|
|
27
|
+
} from "./reactions.js";
|
|
23
28
|
import type { OriginAppOptions, OriginRepositoryRef } from "./types.js";
|
|
24
29
|
|
|
25
30
|
/** Origin operations exposed to hooks (`ctx.origin`). */
|
|
@@ -44,53 +49,77 @@ export interface OriginHandle {
|
|
|
44
49
|
createCheck(
|
|
45
50
|
input: Omit<OriginCheckCreateInput, "origin" | "owner" | "repo">
|
|
46
51
|
): Promise<OriginCheck>;
|
|
52
|
+
/**
|
|
53
|
+
* Add or remove one reaction on a PR comment — the Origin analogue of
|
|
54
|
+
* GitHub's `thread.react("eyes")`. Needs
|
|
55
|
+
* `repository:pull_requests:reviews:write`. Reactions have no REST
|
|
56
|
+
* binding, so this call goes to Origin's ConnectRPC host rather than the
|
|
57
|
+
* public API base {@link request} uses.
|
|
58
|
+
*/
|
|
59
|
+
reactToComment(input: OriginCommentReactionInput): Promise<void>;
|
|
47
60
|
}
|
|
48
61
|
|
|
49
62
|
export function buildOriginBinding(input: {
|
|
50
63
|
repository: OriginRepositoryRef;
|
|
51
64
|
/** Installation id from the delivery envelope, when present. */
|
|
52
65
|
installationId?: string;
|
|
66
|
+
/** Force the signed-in Cursor account / deployment SA credential path. */
|
|
67
|
+
cursorAccount?: boolean;
|
|
53
68
|
/** Channel-authored outbound app credentials / API base. */
|
|
54
69
|
app?: OriginAppOptions;
|
|
55
70
|
/** Injectable fetch for tests. */
|
|
56
71
|
fetch?: typeof fetch;
|
|
57
72
|
}): OriginHandle {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
const buildClient = (apiBaseUrl: string | undefined): OriginClient => {
|
|
74
|
+
const fromEnv = input.cursorAccount
|
|
75
|
+
? {}
|
|
76
|
+
: resolveOriginAppCredentialParts();
|
|
77
|
+
const appId = input.app?.appId ?? fromEnv.appId;
|
|
78
|
+
const installationId =
|
|
79
|
+
input.app?.installationId ??
|
|
80
|
+
input.installationId ??
|
|
81
|
+
fromEnv.installationId;
|
|
82
|
+
const privateKey = input.app?.privateKey ?? fromEnv.privateKey;
|
|
83
|
+
const credentials =
|
|
84
|
+
appId !== undefined &&
|
|
85
|
+
installationId !== undefined &&
|
|
86
|
+
privateKey !== undefined
|
|
87
|
+
? { appId, installationId, privateKey }
|
|
88
|
+
: undefined;
|
|
89
|
+
return createOriginClient({
|
|
90
|
+
token: input.cursorAccount ? undefined : input.app?.token,
|
|
91
|
+
credentials: input.cursorAccount ? false : credentials,
|
|
92
|
+
apiBaseUrl,
|
|
93
|
+
fetch: input.fetch,
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Public REST and ConnectRPC are separate Origin deployments, so the
|
|
98
|
+
// handle keeps a client per host. Both stay lazy: a hook that touches
|
|
99
|
+
// neither needs no credential.
|
|
100
|
+
let restClient: OriginClient | undefined;
|
|
101
|
+
const getRestClient = (): OriginClient => {
|
|
102
|
+
restClient ??= buildClient(input.app?.apiBaseUrl);
|
|
103
|
+
return restClient;
|
|
104
|
+
};
|
|
105
|
+
let rpcClient: OriginClient | undefined;
|
|
106
|
+
const getRpcClient = (): OriginClient => {
|
|
107
|
+
rpcClient ??= buildClient(input.app?.rpcBaseUrl ?? originRpcBaseUrl());
|
|
108
|
+
return rpcClient;
|
|
82
109
|
};
|
|
83
110
|
|
|
84
111
|
return {
|
|
85
112
|
installationId: input.app?.installationId ?? input.installationId,
|
|
86
113
|
repository: input.repository,
|
|
87
|
-
request: (request) =>
|
|
114
|
+
request: (request) => getRestClient().request(request),
|
|
88
115
|
createCheck: (check) =>
|
|
89
116
|
createOriginCheck({
|
|
90
117
|
...check,
|
|
91
|
-
origin:
|
|
118
|
+
origin: getRestClient(),
|
|
92
119
|
owner: input.repository.owner,
|
|
93
120
|
repo: input.repository.name,
|
|
94
121
|
}),
|
|
122
|
+
reactToComment: (reaction) =>
|
|
123
|
+
setOriginCommentReaction({ ...reaction, origin: getRpcClient() }),
|
|
95
124
|
};
|
|
96
125
|
}
|