@cursor/july 0.1.95 → 0.1.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +3 -4
- package/README.md +3 -2
- package/dist/bin/agent-serve.js +14 -3
- package/dist/channels/deployments/types.d.ts +1 -1
- package/dist/channels/deployments/types.d.ts.map +1 -1
- package/dist/channels/deployments/types.js +1 -0
- package/dist/channels/origin/api.d.ts +72 -15
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +185 -28
- package/dist/channels/origin/binding.d.ts +13 -2
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +41 -25
- package/dist/channels/origin/checks.d.ts +6 -6
- package/dist/channels/origin/checks.js +6 -6
- package/dist/channels/origin/cursor-account.d.ts +5 -3
- package/dist/channels/origin/cursor-account.d.ts.map +1 -1
- package/dist/channels/origin/cursor-account.js +5 -3
- package/dist/channels/origin/index.d.ts +1 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +1 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +3 -0
- package/dist/channels/origin/reactions.d.ts +56 -0
- package/dist/channels/origin/reactions.d.ts.map +1 -0
- package/dist/channels/origin/reactions.js +67 -0
- package/dist/channels/origin/types.d.ts +11 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/api.d.ts +9 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +36 -5
- package/dist/channels/slack/approvals.d.ts +16 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -1
- package/dist/channels/slack/approvals.js +86 -0
- package/dist/channels/slack/cli-project.d.ts +19 -0
- package/dist/channels/slack/cli-project.d.ts.map +1 -0
- package/dist/channels/slack/cli-project.js +234 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +110 -81
- package/dist/channels/slack/dispatch.d.ts +7 -1
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +47 -23
- package/dist/channels/slack/inbound.d.ts +8 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +32 -0
- package/dist/channels/slack/init.d.ts +3 -2
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +5 -5
- package/dist/channels/slack/interactive.d.ts +2 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +15 -4
- package/dist/channels/slack/live-delivery.d.ts +26 -29
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +172 -73
- package/dist/channels/slack/manifest.d.ts +1 -1
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +6 -2
- package/dist/channels/slack/nudge-carrier.d.ts +2 -0
- package/dist/channels/slack/nudge-carrier.d.ts.map +1 -1
- package/dist/channels/slack/nudge-carrier.js +48 -1
- package/dist/channels/slack/setup.d.ts +1 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +10 -6
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +3 -2
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +91 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.BBj0klBO.js → app.B3rWNYE1.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.CUEXpL78.js → VPLocalSearchBox.C1lhqJJR.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DabmQnia.js → theme.B40_SXuv.js} +2 -2
- package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
- package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
- package/dist/docs/assets/{index.md.BoHaMdeZ.lean.js → index.md.CVeRUOeZ.lean.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.BsMOxDvh.js → reference_cli.md.RyZf5OTE.js} +10 -6
- package/dist/docs/assets/{reference_cli.md.BsMOxDvh.lean.js → reference_cli.md.RyZf5OTE.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
- package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.5zOAbV86.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.B84gw9Ii.js} +1 -1
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.js +2 -0
- package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/deployment.md +5 -4
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +8 -8
- package/dist/docs/guides/mcp-oauth.md +26 -8
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +17 -33
- package/dist/docs/guides/slack.md +92 -201
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +7 -3
- package/dist/docs/llms-full.txt +398 -653
- package/dist/docs/llms.txt +3 -2
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/agent-config.md +2 -2
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +14 -10
- package/dist/docs/reference/cli.md +39 -16
- package/dist/docs/reference/connections.html +9 -8
- package/dist/docs/reference/connections.md +6 -3
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +2 -1
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +5 -5
- package/dist/docs/reference/sessions.md +4 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +6 -6
- package/dist/docs/reference/tools.md +9 -2
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +28 -0
- package/dist/docs/templates/agents-md.md +105 -0
- package/dist/docs/templates/code-wiki.html +28 -0
- package/dist/docs/templates/code-wiki.md +91 -0
- package/dist/docs/templates/demo.html +5 -5
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +5 -5
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/evals/run-facts.d.ts.map +1 -1
- package/dist/evals/run-facts.js +27 -0
- package/dist/files-backends/cursor-hosted.d.ts +26 -4
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +32 -4
- package/dist/internal/advertise-tools.d.ts +2 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +30 -10
- package/dist/internal/approval-gate.d.ts +12 -13
- package/dist/internal/approval-gate.d.ts.map +1 -1
- package/dist/internal/approval-gate.js +16 -21
- package/dist/internal/bounded.d.ts +7 -0
- package/dist/internal/bounded.d.ts.map +1 -0
- package/dist/internal/bounded.js +32 -0
- package/dist/internal/chat-client.js +10 -0
- package/dist/internal/cli-deploy.d.ts +5 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +57 -18
- package/dist/internal/cli-mcp-oauth.js +8 -18
- package/dist/internal/cli-slack-manual.d.ts +24 -2
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +251 -20
- package/dist/internal/cli-slack.d.ts +9 -2
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +29 -82
- package/dist/internal/conversation-mirror.d.ts +11 -8
- package/dist/internal/conversation-mirror.d.ts.map +1 -1
- package/dist/internal/conversation-mirror.js +116 -55
- package/dist/internal/cursor/account-mcp.d.ts +1 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +17 -0
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +22 -48
- package/dist/internal/cursor/session-token.d.ts +45 -0
- package/dist/internal/cursor/session-token.d.ts.map +1 -0
- package/dist/internal/cursor/session-token.js +99 -0
- package/dist/internal/cursor-agent-template.d.ts +1 -1
- package/dist/internal/cursor-agent-template.d.ts.map +1 -1
- package/dist/internal/cursor-agent-template.js +2 -0
- package/dist/internal/deploy-client.d.ts +17 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +31 -10
- package/dist/internal/env-file.d.ts +19 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +90 -0
- package/dist/internal/framework-file-storage.d.ts +61 -0
- package/dist/internal/framework-file-storage.d.ts.map +1 -0
- package/dist/internal/framework-file-storage.js +210 -0
- package/dist/internal/framework-storage-selection.d.ts +11 -5
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +38 -11
- package/dist/internal/hosted-delivery-protocol.d.ts +7 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +7 -0
- package/dist/internal/hosted-delivery.d.ts +13 -0
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +64 -19
- package/dist/internal/hosted-execution-diag.d.ts +48 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
- package/dist/internal/hosted-execution-diag.js +150 -0
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +81 -1
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +4 -0
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +1 -3
- package/dist/internal/logs-client.d.ts +5 -0
- package/dist/internal/logs-client.d.ts.map +1 -1
- package/dist/internal/logs-client.js +5 -0
- package/dist/internal/managed-delivery.d.ts +80 -0
- package/dist/internal/managed-delivery.d.ts.map +1 -0
- package/dist/internal/managed-delivery.js +86 -0
- package/dist/internal/mcp-endpoint.js +2 -3
- package/dist/internal/mcp-host.d.ts +10 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +57 -8
- package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
- package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-on-demand.js +287 -0
- package/dist/internal/mcp-oauth-persist.d.ts +42 -0
- package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-persist.js +92 -0
- package/dist/internal/mcp-oauth.d.ts +1 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -1
- package/dist/internal/mcp-oauth.js +10 -2
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +22 -9
- package/dist/internal/runtime-dispatch-runner.d.ts +5 -1
- package/dist/internal/runtime-dispatch-runner.d.ts.map +1 -1
- package/dist/internal/runtime-dispatch-runner.js +7 -0
- package/dist/internal/sdk-runner.d.ts +11 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +39 -8
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +49 -21
- package/dist/internal/session-engine.d.ts +101 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +577 -46
- package/dist/internal/sessions-client.d.ts +9 -7
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +3 -1
- package/dist/internal/steering.d.ts +15 -0
- package/dist/internal/steering.d.ts.map +1 -0
- package/dist/internal/steering.js +18 -0
- package/dist/internal/storage-coordinator.d.ts +7 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +28 -5
- package/dist/internal/storage-roles.d.ts +5 -0
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +10 -0
- package/dist/internal/tool-policy.d.ts +9 -1
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +13 -0
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +10 -0
- package/dist/internal/turn-outbox.d.ts +24 -0
- package/dist/internal/turn-outbox.d.ts.map +1 -0
- package/dist/internal/turn-outbox.js +80 -0
- package/dist/playground/assets/{index-CZA1uEWA.js → index-DrkI6y5O.js} +51 -51
- package/dist/playground/assets/index-DzNGwm7q.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +9 -6
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +16 -3
- package/dist/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/types.d.ts +65 -8
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +7 -3
- package/docs/deployment.md +5 -4
- package/docs/guides/mcp-oauth.md +26 -8
- package/docs/guides/slack.md +93 -202
- package/docs/reference/agent-config.md +2 -2
- package/docs/reference/cli.md +39 -16
- package/docs/reference/connections.md +6 -3
- package/docs/reference/http-api.md +2 -1
- package/docs/reference/sessions.md +4 -2
- package/docs/reference/tools.md +9 -2
- package/docs/templates/agents-md.md +110 -0
- package/docs/templates/code-wiki.md +96 -0
- package/docs/troubleshooting.md +2 -2
- package/package.json +2 -2
- package/skills/ab/SKILL.md +13 -97
- package/skills/create-agent/SKILL.md +124 -223
- package/skills/debug/SKILL.md +34 -68
- package/skills/evals/SKILL.md +55 -180
- package/skills/framework-map/SKILL.md +83 -145
- package/skills/github/SKILL.md +53 -111
- package/skills/hillclimb/SKILL.md +40 -163
- package/skills/mcp-auth/SKILL.md +51 -107
- package/skills/otel/SKILL.md +22 -68
- package/skills/setup-slack/SKILL.md +91 -212
- package/src/bin/agent-serve.ts +13 -1
- package/src/channels/deployments/types.ts +1 -0
- package/src/channels/origin/api.ts +264 -33
- package/src/channels/origin/binding.ts +57 -28
- package/src/channels/origin/checks.ts +6 -6
- package/src/channels/origin/cursor-account.ts +5 -3
- package/src/channels/origin/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +4 -0
- package/src/channels/origin/reactions.ts +82 -0
- package/src/channels/origin/types.ts +11 -0
- package/src/channels/slack/api.ts +41 -5
- package/src/channels/slack/approvals.ts +105 -0
- package/src/channels/slack/cli-project.ts +267 -0
- package/src/channels/slack/defaults.ts +122 -93
- package/src/channels/slack/dispatch.ts +56 -22
- package/src/channels/slack/inbound.ts +43 -0
- package/src/channels/slack/init.ts +10 -5
- package/src/channels/slack/interactive.ts +35 -9
- package/src/channels/slack/live-delivery.ts +235 -114
- package/src/channels/slack/manifest.ts +6 -2
- package/src/channels/slack/nudge-carrier.ts +48 -1
- package/src/channels/slack/setup.ts +10 -6
- package/src/channels/slack/slack-channel.ts +3 -0
- package/src/channels/slack/tool-approval-events.ts +93 -0
- package/src/evals/run-facts.ts +32 -0
- package/src/files-backends/cursor-hosted.ts +40 -7
- package/src/internal/advertise-tools.ts +49 -12
- package/src/internal/approval-gate.ts +20 -29
- package/src/internal/bounded.ts +28 -0
- package/src/internal/chat-client.ts +19 -0
- package/src/internal/cli-deploy.ts +91 -9
- package/src/internal/cli-mcp-oauth.ts +7 -21
- package/src/internal/cli-slack-manual.ts +350 -18
- package/src/internal/cli-slack.ts +40 -84
- package/src/internal/conversation-mirror.ts +145 -69
- package/src/internal/cursor/account-mcp.ts +21 -0
- package/src/internal/cursor/backend-client.ts +34 -58
- package/src/internal/cursor/session-token.ts +115 -0
- package/src/internal/cursor-agent-template.ts +2 -0
- package/src/internal/deploy-client.ts +43 -0
- package/src/internal/env-file.ts +84 -0
- package/src/internal/framework-file-storage.ts +228 -0
- package/src/internal/framework-storage-selection.ts +51 -11
- package/src/internal/hosted-delivery-protocol.ts +7 -0
- package/src/internal/hosted-delivery.ts +107 -24
- package/src/internal/hosted-execution-diag.ts +207 -0
- package/src/internal/http-channel.ts +99 -0
- package/src/internal/init-project.ts +4 -0
- package/src/internal/install-cursor-skills.ts +1 -4
- package/src/internal/logs-client.ts +5 -0
- package/src/internal/managed-delivery.ts +125 -0
- package/src/internal/mcp-endpoint.ts +13 -4
- package/src/internal/mcp-host.ts +77 -11
- package/src/internal/mcp-oauth-on-demand.ts +352 -0
- package/src/internal/mcp-oauth-persist.ts +127 -0
- package/src/internal/mcp-oauth.ts +17 -1
- package/src/internal/otel/collector.ts +30 -0
- package/src/internal/runtime-dispatch-runner.ts +10 -0
- package/src/internal/sdk-runner.ts +56 -8
- package/src/internal/server.ts +61 -9
- package/src/internal/session-engine.ts +723 -60
- package/src/internal/sessions-client.ts +17 -8
- package/src/internal/steering.ts +17 -0
- package/src/internal/storage-coordinator.ts +38 -8
- package/src/internal/storage-roles.ts +7 -0
- package/src/internal/stream-progress.ts +19 -0
- package/src/internal/tool-policy.ts +18 -0
- package/src/internal/trajectory.ts +10 -0
- package/src/internal/turn-outbox.ts +85 -0
- package/src/storage-backends/cursor-hosted.ts +22 -8
- package/src/storage.ts +12 -0
- package/src/types.ts +70 -9
- package/templates/agents-md/README.md +39 -0
- package/templates/agents-md/agent/agent.ts +8 -0
- package/templates/agents-md/agent/channels/github.ts +10 -0
- package/templates/agents-md/agent/channels/queue.ts +28 -0
- package/templates/agents-md/agent/channels/slack.ts +9 -0
- package/templates/agents-md/agent/instructions.md +39 -0
- package/templates/agents-md/agent/lib/collect.ts +439 -0
- package/templates/agents-md/agent/lib/config.ts +8 -0
- package/templates/agents-md/agent/lib/paths.ts +51 -0
- package/templates/agents-md/agent/schedules/weekly.ts +17 -0
- package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
- package/templates/agents-md/evals/agents.eval.ts +135 -0
- package/templates/agents-md/evals/evals.config.ts +5 -0
- package/templates/agents-md/init.json +38 -0
- package/templates/agents-md/package.json +18 -0
- package/templates/agents-md/tsconfig.json +12 -0
- package/templates/code-wiki/README.md +34 -0
- package/templates/code-wiki/agent/agent.ts +8 -0
- package/templates/code-wiki/agent/channels/github.ts +144 -0
- package/templates/code-wiki/agent/instructions.md +39 -0
- package/templates/code-wiki/agent/lib/repos.ts +5 -0
- package/templates/code-wiki/agent/lib/wiki.ts +22 -0
- package/templates/code-wiki/agent/tools/apply_wiki.ts +219 -0
- package/templates/code-wiki/evals/evals.config.ts +5 -0
- package/templates/code-wiki/evals/wiki.eval.ts +132 -0
- package/templates/code-wiki/init.json +25 -0
- package/templates/code-wiki/package.json +18 -0
- package/templates/code-wiki/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.oqPawjiD.js +0 -1
- package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
- package/dist/docs/assets/index.md.BoHaMdeZ.js +0 -5
- package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
- package/dist/docs/design/agsh.md +0 -406
- package/dist/internal/deployment-scm-event-stream.d.ts +0 -116
- package/dist/internal/deployment-scm-event-stream.d.ts.map +0 -1
- package/dist/internal/deployment-scm-event-stream.js +0 -474
- package/dist/playground/assets/index-CF7hUDnQ.css +0 -1
- package/docs/design/agsh.md +0 -406
- package/src/internal/deployment-scm-event-stream.ts +0 -593
- /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.5zOAbV86.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.B84gw9Ii.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
|
@@ -27,7 +27,7 @@ import { authorizeCursorAccountConnectors } from "./cursor-account-mcp-auth.js";
|
|
|
27
27
|
import { readDeployTemplate } from "./cursor-agent-template.js";
|
|
28
28
|
import { AgentServeDeployClient, DeployApiError, deploymentServiceAccountId, slugFromDirectoryName, TERMINAL_AGENTKIT_DEPLOY_STATUSES, TERMINAL_DEPLOY_STATUSES, validateDeploymentSlug, } from "./deploy-client.js";
|
|
29
29
|
import { inferDeployGitSource } from "./deploy-source.js";
|
|
30
|
-
import { isAgentProjectDir, listChildAgentDirs, loadAgentProject, } from "./discovery.js";
|
|
30
|
+
import { formatDiagnostics, hasErrorDiagnostics, isAgentProjectDir, listChildAgentDirs, loadAgentProject, } from "./discovery.js";
|
|
31
31
|
import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
|
|
32
32
|
import { isReservedSecretName, isValidCursorEventRepo, validateSettableSecretName, } from "./hosting.js";
|
|
33
33
|
import { deployProgressLabel, sanitizeCustomerError } from "./logs-client.js";
|
|
@@ -152,7 +152,9 @@ export function cmdDeploy(options) {
|
|
|
152
152
|
manifests.push(yield readDeployManifest(target.dir));
|
|
153
153
|
}
|
|
154
154
|
if (manifests.every((manifest) => manifest.architecture === "v2")) {
|
|
155
|
-
return deployAgentsdkApplication(ctx, options, targets
|
|
155
|
+
return deployAgentsdkApplication(ctx, options, targets, {
|
|
156
|
+
hasScmChannels: manifests.some((manifest) => manifest.hasScmChannels),
|
|
157
|
+
});
|
|
156
158
|
}
|
|
157
159
|
if (!ctx.json &&
|
|
158
160
|
manifests.some((manifest) => manifest.architecture === "v2")) {
|
|
@@ -488,8 +490,14 @@ function deployOne(ctx, options, target, extras) {
|
|
|
488
490
|
gitRef,
|
|
489
491
|
agentPath,
|
|
490
492
|
repositories: options.cursorEventsRepos,
|
|
493
|
+
hasScmChannels: manifest.hasScmChannels,
|
|
494
|
+
multiTenant: options.multiTenant === true,
|
|
491
495
|
});
|
|
492
496
|
}
|
|
497
|
+
if (options.multiTenant === true) {
|
|
498
|
+
ctx.err("--multi-tenant is only valid for architecture: v2 deploys (Cursor-managed products).\n");
|
|
499
|
+
return 1;
|
|
500
|
+
}
|
|
493
501
|
// Today's only source shape: the control plane builds from a git ref.
|
|
494
502
|
// See DeploySource for the artifact seam.
|
|
495
503
|
const source = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind: "git-ref", gitRepoUrl }, (gitRef === undefined ? {} : { gitRef })), (agentPath === undefined ? {} : { agentPath })), (options.cursorEventsRepos === undefined ||
|
|
@@ -546,10 +554,7 @@ function deployOne(ctx, options, target, extras) {
|
|
|
546
554
|
return detail.status === "running" ? 0 : 1;
|
|
547
555
|
}
|
|
548
556
|
if (detail.status !== "running") {
|
|
549
|
-
|
|
550
|
-
? ""
|
|
551
|
-
: `: ${sanitizeCustomerError(detail.lastError)}`;
|
|
552
|
-
ctx.err(`Deployment ${slug} ended ${detail.status}${errorDetail}\n`);
|
|
557
|
+
ctx.err(`Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`);
|
|
553
558
|
return 1;
|
|
554
559
|
}
|
|
555
560
|
const deployedPublicRoutes = (_h = detail.publicRoutePaths) !== null && _h !== void 0 ? _h : [];
|
|
@@ -580,7 +585,7 @@ function deployOne(ctx, options, target, extras) {
|
|
|
580
585
|
* key is the child's slug and its path is the child directory relative to
|
|
581
586
|
* the repo root (a shared --path names the parent's directory in the repo).
|
|
582
587
|
*/
|
|
583
|
-
function deployAgentsdkApplication(ctx, options, targets) {
|
|
588
|
+
function deployAgentsdkApplication(ctx, options, targets, declarations) {
|
|
584
589
|
return __awaiter(this, void 0, void 0, function* () {
|
|
585
590
|
var _a, _b, _c, _d, _e;
|
|
586
591
|
const parentDir = resolve((_a = options.dir) !== null && _a !== void 0 ? _a : ".");
|
|
@@ -640,6 +645,8 @@ function deployAgentsdkApplication(ctx, options, targets) {
|
|
|
640
645
|
agentPath: undefined,
|
|
641
646
|
components,
|
|
642
647
|
repositories: options.cursorEventsRepos,
|
|
648
|
+
hasScmChannels: declarations.hasScmChannels,
|
|
649
|
+
multiTenant: options.multiTenant === true,
|
|
643
650
|
});
|
|
644
651
|
});
|
|
645
652
|
}
|
|
@@ -650,23 +657,19 @@ function deployAgentsdkApplication(ctx, options, targets) {
|
|
|
650
657
|
*/
|
|
651
658
|
function deployOneAgentsdk(ctx, extras, args) {
|
|
652
659
|
return __awaiter(this, void 0, void 0, function* () {
|
|
660
|
+
var _a;
|
|
653
661
|
const { slug } = args;
|
|
654
662
|
const componentsLine = args.components === undefined
|
|
655
663
|
? ""
|
|
656
664
|
: ` components: ${args.components
|
|
657
665
|
.map((component) => component.componentKey)
|
|
658
666
|
.join(", ")}\n`;
|
|
667
|
+
if (args.multiTenant && !ctx.json) {
|
|
668
|
+
ctx.err(" multi-tenant: existing product\n");
|
|
669
|
+
}
|
|
659
670
|
let accepted;
|
|
660
671
|
try {
|
|
661
|
-
accepted = yield ctx.client.deployAgentkit({
|
|
662
|
-
teamId: ctx.teamId,
|
|
663
|
-
slug,
|
|
664
|
-
gitRepoUrl: args.gitRepoUrl,
|
|
665
|
-
gitRef: args.gitRef,
|
|
666
|
-
agentPath: args.agentPath,
|
|
667
|
-
components: args.components,
|
|
668
|
-
repositories: args.repositories,
|
|
669
|
-
});
|
|
672
|
+
accepted = yield ctx.client.deployAgentkit(Object.assign({ teamId: ctx.teamId, slug, gitRepoUrl: args.gitRepoUrl, gitRef: args.gitRef, agentPath: args.agentPath, components: args.components, repositories: args.repositories }, (args.multiTenant ? { multiTenant: true } : {})));
|
|
670
673
|
}
|
|
671
674
|
catch (error) {
|
|
672
675
|
return renderApiError(error, ctx.err);
|
|
@@ -702,7 +705,7 @@ function deployOneAgentsdk(ctx, extras, args) {
|
|
|
702
705
|
return detail.status === "running" ? 0 : 1;
|
|
703
706
|
}
|
|
704
707
|
if (detail.status !== "running") {
|
|
705
|
-
ctx.err(`Deployment ${slug} ended ${detail.status}\n`);
|
|
708
|
+
ctx.err(`Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`);
|
|
706
709
|
return 1;
|
|
707
710
|
}
|
|
708
711
|
ctx.out(`Deployed ${slug} (team ${ctx.teamId})\n` +
|
|
@@ -714,7 +717,16 @@ function deployOneAgentsdk(ctx, extras, args) {
|
|
|
714
717
|
? ""
|
|
715
718
|
: ` components: ${args.components
|
|
716
719
|
.map((component) => component.componentKey)
|
|
717
|
-
.join(", ")}\n`)
|
|
720
|
+
.join(", ")}\n`) +
|
|
721
|
+
(detail.repositories === undefined || !args.hasScmChannels
|
|
722
|
+
? ""
|
|
723
|
+
: ` watching: ${detail.repositories.length === 0 ? "(nothing)" : detail.repositories.join(", ")}\n`));
|
|
724
|
+
// An agent with GitHub/Origin channels bound to no repository scope gets
|
|
725
|
+
// no deliveries at all, which is otherwise invisible in this output.
|
|
726
|
+
if (args.hasScmChannels && ((_a = detail.repositories) === null || _a === void 0 ? void 0 : _a.length) === 0) {
|
|
727
|
+
ctx.err(`warning: ${slug} watches no repositories, so its GitHub/Origin channels receive no events.\n` +
|
|
728
|
+
` Redeploy with --cursor-events-repo <owner>/<name> to set the scope.\n`);
|
|
729
|
+
}
|
|
718
730
|
return 0;
|
|
719
731
|
});
|
|
720
732
|
}
|
|
@@ -790,6 +802,12 @@ function readDeployManifest(dir) {
|
|
|
790
802
|
return __awaiter(this, void 0, void 0, function* () {
|
|
791
803
|
var _a;
|
|
792
804
|
const project = yield loadAgentProject(dir);
|
|
805
|
+
// Fail here, before anything is dispatched: a project with error
|
|
806
|
+
// diagnostics (e.g. agent/storage.ts on architecture v2) would only be
|
|
807
|
+
// refused later by `serve` inside the hosted build, wasting a bake.
|
|
808
|
+
if (hasErrorDiagnostics(project)) {
|
|
809
|
+
throw new Error(`Refusing to deploy ${project.name} — it has errors:\n${formatDiagnostics(project.diagnostics.filter((d) => d.severity === "error"))}`);
|
|
810
|
+
}
|
|
793
811
|
return {
|
|
794
812
|
hosting: project.agent.hosting,
|
|
795
813
|
architecture: project.agent.architecture,
|
|
@@ -800,6 +818,11 @@ function readDeployManifest(dir) {
|
|
|
800
818
|
.filter((channel) => { var _a; return ((_a = channel.definition.auth) !== null && _a !== void 0 ? _a : []).some(isPublicEndpointPolicy); })
|
|
801
819
|
.map((channel) => channel.id),
|
|
802
820
|
httpChannelPublicEndpoint: ((_a = project.httpChannel.auth) !== null && _a !== void 0 ? _a : []).some(isPublicEndpointPolicy),
|
|
821
|
+
hasScmChannels: project.channels.some((channel) => {
|
|
822
|
+
var _a;
|
|
823
|
+
const kind = (_a = channel.definition.meta) === null || _a === void 0 ? void 0 : _a.kind;
|
|
824
|
+
return kind === "github" || kind === "origin";
|
|
825
|
+
}),
|
|
803
826
|
};
|
|
804
827
|
});
|
|
805
828
|
}
|
|
@@ -1456,9 +1479,25 @@ function aliasTokenBlock(aliasToken) {
|
|
|
1456
1479
|
` or paste it into the hosted playground (<alias>/playground) sign-in gate.\n` +
|
|
1457
1480
|
` Lost tokens: \`${CLI} rotate-token <slug>\` mints a replacement.\n\n`);
|
|
1458
1481
|
}
|
|
1482
|
+
/**
|
|
1483
|
+
* `: <reason>` suffix for a deploy that ended in a non-running state, or
|
|
1484
|
+
* empty when the control plane recorded no reason.
|
|
1485
|
+
*/
|
|
1486
|
+
function deployFailureDetail(lastError) {
|
|
1487
|
+
if (lastError === null ||
|
|
1488
|
+
lastError === undefined ||
|
|
1489
|
+
lastError.trim() === "") {
|
|
1490
|
+
return "";
|
|
1491
|
+
}
|
|
1492
|
+
return `: ${sanitizeCustomerError(lastError.trim())}`;
|
|
1493
|
+
}
|
|
1459
1494
|
function renderApiError(error, err) {
|
|
1460
1495
|
if (error instanceof DeployApiError) {
|
|
1461
1496
|
err(`${error.message}\n`);
|
|
1497
|
+
if (error.status === 409 &&
|
|
1498
|
+
error.message.includes("application multiTenant does not match")) {
|
|
1499
|
+
err("This slug is a Cursor-managed (multi-tenant) product. Redeploy it with --multi-tenant.\n");
|
|
1500
|
+
}
|
|
1462
1501
|
return 1;
|
|
1463
1502
|
}
|
|
1464
1503
|
throw error;
|
|
@@ -27,7 +27,8 @@ import { authorizeCursorAccountConnectors } from "./cursor-account-mcp-auth.js";
|
|
|
27
27
|
import { deploymentServiceAccountId } from "./deploy-client.js";
|
|
28
28
|
import { loadAgentProject } from "./discovery.js";
|
|
29
29
|
import { CLI_COMMAND_NAME as CLI, LOG_PREFIX } from "./distribution.js";
|
|
30
|
-
import { createHostMcpOAuthProvider, MCP_OAUTH_CALLBACK_URL,
|
|
30
|
+
import { createHostMcpOAuthProvider, MCP_OAUTH_CALLBACK_URL, openBrowser, waitForMcpOAuthCallback, } from "./mcp-oauth.js";
|
|
31
|
+
import { upsertHostMcpOauthSecrets } from "./mcp-oauth-persist.js";
|
|
31
32
|
import { resolveProdSlug } from "./resolve-prod-target.js";
|
|
32
33
|
function describe(error) {
|
|
33
34
|
if (!(error instanceof Error)) {
|
|
@@ -287,25 +288,14 @@ function storeOauthSecrets(args) {
|
|
|
287
288
|
if (typeof auth === "number") {
|
|
288
289
|
return auth;
|
|
289
290
|
}
|
|
290
|
-
const names = mcpOauthSecretNames(args.connection);
|
|
291
|
-
const secrets = [
|
|
292
|
-
{ name: names.accessToken, value: tokens.access_token },
|
|
293
|
-
];
|
|
294
|
-
if (tokens.refresh_token !== undefined &&
|
|
295
|
-
tokens.refresh_token.trim() !== "") {
|
|
296
|
-
secrets.push({ name: names.refreshToken, value: tokens.refresh_token });
|
|
297
|
-
}
|
|
298
|
-
if (args.clientId !== undefined && args.clientId.trim() !== "") {
|
|
299
|
-
secrets.push({ name: names.clientId, value: args.clientId });
|
|
300
|
-
}
|
|
301
291
|
try {
|
|
302
|
-
const secretNames = yield
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
292
|
+
const secretNames = yield upsertHostMcpOauthSecrets({
|
|
293
|
+
connection: args.connection,
|
|
294
|
+
tokens,
|
|
295
|
+
clientId: args.clientId,
|
|
296
|
+
target: { client: auth.client, teamId: auth.teamId, slug },
|
|
306
297
|
});
|
|
307
|
-
args.out(`${LOG_PREFIX} Stored on ${slug}: ${
|
|
308
|
-
`${LOG_PREFIX} Secrets now: ${secretNames.join(", ")}. Next deploy picks them up.\n`);
|
|
298
|
+
args.out(`${LOG_PREFIX} Stored on ${slug}. Secrets now: ${secretNames.join(", ")}. Next deploy picks them up.\n`);
|
|
309
299
|
return 0;
|
|
310
300
|
}
|
|
311
301
|
catch (error) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `slack init --manual` and `slack manifest` —
|
|
3
|
-
*
|
|
2
|
+
* `slack init --manual` and `slack manifest` — unmanaged Slack app.
|
|
3
|
+
* Slack CLI create+install when `~/.slack/bin/slack` is present;
|
|
4
|
+
* paste-at-api.slack.com is the fallback. Create/destroy/icon stay
|
|
5
|
+
* in `cli-slack.ts`.
|
|
4
6
|
*/
|
|
5
7
|
export interface SlackManualCliOptions {
|
|
6
8
|
dir: string;
|
|
@@ -12,9 +14,29 @@ export interface SlackManualCliOptions {
|
|
|
12
14
|
channelPosts?: boolean;
|
|
13
15
|
/** Gate for `slack init`; ignored by `slack manifest`. */
|
|
14
16
|
manual?: boolean;
|
|
17
|
+
/** Require Slack CLI install (fail if missing or install fails). */
|
|
18
|
+
install?: boolean;
|
|
19
|
+
/** Skip Slack CLI install even when the CLI is present. */
|
|
20
|
+
noInstall?: boolean;
|
|
21
|
+
slackTeam?: string;
|
|
22
|
+
prod?: boolean;
|
|
23
|
+
detectSlackCli?: () => string | undefined;
|
|
24
|
+
runSlackCli?: SlackCliExec;
|
|
15
25
|
out?: (text: string) => void;
|
|
16
26
|
err?: (text: string) => void;
|
|
17
27
|
}
|
|
28
|
+
export interface SlackCliExecRequest {
|
|
29
|
+
bin: string;
|
|
30
|
+
argv: string[];
|
|
31
|
+
cwd: string;
|
|
32
|
+
env?: NodeJS.ProcessEnv;
|
|
33
|
+
}
|
|
34
|
+
export interface SlackCliExecResult {
|
|
35
|
+
code: number;
|
|
36
|
+
stdout: string;
|
|
37
|
+
stderr: string;
|
|
38
|
+
}
|
|
39
|
+
export type SlackCliExec = (request: SlackCliExecRequest) => Promise<SlackCliExecResult>;
|
|
18
40
|
export declare function cmdSlackInit(options: SlackManualCliOptions): Promise<number>;
|
|
19
41
|
export declare function runSlackManifest(options: SlackManualCliOptions): Promise<number>;
|
|
20
42
|
//# sourceMappingURL=cli-slack-manual.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-slack-manual.d.ts","sourceRoot":"","sources":["../../src/internal/cli-slack-manual.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cli-slack-manual.d.ts","sourceRoot":"","sources":["../../src/internal/cli-slack-manual.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC1C,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAoGjC,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAoFjB;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `slack init --manual` and `slack manifest` —
|
|
3
|
-
*
|
|
2
|
+
* `slack init --manual` and `slack manifest` — unmanaged Slack app.
|
|
3
|
+
* Slack CLI create+install when `~/.slack/bin/slack` is present;
|
|
4
|
+
* paste-at-api.slack.com is the fallback. Create/destroy/icon stay
|
|
5
|
+
* in `cli-slack.ts`.
|
|
4
6
|
*/
|
|
5
7
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
8
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -11,18 +13,75 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
13
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
14
|
});
|
|
13
15
|
};
|
|
14
|
-
import {
|
|
16
|
+
import { execFile } from "node:child_process";
|
|
17
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
15
18
|
import { basename, join, resolve as resolvePath } from "node:path";
|
|
19
|
+
import { promisify } from "node:util";
|
|
20
|
+
import { detectSlackCli, parseSlackAuthTeams, readSlackCliAppId, SLACK_CLI_HOME_BIN, } from "../channels/slack/cli-project.js";
|
|
16
21
|
import { buildSlackManifestPair, initSlackManual, slackManifestFileEntries, } from "../channels/slack/index.js";
|
|
17
22
|
import { describeError } from "./describe-error.js";
|
|
18
23
|
import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
|
|
24
|
+
import { ensureEnvLocalGitignored, upsertEnvFile } from "./env-file.js";
|
|
25
|
+
const execFileAsync = promisify(execFile);
|
|
19
26
|
function errStream(options) {
|
|
20
27
|
var _a;
|
|
21
28
|
return (_a = options.err) !== null && _a !== void 0 ? _a : ((text) => void process.stderr.write(text));
|
|
22
29
|
}
|
|
30
|
+
function afterDoctor(prefix) {
|
|
31
|
+
return [
|
|
32
|
+
prefix === undefined
|
|
33
|
+
? `${CLI} slack doctor`
|
|
34
|
+
: `${CLI} slack doctor --prefix ${prefix}`,
|
|
35
|
+
`${CLI} serve --dir . --dev`,
|
|
36
|
+
`${CLI} slack setup`,
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
function slackCliEnvironment(prod) {
|
|
40
|
+
return prod === true ? "deployed" : "local";
|
|
41
|
+
}
|
|
42
|
+
function slackAppSettingsUrl(appId) {
|
|
43
|
+
return appId === undefined
|
|
44
|
+
? "https://api.slack.com/apps"
|
|
45
|
+
: `https://api.slack.com/apps/${appId}`;
|
|
46
|
+
}
|
|
47
|
+
function pasteNext(envKeys, options) {
|
|
48
|
+
return [
|
|
49
|
+
"Ask the user to install this Slack app on their workspace",
|
|
50
|
+
`Open ${slackAppSettingsUrl()} → Create from manifest`,
|
|
51
|
+
"Import .slack/manifest.dev.json (then prod)",
|
|
52
|
+
`Install apps; set ${envKeys.bot} + ${envKeys.app}`,
|
|
53
|
+
`Or install Slack CLI to ~/${SLACK_CLI_HOME_BIN}, then slack app install --environment ${options.environment} --team <T> --force`,
|
|
54
|
+
...afterDoctor(options.prefix),
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
function cliNext(cli, envKeys, options) {
|
|
58
|
+
var _a;
|
|
59
|
+
const workspace = (_a = options.team) !== null && _a !== void 0 ? _a : "<T>";
|
|
60
|
+
return [
|
|
61
|
+
"Ask the user to install this Slack app on their workspace",
|
|
62
|
+
`${cli} login --no-prompt`,
|
|
63
|
+
`In Slack send /slackauthticket <ticket>; then ${cli} login --ticket <ticket> --challenge <code>`,
|
|
64
|
+
`${cli} app install --environment ${options.environment} --team ${workspace} --force`,
|
|
65
|
+
`Copy xoxb + xapp (connections:write) from ${slackAppSettingsUrl()} into .env.local as ${envKeys.bot} + ${envKeys.app}`,
|
|
66
|
+
`Fallback: paste .slack/manifest.dev.json at ${slackAppSettingsUrl()}`,
|
|
67
|
+
...afterDoctor(options.prefix),
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
function installedNext(install, envKeys, prefix) {
|
|
71
|
+
const settings = slackAppSettingsUrl(install.appId);
|
|
72
|
+
const next = [];
|
|
73
|
+
if (!install.tokens.bot) {
|
|
74
|
+
next.push(`Copy the bot token (xoxb-...) from ${settings} into ${envKeys.bot}`);
|
|
75
|
+
}
|
|
76
|
+
if (!install.tokens.app) {
|
|
77
|
+
next.push(`Mint an app-level token with connections:write at ${settings}; set ${envKeys.app}`);
|
|
78
|
+
}
|
|
79
|
+
next.push(...afterDoctor(prefix));
|
|
80
|
+
return next;
|
|
81
|
+
}
|
|
23
82
|
export function cmdSlackInit(options) {
|
|
24
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
var _a, _b;
|
|
84
|
+
var _a, _b, _c, _d, _e;
|
|
26
85
|
if (options.manual !== true) {
|
|
27
86
|
errStream(options)(`\`slack init\` without --manual is not the first-run path. Socket Mode apps are created with:
|
|
28
87
|
|
|
@@ -30,7 +89,7 @@ export function cmdSlackInit(options) {
|
|
|
30
89
|
|
|
31
90
|
That opens the Cursor dashboard wizard.
|
|
32
91
|
|
|
33
|
-
To install a custom Slack app from a manifest (api.slack.com):
|
|
92
|
+
To install a custom Slack app from a manifest (Slack CLI or api.slack.com):
|
|
34
93
|
|
|
35
94
|
${CLI} slack init --manual --dir .
|
|
36
95
|
`);
|
|
@@ -38,6 +97,7 @@ To install a custom Slack app from a manifest (api.slack.com):
|
|
|
38
97
|
}
|
|
39
98
|
const dir = resolvePath(options.dir);
|
|
40
99
|
const out = (_a = options.out) !== null && _a !== void 0 ? _a : ((text) => void process.stdout.write(text));
|
|
100
|
+
const err = errStream(options);
|
|
41
101
|
try {
|
|
42
102
|
const result = yield initSlackManual({
|
|
43
103
|
dir,
|
|
@@ -45,27 +105,53 @@ To install a custom Slack app from a manifest (api.slack.com):
|
|
|
45
105
|
envPrefix: options.noPrefix === true ? "" : options.prefix,
|
|
46
106
|
channelPosts: options.channelPosts,
|
|
47
107
|
});
|
|
108
|
+
const cli = ((_b = options.detectSlackCli) !== null && _b !== void 0 ? _b : detectSlackCli)();
|
|
109
|
+
const skipInstall = options.noInstall === true;
|
|
110
|
+
const requireInstall = options.install === true && !skipInstall;
|
|
111
|
+
let install;
|
|
112
|
+
if (!skipInstall && cli !== undefined) {
|
|
113
|
+
install = yield installSlackApp({
|
|
114
|
+
dir: result.rootDir,
|
|
115
|
+
bin: cli,
|
|
116
|
+
envKeys: result.envKeys,
|
|
117
|
+
environment: slackCliEnvironment(options.prod),
|
|
118
|
+
team: options.slackTeam,
|
|
119
|
+
exec: options.runSlackCli,
|
|
120
|
+
});
|
|
121
|
+
if (!install.ok && requireInstall) {
|
|
122
|
+
err(`${(_c = install.error) !== null && _c !== void 0 ? _c : "slack app install failed"}\n`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (requireInstall) {
|
|
126
|
+
err(`Slack CLI not found (~/${SLACK_CLI_HOME_BIN}). Install it or omit --install and paste at api.slack.com.\n`);
|
|
127
|
+
}
|
|
128
|
+
const ok = !requireInstall || (install === null || install === void 0 ? void 0 : install.ok) === true;
|
|
129
|
+
const next = (install === null || install === void 0 ? void 0 : install.ok) === true
|
|
130
|
+
? installedNext(install, result.envKeys, result.envPrefix)
|
|
131
|
+
: cli !== undefined
|
|
132
|
+
? cliNext(cli, result.envKeys, {
|
|
133
|
+
team: (_d = install === null || install === void 0 ? void 0 : install.team) !== null && _d !== void 0 ? _d : options.slackTeam,
|
|
134
|
+
environment: slackCliEnvironment(options.prod),
|
|
135
|
+
prefix: result.envPrefix,
|
|
136
|
+
})
|
|
137
|
+
: pasteNext(result.envKeys, {
|
|
138
|
+
environment: slackCliEnvironment(options.prod),
|
|
139
|
+
prefix: result.envPrefix,
|
|
140
|
+
});
|
|
48
141
|
out(`${JSON.stringify({
|
|
49
|
-
ok
|
|
142
|
+
ok,
|
|
50
143
|
directory: result.rootDir,
|
|
51
144
|
created: result.files,
|
|
52
|
-
envPrefix: (
|
|
145
|
+
envPrefix: (_e = result.envPrefix) !== null && _e !== void 0 ? _e : null,
|
|
53
146
|
envKeys: result.envKeys,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
`Install apps; set ${result.envKeys.bot} + ${result.envKeys.app}`,
|
|
58
|
-
result.envPrefix === undefined
|
|
59
|
-
? `${CLI} slack doctor`
|
|
60
|
-
: `${CLI} slack doctor --prefix ${result.envPrefix}`,
|
|
61
|
-
`${CLI} serve --dir . --dev`,
|
|
62
|
-
`${CLI} slack setup`,
|
|
63
|
-
],
|
|
147
|
+
cli: cli !== null && cli !== void 0 ? cli : null,
|
|
148
|
+
install: install !== null && install !== void 0 ? install : null,
|
|
149
|
+
next,
|
|
64
150
|
}, null, 2)}\n`);
|
|
65
|
-
return 0;
|
|
151
|
+
return ok ? 0 : 1;
|
|
66
152
|
}
|
|
67
153
|
catch (error) {
|
|
68
|
-
|
|
154
|
+
err(`${describeError(error)}\n`);
|
|
69
155
|
return 1;
|
|
70
156
|
}
|
|
71
157
|
});
|
|
@@ -92,7 +178,7 @@ export function runSlackManifest(options) {
|
|
|
92
178
|
}
|
|
93
179
|
return 0;
|
|
94
180
|
}
|
|
95
|
-
const outDir = join(dir, ".
|
|
181
|
+
const outDir = join(dir, ".slack");
|
|
96
182
|
yield mkdir(outDir, { recursive: true });
|
|
97
183
|
const written = [];
|
|
98
184
|
for (const file of slackManifestFileEntries(pair, env)) {
|
|
@@ -104,3 +190,148 @@ export function runSlackManifest(options) {
|
|
|
104
190
|
return 0;
|
|
105
191
|
});
|
|
106
192
|
}
|
|
193
|
+
function parseEnvAssignments(text) {
|
|
194
|
+
const out = {};
|
|
195
|
+
for (const line of text.split(/\r?\n/)) {
|
|
196
|
+
const trimmed = line.trim();
|
|
197
|
+
if (trimmed === "" || trimmed.startsWith("#")) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
const raw = trimmed.startsWith("export ") ? trimmed.slice(7) : trimmed;
|
|
201
|
+
const eq = raw.indexOf("=");
|
|
202
|
+
if (eq <= 0) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
out[raw.slice(0, eq)] = raw.slice(eq + 1);
|
|
206
|
+
}
|
|
207
|
+
return out;
|
|
208
|
+
}
|
|
209
|
+
function readDotenv(dir) {
|
|
210
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
211
|
+
return parseEnvAssignments(yield readFile(join(dir, ".env"), "utf8").catch(() => ""));
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function newToken(before, after, prefix) {
|
|
215
|
+
if (after === undefined || !after.startsWith(prefix) || after === before) {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
return after;
|
|
219
|
+
}
|
|
220
|
+
function copySlackCliTokensToLocalEnv(options) {
|
|
221
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
222
|
+
const after = yield readDotenv(options.dir);
|
|
223
|
+
const bot = newToken(options.before.SLACK_BOT_TOKEN, after.SLACK_BOT_TOKEN, "xoxb-");
|
|
224
|
+
const app = newToken(options.before.SLACK_APP_TOKEN, after.SLACK_APP_TOKEN, "xapp-");
|
|
225
|
+
const entries = [];
|
|
226
|
+
const wrote = { bot: false, app: false };
|
|
227
|
+
if (bot !== undefined) {
|
|
228
|
+
entries.push({ key: options.envKeys.bot, value: bot });
|
|
229
|
+
wrote.bot = true;
|
|
230
|
+
}
|
|
231
|
+
if (app !== undefined) {
|
|
232
|
+
entries.push({ key: options.envKeys.app, value: app });
|
|
233
|
+
wrote.app = true;
|
|
234
|
+
}
|
|
235
|
+
if (entries.length === 0) {
|
|
236
|
+
return wrote;
|
|
237
|
+
}
|
|
238
|
+
yield upsertEnvFile(join(options.dir, ".env.local"), entries);
|
|
239
|
+
yield ensureEnvLocalGitignored(options.dir);
|
|
240
|
+
return wrote;
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
function installSlackApp(options) {
|
|
244
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
245
|
+
var _a;
|
|
246
|
+
const exec = (_a = options.exec) !== null && _a !== void 0 ? _a : defaultSlackCliExec;
|
|
247
|
+
const auth = yield exec({
|
|
248
|
+
bin: options.bin,
|
|
249
|
+
argv: ["auth", "list"],
|
|
250
|
+
cwd: options.dir,
|
|
251
|
+
});
|
|
252
|
+
const teams = parseSlackAuthTeams(`${auth.stdout}\n${auth.stderr}`);
|
|
253
|
+
if (teams.length === 0) {
|
|
254
|
+
return {
|
|
255
|
+
ok: false,
|
|
256
|
+
environment: options.environment,
|
|
257
|
+
error: "Slack CLI is not logged in. Run slack login --no-prompt.",
|
|
258
|
+
tokens: { bot: false, app: false },
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
let team = options.team;
|
|
262
|
+
if (team === undefined) {
|
|
263
|
+
if (teams.length > 1) {
|
|
264
|
+
return {
|
|
265
|
+
ok: false,
|
|
266
|
+
environment: options.environment,
|
|
267
|
+
error: `Multiple Slack CLI teams (${teams.join(", ")}). Pass --slack-team.`,
|
|
268
|
+
tokens: { bot: false, app: false },
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
team = teams[0];
|
|
272
|
+
}
|
|
273
|
+
const before = yield readDotenv(options.dir);
|
|
274
|
+
const installed = yield exec({
|
|
275
|
+
bin: options.bin,
|
|
276
|
+
argv: [
|
|
277
|
+
"app",
|
|
278
|
+
"install",
|
|
279
|
+
"--environment",
|
|
280
|
+
options.environment,
|
|
281
|
+
"--force",
|
|
282
|
+
"--team",
|
|
283
|
+
team,
|
|
284
|
+
],
|
|
285
|
+
cwd: options.dir,
|
|
286
|
+
env: Object.assign(Object.assign({}, process.env), { SLACK_ENV: options.environment }),
|
|
287
|
+
});
|
|
288
|
+
if (installed.code !== 0) {
|
|
289
|
+
const detail = installed.stderr.trim() || installed.stdout.trim();
|
|
290
|
+
return {
|
|
291
|
+
ok: false,
|
|
292
|
+
environment: options.environment,
|
|
293
|
+
team,
|
|
294
|
+
error: detail === "" ? `slack app install exited ${installed.code}` : detail,
|
|
295
|
+
tokens: { bot: false, app: false },
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
yield writeFile(join(options.dir, ".slack/cli-environment"), `${options.environment}\n`);
|
|
299
|
+
const appId = yield readSlackCliAppId(options.dir, options.environment, team);
|
|
300
|
+
const tokens = yield copySlackCliTokensToLocalEnv({
|
|
301
|
+
dir: options.dir,
|
|
302
|
+
envKeys: options.envKeys,
|
|
303
|
+
before,
|
|
304
|
+
});
|
|
305
|
+
return {
|
|
306
|
+
ok: true,
|
|
307
|
+
environment: options.environment,
|
|
308
|
+
team,
|
|
309
|
+
appId,
|
|
310
|
+
tokens,
|
|
311
|
+
};
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
function defaultSlackCliExec(request) {
|
|
315
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
316
|
+
var _a, _b;
|
|
317
|
+
try {
|
|
318
|
+
const { stdout, stderr } = yield execFileAsync(request.bin, request.argv, {
|
|
319
|
+
cwd: request.cwd,
|
|
320
|
+
env: request.env,
|
|
321
|
+
timeout: 120000,
|
|
322
|
+
});
|
|
323
|
+
return { code: 0, stdout, stderr };
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
if (!(error instanceof Error)) {
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
const execError = error;
|
|
330
|
+
return {
|
|
331
|
+
code: typeof execError.code === "number" ? execError.code : 1,
|
|
332
|
+
stdout: (_a = execError.stdout) !== null && _a !== void 0 ? _a : "",
|
|
333
|
+
stderr: (_b = execError.stderr) !== null && _b !== void 0 ? _b : execError.message,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `agent-serve slack …` CLI — doctor, destroy/icon, `create` as a
|
|
3
3
|
* dashboard-wizard launcher (`slack-provision-client.ts`), and
|
|
4
|
-
* `init --manual` for
|
|
4
|
+
* `init --manual` for Slack CLI / paste-at-api.slack.com manifests.
|
|
5
5
|
*/
|
|
6
6
|
import { runSlackDoctor } from "../channels/slack/index.js";
|
|
7
|
+
import { type SlackCliExec } from "./cli-slack-manual.js";
|
|
7
8
|
import { type TerminalPalette } from "./terminal-style.js";
|
|
8
9
|
export interface SlackCliOptions {
|
|
9
10
|
dir: string;
|
|
@@ -29,8 +30,14 @@ export interface SlackCliOptions {
|
|
|
29
30
|
icon?: string;
|
|
30
31
|
/** create: accepted for compatibility; live-app updates always overwrite. */
|
|
31
32
|
force?: boolean;
|
|
32
|
-
/** `slack init --manual`:
|
|
33
|
+
/** `slack init --manual`: Slack CLI project + paste fallback. */
|
|
33
34
|
manual?: boolean;
|
|
35
|
+
/** `slack init --manual`: require Slack CLI install. */
|
|
36
|
+
install?: boolean;
|
|
37
|
+
/** `slack init --manual`: skip Slack CLI install. */
|
|
38
|
+
noInstall?: boolean;
|
|
39
|
+
detectSlackCli?: () => string | undefined;
|
|
40
|
+
runSlackCli?: SlackCliExec;
|
|
34
41
|
/** `slack icon <source>` positional (same URL-or-file forms as --icon). */
|
|
35
42
|
iconSource?: string;
|
|
36
43
|
/** doctor: watched channel ids (`C…`) to verify visibility/membership. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-slack.d.ts","sourceRoot":"","sources":["../../src/internal/cli-slack.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAIL,cAAc,EAGf,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-slack.d.ts","sourceRoot":"","sources":["../../src/internal/cli-slack.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAIL,cAAc,EAGf,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAoB/B,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC1C,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,kBAAkB;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,cAAc,CAAC;IACnC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAmDD,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AA6RD,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CAoLjB;AAiDD,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAsD5E"}
|