@cursor/july 0.1.97 → 0.1.100
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 +5 -3
- package/dist/bin/agent-serve.js +6 -7
- package/dist/channels/github/defaults.d.ts.map +1 -1
- package/dist/channels/github/defaults.js +28 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +16 -0
- package/dist/channels/github/progress.d.ts +7 -0
- package/dist/channels/github/progress.d.ts.map +1 -1
- 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 +37 -4
- package/dist/channels/slack/api.d.ts +16 -7
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +29 -13
- package/dist/channels/slack/constants.d.ts +6 -0
- package/dist/channels/slack/constants.d.ts.map +1 -1
- package/dist/channels/slack/constants.js +6 -0
- package/dist/channels/slack/defaults.d.ts +9 -4
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +221 -122
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +3 -3
- package/dist/channels/slack/inbound.d.ts +9 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +14 -0
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/live-delivery.d.ts +6 -1
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +110 -20
- 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/reasoning-card.d.ts +38 -0
- package/dist/channels/slack/reasoning-card.d.ts.map +1 -0
- package/dist/channels/slack/reasoning-card.js +104 -0
- package/dist/channels/slack/redact.d.ts +2 -0
- package/dist/channels/slack/redact.d.ts.map +1 -0
- package/dist/channels/slack/redact.js +5 -0
- package/dist/channels/slack/reply-options.d.ts +40 -0
- package/dist/channels/slack/reply-options.d.ts.map +1 -0
- package/dist/channels/slack/reply-options.js +150 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +8 -4
- package/dist/channels/slack/stream.d.ts +22 -10
- package/dist/channels/slack/stream.d.ts.map +1 -1
- package/dist/channels/slack/stream.js +9 -16
- package/dist/channels/slack/tool-cards.d.ts +22 -0
- package/dist/channels/slack/tool-cards.d.ts.map +1 -0
- package/dist/channels/slack/tool-cards.js +178 -0
- package/dist/channels/slack/types.d.ts +154 -7
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +6 -6
- package/dist/docs/ab.md +1 -1
- package/dist/docs/assets/{ab.md.DJo5r4R-.js → ab.md.mlVgqvSk.js} +1 -1
- package/dist/docs/assets/{app.B3rWNYE1.js → app.DZ1e0Ycq.js} +1 -1
- package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.js → building-with-agents.md.CUSWxlP_.js} +2 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.j70vvPL4.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.C1lhqJJR.js → VPLocalSearchBox.l8omwc6D.js} +1 -1
- package/dist/docs/assets/chunks/{theme.B40_SXuv.js → theme.JVcD6gel.js} +2 -2
- package/dist/docs/assets/{evals.md.lfJoEVc8.js → evals.md.CPzDAwoH.js} +1 -1
- package/dist/docs/assets/{guides_github.md.Cnh2mL4a.js → guides_github.md.BtPr9GaP.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.js → guides_mcp-oauth.md.Dp6cDP7f.js} +1 -1
- package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.js → guides_opentelemetry.md.BVTXDCRg.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.VDXQV3ja.js → guides_slack.md.9oHPye9o.js} +19 -3
- package/dist/docs/assets/{guides_slack.md.VDXQV3ja.lean.js → guides_slack.md.9oHPye9o.lean.js} +1 -1
- package/dist/docs/assets/hillclimbing.md.CpTGTCle.js +4 -0
- package/dist/docs/assets/{index.md.CVeRUOeZ.js → index.md.Bb4k8kUm.js} +1 -1
- package/dist/docs/assets/{quickstart.md.Nj_LjW_a.js → quickstart.md.DdQOF7Y8.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.RyZf5OTE.js → reference_cli.md.DfoeyvL0.js} +4 -4
- package/dist/docs/assets/{reference_cli.md.RyZf5OTE.lean.js → reference_cli.md.DfoeyvL0.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.DxldvyIB.js → reference_connections.md.BiGoBAk2.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.5zOAbV86.js → reference_http-api.md.BEJx9XVj.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.B84gw9Ii.js → reference_tools.md.CvAHsdSp.js} +10 -2
- package/dist/docs/assets/{reference_tools.md.B84gw9Ii.lean.js → reference_tools.md.CvAHsdSp.lean.js} +1 -1
- package/dist/docs/assets/scaffolding-agents.md.em43xlY1.js +1 -0
- package/dist/docs/assets/skills_ab.md.CsFNatVx.js +26 -0
- package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +1 -0
- package/dist/docs/assets/skills_create-agent.md.BVoWPcan.js +8 -0
- package/dist/docs/assets/skills_create-agent.md.BVoWPcan.lean.js +1 -0
- package/dist/docs/assets/skills_debug.md.CDbPhHfg.js +1 -0
- package/dist/docs/assets/skills_debug.md.CDbPhHfg.lean.js +1 -0
- package/dist/docs/assets/skills_evals.md.723kpUmA.js +25 -0
- package/dist/docs/assets/skills_evals.md.723kpUmA.lean.js +1 -0
- package/dist/docs/assets/skills_framework-map.md.BTi817yv.js +1 -0
- package/dist/docs/assets/skills_framework-map.md.BTi817yv.lean.js +1 -0
- package/dist/docs/assets/skills_github.md.D0JahM8c.js +16 -0
- package/dist/docs/assets/skills_github.md.D0JahM8c.lean.js +1 -0
- package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.js +7 -0
- package/dist/docs/assets/skills_hillclimb.md.B_zJerxA.lean.js +1 -0
- package/dist/docs/assets/skills_index.md.DKwIxzGg.js +1 -0
- package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +1 -0
- package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.js +18 -0
- package/dist/docs/assets/skills_mcp-auth.md.DGvFP3HE.lean.js +1 -0
- package/dist/docs/assets/skills_otel.md.CgiZryR3.js +8 -0
- package/dist/docs/assets/skills_otel.md.CgiZryR3.lean.js +1 -0
- package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.js +20 -0
- package/dist/docs/assets/skills_setup-slack.md.BBgx8lUz.lean.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.js → troubleshooting.md.Cus_YZga.js} +1 -1
- package/dist/docs/building-with-agents.html +6 -6
- package/dist/docs/building-with-agents.md +14 -11
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/design/runtime-abstraction.md +1757 -0
- package/dist/docs/evals.html +6 -6
- package/dist/docs/evals.md +1 -1
- 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 +5 -5
- package/dist/docs/guides/github.md +1 -1
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +5 -5
- package/dist/docs/guides/mcp-oauth.md +1 -1
- package/dist/docs/guides/opentelemetry.html +7 -7
- package/dist/docs/guides/opentelemetry.md +2 -2
- package/dist/docs/guides/slack.html +22 -6
- package/dist/docs/guides/slack.md +80 -1
- package/dist/docs/guides/webhooks.html +5 -5
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +6 -6
- package/dist/docs/hillclimbing.md +5 -5
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +1 -1
- package/dist/docs/llms-full.txt +2830 -37
- package/dist/docs/llms.txt +15 -0
- package/dist/docs/quickstart.html +5 -5
- package/dist/docs/quickstart.md +1 -1
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +7 -7
- package/dist/docs/reference/cli.md +1 -7
- package/dist/docs/reference/connections.html +6 -6
- package/dist/docs/reference/connections.md +1 -1
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +1 -0
- 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 +4 -4
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +14 -6
- package/dist/docs/reference/tools.md +25 -0
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/scaffolding-agents.md +3 -3
- package/dist/docs/skills/ab.html +52 -0
- package/dist/docs/skills/ab.md +50 -0
- package/dist/docs/skills/create-agent.html +34 -0
- package/dist/docs/skills/create-agent.md +160 -0
- package/dist/docs/skills/debug.html +27 -0
- package/dist/docs/skills/debug.md +36 -0
- package/dist/docs/skills/evals.html +51 -0
- package/dist/docs/skills/evals.md +99 -0
- package/dist/docs/skills/framework-map.html +27 -0
- package/dist/docs/skills/framework-map.md +95 -0
- package/dist/docs/skills/github.html +42 -0
- package/dist/docs/skills/github.md +93 -0
- package/dist/docs/skills/hillclimb.html +33 -0
- package/dist/docs/skills/hillclimb.md +55 -0
- package/dist/docs/skills/index.html +27 -0
- package/dist/docs/skills/index.md +21 -0
- package/dist/docs/skills/mcp-auth.html +44 -0
- package/dist/docs/skills/mcp-auth.md +76 -0
- package/dist/docs/skills/otel.html +34 -0
- package/dist/docs/skills/otel.md +48 -0
- package/dist/docs/skills/setup-slack.html +46 -0
- package/dist/docs/skills/setup-slack.md +141 -0
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +4 -4
- package/dist/docs/templates/code-wiki.html +4 -4
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +4 -4
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +1 -1
- package/dist/files-backends/cursor-hosted.d.ts +9 -2
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +9 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- 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/cli-deploy.d.ts +2 -1
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +102 -7
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +3 -4
- package/dist/internal/cursor/hosted-store-secrets.d.ts +15 -0
- package/dist/internal/cursor/hosted-store-secrets.d.ts.map +1 -0
- package/dist/internal/cursor/hosted-store-secrets.js +48 -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 +6 -6
- package/dist/internal/deploy-client.js +7 -7
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +11 -1
- package/dist/internal/framework-file-storage.d.ts +5 -4
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +6 -4
- 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 +28 -23
- 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 +6 -1
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +1 -1
- package/dist/internal/hosted-delivery.d.ts +15 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +47 -21
- package/dist/internal/hosted-execution-diag.d.ts +11 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -1
- package/dist/internal/hosted-execution-diag.js +39 -2
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +4 -1
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +82 -19
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +24 -4
- 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 +358 -0
- package/dist/internal/tool-policy.d.ts +20 -8
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +11 -0
- package/dist/playground/assets/index-BszoQDc6.css +1 -0
- package/dist/playground/assets/index-DVs98vPL.js +69 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted-v2.d.ts +83 -0
- package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -0
- package/dist/storage-backends/cursor-hosted-v2.js +164 -0
- package/dist/storage-backends/cursor-hosted.d.ts +6 -0
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +6 -1
- 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/tools.d.ts +12 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +1 -1
- package/docs/ab.md +1 -1
- package/docs/building-with-agents.md +14 -11
- package/docs/design/runtime-abstraction.md +1757 -0
- package/docs/evals.md +1 -1
- package/docs/guides/github.md +1 -1
- package/docs/guides/mcp-oauth.md +1 -1
- package/docs/guides/opentelemetry.md +2 -2
- package/docs/guides/slack.md +80 -1
- package/docs/hillclimbing.md +5 -5
- package/docs/quickstart.md +1 -1
- package/docs/reference/cli.md +1 -7
- package/docs/reference/connections.md +1 -1
- package/docs/reference/http-api.md +1 -0
- package/docs/reference/tools.md +25 -0
- package/docs/scaffolding-agents.md +3 -3
- package/docs/skills/index.md +26 -0
- package/docs/troubleshooting.md +1 -1
- package/package.json +1 -1
- package/src/bin/agent-serve.ts +6 -7
- package/src/channels/github/defaults.ts +36 -3
- package/src/channels/github/github-channel.ts +17 -0
- package/src/channels/github/progress.ts +7 -0
- package/src/channels/origin/origin-channel.ts +74 -10
- package/src/channels/slack/api.ts +35 -17
- package/src/channels/slack/constants.ts +6 -0
- package/src/channels/slack/defaults.ts +253 -144
- package/src/channels/slack/dispatch.ts +10 -1
- package/src/channels/slack/inbound.ts +17 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/live-delivery.ts +135 -22
- package/src/channels/slack/progress-delivery.ts +133 -0
- package/src/channels/slack/reasoning-card.ts +140 -0
- package/src/channels/slack/redact.ts +6 -0
- package/src/channels/slack/reply-options.ts +229 -0
- package/src/channels/slack/slack-channel.ts +7 -2
- package/src/channels/slack/stream.ts +31 -24
- package/src/channels/slack/tool-cards.ts +221 -0
- package/src/channels/slack/types.ts +168 -7
- package/src/files-backends/cursor-hosted.ts +18 -7
- package/src/index.ts +4 -0
- package/src/internal/as-of.ts +107 -0
- package/src/internal/cli-deploy.ts +130 -10
- package/src/internal/conversation-mirror.ts +3 -8
- package/src/internal/cursor/hosted-store-secrets.ts +72 -0
- package/src/internal/cursor-event-relay.ts +5 -6
- package/src/internal/deploy-client.ts +10 -10
- package/src/internal/discovery.ts +9 -1
- package/src/internal/framework-file-storage.ts +6 -4
- package/src/internal/framework-storage-selection.ts +28 -25
- package/src/internal/hosted-admission-adapter.ts +42 -0
- package/src/internal/hosted-delivery-protocol.ts +7 -2
- package/src/internal/hosted-delivery.ts +88 -36
- package/src/internal/hosted-execution-diag.ts +45 -0
- package/src/internal/http-channel.ts +8 -0
- package/src/internal/server.ts +100 -2
- package/src/internal/session-engine.ts +32 -1
- package/src/internal/session-run-log.ts +579 -0
- package/src/internal/tool-policy.ts +31 -9
- package/src/storage-backends/cursor-hosted-v2.ts +219 -0
- package/src/storage-backends/cursor-hosted.ts +6 -1
- package/src/storage-protocol.ts +10 -0
- package/src/tools.ts +12 -2
- package/src/types.ts +30 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +0 -1
- package/dist/docs/assets/hillclimbing.md.DhESf3OO.js +0 -4
- package/dist/docs/assets/scaffolding-agents.md.D7UUkWw0.js +0 -1
- package/dist/playground/assets/index-DrkI6y5O.js +0 -88
- package/dist/playground/assets/index-DzNGwm7q.css +0 -1
- /package/dist/docs/assets/{ab.md.DJo5r4R-.lean.js → ab.md.mlVgqvSk.lean.js} +0 -0
- /package/dist/docs/assets/{building-with-agents.md.DI4mEzlt.lean.js → building-with-agents.md.CUSWxlP_.lean.js} +0 -0
- /package/dist/docs/assets/{evals.md.lfJoEVc8.lean.js → evals.md.CPzDAwoH.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.Cnh2mL4a.lean.js → guides_github.md.BtPr9GaP.lean.js} +0 -0
- /package/dist/docs/assets/{guides_mcp-oauth.md.CN-6YmTJ.lean.js → guides_mcp-oauth.md.Dp6cDP7f.lean.js} +0 -0
- /package/dist/docs/assets/{guides_opentelemetry.md.bmPmkvJu.lean.js → guides_opentelemetry.md.BVTXDCRg.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.DhESf3OO.lean.js → hillclimbing.md.CpTGTCle.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.CVeRUOeZ.lean.js → index.md.Bb4k8kUm.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.Nj_LjW_a.lean.js → quickstart.md.DdQOF7Y8.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.DxldvyIB.lean.js → reference_connections.md.BiGoBAk2.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.5zOAbV86.lean.js → reference_http-api.md.BEJx9XVj.lean.js} +0 -0
- /package/dist/docs/assets/{scaffolding-agents.md.D7UUkWw0.lean.js → scaffolding-agents.md.em43xlY1.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.DCiPBhYs.lean.js → troubleshooting.md.Cus_YZga.lean.js} +0 -0
|
@@ -61,8 +61,14 @@ export interface SlackChannelState {
|
|
|
61
61
|
streamTs: string | null;
|
|
62
62
|
/** Channel id used when the stream was started. */
|
|
63
63
|
streamChannelId?: string | null;
|
|
64
|
-
/** Last
|
|
64
|
+
/** Last assistant text delivered to the thread (stream or postMessage). */
|
|
65
65
|
lastPostedText?: string | null;
|
|
66
|
+
/**
|
|
67
|
+
* Text of the current assistant block already written into the open stream.
|
|
68
|
+
* The harness restarts its cumulative text at every tool boundary, so the
|
|
69
|
+
* append delta cannot be measured against {@link lastPostedText}.
|
|
70
|
+
*/
|
|
71
|
+
streamBlockText?: string | null;
|
|
66
72
|
/**
|
|
67
73
|
* Slack message ts of the agent's last delivered reply in this thread.
|
|
68
74
|
* Warm turns use this as the `<slack_thread_delta>` watermark.
|
|
@@ -73,13 +79,160 @@ export interface SlackChannelState {
|
|
|
73
79
|
* for the rest of the turn.
|
|
74
80
|
*/
|
|
75
81
|
streamingUnavailable?: boolean;
|
|
82
|
+
/** The open stream hit Slack's size cap; appends stop until it closes. */
|
|
83
|
+
streamFull?: boolean;
|
|
84
|
+
/** Editable progress message ts when `chat.startStream` is unavailable. */
|
|
85
|
+
progressTs: string | null;
|
|
76
86
|
/**
|
|
77
87
|
* Message ts of approval cards keyed by tool call id (for
|
|
78
88
|
* replacing Approve/Deny buttons after a decision).
|
|
79
89
|
*/
|
|
80
90
|
approvalMessageByCallId?: Record<string, string>;
|
|
91
|
+
/** `reply.reasoningCard` bookkeeping for the current turn. */
|
|
92
|
+
reasoningCard?: ReasoningCardState;
|
|
93
|
+
/** `reply.toolCards` per-tool tallies for the current turn, keyed by tool name. */
|
|
94
|
+
toolCardCounts?: Record<string, ToolCardCount>;
|
|
81
95
|
}
|
|
82
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Slack appends a task card's `details` across updates, so the reasoning
|
|
99
|
+
* card is fed deltas: `blockSent` is how much of the current reasoning block
|
|
100
|
+
* is already on Slack, `pending` is buffered text awaiting a flush.
|
|
101
|
+
*/
|
|
102
|
+
export interface ReasoningCardState {
|
|
103
|
+
status: "in_progress" | "complete" | null;
|
|
104
|
+
blockSent: number | null;
|
|
105
|
+
pending: string;
|
|
106
|
+
lastFlushMs: number | null;
|
|
107
|
+
chars: number;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* `details` / `output` count the lines already on the card, so a later
|
|
112
|
+
* batch can start on a new line (Slack appends updates verbatim).
|
|
113
|
+
*/
|
|
114
|
+
export interface ToolCardCount {
|
|
115
|
+
started: number;
|
|
116
|
+
done: number;
|
|
117
|
+
errors: number;
|
|
118
|
+
details?: number;
|
|
119
|
+
output?: number;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** A tool call as the model requested it (`actions.requested`). */
|
|
123
|
+
export interface SlackToolCall {
|
|
124
|
+
callId: string;
|
|
125
|
+
toolName: string;
|
|
126
|
+
args?: unknown;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** A finished tool call (`action.result`). */
|
|
130
|
+
export interface SlackToolResult {
|
|
131
|
+
callId: string;
|
|
132
|
+
toolName: string;
|
|
133
|
+
output?: unknown;
|
|
134
|
+
isError: boolean;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* What the status chip under the thread shows while a turn runs. Slack caps
|
|
139
|
+
* each line at 50 characters. While a `chat.startStream` is open Slack shows
|
|
140
|
+
* its own generic "is working…" instead, so in `"stream"` mode these lines
|
|
141
|
+
* are only visible until the first chunk goes out.
|
|
142
|
+
*/
|
|
143
|
+
export interface SlackStatusOptions {
|
|
144
|
+
/** First line of each reasoning block, throttled. Defaults to `true`. */
|
|
145
|
+
reasoning?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Tool calls as they start: `"Running grep, glob…"` (tool names through
|
|
148
|
+
* {@link SlackChannelOptions.toolLabels}), or your own line. Defaults to
|
|
149
|
+
* `true`.
|
|
150
|
+
*/
|
|
151
|
+
tools?: boolean | ((calls: readonly SlackToolCall[]) => string);
|
|
152
|
+
/**
|
|
153
|
+
* Rotation Slack cycles through while nothing more specific is known
|
|
154
|
+
* (turn start, long silent stretches). Up to 5 entries. Defaults to
|
|
155
|
+
* Thinking… / Working on it… / Almost there….
|
|
156
|
+
*/
|
|
157
|
+
idle?: readonly string[];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type SlackToolCardGroup = "per-call" | "per-tool";
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Task cards for tool calls inside the streamed reply. Slack appends each
|
|
164
|
+
* update's `details` / `output` to the card, so the callbacks return the
|
|
165
|
+
* text to add, not the full card.
|
|
166
|
+
*/
|
|
167
|
+
export interface SlackToolCardOptions {
|
|
168
|
+
/**
|
|
169
|
+
* `"per-tool"` (default) keeps one card per tool name and counts calls in
|
|
170
|
+
* the title (`grep ×3`). `"per-call"` shows one card per call.
|
|
171
|
+
*/
|
|
172
|
+
group?: SlackToolCardGroup;
|
|
173
|
+
/**
|
|
174
|
+
* `true` (default): cards expand to show one line per call, the way the
|
|
175
|
+
* reasoning card does. `false`: cards are their titles only.
|
|
176
|
+
*/
|
|
177
|
+
collapsible?: boolean;
|
|
178
|
+
/**
|
|
179
|
+
* The line a collapsible card shows for a call. Defaults to what the
|
|
180
|
+
* playground shows in that tool's header: the grep pattern, the file
|
|
181
|
+
* path, the shell command.
|
|
182
|
+
*/
|
|
183
|
+
details?: (call: SlackToolCall) => string | undefined;
|
|
184
|
+
/** Text appended to a collapsible card when a call finishes. */
|
|
185
|
+
output?: (result: SlackToolResult) => string | undefined;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* One task card that receives the model's reasoning as it streams. Its
|
|
190
|
+
* status is `in_progress` while the model thinks and `complete` once the
|
|
191
|
+
* answer text starts.
|
|
192
|
+
*/
|
|
193
|
+
export interface SlackReasoningCardOptions {
|
|
194
|
+
/** Card title. Defaults to `"Thinking"`. */
|
|
195
|
+
title?: string;
|
|
196
|
+
/**
|
|
197
|
+
* Stop appending after this many characters. Defaults to 1500: Slack caps
|
|
198
|
+
* a streamed message (answer text plus cards) near 12k, so a long card
|
|
199
|
+
* shortens the answer that fits before the reply spills into a second
|
|
200
|
+
* message.
|
|
201
|
+
*/
|
|
202
|
+
maxChars?: number;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* How the reply reaches the thread while the turn runs.
|
|
207
|
+
*
|
|
208
|
+
* - `"post"` (default): live feedback is the status chip; the answer lands
|
|
209
|
+
* as one message when the turn finishes.
|
|
210
|
+
* - `"stream"`: the answer text streams into one message as it is written.
|
|
211
|
+
* Slack replaces the status chip with its generic "is working…" for the
|
|
212
|
+
* duration, so live feedback inside the message comes from cards.
|
|
213
|
+
*/
|
|
214
|
+
export type SlackReplyOptions =
|
|
215
|
+
| {
|
|
216
|
+
mode: "post";
|
|
217
|
+
status?: SlackStatusOptions;
|
|
218
|
+
}
|
|
219
|
+
| {
|
|
220
|
+
mode: "stream";
|
|
221
|
+
status?: SlackStatusOptions;
|
|
222
|
+
/** Defaults to `false`. `true` is `{ group: "per-tool" }`. */
|
|
223
|
+
toolCards?: boolean | SlackToolCardOptions;
|
|
224
|
+
/** Defaults to `false`. */
|
|
225
|
+
reasoningCard?: boolean | SlackReasoningCardOptions;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Human labels for tool names, shared by the status chip and the cards.
|
|
230
|
+
* A function may return `undefined` to keep the raw tool name.
|
|
231
|
+
*/
|
|
232
|
+
export type SlackToolLabels =
|
|
233
|
+
| Readonly<Record<string, string>>
|
|
234
|
+
| ((toolName: string) => string | undefined);
|
|
235
|
+
|
|
83
236
|
export interface SlackAuthor {
|
|
84
237
|
/** Slack user id. Empty string for bot posts with no `user` field. */
|
|
85
238
|
userId: string;
|
|
@@ -494,13 +647,21 @@ export interface SlackChannelOptions {
|
|
|
494
647
|
*/
|
|
495
648
|
deliverDefaults?: boolean;
|
|
496
649
|
/**
|
|
497
|
-
*
|
|
498
|
-
* `
|
|
650
|
+
* How the reply reaches the thread: status chip + one message at the end
|
|
651
|
+
* (`"post"`, default), or a live-streamed message with optional tool and
|
|
652
|
+
* reasoning cards (`"stream"`). See {@link SlackReplyOptions}.
|
|
653
|
+
*/
|
|
654
|
+
reply?: SlackReplyOptions;
|
|
655
|
+
/** Human labels for tool names in the status chip and cards. */
|
|
656
|
+
toolLabels?: SlackToolLabels;
|
|
657
|
+
/**
|
|
658
|
+
* @deprecated Use `reply: { mode: "stream" }` / `reply: { mode: "post" }`.
|
|
659
|
+
* Ignored when `reply` is set.
|
|
499
660
|
*/
|
|
500
661
|
streaming?: boolean;
|
|
501
662
|
/**
|
|
502
|
-
*
|
|
503
|
-
*
|
|
663
|
+
* @deprecated Use `reply: { mode: "stream", toolCards: true }`. Ignored
|
|
664
|
+
* when `reply` is set.
|
|
504
665
|
*/
|
|
505
666
|
thinkingSteps?: boolean;
|
|
506
667
|
/**
|
|
@@ -548,8 +709,8 @@ export interface SlackChannelOptions {
|
|
|
548
709
|
suggestedPrompts?: SlackSuggestedPrompt[];
|
|
549
710
|
suggestedPromptsTitle?: string;
|
|
550
711
|
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
712
|
+
* @deprecated Use `reply: { mode, status: { idle: [...] } }`. Ignored when
|
|
713
|
+
* `reply` is set.
|
|
553
714
|
*/
|
|
554
715
|
loadingMessages?: string[];
|
|
555
716
|
/**
|
|
@@ -51,6 +51,10 @@ import {
|
|
|
51
51
|
type FileSinkEntry,
|
|
52
52
|
type FileSinkPutResult,
|
|
53
53
|
} from "../files.js";
|
|
54
|
+
import {
|
|
55
|
+
resolveDeploymentStoreSourceIdSync,
|
|
56
|
+
resolveFrameworkStoreSourceIdSync,
|
|
57
|
+
} from "../internal/cursor/hosted-store-secrets.js";
|
|
54
58
|
import { createAgentStorePresignedUrlValidatorForBackend } from "./agent-store-presigned-url.js";
|
|
55
59
|
|
|
56
60
|
/**
|
|
@@ -76,8 +80,9 @@ export const AGENT_SERVE_STORE_SOURCE_ID_ENV_VAR =
|
|
|
76
80
|
* user-level store above. The user store carries author-facing bytes
|
|
77
81
|
* (`ctx.host.files`, skills, memory, artifacts) and is browsable and
|
|
78
82
|
* mountable; the framework store carries engine-owned session state —
|
|
79
|
-
* session records, event transcripts,
|
|
80
|
-
* conversation mirror — and is never
|
|
83
|
+
* session records, event transcripts, hosted-execution run logs,
|
|
84
|
+
* continuation index, and the SDK conversation mirror — and is never
|
|
85
|
+
* exposed to authors or models.
|
|
81
86
|
* Provisioned by the v2 deploy pipeline alongside the user store; v1
|
|
82
87
|
* deployments have only the user store.
|
|
83
88
|
*/
|
|
@@ -110,8 +115,7 @@ const MAX_LIST_WALK_PAGES = 1_000;
|
|
|
110
115
|
export function isCursorHostedFilesAvailable(
|
|
111
116
|
env: NodeJS.ProcessEnv = process.env
|
|
112
117
|
): boolean {
|
|
113
|
-
|
|
114
|
-
return sourceId !== undefined && sourceId !== "";
|
|
118
|
+
return resolveDeploymentStoreSourceIdSync(env) !== undefined;
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
/**
|
|
@@ -124,8 +128,7 @@ export function isCursorHostedFilesAvailable(
|
|
|
124
128
|
export function cursorFrameworkStoreSourceId(
|
|
125
129
|
env: NodeJS.ProcessEnv = process.env
|
|
126
130
|
): string | undefined {
|
|
127
|
-
|
|
128
|
-
return sourceId === undefined || sourceId === "" ? undefined : sourceId;
|
|
131
|
+
return resolveFrameworkStoreSourceIdSync(env);
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
/**
|
|
@@ -163,6 +166,12 @@ export interface CursorHostedFilesOptions {
|
|
|
163
166
|
resolveApiKey?: () => string | undefined;
|
|
164
167
|
/** File store to address (default: `AGENT_SERVE_STORE_SOURCE_ID`). */
|
|
165
168
|
storeSourceId?: string;
|
|
169
|
+
/**
|
|
170
|
+
* Lazy store source id, re-resolved on every call and preferred over
|
|
171
|
+
* {@link storeSourceId} — freeze bind drops ids into `/run/cursor/secrets`
|
|
172
|
+
* after serve start without restarting July.
|
|
173
|
+
*/
|
|
174
|
+
resolveStoreSourceId?: () => string | undefined;
|
|
166
175
|
/** Test seam; defaults to global fetch. */
|
|
167
176
|
fetch?: typeof fetch;
|
|
168
177
|
}
|
|
@@ -649,7 +658,9 @@ function fetchImpl(options: CursorHostedFilesOptions): typeof fetch {
|
|
|
649
658
|
*/
|
|
650
659
|
function resolveStoreSourceId(options: CursorHostedFilesOptions): string {
|
|
651
660
|
const id = (
|
|
652
|
-
options.
|
|
661
|
+
options.resolveStoreSourceId?.() ??
|
|
662
|
+
options.storeSourceId ??
|
|
663
|
+
resolveDeploymentStoreSourceIdSync(process.env)
|
|
653
664
|
)?.trim();
|
|
654
665
|
if (id === undefined || id === "") {
|
|
655
666
|
throw new Error(
|
package/src/index.ts
CHANGED
|
@@ -79,6 +79,10 @@ export {
|
|
|
79
79
|
V2EngineError,
|
|
80
80
|
} from "./continuation.js";
|
|
81
81
|
export { defineHook } from "./hooks.js";
|
|
82
|
+
export {
|
|
83
|
+
InvalidAsOfError,
|
|
84
|
+
VacuousTimeArgsError,
|
|
85
|
+
} from "./internal/as-of.js";
|
|
82
86
|
export type { LoadAgentProjectOptions } from "./internal/discovery.js";
|
|
83
87
|
export {
|
|
84
88
|
formatDiagnostics,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const TIMEZONE_SUFFIX = /(?:Z|[+-]\d{2}:?\d{2})$/i;
|
|
2
|
+
|
|
3
|
+
export class InvalidAsOfError extends Error {
|
|
4
|
+
constructor(value: string) {
|
|
5
|
+
super(
|
|
6
|
+
`asOf must be an ISO-8601 instant with a timezone (e.g. ` +
|
|
7
|
+
`2026-08-31T12:00:00Z); received ${JSON.stringify(value)}.`
|
|
8
|
+
);
|
|
9
|
+
this.name = "InvalidAsOfError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function parseInstant(value: string): Date | undefined {
|
|
14
|
+
const trimmed = value.trim();
|
|
15
|
+
if (trimmed === "" || !TIMEZONE_SUFFIX.test(trimmed)) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const instant = new Date(trimmed);
|
|
19
|
+
return Number.isNaN(instant.getTime()) ? undefined : instant;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function normalizeAsOf(value: string | undefined): string | undefined {
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const instant = parseInstant(value);
|
|
27
|
+
if (instant === undefined) {
|
|
28
|
+
throw new InvalidAsOfError(value);
|
|
29
|
+
}
|
|
30
|
+
return instant.toISOString();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function sessionClock(asOf: string | undefined): () => Date {
|
|
34
|
+
if (asOf === undefined) {
|
|
35
|
+
return () => new Date();
|
|
36
|
+
}
|
|
37
|
+
const frozen = new Date(asOf).getTime();
|
|
38
|
+
return () => new Date(frozen);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class VacuousTimeArgsError extends Error {
|
|
42
|
+
constructor(toolName: string, missing: readonly string[]) {
|
|
43
|
+
super(
|
|
44
|
+
`Tool "${toolName}" declares timeArgs ` +
|
|
45
|
+
`${JSON.stringify(missing)} that its input schema does not define, ` +
|
|
46
|
+
`so bounding would silently check nothing. Make the declaration ` +
|
|
47
|
+
`match the schema's property names.`
|
|
48
|
+
);
|
|
49
|
+
this.name = "VacuousTimeArgsError";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function assertTimeArgs(
|
|
54
|
+
tools: readonly {
|
|
55
|
+
name: string;
|
|
56
|
+
definition: { timeArgs?: readonly string[] };
|
|
57
|
+
inputSchema?: { properties?: Record<string, unknown> };
|
|
58
|
+
}[],
|
|
59
|
+
asOf: string | undefined
|
|
60
|
+
): void {
|
|
61
|
+
if (asOf === undefined) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
for (const tool of tools) {
|
|
65
|
+
const declared = tool.definition.timeArgs;
|
|
66
|
+
if (declared === undefined || declared.length === 0) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const properties = tool.inputSchema?.properties ?? {};
|
|
70
|
+
const missing = declared.filter((name) => !(name in properties));
|
|
71
|
+
if (missing.length > 0) {
|
|
72
|
+
throw new VacuousTimeArgsError(tool.name, missing);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function timeArgViolation(
|
|
78
|
+
input: unknown,
|
|
79
|
+
timeArgs: readonly string[],
|
|
80
|
+
asOf: string
|
|
81
|
+
): string | undefined {
|
|
82
|
+
const record =
|
|
83
|
+
typeof input === "object" && input !== null
|
|
84
|
+
? (input as Record<string, unknown>)
|
|
85
|
+
: {};
|
|
86
|
+
const frozen = new Date(asOf).getTime();
|
|
87
|
+
for (const name of timeArgs) {
|
|
88
|
+
const value = record[name];
|
|
89
|
+
const instant = typeof value === "string" ? parseInstant(value) : undefined;
|
|
90
|
+
if (instant === undefined) {
|
|
91
|
+
return (
|
|
92
|
+
`Time argument "${name}" must be an absolute ISO-8601 instant with ` +
|
|
93
|
+
`a timezone (e.g. ${asOf}); received ${JSON.stringify(value)}. This ` +
|
|
94
|
+
`session reads the world as of ${asOf} — supply absolute bounds at ` +
|
|
95
|
+
`or before that instant and retry.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (instant.getTime() > frozen) {
|
|
99
|
+
return (
|
|
100
|
+
`Time argument "${name}" (${JSON.stringify(value)}) is later than ` +
|
|
101
|
+
`the instant this session reads the world as of (${asOf}). Supply ` +
|
|
102
|
+
`bounds at or before that instant and retry.`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
@@ -66,6 +66,8 @@ import { stderrPalette } from "./terminal-style.js";
|
|
|
66
66
|
|
|
67
67
|
const DEFAULT_POLL_INTERVAL_MS = 3_000;
|
|
68
68
|
const DEFAULT_DEPLOY_TIMEOUT_MS = 10 * 60 * 1000;
|
|
69
|
+
/** `--multi-tenant` HTTP deploy is Anysphere-only (team id 1). */
|
|
70
|
+
const MULTI_TENANT_HTTP_DEPLOY_TEAM_ID = 1;
|
|
69
71
|
|
|
70
72
|
/** One agent directory selected for deploy (single or multi-agent parent). */
|
|
71
73
|
export type DeployTarget = ChildAgentDir;
|
|
@@ -114,7 +116,8 @@ export interface DeployCliOptions {
|
|
|
114
116
|
allowDomains?: string[];
|
|
115
117
|
/**
|
|
116
118
|
* deploy `--multi-tenant`: add a release to an existing Cursor-managed
|
|
117
|
-
* (multi-tenant) product. Cannot create a
|
|
119
|
+
* (multi-tenant) product. Hidden Anysphere-only flag. Cannot create a
|
|
120
|
+
* new multi-tenant application.
|
|
118
121
|
*/
|
|
119
122
|
multiTenant?: boolean;
|
|
120
123
|
/** Test seams. */
|
|
@@ -297,6 +300,14 @@ export async function cmdDeploy(options: DeployCliOptions): Promise<number> {
|
|
|
297
300
|
return ctx;
|
|
298
301
|
}
|
|
299
302
|
|
|
303
|
+
if (
|
|
304
|
+
options.multiTenant === true &&
|
|
305
|
+
ctx.teamId !== MULTI_TENANT_HTTP_DEPLOY_TEAM_ID
|
|
306
|
+
) {
|
|
307
|
+
ctx.err("--multi-tenant is not available for this team.\n");
|
|
308
|
+
return 1;
|
|
309
|
+
}
|
|
310
|
+
|
|
300
311
|
const targets = await resolveDeployTargets(options, ctx);
|
|
301
312
|
if (typeof targets === "number") {
|
|
302
313
|
return targets;
|
|
@@ -947,7 +958,7 @@ async function deployAgentsdkApplication(
|
|
|
947
958
|
}
|
|
948
959
|
|
|
949
960
|
/**
|
|
950
|
-
* `architecture: "v2"` deploy: POST `/internal/
|
|
961
|
+
* `architecture: "v2"` deploy: POST `/internal/agentsdk/deployments` and
|
|
951
962
|
* poll the matching GET. The v2 accept path starts freeze bake; it does
|
|
952
963
|
* not mint an engine alias or alias token.
|
|
953
964
|
*/
|
|
@@ -990,7 +1001,10 @@ async function deployOneAgentsdk(
|
|
|
990
1001
|
...(args.multiTenant ? { multiTenant: true } : {}),
|
|
991
1002
|
});
|
|
992
1003
|
} catch (error) {
|
|
993
|
-
return renderApiError(error, ctx.err
|
|
1004
|
+
return renderApiError(error, ctx.err, {
|
|
1005
|
+
multiTenant: args.multiTenant,
|
|
1006
|
+
teamId: ctx.teamId,
|
|
1007
|
+
});
|
|
994
1008
|
}
|
|
995
1009
|
|
|
996
1010
|
if (ctx.noWait) {
|
|
@@ -1301,6 +1315,21 @@ export async function cmdDeploymentStatus(
|
|
|
1301
1315
|
if (typeof ctx === "number") {
|
|
1302
1316
|
return ctx;
|
|
1303
1317
|
}
|
|
1318
|
+
// Same dispatch as `stop`: v1 409s architecture-v2 slugs, so the v2
|
|
1319
|
+
// GET goes first. A v2 404 (missing slug, or an older backend) falls
|
|
1320
|
+
// through to the v1 agent-serve detail.
|
|
1321
|
+
try {
|
|
1322
|
+
const detail = await ctx.client.getAgentkitDeploy({
|
|
1323
|
+
teamId: ctx.teamId,
|
|
1324
|
+
slug,
|
|
1325
|
+
});
|
|
1326
|
+
renderAgentkitDeploymentStatus(ctx, detail);
|
|
1327
|
+
return 0;
|
|
1328
|
+
} catch (error) {
|
|
1329
|
+
if (!(error instanceof DeployApiError) || error.status !== 404) {
|
|
1330
|
+
return renderApiError(error, ctx.err);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1304
1333
|
let detail: DeploymentDetail;
|
|
1305
1334
|
try {
|
|
1306
1335
|
detail = await ctx.client.getDeployment({ teamId: ctx.teamId, slug });
|
|
@@ -1393,6 +1422,40 @@ export async function cmdDeploymentStatus(
|
|
|
1393
1422
|
return 0;
|
|
1394
1423
|
}
|
|
1395
1424
|
|
|
1425
|
+
function renderAgentkitDeploymentStatus(
|
|
1426
|
+
ctx: DeployCliContext,
|
|
1427
|
+
detail: AgentkitDeployStatus
|
|
1428
|
+
): void {
|
|
1429
|
+
if (ctx.json) {
|
|
1430
|
+
ctx.out(`${JSON.stringify(detail, null, 2)}\n`);
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
const lines = [
|
|
1434
|
+
`${detail.slug} (team ${detail.teamId})`,
|
|
1435
|
+
` status: ${detail.status}`,
|
|
1436
|
+
` architecture: v2`,
|
|
1437
|
+
` application: ${detail.applicationId}`,
|
|
1438
|
+
` release: ${detail.releaseId}`,
|
|
1439
|
+
` progress: ${detail.progress}`,
|
|
1440
|
+
];
|
|
1441
|
+
if (detail.statusMessage !== null && detail.statusMessage.trim() !== "") {
|
|
1442
|
+
lines.push(` step: ${detail.statusMessage}`);
|
|
1443
|
+
}
|
|
1444
|
+
if (detail.repositories !== undefined) {
|
|
1445
|
+
lines.push(
|
|
1446
|
+
` watching: ${
|
|
1447
|
+
detail.repositories.length === 0
|
|
1448
|
+
? "(nothing)"
|
|
1449
|
+
: detail.repositories.join(", ")
|
|
1450
|
+
}`
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
if (detail.lastError !== null && detail.lastError !== undefined) {
|
|
1454
|
+
lines.push(` last error: ${sanitizeCustomerError(detail.lastError)}`);
|
|
1455
|
+
}
|
|
1456
|
+
ctx.out(`${lines.join("\n")}\n`);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1396
1459
|
// ============================================================================
|
|
1397
1460
|
// stop <slug>
|
|
1398
1461
|
// ============================================================================
|
|
@@ -1415,7 +1478,7 @@ export async function cmdStop(
|
|
|
1415
1478
|
// deploy). The v2 agentsdk control plane goes first: v1 endpoints refuse
|
|
1416
1479
|
// `architecture: "v2"` slugs with a 409 rather than a 404, so v1-first
|
|
1417
1480
|
// could not fall through. A v2 404 (including an older backend without
|
|
1418
|
-
// the `/internal/
|
|
1481
|
+
// the `/internal/agentsdk` mount) falls back to the v1 stop.
|
|
1419
1482
|
let architecture: "v1" | "v2" = "v2";
|
|
1420
1483
|
let accepted: StopAccepted | AgentkitStopAccepted;
|
|
1421
1484
|
try {
|
|
@@ -1901,10 +1964,35 @@ async function pollUntil<
|
|
|
1901
1964
|
};
|
|
1902
1965
|
|
|
1903
1966
|
for (;;) {
|
|
1904
|
-
|
|
1967
|
+
let detail: T;
|
|
1968
|
+
try {
|
|
1969
|
+
detail = await fetchDetail();
|
|
1970
|
+
} catch (error: unknown) {
|
|
1971
|
+
// Capacity / rate-limit on GET is not a bake failure. The v2 accept
|
|
1972
|
+
// already started freeze; keep polling until the wait budget expires.
|
|
1973
|
+
if (
|
|
1974
|
+
isTransientDeployStatusError(error) &&
|
|
1975
|
+
Date.now() - startedAt < ctx.timeoutMs
|
|
1976
|
+
) {
|
|
1977
|
+
if (!ctx.json) {
|
|
1978
|
+
const elapsed = Math.round((Date.now() - startedAt) / 1000);
|
|
1979
|
+
const label = "Waiting for status (server busy)";
|
|
1980
|
+
if (tty) {
|
|
1981
|
+
ctx.err(`\r\x1b[2K${slug}: ${label} (${elapsed}s)`);
|
|
1982
|
+
sawProgress = true;
|
|
1983
|
+
} else if (label !== lastLabel) {
|
|
1984
|
+
ctx.err(`${slug}: ${label}\n`);
|
|
1985
|
+
}
|
|
1986
|
+
lastLabel = label;
|
|
1987
|
+
}
|
|
1988
|
+
const waitMs = transientDeployStatusWaitMs(error, ctx.pollIntervalMs);
|
|
1989
|
+
const remaining = ctx.timeoutMs - (Date.now() - startedAt);
|
|
1990
|
+
await sleep(Math.max(0, Math.min(waitMs, remaining)));
|
|
1991
|
+
continue;
|
|
1992
|
+
}
|
|
1905
1993
|
finishProgressLine();
|
|
1906
1994
|
throw error;
|
|
1907
|
-
}
|
|
1995
|
+
}
|
|
1908
1996
|
report(detail);
|
|
1909
1997
|
if (terminal.has(detail.status)) {
|
|
1910
1998
|
finishProgressLine();
|
|
@@ -1922,6 +2010,28 @@ async function pollUntil<
|
|
|
1922
2010
|
}
|
|
1923
2011
|
}
|
|
1924
2012
|
|
|
2013
|
+
/** Load-shed / rate-limit on status GET — the deploy itself may still be baking. */
|
|
2014
|
+
function isTransientDeployStatusError(error: unknown): error is DeployApiError {
|
|
2015
|
+
return (
|
|
2016
|
+
error instanceof DeployApiError &&
|
|
2017
|
+
(error.status === 503 || error.status === 429)
|
|
2018
|
+
);
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
function transientDeployStatusWaitMs(
|
|
2022
|
+
error: DeployApiError,
|
|
2023
|
+
pollIntervalMs: number
|
|
2024
|
+
): number {
|
|
2025
|
+
if (
|
|
2026
|
+
error.status === 429 &&
|
|
2027
|
+
error.retryAfterSeconds !== undefined &&
|
|
2028
|
+
error.retryAfterSeconds > 0
|
|
2029
|
+
) {
|
|
2030
|
+
return Math.max(pollIntervalMs, error.retryAfterSeconds * 1000);
|
|
2031
|
+
}
|
|
2032
|
+
return pollIntervalMs;
|
|
2033
|
+
}
|
|
2034
|
+
|
|
1925
2035
|
/**
|
|
1926
2036
|
* Wait until GET 404s (the delete reconciler purged the record). Treats
|
|
1927
2037
|
* other errors as failures. Throws DeployApiError on timeout.
|
|
@@ -2000,16 +2110,26 @@ function deployFailureDetail(lastError: string | null | undefined): string {
|
|
|
2000
2110
|
return `: ${sanitizeCustomerError(lastError.trim())}`;
|
|
2001
2111
|
}
|
|
2002
2112
|
|
|
2003
|
-
function renderApiError(
|
|
2113
|
+
function renderApiError(
|
|
2114
|
+
error: unknown,
|
|
2115
|
+
err: (text: string) => void,
|
|
2116
|
+
context?: { multiTenant?: boolean; teamId?: number }
|
|
2117
|
+
): number {
|
|
2004
2118
|
if (error instanceof DeployApiError) {
|
|
2005
2119
|
err(`${error.message}\n`);
|
|
2006
2120
|
if (
|
|
2007
2121
|
error.status === 409 &&
|
|
2008
2122
|
error.message.includes("application multiTenant does not match")
|
|
2009
2123
|
) {
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2124
|
+
if (context?.multiTenant === true) {
|
|
2125
|
+
err(
|
|
2126
|
+
"This slug is a single-tenant application. Redeploy it without --multi-tenant.\n"
|
|
2127
|
+
);
|
|
2128
|
+
} else if (context?.teamId === MULTI_TENANT_HTTP_DEPLOY_TEAM_ID) {
|
|
2129
|
+
err(
|
|
2130
|
+
"This slug is a Cursor-managed (multi-tenant) product. Redeploy it with --multi-tenant.\n"
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2013
2133
|
}
|
|
2014
2134
|
return 1;
|
|
2015
2135
|
}
|
|
@@ -383,18 +383,13 @@ export function selectConversationMirror(input: {
|
|
|
383
383
|
return undefined;
|
|
384
384
|
}
|
|
385
385
|
const env = input.env ?? process.env;
|
|
386
|
-
|
|
387
|
-
env as NodeJS.ProcessEnv
|
|
388
|
-
);
|
|
389
|
-
if (
|
|
390
|
-
env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined ||
|
|
391
|
-
frameworkStoreId === undefined
|
|
392
|
-
) {
|
|
386
|
+
if (env[AGENT_SERVE_GENERATION_ENV_VAR] === undefined) {
|
|
393
387
|
return undefined;
|
|
394
388
|
}
|
|
389
|
+
const envSnapshot = env as NodeJS.ProcessEnv;
|
|
395
390
|
return createConversationMirror({
|
|
396
391
|
sink: cursorHostedFiles({
|
|
397
|
-
|
|
392
|
+
resolveStoreSourceId: () => cursorFrameworkStoreSourceId(envSnapshot),
|
|
398
393
|
// Full chain (env → key file → stored login): frozen engines listen
|
|
399
394
|
// unsigned and bind CURSOR_API_KEY_FILE at task time, after this sink
|
|
400
395
|
// is constructed.
|