@cursor/bdk 0.2.3 → 0.2.4
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/dist/bin/agent-serve.js +9 -1
- package/dist/channels/slack/attachments.d.ts +2 -1
- package/dist/channels/slack/attachments.d.ts.map +1 -1
- package/dist/channels/slack/attachments.js +19 -9
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +26 -24
- package/dist/channels/slack/thread-context.d.ts +21 -11
- package/dist/channels/slack/thread-context.d.ts.map +1 -1
- package/dist/channels/slack/thread-context.js +75 -27
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BOIHhrKi.js → app.4kQ8Db_q.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.CvuAJ0My.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.D49zVZqM.js → VPLocalSearchBox.DY1RwB8Q.js} +1 -1
- package/dist/docs/assets/chunks/{arc.hmjb-sc4.js → arc.CxE_fSPK.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CxEI1KqM.js → architectureDiagram-Q4EWVU46.CPX426ui.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.DHHvBWoV.js → baseUniq.CB52JrKG.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DnXW-3bu.js → blockDiagram-DXYQGD6D.J0cNaQCL.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.e-47O2jM.js → c4Diagram-AHTNJAMY.DJn3vEGT.js} +1 -1
- package/dist/docs/assets/chunks/channel.BoNycAoN.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.3ry4pYXB.js → chunk-4BX2VUAB.Dao618F6.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DGIZFRx6.js → chunk-4TB4RGXK.QW8Rhjai.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.DKBnqg9U.js → chunk-55IACEB6.DfRLLKF_.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.BIU8Ue5k.js → chunk-EDXVE4YY.CIV2ApKQ.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.DP-TFhjI.js → chunk-FMBD7UC4.BEheSuxp.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.Ux0OYj5v.js → chunk-OYMX7WX6.CUN88ENB.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BzHMwYox.js → chunk-QZHKN3VN.CgqCs8b_.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.D4OGAsSP.js → chunk-YZCP3GAM.iCH0nnTJ.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.C4x07Gkj.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.C4x07Gkj.js +1 -0
- package/dist/docs/assets/chunks/clone.Db22cH_-.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Jq_7BUNx.js → cose-bilkent-S5V4N54A.BLcUxhWE.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.Di-skR2x.js → dagre-KV5264BT.Ep7LofOm.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.DeREHIdH.js → diagram-5BDNPKRD.Bzf4GSQ4.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.C7Kcqxro.js → diagram-G4DWMVQ6.DD6Jh-eM.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BK3eohyo.js → diagram-MMDJMWI5.oOIl8bWd.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.C6TyymXT.js → diagram-TYMM5635.DHs85Ade.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DYGG-gGx.js → erDiagram-SMLLAGMA.BIb5ghCk.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.C9nBcSV4.js → flowDiagram-DWJPFMVM.DV4paY9k.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.wAg_ymsp.js → ganttDiagram-T4ZO3ILL.AyEKA6_v.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.B87j9Oeg.js → gitGraphDiagram-UUTBAWPF.BltiCDFo.js} +1 -1
- package/dist/docs/assets/chunks/{graph.CuFMj31w.js → graph.DzuEYGdC.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.P_mLGumP.js → infoDiagram-42DDH7IO.BV2l981J.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DyuL_MsT.js → ishikawaDiagram-UXIWVN3A.BA4Izf-m.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CtP09IoJ.js → journeyDiagram-VCZTEJTY.DjaFbFS3.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.BoeSYPZo.js → kanban-definition-6JOO6SKY.CfTFieDs.js} +1 -1
- package/dist/docs/assets/chunks/{layout.B0lMMtNo.js → layout.DzfWqTBV.js} +1 -1
- package/dist/docs/assets/chunks/{linear.HxRBiAFX.js → linear.BO6mpulV.js} +1 -1
- package/dist/docs/assets/chunks/{min.BGlFFHwS.js → min.BGgTadgT.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.JyLBD9M8.js → mindmap-definition-QFDTVHPH.DPuIXVWY.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DnSmNZF8.js → pieDiagram-DEJITSTG.BOnl3bBg.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CUCnbfCa.js → quadrantDiagram-34T5L4WZ.DNB6Ckdc.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.py0IVUn5.js → requirementDiagram-MS252O5E.D5-Qo7vb.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.Bkc-HWYp.js → sankeyDiagram-XADWPNL6.8t65cesf.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.Dqn8Mlv2.js → sequenceDiagram-FGHM5R23.CaG07BdS.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.JikkoQUU.js → stateDiagram-FHFEXIEX.TKOweTB6.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CuqmyQc4.js +1 -0
- package/dist/docs/assets/chunks/{theme.b6HQ6zG_.js → theme.Dx-JhpTB.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BvpSXiBj.js → timeline-definition-GMOUNBTQ.fE53zQ2s.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CU7MVnZx.js → vennDiagram-DHZGUBPP.DJsZZaJg.js} +1 -1
- package/dist/docs/assets/chunks/{wardley-RL74JXVD.BKwC4ctG.js → wardley-RL74JXVD.844kyrjl.js} +1 -1
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.BfaF6Uhe.js → wardleyDiagram-NUSXRM2D.CMZ-Ru_t.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.Bg5dcpj4.js → xychartDiagram-5P7HB3ND.XXrhBc7a.js} +1 -1
- package/dist/docs/assets/{deployment.md.BJ8i7Q6p.js → deployment.md.UhnJIMr-.js} +2 -2
- package/dist/docs/assets/{deployment.md.BJ8i7Q6p.lean.js → deployment.md.UhnJIMr-.lean.js} +1 -1
- package/dist/docs/assets/{guides_jev.md.BNDm14Gy.js → guides_jev.md.CRcgmjDb.js} +2 -2
- package/dist/docs/assets/{guides_jev.md.BNDm14Gy.lean.js → guides_jev.md.CRcgmjDb.lean.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.DzGI777n.js → reference_agent-config.md.Cj5uBKp4.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.js → reference_extensions.md.pa2tN-e4.js} +4 -3
- package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.lean.js → reference_extensions.md.pa2tN-e4.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +35 -35
- package/dist/docs/deployment.html +37 -37
- package/dist/docs/deployment.md +4 -1
- package/dist/docs/evals.html +35 -35
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +35 -35
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/github.html +35 -35
- package/dist/docs/guides/gitlab.html +35 -35
- package/dist/docs/guides/grokbot-agents.html +35 -35
- package/dist/docs/guides/hooks.html +35 -35
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +37 -37
- package/dist/docs/guides/jev.md +7 -0
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/opentelemetry.html +35 -35
- package/dist/docs/guides/slack.html +35 -35
- package/dist/docs/guides/webhooks.html +35 -35
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +35 -35
- package/dist/docs/index.html +35 -35
- package/dist/docs/llms-full.txt +25 -2
- package/dist/docs/quickstart.html +35 -35
- package/dist/docs/reference/agent-config.html +37 -37
- package/dist/docs/reference/agent-config.md +1 -1
- package/dist/docs/reference/artifacts.html +35 -35
- package/dist/docs/reference/channels.html +35 -35
- package/dist/docs/reference/cli.html +35 -35
- package/dist/docs/reference/connections.html +35 -35
- package/dist/docs/reference/evals.html +35 -35
- package/dist/docs/reference/extensions.html +39 -38
- package/dist/docs/reference/extensions.md +13 -0
- package/dist/docs/reference/hooks.html +35 -35
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +35 -35
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +35 -35
- package/dist/docs/reference/skills.html +35 -35
- package/dist/docs/reference/subagents.html +35 -35
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +35 -35
- package/dist/extensions/jev/extension.d.ts +3 -0
- package/dist/extensions/jev/extension.d.ts.map +1 -1
- package/dist/extensions/jev/extension.js +10 -1
- package/dist/extensions/jev/lib/evaluate.d.ts +4 -0
- package/dist/extensions/jev/lib/evaluate.d.ts.map +1 -1
- package/dist/extensions/jev/lib/evaluate.js +6 -2
- package/dist/extensions.d.ts +4 -2
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +5 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +19 -5
- package/dist/internal/discovery/agent-config.d.ts +6 -5
- package/dist/internal/discovery/agent-config.d.ts.map +1 -1
- package/dist/internal/discovery/agent-config.js +29 -28
- package/dist/internal/discovery/agent.js +1 -1
- package/dist/internal/discovery/extensions.d.ts.map +1 -1
- package/dist/internal/discovery/extensions.js +12 -0
- package/dist/internal/hosting.d.ts +8 -0
- package/dist/internal/hosting.d.ts.map +1 -1
- package/dist/internal/hosting.js +24 -0
- package/dist/types.d.ts +18 -2
- package/dist/types.d.ts.map +1 -1
- package/docs/deployment.md +4 -1
- package/docs/guides/jev.md +7 -0
- package/docs/reference/agent-config.md +1 -1
- package/docs/reference/extensions.md +13 -0
- package/package.json +1 -9
- package/dist/docs/assets/chunks/@localSearchIndexroot.D5L-b34G.js +0 -1
- package/dist/docs/assets/chunks/channel.BbOGaJQP.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Db58HCb1.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Db58HCb1.js +0 -1
- package/dist/docs/assets/chunks/clone.Co4MBflG.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CMsKhrW0.js +0 -1
- package/src/artifacts.ts +0 -68
- package/src/bin/agent-serve.ts +0 -1854
- package/src/channels/bitbucket/api.ts +0 -891
- package/src/channels/bitbucket/binding.ts +0 -417
- package/src/channels/bitbucket/bitbucket-channel.ts +0 -162
- package/src/channels/bitbucket/bitbucket-webhook.ts +0 -519
- package/src/channels/bitbucket/checks.ts +0 -146
- package/src/channels/bitbucket/cursor-account.ts +0 -106
- package/src/channels/bitbucket/defaults.ts +0 -100
- package/src/channels/bitbucket/events.ts +0 -74
- package/src/channels/bitbucket/index.ts +0 -51
- package/src/channels/bitbucket/replay.ts +0 -421
- package/src/channels/bitbucket/state.ts +0 -59
- package/src/channels/bitbucket/types.ts +0 -261
- package/src/channels/change-monitors/change-monitors-channel.ts +0 -63
- package/src/channels/change-monitors/index.ts +0 -8
- package/src/channels/change-monitors/types.ts +0 -42
- package/src/channels/checks.ts +0 -185
- package/src/channels/deployments/deployments-channel.ts +0 -224
- package/src/channels/deployments/index.ts +0 -25
- package/src/channels/deployments/types.ts +0 -92
- package/src/channels/github/api.ts +0 -526
- package/src/channels/github/auth.ts +0 -293
- package/src/channels/github/binding.ts +0 -233
- package/src/channels/github/checks.ts +0 -145
- package/src/channels/github/cursor-account.ts +0 -303
- package/src/channels/github/defaults.ts +0 -168
- package/src/channels/github/events.ts +0 -67
- package/src/channels/github/forward.ts +0 -359
- package/src/channels/github/github-channel.ts +0 -2334
- package/src/channels/github/index.ts +0 -54
- package/src/channels/github/progress.ts +0 -365
- package/src/channels/github/replay.ts +0 -372
- package/src/channels/github/state.ts +0 -124
- package/src/channels/github/types.ts +0 -590
- package/src/channels/gitlab/api.ts +0 -329
- package/src/channels/gitlab/binding.ts +0 -231
- package/src/channels/gitlab/checks.ts +0 -228
- package/src/channels/gitlab/cursor-account.ts +0 -105
- package/src/channels/gitlab/defaults.ts +0 -80
- package/src/channels/gitlab/events.ts +0 -37
- package/src/channels/gitlab/gitlab-channel.ts +0 -160
- package/src/channels/gitlab/gitlab-webhook.ts +0 -509
- package/src/channels/gitlab/index.ts +0 -44
- package/src/channels/gitlab/replay.ts +0 -328
- package/src/channels/gitlab/state.ts +0 -55
- package/src/channels/gitlab/types.ts +0 -247
- package/src/channels/issues/index.ts +0 -9
- package/src/channels/issues/issues-channel.ts +0 -45
- package/src/channels/issues/types.ts +0 -38
- package/src/channels/origin/api.ts +0 -507
- package/src/channels/origin/binding.ts +0 -114
- package/src/channels/origin/checks.ts +0 -250
- package/src/channels/origin/cursor-account.ts +0 -58
- package/src/channels/origin/defaults.ts +0 -140
- package/src/channels/origin/events.ts +0 -35
- package/src/channels/origin/index.ts +0 -35
- package/src/channels/origin/origin-channel.ts +0 -815
- package/src/channels/origin/origin-webhook.ts +0 -296
- package/src/channels/origin/reactions.ts +0 -72
- package/src/channels/origin/state.ts +0 -54
- package/src/channels/origin/types.ts +0 -295
- package/src/channels/slack/agentic-delivery.ts +0 -634
- package/src/channels/slack/agentic-posted.ts +0 -135
- package/src/channels/slack/agentic-signals.ts +0 -231
- package/src/channels/slack/api.ts +0 -761
- package/src/channels/slack/approvals.ts +0 -279
- package/src/channels/slack/assistant.ts +0 -76
- package/src/channels/slack/attachments.ts +0 -596
- package/src/channels/slack/auth.ts +0 -127
- package/src/channels/slack/blocks.ts +0 -131
- package/src/channels/slack/bot-mentions.ts +0 -318
- package/src/channels/slack/channel-watch.ts +0 -314
- package/src/channels/slack/cli-project.ts +0 -249
- package/src/channels/slack/code-fences.ts +0 -171
- package/src/channels/slack/constants.ts +0 -38
- package/src/channels/slack/credentials.ts +0 -88
- package/src/channels/slack/defaults.ts +0 -714
- package/src/channels/slack/dispatch.ts +0 -1060
- package/src/channels/slack/doctor.ts +0 -338
- package/src/channels/slack/eval-directive.ts +0 -306
- package/src/channels/slack/event-id-dedupe.ts +0 -30
- package/src/channels/slack/external-policy.ts +0 -75
- package/src/channels/slack/footer.ts +0 -106
- package/src/channels/slack/inbound.ts +0 -416
- package/src/channels/slack/index.ts +0 -53
- package/src/channels/slack/init.ts +0 -169
- package/src/channels/slack/interactive.ts +0 -406
- package/src/channels/slack/links.ts +0 -23
- package/src/channels/slack/live-delivery.ts +0 -489
- package/src/channels/slack/log.ts +0 -70
- package/src/channels/slack/manifest.ts +0 -240
- package/src/channels/slack/message-body.ts +0 -82
- package/src/channels/slack/nudge-carrier.ts +0 -224
- package/src/channels/slack/nudge-store.ts +0 -334
- package/src/channels/slack/paint-start.ts +0 -93
- package/src/channels/slack/placeholder.ts +0 -358
- package/src/channels/slack/pr-ref.ts +0 -74
- package/src/channels/slack/progress-delivery.ts +0 -138
- package/src/channels/slack/reasoning-card.ts +0 -125
- package/src/channels/slack/reasoning-chip.ts +0 -41
- package/src/channels/slack/recording-sink.ts +0 -167
- package/src/channels/slack/redact.ts +0 -6
- package/src/channels/slack/reply-options.ts +0 -279
- package/src/channels/slack/setup.ts +0 -125
- package/src/channels/slack/slack-channel.ts +0 -744
- package/src/channels/slack/socket-mode.ts +0 -140
- package/src/channels/slack/stop.ts +0 -25
- package/src/channels/slack/stream.ts +0 -66
- package/src/channels/slack/thread-context.ts +0 -485
- package/src/channels/slack/tool-approval-events.ts +0 -233
- package/src/channels/slack/tool-cards.ts +0 -198
- package/src/channels/slack/tool-chip.ts +0 -34
- package/src/channels/slack/types.ts +0 -787
- package/src/channels/slack/upload.ts +0 -137
- package/src/channels.ts +0 -543
- package/src/connections.ts +0 -153
- package/src/dashboard-session-url.ts +0 -30
- package/src/evals/assertions.ts +0 -688
- package/src/evals/expect.ts +0 -250
- package/src/evals/judge.ts +0 -329
- package/src/evals/loaders.ts +0 -111
- package/src/evals/matchers.ts +0 -223
- package/src/evals/reporters.ts +0 -257
- package/src/evals/results.ts +0 -130
- package/src/evals/run-facts.ts +0 -306
- package/src/evals.ts +0 -709
- package/src/extensions/cursor-cloud-agents/extension.ts +0 -131
- package/src/extensions/cursor-cloud-agents/lib/backend.ts +0 -386
- package/src/extensions/cursor-cloud-agents/lib/channels.ts +0 -11
- package/src/extensions/cursor-cloud-agents/lib/fleet.ts +0 -98
- package/src/extensions/cursor-cloud-agents/lib/inputs.ts +0 -5
- package/src/extensions/cursor-cloud-agents/lib/repos.ts +0 -80
- package/src/extensions/cursor-cloud-agents/lib/transcript.ts +0 -19
- package/src/extensions/cursor-cloud-agents/skills/handoff.md +0 -37
- package/src/extensions/cursor-cloud-agents/tools/cancel.ts +0 -21
- package/src/extensions/cursor-cloud-agents/tools/dump.ts +0 -47
- package/src/extensions/cursor-cloud-agents/tools/get.ts +0 -18
- package/src/extensions/cursor-cloud-agents/tools/launch.ts +0 -62
- package/src/extensions/cursor-cloud-agents/tools/list.ts +0 -31
- package/src/extensions/cursor-cloud-agents/tools/reply.ts +0 -36
- package/src/extensions/cursor-grokbot-agents/extension.ts +0 -132
- package/src/extensions/cursor-grokbot-agents/lib/agents.ts +0 -42
- package/src/extensions/cursor-grokbot-agents/lib/backend.ts +0 -208
- package/src/extensions/cursor-grokbot-agents/lib/contacts.ts +0 -74
- package/src/extensions/cursor-grokbot-agents/lib/conversation.ts +0 -260
- package/src/extensions/cursor-grokbot-agents/lib/inputs.ts +0 -21
- package/src/extensions/cursor-grokbot-agents/lib/lock.ts +0 -26
- package/src/extensions/cursor-grokbot-agents/skills/consult.md +0 -40
- package/src/extensions/cursor-grokbot-agents/tools/ask.ts +0 -32
- package/src/extensions/cursor-grokbot-agents/tools/check.ts +0 -25
- package/src/extensions/cursor-grokbot-agents/tools/interrupt.ts +0 -17
- package/src/extensions/cursor-grokbot-agents/tools/list.ts +0 -26
- package/src/extensions/improve/extension.ts +0 -69
- package/src/extensions/improve/skills/yourself.ts +0 -50
- package/src/extensions/jev/extension.ts +0 -95
- package/src/extensions/jev/lib/evaluate.ts +0 -266
- package/src/extensions/jev/skills/gated-write.md +0 -25
- package/src/extensions/jev/skills/questions.md +0 -33
- package/src/extensions/jev/tools/evaluate.ts +0 -82
- package/src/extensions/slack-communication/evals/harness.ts +0 -705
- package/src/extensions/slack-communication/evals/slack-communication.eval.ts +0 -830
- package/src/extensions/slack-communication/evals/slack-placeholder.eval.ts +0 -172
- package/src/extensions/slack-communication/extension.ts +0 -44
- package/src/extensions/slack-communication/skills/slack-voice.ts +0 -56
- package/src/extensions/slack-communication/tools/delete-message.ts +0 -33
- package/src/extensions/slack-communication/tools/edit-message.ts +0 -42
- package/src/extensions/slack-communication/tools/post-card.ts +0 -28
- package/src/extensions/slack-communication/tools/post-file.ts +0 -82
- package/src/extensions/slack-communication/tools/post-update.ts +0 -40
- package/src/extensions/slack-communication/tools/react.ts +0 -30
- package/src/extensions/slack-communication/tools/set-status.ts +0 -21
- package/src/extensions.ts +0 -179
- package/src/files-backends/agent-store-presigned-url.ts +0 -11
- package/src/files-backends/cursor-hosted.ts +0 -1212
- package/src/files-backends/local-fs.ts +0 -163
- package/src/files.ts +0 -293
- package/src/filesystem.ts +0 -2005
- package/src/hooks.ts +0 -30
- package/src/index.ts +0 -259
- package/src/internal/advertise-tools.ts +0 -370
- package/src/internal/approval-gate.ts +0 -103
- package/src/internal/artifacts-store.ts +0 -836
- package/src/internal/as-of.ts +0 -257
- package/src/internal/auth.ts +0 -46
- package/src/internal/authored-alias-hooks.ts +0 -138
- package/src/internal/authored-loaders.ts +0 -188
- package/src/internal/bounded-int.ts +0 -24
- package/src/internal/bounded.ts +0 -25
- package/src/internal/brand.ts +0 -28
- package/src/internal/browser-origin-guard.ts +0 -67
- package/src/internal/builtin-tools/artifacts.ts +0 -62
- package/src/internal/builtin-tools/index.ts +0 -53
- package/src/internal/builtin-tools/reminders.ts +0 -145
- package/src/internal/channel-dispatch.ts +0 -129
- package/src/internal/channel-route-dispatch.ts +0 -58
- package/src/internal/channel-state.ts +0 -83
- package/src/internal/chat-client.ts +0 -594
- package/src/internal/cli-ax.ts +0 -2318
- package/src/internal/cli-bitbucket.ts +0 -438
- package/src/internal/cli-convert-automation.ts +0 -335
- package/src/internal/cli-cursor.ts +0 -282
- package/src/internal/cli-deploy.ts +0 -2519
- package/src/internal/cli-docs.ts +0 -192
- package/src/internal/cli-github.ts +0 -806
- package/src/internal/cli-gitlab.ts +0 -452
- package/src/internal/cli-images.ts +0 -672
- package/src/internal/cli-manifest.ts +0 -56
- package/src/internal/cli-mcp-oauth.ts +0 -396
- package/src/internal/cli-mcp.ts +0 -808
- package/src/internal/cli-skills.ts +0 -98
- package/src/internal/cli-slack-manual.ts +0 -418
- package/src/internal/cli-slack.ts +0 -874
- package/src/internal/cloud-merge.ts +0 -51
- package/src/internal/cloud-turn-cost.ts +0 -159
- package/src/internal/connection-env.ts +0 -106
- package/src/internal/continuation-channel.ts +0 -233
- package/src/internal/continuation-identity.ts +0 -935
- package/src/internal/conversation-mirror.ts +0 -423
- package/src/internal/convert-automation/convert-workflow.ts +0 -1377
- package/src/internal/convert-automation/slug.ts +0 -29
- package/src/internal/convert-automation/types.ts +0 -212
- package/src/internal/cron.ts +0 -76
- package/src/internal/cursor/account-mcp.ts +0 -692
- package/src/internal/cursor/backend-client.ts +0 -984
- package/src/internal/cursor/bound-secret-file.ts +0 -101
- package/src/internal/cursor/credentials.ts +0 -560
- package/src/internal/cursor/cursor-api-transport.ts +0 -65
- package/src/internal/cursor/github-credentials.ts +0 -228
- package/src/internal/cursor/hosted-bound-secrets.ts +0 -71
- package/src/internal/cursor/hosted-deployment-secrets.ts +0 -100
- package/src/internal/cursor/hosted-store-secrets.ts +0 -152
- package/src/internal/cursor/session-token.ts +0 -111
- package/src/internal/cursor/store-api-client.ts +0 -323
- package/src/internal/cursor-account-mcp-auth.ts +0 -303
- package/src/internal/cursor-agent-template.ts +0 -50
- package/src/internal/cursor-deployment-relay.ts +0 -315
- package/src/internal/cursor-event-relay.ts +0 -675
- package/src/internal/cursor-relay-core.ts +0 -563
- package/src/internal/deferred-channel-session.ts +0 -61
- package/src/internal/deploy-client.ts +0 -1574
- package/src/internal/deploy-manifest.ts +0 -361
- package/src/internal/deploy-source.ts +0 -144
- package/src/internal/describe-error.ts +0 -32
- package/src/internal/dev-mode.ts +0 -20
- package/src/internal/discovery/agent-config.ts +0 -288
- package/src/internal/discovery/agent.ts +0 -381
- package/src/internal/discovery/channels.ts +0 -100
- package/src/internal/discovery/connections.ts +0 -516
- package/src/internal/discovery/context.ts +0 -38
- package/src/internal/discovery/cursor-plugin.ts +0 -628
- package/src/internal/discovery/extension-overlay.ts +0 -247
- package/src/internal/discovery/extensions.ts +0 -490
- package/src/internal/discovery/fs.ts +0 -103
- package/src/internal/discovery/hooks.ts +0 -63
- package/src/internal/discovery/info.ts +0 -174
- package/src/internal/discovery/instructions.ts +0 -98
- package/src/internal/discovery/modules.ts +0 -107
- package/src/internal/discovery/names.ts +0 -45
- package/src/internal/discovery/project.ts +0 -319
- package/src/internal/discovery/reminders.ts +0 -65
- package/src/internal/discovery/runtime.ts +0 -158
- package/src/internal/discovery/schedules.ts +0 -120
- package/src/internal/discovery/seed-files.ts +0 -34
- package/src/internal/discovery/services.ts +0 -151
- package/src/internal/discovery/skills.ts +0 -174
- package/src/internal/discovery/subagent.ts +0 -138
- package/src/internal/discovery/tools.ts +0 -170
- package/src/internal/discovery.ts +0 -27
- package/src/internal/distribution.ts +0 -126
- package/src/internal/docs-site.ts +0 -248
- package/src/internal/duration.ts +0 -37
- package/src/internal/env-file.ts +0 -83
- package/src/internal/eval-judge-model.ts +0 -142
- package/src/internal/eval-run-store.ts +0 -585
- package/src/internal/eval-runner.ts +0 -823
- package/src/internal/evals-client.ts +0 -475
- package/src/internal/event-log.ts +0 -342
- package/src/internal/event-mapper.ts +0 -811
- package/src/internal/expected-delivery-failure.ts +0 -34
- package/src/internal/factory-resource-channel.ts +0 -103
- package/src/internal/filesystem/errors.ts +0 -207
- package/src/internal/filesystem/format.ts +0 -253
- package/src/internal/filesystem/merge.ts +0 -192
- package/src/internal/filesystem/nearest.ts +0 -112
- package/src/internal/filesystem/scratch.ts +0 -239
- package/src/internal/filesystem/sdk-schemas.ts +0 -204
- package/src/internal/filesystem/tools.ts +0 -804
- package/src/internal/filesystem/walk.ts +0 -366
- package/src/internal/fixtures/units-server.ts +0 -52
- package/src/internal/framework-file-storage.ts +0 -357
- package/src/internal/framework-storage-selection.ts +0 -156
- package/src/internal/frontmatter.ts +0 -108
- package/src/internal/github-fanout.ts +0 -144
- package/src/internal/guest-network.ts +0 -391
- package/src/internal/handleAgentServeTrigger.ts +0 -286
- package/src/internal/host-files.ts +0 -341
- package/src/internal/host-kv.ts +0 -81
- package/src/internal/host-otel.ts +0 -231
- package/src/internal/host-platforms.ts +0 -170
- package/src/internal/hosted-admission-adapter.ts +0 -47
- package/src/internal/hosted-admission-context.ts +0 -37
- package/src/internal/hosted-catch-protocol.ts +0 -112
- package/src/internal/hosted-catch.ts +0 -179
- package/src/internal/hosted-delivery-protocol.ts +0 -824
- package/src/internal/hosted-delivery.ts +0 -1410
- package/src/internal/hosted-execution-diag.ts +0 -291
- package/src/internal/hosted-execution-flush.ts +0 -136
- package/src/internal/hosted-execution-latency.ts +0 -301
- package/src/internal/hosted-managed-automation.ts +0 -116
- package/src/internal/hosting.ts +0 -114
- package/src/internal/http-channel-define.ts +0 -25
- package/src/internal/http-channel.ts +0 -669
- package/src/internal/http-control-plane-session.ts +0 -110
- package/src/internal/ids.ts +0 -39
- package/src/internal/incoming-headers-to-fetch.ts +0 -45
- package/src/internal/init-interview.ts +0 -360
- package/src/internal/init-project.ts +0 -711
- package/src/internal/init-scaffold.ts +0 -182
- package/src/internal/inline-stdio-define-stub.ts +0 -4
- package/src/internal/inline-stdio-mcp.ts +0 -230
- package/src/internal/install-cursor-skills.ts +0 -604
- package/src/internal/is-record.ts +0 -3
- package/src/internal/json-schema.ts +0 -95
- package/src/internal/legacy-command-guard.ts +0 -66
- package/src/internal/listen-port.ts +0 -85
- package/src/internal/local-control-plane.ts +0 -442
- package/src/internal/local-env.ts +0 -59
- package/src/internal/local-ingress.ts +0 -90
- package/src/internal/log-ring.ts +0 -59
- package/src/internal/logs-client.ts +0 -477
- package/src/internal/map-pool.ts +0 -39
- package/src/internal/mcp-endpoint.ts +0 -747
- package/src/internal/mcp-host.ts +0 -509
- package/src/internal/mcp-oauth-on-demand.ts +0 -337
- package/src/internal/mcp-oauth-persist.ts +0 -118
- package/src/internal/mcp-oauth.ts +0 -549
- package/src/internal/net.ts +0 -29
- package/src/internal/open-browser.ts +0 -41
- package/src/internal/otel/attrs.ts +0 -16
- package/src/internal/otel/collector.ts +0 -937
- package/src/internal/otel/config.ts +0 -287
- package/src/internal/otel/http.ts +0 -122
- package/src/internal/otel/mcp.ts +0 -56
- package/src/internal/otel/propagation.ts +0 -17
- package/src/internal/otel/runtime.ts +0 -441
- package/src/internal/package-inline-stdio.ts +0 -114
- package/src/internal/peer-connections.ts +0 -96
- package/src/internal/platform-schedule-sync.ts +0 -75
- package/src/internal/platform-timers.ts +0 -365
- package/src/internal/playground/static.ts +0 -278
- package/src/internal/playground/toolchain.ts +0 -270
- package/src/internal/playground-proxy.ts +0 -564
- package/src/internal/process-memory-telemetry.ts +0 -334
- package/src/internal/project-layout.ts +0 -31
- package/src/internal/prompt-context.ts +0 -116
- package/src/internal/reminder-control-plane-protocol.ts +0 -482
- package/src/internal/reminder-runner.ts +0 -1559
- package/src/internal/reminder-schedule.ts +0 -104
- package/src/internal/reminder-store.ts +0 -176
- package/src/internal/request-error-status.ts +0 -95
- package/src/internal/request-headers.ts +0 -21
- package/src/internal/resolve-prod-target.ts +0 -334
- package/src/internal/resolved-connections.ts +0 -190
- package/src/internal/router.ts +0 -143
- package/src/internal/run-client.ts +0 -354
- package/src/internal/runtime-dispatch-runner.ts +0 -50
- package/src/internal/sanitize-mcp-tool-name.ts +0 -31
- package/src/internal/schedule-runner.ts +0 -154
- package/src/internal/scm/pr-url.ts +0 -245
- package/src/internal/sdk-runner.ts +0 -959
- package/src/internal/serve-restart.ts +0 -113
- package/src/internal/server.ts +0 -3147
- package/src/internal/session-cost.ts +0 -208
- package/src/internal/session-engine.ts +0 -5622
- package/src/internal/session-links.ts +0 -84
- package/src/internal/session-run-log.ts +0 -535
- package/src/internal/session-store.ts +0 -307
- package/src/internal/session-urls.ts +0 -32
- package/src/internal/sessions-client.ts +0 -239
- package/src/internal/skill-catalog.ts +0 -66
- package/src/internal/skills-sync.ts +0 -55
- package/src/internal/slack-provision-client.ts +0 -544
- package/src/internal/slack-thread-key.ts +0 -11
- package/src/internal/sleep.ts +0 -3
- package/src/internal/start-log-store.ts +0 -164
- package/src/internal/steering.ts +0 -17
- package/src/internal/storage-coordinator.ts +0 -800
- package/src/internal/storage-roles.ts +0 -86
- package/src/internal/storage.ts +0 -1
- package/src/internal/store-api-protocol.ts +0 -205
- package/src/internal/store-mirror.ts +0 -73
- package/src/internal/stream-progress.ts +0 -294
- package/src/internal/terminal-style.ts +0 -133
- package/src/internal/testing/factory-resource-fixtures.ts +0 -84
- package/src/internal/testing/scm-continuation-fixtures.ts +0 -285
- package/src/internal/tool-catalog.ts +0 -104
- package/src/internal/tool-policy.ts +0 -222
- package/src/internal/tool-result.ts +0 -50
- package/src/internal/trajectory.ts +0 -418
- package/src/internal/turn-cost.ts +0 -136
- package/src/internal/turn-governor.ts +0 -145
- package/src/internal/turn-lease-store.ts +0 -144
- package/src/internal/turn-outbox.ts +0 -77
- package/src/internal/update-check.ts +0 -517
- package/src/internal/v2-hosting.ts +0 -52
- package/src/internal/workspace-sync.ts +0 -114
- package/src/internal/workspace.ts +0 -505
- package/src/kv/memory-kv.ts +0 -94
- package/src/kv.ts +0 -18
- package/src/memory.ts +0 -487
- package/src/otel-public.ts +0 -24
- package/src/otel.ts +0 -320
- package/src/prompt.ts +0 -80
- package/src/reminders.ts +0 -65
- package/src/schedules.ts +0 -31
- package/src/skills.ts +0 -27
- package/src/storage-backends/cursor-hosted-v2.ts +0 -204
- package/src/storage-backends/cursor-hosted.ts +0 -388
- package/src/storage-backends/file-kv.ts +0 -276
- package/src/storage-protocol.ts +0 -261
- package/src/storage.ts +0 -408
- package/src/tools.ts +0 -166
- package/src/types.ts +0 -3776
- /package/dist/docs/assets/{reference_agent-config.md.DzGI777n.lean.js → reference_agent-config.md.Cj5uBKp4.lean.js} +0 -0
|
@@ -1,874 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `agent-sdk slack …` CLI — doctor, destroy/icon, `create` as a
|
|
3
|
-
* dashboard-wizard launcher (`slack-provision-client.ts`), and
|
|
4
|
-
* `init --manual` for Slack CLI / paste-at-api.slack.com manifests.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { access, readFile } from "node:fs/promises";
|
|
8
|
-
import { basename, extname, join, resolve as resolvePath } from "node:path";
|
|
9
|
-
import {
|
|
10
|
-
envPrefixFromName,
|
|
11
|
-
formatSlackSetupGuide,
|
|
12
|
-
initSlackChannel,
|
|
13
|
-
runSlackDoctor,
|
|
14
|
-
type SlackDoctorResult,
|
|
15
|
-
slackEnvKeys,
|
|
16
|
-
} from "../channels/slack/index.js";
|
|
17
|
-
import type { AgentArchitecture } from "../types.js";
|
|
18
|
-
import { resolveDeployAuth } from "./cli-deploy.js";
|
|
19
|
-
import { cmdSlackInit, runSlackManifest, type SlackCliExec } from "./cli-slack-manual.js";
|
|
20
|
-
import { cursorExternalApiUrl, resolveApiKeySync } from "./cursor/credentials.js";
|
|
21
|
-
import { slugFromDirectoryName } from "./deploy-client.js";
|
|
22
|
-
import { inferDeployGitSource } from "./deploy-source.js";
|
|
23
|
-
import { describeError } from "./describe-error.js";
|
|
24
|
-
import { DEFAULT_AGENT_ARCHITECTURE, isAgentProjectDir, loadAgentProject } from "./discovery.js";
|
|
25
|
-
import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
|
|
26
|
-
import { ensureEnvLocalGitignored, upsertEnvFile } from "./env-file.js";
|
|
27
|
-
import { loadAgentLocalEnv } from "./local-env.js";
|
|
28
|
-
import { openBrowser } from "./open-browser.js";
|
|
29
|
-
import { projectPath, resolveProjectRoot } from "./project-layout.js";
|
|
30
|
-
import {
|
|
31
|
-
AgentServeSlackClient,
|
|
32
|
-
type SlackAppEnv,
|
|
33
|
-
type SlackAppIconContentType,
|
|
34
|
-
type SlackAppIconInput,
|
|
35
|
-
type SlackManagedAppInfo,
|
|
36
|
-
SlackProvisionApiError,
|
|
37
|
-
type SlackProvisionStatus,
|
|
38
|
-
type SlackWizardMintResult,
|
|
39
|
-
type SlackWizardPollResult,
|
|
40
|
-
} from "./slack-provision-client.js";
|
|
41
|
-
import { sleep } from "./sleep.js";
|
|
42
|
-
import { stderrPalette, type TerminalPalette } from "./terminal-style.js";
|
|
43
|
-
|
|
44
|
-
export interface SlackCliOptions {
|
|
45
|
-
dir: string;
|
|
46
|
-
name?: string;
|
|
47
|
-
env?: "dev" | "prod" | "both";
|
|
48
|
-
json?: boolean;
|
|
49
|
-
print?: boolean;
|
|
50
|
-
/** Per-agent env prefix for tokens (`MY_AGENT`). */
|
|
51
|
-
prefix?: string;
|
|
52
|
-
/** Use shared `SLACK_*` env vars (no per-agent prefix). */
|
|
53
|
-
noPrefix?: boolean;
|
|
54
|
-
/** Subscribe manifests to channel-post events (opt-in channel watch). */
|
|
55
|
-
channelPosts?: boolean;
|
|
56
|
-
/** create/destroy: target Slack workspace id (`T…`). */
|
|
57
|
-
slackTeam?: string;
|
|
58
|
-
/** create/destroy: target the prod app (default dev). */
|
|
59
|
-
prod?: boolean;
|
|
60
|
-
/** create/destroy: Cursor team id; resolved from the account when omitted. */
|
|
61
|
-
team?: string;
|
|
62
|
-
/** create/destroy: Cursor API key (defaults to the stored login / env). */
|
|
63
|
-
apiKey?: string;
|
|
64
|
-
/** create: app icon — an https image URL or a local png/jpg/gif ≤512KB. */
|
|
65
|
-
icon?: string;
|
|
66
|
-
/** create: accepted for compatibility; live-app updates always overwrite. */
|
|
67
|
-
force?: boolean;
|
|
68
|
-
/** `slack init --manual`: Slack CLI project + paste fallback. */
|
|
69
|
-
manual?: boolean;
|
|
70
|
-
/** `slack init --manual`: require Slack CLI install. */
|
|
71
|
-
install?: boolean;
|
|
72
|
-
/** `slack init --manual`: skip Slack CLI install. */
|
|
73
|
-
noInstall?: boolean;
|
|
74
|
-
detectSlackCli?: () => string | undefined;
|
|
75
|
-
runSlackCli?: SlackCliExec;
|
|
76
|
-
/** `slack icon <source>` positional (same URL-or-file forms as --icon). */
|
|
77
|
-
iconSource?: string;
|
|
78
|
-
/** doctor: watched channel ids (`C…`) to verify visibility/membership. */
|
|
79
|
-
channels?: string[];
|
|
80
|
-
/** Test seams. */
|
|
81
|
-
fetchImpl?: typeof fetch;
|
|
82
|
-
openBrowserImpl?: (url: string) => void;
|
|
83
|
-
connectPollIntervalMs?: number;
|
|
84
|
-
connectPollTimeoutMs?: number;
|
|
85
|
-
doctorImpl?: typeof runSlackDoctor;
|
|
86
|
-
out?: (text: string) => void;
|
|
87
|
-
err?: (text: string) => void;
|
|
88
|
-
palette?: TerminalPalette;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const SLACK_HELP = `${CLI} slack — Slack channel pack helpers (Socket Mode)
|
|
92
|
-
|
|
93
|
-
Usage:
|
|
94
|
-
${CLI} slack setup
|
|
95
|
-
${CLI} slack create [--dir .] [--name NAME] [--slack-team T0123ABCD]
|
|
96
|
-
[--prod] [--team <id>] [--icon URL-or-FILE]
|
|
97
|
-
[--force] [--prefix PREFIX | --no-prefix] [--json]
|
|
98
|
-
${CLI} slack destroy [--dir .] [--slack-team T0123ABCD] [--prod]
|
|
99
|
-
[--team <id>] [--json]
|
|
100
|
-
${CLI} slack icon <URL-or-FILE> [--dir .] [--slack-team T0123ABCD]
|
|
101
|
-
[--prod] [--team <id>] [--json]
|
|
102
|
-
${CLI} slack init --manual [--dir .] [--name NAME]
|
|
103
|
-
[--prefix PREFIX | --no-prefix] [--channel-posts]
|
|
104
|
-
[--install | --no-install]
|
|
105
|
-
[--slack-team T0123ABCD] [--prod]
|
|
106
|
-
${CLI} slack manifest --env dev|prod|both [--dir .] [--name NAME]
|
|
107
|
-
[--print]
|
|
108
|
-
${CLI} slack doctor [--dir .] [--prefix PREFIX | --no-prefix] [--json]
|
|
109
|
-
[--channel C0123ABCD]...
|
|
110
|
-
|
|
111
|
-
create/destroy/icon — dedicated Socket Mode app via the Cursor dashboard:
|
|
112
|
-
create Opens the signed-in dashboard wizard. Finish name, workspace,
|
|
113
|
-
and Slack consent there. The CLI writes the token pair into
|
|
114
|
-
<dir>/.env.local and runs doctor. Requires \`${CLI} login\`
|
|
115
|
-
(or CURSOR_API_KEY). A team service-account key cannot
|
|
116
|
-
provision Slack apps. --prod provisions the prod app (default
|
|
117
|
-
dev). --name / --icon / --channel-posts prefill the wizard.
|
|
118
|
-
All three follow the agent's \`architecture\` (agent.ts;
|
|
119
|
-
default v2): the wizard stores tokens on that deployment and
|
|
120
|
-
the app inventory lives on that control plane.
|
|
121
|
-
destroy Delete the provisioned Slack app for this agent (+env). Tokens
|
|
122
|
-
already in .env.local are left in place (they just stop working).
|
|
123
|
-
icon Set the provisioned app's icon: an https image URL or a local
|
|
124
|
-
png/jpg/gif file (at most 512KB).
|
|
125
|
-
|
|
126
|
-
\`slack init\` without --manual is not the first-run path. Use \`slack create\`.
|
|
127
|
-
\`slack init --manual\` writes the channel file, manifests, a Slack CLI
|
|
128
|
-
\`.slack/\` project (get-manifest → those JSON files), env.example, and
|
|
129
|
-
setup-status.json. When \`~/.slack/bin/slack\` is logged in, it installs
|
|
130
|
-
the app. Otherwise \`next\` asks the user to install it. \`--install\`
|
|
131
|
-
requires that install. \`--no-install\` skips it. \`--prod\` selects the
|
|
132
|
-
deployed app. Paste at api.slack.com is the fallback. Do not
|
|
133
|
-
\`slack deploy\`.
|
|
134
|
-
|
|
135
|
-
Env tokens:
|
|
136
|
-
single agent: SLACK_BOT_TOKEN + SLACK_APP_TOKEN
|
|
137
|
-
multi-agent: <PREFIX>_SLACK_BOT_TOKEN + <PREFIX>_SLACK_APP_TOKEN
|
|
138
|
-
(create / init --manual default PREFIX from the directory name;
|
|
139
|
-
doctor defaults to it too when those keys are set)
|
|
140
|
-
|
|
141
|
-
See also: skills/setup-slack/SKILL.md
|
|
142
|
-
`;
|
|
143
|
-
|
|
144
|
-
export async function cmdSlack(
|
|
145
|
-
subcommand: string | undefined,
|
|
146
|
-
options: SlackCliOptions,
|
|
147
|
-
): Promise<number> {
|
|
148
|
-
switch (subcommand) {
|
|
149
|
-
case undefined:
|
|
150
|
-
case "help":
|
|
151
|
-
case "--help":
|
|
152
|
-
case "-h":
|
|
153
|
-
process.stdout.write(SLACK_HELP);
|
|
154
|
-
return subcommand === undefined ? 1 : 0;
|
|
155
|
-
case "setup":
|
|
156
|
-
process.stdout.write(formatSlackSetupGuide());
|
|
157
|
-
return 0;
|
|
158
|
-
case "create":
|
|
159
|
-
return cmdSlackCreate(options);
|
|
160
|
-
case "destroy":
|
|
161
|
-
return cmdSlackDestroy(options);
|
|
162
|
-
case "icon":
|
|
163
|
-
return cmdSlackIcon(options);
|
|
164
|
-
case "init":
|
|
165
|
-
return cmdSlackInit({
|
|
166
|
-
dir: options.dir,
|
|
167
|
-
name: options.name,
|
|
168
|
-
prefix: options.prefix,
|
|
169
|
-
noPrefix: options.noPrefix,
|
|
170
|
-
channelPosts: options.channelPosts,
|
|
171
|
-
manual: options.manual,
|
|
172
|
-
install: options.install,
|
|
173
|
-
noInstall: options.noInstall,
|
|
174
|
-
slackTeam: options.slackTeam,
|
|
175
|
-
detectSlackCli: options.detectSlackCli,
|
|
176
|
-
runSlackCli: options.runSlackCli,
|
|
177
|
-
prod: options.prod,
|
|
178
|
-
out: options.out,
|
|
179
|
-
err: options.err,
|
|
180
|
-
});
|
|
181
|
-
case "manifest":
|
|
182
|
-
return runSlackManifest(options);
|
|
183
|
-
case "doctor":
|
|
184
|
-
return runDoctor(options);
|
|
185
|
-
default:
|
|
186
|
-
process.stderr.write(`Unknown slack subcommand: ${subcommand}\n`);
|
|
187
|
-
process.stdout.write(SLACK_HELP);
|
|
188
|
-
return 1;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
async function runDoctor(options: SlackCliOptions): Promise<number> {
|
|
193
|
-
const dir = resolvePath(options.dir);
|
|
194
|
-
// Tokens usually live in the agent's .env.local; real env still wins.
|
|
195
|
-
loadAgentLocalEnv(dir);
|
|
196
|
-
const envPrefix = resolveDoctorEnvPrefix(options, dir);
|
|
197
|
-
const doctor = options.doctorImpl ?? runSlackDoctor;
|
|
198
|
-
const channels = options.channels ?? [];
|
|
199
|
-
const result = await doctor({
|
|
200
|
-
envPrefix,
|
|
201
|
-
channels: channels.length > 0 ? channels : undefined,
|
|
202
|
-
});
|
|
203
|
-
if (options.json) {
|
|
204
|
-
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
205
|
-
} else {
|
|
206
|
-
process.stdout.write(renderDoctorReport(result));
|
|
207
|
-
}
|
|
208
|
-
return result.ok ? 0 : 1;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* --prefix / --no-prefix win; otherwise the directory-derived prefix
|
|
213
|
-
* create/init use, but only when one of its keys is set — unprefixed
|
|
214
|
-
* setups keep the bare SLACK_* default.
|
|
215
|
-
*/
|
|
216
|
-
function resolveDoctorEnvPrefix(options: SlackCliOptions, dir: string): string | undefined {
|
|
217
|
-
if (options.noPrefix === true) {
|
|
218
|
-
return undefined;
|
|
219
|
-
}
|
|
220
|
-
if (options.prefix !== undefined) {
|
|
221
|
-
return options.prefix;
|
|
222
|
-
}
|
|
223
|
-
const derived = envPrefixFromName(basename(dir));
|
|
224
|
-
const keys = slackEnvKeys(derived);
|
|
225
|
-
return process.env[keys.bot] !== undefined || process.env[keys.app] !== undefined
|
|
226
|
-
? derived
|
|
227
|
-
: undefined;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// ============================================================================
|
|
231
|
-
// create / destroy — Cursor "Add to Slack" managed provisioning
|
|
232
|
-
// ============================================================================
|
|
233
|
-
|
|
234
|
-
const DEFAULT_WIZARD_POLL_INTERVAL_MS = 3_000;
|
|
235
|
-
const DEFAULT_WIZARD_POLL_TIMEOUT_MS = 60 * 60 * 1000;
|
|
236
|
-
|
|
237
|
-
interface SlackProvisionContext {
|
|
238
|
-
client: AgentServeSlackClient;
|
|
239
|
-
teamId: number;
|
|
240
|
-
/** The control plane `client` is pinned to; see {@link resolveSlackAppArchitecture}. */
|
|
241
|
-
architecture: AgentArchitecture;
|
|
242
|
-
json: boolean;
|
|
243
|
-
out: (text: string) => void;
|
|
244
|
-
err: (text: string) => void;
|
|
245
|
-
dim: (s: string) => string;
|
|
246
|
-
openBrowserImpl: (url: string) => void;
|
|
247
|
-
pollIntervalMs: number;
|
|
248
|
-
pollTimeoutMs: number;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/** Local facts about the app being provisioned, resolved before any I/O. */
|
|
252
|
-
interface SlackAppTarget {
|
|
253
|
-
dir: string;
|
|
254
|
-
name: string;
|
|
255
|
-
slug: string;
|
|
256
|
-
env: SlackAppEnv;
|
|
257
|
-
envPrefix: string | undefined;
|
|
258
|
-
envKeys: { bot: string; app: string };
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function resolveSlackAppTarget(
|
|
262
|
-
options: SlackCliOptions,
|
|
263
|
-
err: (text: string) => void,
|
|
264
|
-
): SlackAppTarget | number {
|
|
265
|
-
if (options.env === "both" && options.prod !== true) {
|
|
266
|
-
err("Provisioning targets one env at a time; pass --prod for the prod app (default dev).\n");
|
|
267
|
-
return 1;
|
|
268
|
-
}
|
|
269
|
-
const env: SlackAppEnv = options.prod === true || options.env === "prod" ? "prod" : "dev";
|
|
270
|
-
const dir = resolvePath(options.dir);
|
|
271
|
-
// Backend slug rule, mirrored so the error names the real problem
|
|
272
|
-
// instead of a generic 400.
|
|
273
|
-
const slug = slugFromDirectoryName(basename(dir));
|
|
274
|
-
if (slug === undefined || !/^[a-z0-9][a-z0-9_-]{0,63}$/.test(slug)) {
|
|
275
|
-
err(
|
|
276
|
-
`Could not derive a valid app slug from the directory name ${JSON.stringify(basename(dir))} (slugs start with a letter or digit; lowercase letters, digits, '-', '_'); rename the directory or pass --dir <agent>.\n`,
|
|
277
|
-
);
|
|
278
|
-
return 1;
|
|
279
|
-
}
|
|
280
|
-
const name = options.name ?? basename(dir);
|
|
281
|
-
const envPrefix =
|
|
282
|
-
options.noPrefix === true ? undefined : (options.prefix ?? envPrefixFromName(basename(dir)));
|
|
283
|
-
return { dir, name, slug, env, envPrefix, envKeys: slackEnvKeys(envPrefix) };
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function errStream(options: SlackCliOptions): (text: string) => void {
|
|
287
|
-
return options.err ?? ((text: string) => void process.stderr.write(text));
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const SLACK_ICON_MAX_BYTES = 524_288;
|
|
291
|
-
|
|
292
|
-
const SLACK_ICON_URL_MAX_LENGTH = 3000;
|
|
293
|
-
|
|
294
|
-
const SLACK_ICON_CONTENT_TYPES: Record<string, SlackAppIconContentType> = {
|
|
295
|
-
".png": "image/png",
|
|
296
|
-
".jpg": "image/jpeg",
|
|
297
|
-
".jpeg": "image/jpeg",
|
|
298
|
-
".gif": "image/gif",
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
type SlackIconSource =
|
|
302
|
-
| { kind: "url"; url: string }
|
|
303
|
-
| {
|
|
304
|
-
kind: "file";
|
|
305
|
-
base64: string;
|
|
306
|
-
contentType: SlackAppIconContentType;
|
|
307
|
-
path: string;
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
async function resolveSlackIconSource(
|
|
311
|
-
raw: string,
|
|
312
|
-
err: (text: string) => void,
|
|
313
|
-
): Promise<SlackIconSource | number> {
|
|
314
|
-
if (raw.startsWith("https://")) {
|
|
315
|
-
if (raw.length > SLACK_ICON_URL_MAX_LENGTH) {
|
|
316
|
-
err(
|
|
317
|
-
`Icon URLs must be at most ${SLACK_ICON_URL_MAX_LENGTH} characters (got ${raw.length}).\n`,
|
|
318
|
-
);
|
|
319
|
-
return 1;
|
|
320
|
-
}
|
|
321
|
-
return { kind: "url", url: raw };
|
|
322
|
-
}
|
|
323
|
-
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(raw)) {
|
|
324
|
-
err(`Icon URLs must be https (got ${JSON.stringify(raw)}).\n`);
|
|
325
|
-
return 1;
|
|
326
|
-
}
|
|
327
|
-
const path = resolvePath(raw);
|
|
328
|
-
const contentType = SLACK_ICON_CONTENT_TYPES[extname(path).toLowerCase()];
|
|
329
|
-
if (contentType === undefined) {
|
|
330
|
-
err(`Icon files must be .png, .jpg/.jpeg, or .gif (got ${JSON.stringify(basename(path))}).\n`);
|
|
331
|
-
return 1;
|
|
332
|
-
}
|
|
333
|
-
let data: Buffer;
|
|
334
|
-
try {
|
|
335
|
-
data = await readFile(path);
|
|
336
|
-
} catch (error) {
|
|
337
|
-
err(`Could not read the icon file ${path}: ${describeError(error)}\n`);
|
|
338
|
-
return 1;
|
|
339
|
-
}
|
|
340
|
-
if (data.length > SLACK_ICON_MAX_BYTES) {
|
|
341
|
-
err(`Icon files must be at most ${SLACK_ICON_MAX_BYTES} bytes (${path} is ${data.length}).\n`);
|
|
342
|
-
return 1;
|
|
343
|
-
}
|
|
344
|
-
return { kind: "file", base64: data.toString("base64"), contentType, path };
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
function toSlackAppIconInput(source: SlackIconSource): SlackAppIconInput {
|
|
348
|
-
return source.kind === "url"
|
|
349
|
-
? { url: source.url }
|
|
350
|
-
: { base64: source.base64, contentType: source.contentType };
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* File icons post after the wizard finishes. URL icons ride the mint
|
|
355
|
-
* payload. Best-effort: failures warn, never fail the create.
|
|
356
|
-
*/
|
|
357
|
-
async function applySlackCreateFileIcon(
|
|
358
|
-
ctx: SlackProvisionContext,
|
|
359
|
-
source: SlackIconSource | undefined,
|
|
360
|
-
appId: string,
|
|
361
|
-
): Promise<"set" | "failed" | undefined> {
|
|
362
|
-
if (source === undefined || source.kind === "url") {
|
|
363
|
-
return undefined;
|
|
364
|
-
}
|
|
365
|
-
try {
|
|
366
|
-
await ctx.client.setAppIcon({
|
|
367
|
-
teamId: ctx.teamId,
|
|
368
|
-
slackAppId: appId,
|
|
369
|
-
icon: toSlackAppIconInput(source),
|
|
370
|
-
});
|
|
371
|
-
return "set";
|
|
372
|
-
} catch (error) {
|
|
373
|
-
ctx.err(
|
|
374
|
-
`warning: setting the Slack app icon failed: ${describeError(error)}\nRetry with \`${CLI} slack icon ${source.path}\`.\n`,
|
|
375
|
-
);
|
|
376
|
-
return "failed";
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* The Slack control plane follows the agent's hosted architecture
|
|
382
|
-
* (`defineAgent({ architecture })`, `"v2"` when omitted): the dashboard
|
|
383
|
-
* wizard stores the minted tokens on that architecture's deployment, and
|
|
384
|
-
* the app inventory `destroy` / `icon` read lives there too. A directory
|
|
385
|
-
* that is not an agent project yet has nothing to read and takes the
|
|
386
|
-
* framework default, same as an `agent.ts` that omits the field.
|
|
387
|
-
*/
|
|
388
|
-
async function resolveSlackAppArchitecture(dir: string): Promise<AgentArchitecture> {
|
|
389
|
-
if (!(await isAgentProjectDir(dir))) {
|
|
390
|
-
return DEFAULT_AGENT_ARCHITECTURE;
|
|
391
|
-
}
|
|
392
|
-
const project = await loadAgentProject(dir);
|
|
393
|
-
return project.agent.architecture ?? DEFAULT_AGENT_ARCHITECTURE;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Credentials → provisioning client → team id, sharing the deploy CLI's
|
|
398
|
-
* resolution (stored login / CURSOR_API_KEY, `--team` override, GetMe
|
|
399
|
-
* default-team fallback). Returns an exit code (error already rendered)
|
|
400
|
-
* on failure.
|
|
401
|
-
*/
|
|
402
|
-
async function prepareProvision(options: SlackCliOptions): Promise<SlackProvisionContext | number> {
|
|
403
|
-
const out = options.out ?? ((text: string) => void process.stdout.write(text));
|
|
404
|
-
const err = errStream(options);
|
|
405
|
-
const credential = resolveApiKeySync(
|
|
406
|
-
options.apiKey === undefined ? undefined : { apiKey: options.apiKey },
|
|
407
|
-
);
|
|
408
|
-
if (credential?.source === "service-account") {
|
|
409
|
-
err(
|
|
410
|
-
`A team service-account key cannot provision Slack apps. Sign in with \`${CLI} login\` or set CURSOR_API_KEY.\n`,
|
|
411
|
-
);
|
|
412
|
-
return 1;
|
|
413
|
-
}
|
|
414
|
-
const auth = await resolveDeployAuth({
|
|
415
|
-
team: options.team,
|
|
416
|
-
apiKey: options.apiKey,
|
|
417
|
-
fetchImpl: options.fetchImpl,
|
|
418
|
-
err,
|
|
419
|
-
});
|
|
420
|
-
if (typeof auth === "number") {
|
|
421
|
-
return auth;
|
|
422
|
-
}
|
|
423
|
-
// Loading the project imports its authored modules; do it only once the
|
|
424
|
-
// credentials are known good.
|
|
425
|
-
const architecture = await resolveSlackAppArchitecture(resolvePath(options.dir));
|
|
426
|
-
// Provisioning routes live on the external API host beside deploys.
|
|
427
|
-
return {
|
|
428
|
-
client: new AgentServeSlackClient({
|
|
429
|
-
backendUrl: cursorExternalApiUrl(),
|
|
430
|
-
apiKey: auth.apiKey,
|
|
431
|
-
architecture,
|
|
432
|
-
fetchImpl: options.fetchImpl,
|
|
433
|
-
}),
|
|
434
|
-
teamId: auth.teamId,
|
|
435
|
-
architecture,
|
|
436
|
-
json: options.json === true,
|
|
437
|
-
out,
|
|
438
|
-
err,
|
|
439
|
-
dim: (options.palette ?? stderrPalette()).dim,
|
|
440
|
-
openBrowserImpl: options.openBrowserImpl ?? openBrowser,
|
|
441
|
-
pollIntervalMs: options.connectPollIntervalMs ?? DEFAULT_WIZARD_POLL_INTERVAL_MS,
|
|
442
|
-
pollTimeoutMs: options.connectPollTimeoutMs ?? DEFAULT_WIZARD_POLL_TIMEOUT_MS,
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
function writePendingAdminWait(ctx: SlackProvisionContext, poll: SlackWizardPollResult): void {
|
|
447
|
-
const appSuffix = poll.appId === undefined ? "" : ` (${poll.appId})`;
|
|
448
|
-
const requestUrl =
|
|
449
|
-
poll.oauthAuthorizeUrl !== undefined && poll.oauthAuthorizeUrl.length > 0
|
|
450
|
-
? poll.oauthAuthorizeUrl
|
|
451
|
-
: undefined;
|
|
452
|
-
ctx.err(`Waiting for a Slack admin to approve the app${appSuffix}.\n\n`);
|
|
453
|
-
if (poll.approvalRequest === "pending") {
|
|
454
|
-
// Already in the admin queue: nothing to file, so no browser hop.
|
|
455
|
-
ctx.err(ctx.dim(` Approval request sent; workspace owners were notified.\n\n`));
|
|
456
|
-
if (requestUrl !== undefined) {
|
|
457
|
-
ctx.err(ctx.dim(` Send a reminder from:\n\n`));
|
|
458
|
-
ctx.err(` ${requestUrl}\n\n`);
|
|
459
|
-
}
|
|
460
|
-
} else if (requestUrl !== undefined) {
|
|
461
|
-
ctx.err(
|
|
462
|
-
ctx.dim(
|
|
463
|
-
` Slack will notify workspace owners once the request is in their queue.\n` +
|
|
464
|
-
` Open this page to file it or send a reminder:\n\n`,
|
|
465
|
-
),
|
|
466
|
-
);
|
|
467
|
-
ctx.err(` ${requestUrl}\n\n`);
|
|
468
|
-
ctx.openBrowserImpl(requestUrl);
|
|
469
|
-
} else {
|
|
470
|
-
ctx.err(
|
|
471
|
-
ctx.dim(` Slack will notify workspace owners once the request is in their queue.\n\n`),
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
ctx.err(
|
|
475
|
-
ctx.dim(
|
|
476
|
-
` Keep this command running.\n` +
|
|
477
|
-
` After an admin approves, click Retry in the dashboard.\n`,
|
|
478
|
-
),
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
export async function cmdSlackCreate(options: SlackCliOptions): Promise<number> {
|
|
483
|
-
const target = resolveSlackAppTarget(options, errStream(options));
|
|
484
|
-
if (typeof target === "number") {
|
|
485
|
-
return target;
|
|
486
|
-
}
|
|
487
|
-
let iconSource: SlackIconSource | undefined;
|
|
488
|
-
if (options.icon !== undefined) {
|
|
489
|
-
const resolved = await resolveSlackIconSource(options.icon, errStream(options));
|
|
490
|
-
if (typeof resolved === "number") {
|
|
491
|
-
return resolved;
|
|
492
|
-
}
|
|
493
|
-
iconSource = resolved;
|
|
494
|
-
}
|
|
495
|
-
const ctx = await prepareProvision(options);
|
|
496
|
-
if (typeof ctx === "number") {
|
|
497
|
-
return ctx;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
let wrote: string[];
|
|
501
|
-
try {
|
|
502
|
-
wrote = await scaffoldSlackChannelFiles(target);
|
|
503
|
-
} catch (error) {
|
|
504
|
-
ctx.err(`${describeError(error)}\n`);
|
|
505
|
-
return 1;
|
|
506
|
-
}
|
|
507
|
-
if (wrote.length > 0 && !ctx.json) {
|
|
508
|
-
ctx.err(`${ctx.dim(`Scaffolded the Slack channel: ${wrote.join(", ")}`)}\n`);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const source = await inferDeployGitSource(target.dir);
|
|
512
|
-
let minted: SlackWizardMintResult;
|
|
513
|
-
try {
|
|
514
|
-
minted = await ctx.client.mintWizard({
|
|
515
|
-
teamId: ctx.teamId,
|
|
516
|
-
slug: target.slug,
|
|
517
|
-
env: target.env,
|
|
518
|
-
envPrefix: target.envPrefix,
|
|
519
|
-
name: options.name ?? target.name,
|
|
520
|
-
gitRepoUrl: source.gitRepoUrl,
|
|
521
|
-
gitRef: source.gitRef,
|
|
522
|
-
agentPath: source.agentPath,
|
|
523
|
-
channelPosts: options.channelPosts === true ? true : undefined,
|
|
524
|
-
slackTeamId: options.slackTeam,
|
|
525
|
-
iconUrl: iconSource?.kind === "url" ? iconSource.url : undefined,
|
|
526
|
-
force: options.force === true ? true : undefined,
|
|
527
|
-
});
|
|
528
|
-
} catch (error) {
|
|
529
|
-
return renderSlackApiError(error, ctx.err);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const waitMinutes = Math.round(ctx.pollTimeoutMs / 60_000);
|
|
533
|
-
ctx.err(`Finish Slack setup in the browser:\n\n ${minted.url}\n\n`);
|
|
534
|
-
ctx.err(
|
|
535
|
-
ctx.dim(
|
|
536
|
-
` Sign in as the same Cursor account that ran this command.\n` +
|
|
537
|
-
` The CLI waits here (up to ${waitMinutes} minutes).\n`,
|
|
538
|
-
),
|
|
539
|
-
);
|
|
540
|
-
ctx.openBrowserImpl(minted.url);
|
|
541
|
-
|
|
542
|
-
const deadline = Date.now() + ctx.pollTimeoutMs;
|
|
543
|
-
let sawPendingAdmin = false;
|
|
544
|
-
let poll: SlackWizardPollResult | undefined;
|
|
545
|
-
for (;;) {
|
|
546
|
-
try {
|
|
547
|
-
poll = await ctx.client.pollWizard(minted.wizardId);
|
|
548
|
-
} catch (error) {
|
|
549
|
-
if (Date.now() >= deadline) {
|
|
550
|
-
return renderSlackApiError(error, ctx.err);
|
|
551
|
-
}
|
|
552
|
-
await sleep(ctx.pollIntervalMs);
|
|
553
|
-
continue;
|
|
554
|
-
}
|
|
555
|
-
if (poll.status === "complete") {
|
|
556
|
-
break;
|
|
557
|
-
}
|
|
558
|
-
if (poll.status === "failed") {
|
|
559
|
-
ctx.err(`${poll.error ?? "Slack setup failed"}\n`);
|
|
560
|
-
return 1;
|
|
561
|
-
}
|
|
562
|
-
if (poll.status === "pending_admin_approval" && !sawPendingAdmin) {
|
|
563
|
-
sawPendingAdmin = true;
|
|
564
|
-
writePendingAdminWait(ctx, poll);
|
|
565
|
-
}
|
|
566
|
-
if (Date.now() >= deadline) {
|
|
567
|
-
ctx.err(`Timed out waiting for Slack setup.\n\n`);
|
|
568
|
-
ctx.err(ctx.dim(` Finish it in the browser, then re-run \`${CLI} slack create\`.\n\n`));
|
|
569
|
-
ctx.err(` ${minted.url}\n`);
|
|
570
|
-
return 1;
|
|
571
|
-
}
|
|
572
|
-
await sleep(ctx.pollIntervalMs);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
if (poll === undefined || poll.localEnv === undefined) {
|
|
576
|
-
ctx.err(
|
|
577
|
-
poll.localEnvClaimed === true
|
|
578
|
-
? "Tokens were already claimed by another poll; re-run create to rotate them.\n"
|
|
579
|
-
: "Slack setup finished but no tokens were returned; re-run create.\n",
|
|
580
|
-
);
|
|
581
|
-
return 1;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
const envEntries = [{ key: target.envKeys.bot, value: poll.localEnv.botToken }];
|
|
585
|
-
if (poll.localEnv.appToken !== undefined) {
|
|
586
|
-
envEntries.push({ key: target.envKeys.app, value: poll.localEnv.appToken });
|
|
587
|
-
}
|
|
588
|
-
const envFile = join(target.dir, ".env.local");
|
|
589
|
-
try {
|
|
590
|
-
await upsertEnvFile(envFile, envEntries);
|
|
591
|
-
if (await ensureEnvLocalGitignored(target.dir)) {
|
|
592
|
-
wrote.push(".gitignore (+.env.local)");
|
|
593
|
-
}
|
|
594
|
-
} catch (error) {
|
|
595
|
-
ctx.err(`Could not write ${envFile}: ${describeError(error)}\n`);
|
|
596
|
-
return 1;
|
|
597
|
-
}
|
|
598
|
-
wrote.push(".env.local");
|
|
599
|
-
for (const { key, value } of envEntries) {
|
|
600
|
-
process.env[key] = value;
|
|
601
|
-
}
|
|
602
|
-
if (poll.localEnv.appToken === undefined) {
|
|
603
|
-
ctx.err(
|
|
604
|
-
ctx.dim(
|
|
605
|
-
`warning: Slack did not return an app-level token, so ${target.envKeys.app} was not written.\n` +
|
|
606
|
-
` Re-run \`${CLI} slack create\` to recover it.\n`,
|
|
607
|
-
),
|
|
608
|
-
);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
let iconStatus: "set" | "failed" | undefined;
|
|
612
|
-
if (poll.appId !== undefined) {
|
|
613
|
-
iconStatus = await applySlackCreateFileIcon(ctx, iconSource, poll.appId);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
if (ctx.json) {
|
|
617
|
-
ctx.out(
|
|
618
|
-
`${JSON.stringify(
|
|
619
|
-
{
|
|
620
|
-
ok: true,
|
|
621
|
-
appId: poll.appId,
|
|
622
|
-
status: poll.status,
|
|
623
|
-
architecture: ctx.architecture,
|
|
624
|
-
envKeys: target.envKeys,
|
|
625
|
-
wrote,
|
|
626
|
-
iconStatus,
|
|
627
|
-
},
|
|
628
|
-
null,
|
|
629
|
-
2,
|
|
630
|
-
)}\n`,
|
|
631
|
-
);
|
|
632
|
-
return 0;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
ctx.out(
|
|
636
|
-
`Slack is connected for ${target.slug}` +
|
|
637
|
-
(poll.appId === undefined ? "" : ` (app ${poll.appId})`) +
|
|
638
|
-
`.\n wrote ${envEntries.map(entry => entry.key).join(" + ")} to ${envFile}\n\n`,
|
|
639
|
-
);
|
|
640
|
-
|
|
641
|
-
const doctor = options.doctorImpl ?? runSlackDoctor;
|
|
642
|
-
const doctorResult = await doctor(
|
|
643
|
-
target.envPrefix === undefined ? {} : { envPrefix: target.envPrefix },
|
|
644
|
-
);
|
|
645
|
-
ctx.out(renderDoctorReport(doctorResult));
|
|
646
|
-
ctx.out(
|
|
647
|
-
`\nNext steps:\n` +
|
|
648
|
-
` 1. ${CLI} serve --dir ${options.dir} --dev\n` +
|
|
649
|
-
` 2. Invite the bot in Slack and @mention it.\n`,
|
|
650
|
-
);
|
|
651
|
-
return 0;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
/**
|
|
655
|
-
* Resolve the one provisioned app for (slug, env[, --slack-team]) from
|
|
656
|
-
* `GET /status`. Returns an exit code with the error already rendered
|
|
657
|
-
* when zero or several apps match.
|
|
658
|
-
*/
|
|
659
|
-
async function resolveProvisionedApp(
|
|
660
|
-
ctx: SlackProvisionContext,
|
|
661
|
-
target: SlackAppTarget,
|
|
662
|
-
options: SlackCliOptions,
|
|
663
|
-
): Promise<SlackManagedAppInfo | number> {
|
|
664
|
-
let status: SlackProvisionStatus;
|
|
665
|
-
try {
|
|
666
|
-
status = await ctx.client.status(ctx.teamId);
|
|
667
|
-
} catch (error) {
|
|
668
|
-
return renderSlackApiError(error, ctx.err);
|
|
669
|
-
}
|
|
670
|
-
const sameSlug = status.apps.filter(app => app.slug === target.slug);
|
|
671
|
-
let candidates = sameSlug.filter(app => app.env === target.env);
|
|
672
|
-
if (options.slackTeam !== undefined) {
|
|
673
|
-
candidates = candidates.filter(app => app.slackTeamId === options.slackTeam);
|
|
674
|
-
}
|
|
675
|
-
if (candidates.length === 0) {
|
|
676
|
-
ctx.err(
|
|
677
|
-
`No provisioned ${target.env} Slack app for "${target.slug}"${
|
|
678
|
-
options.slackTeam === undefined ? "" : ` in workspace ${options.slackTeam}`
|
|
679
|
-
} (team ${ctx.teamId}).\n` +
|
|
680
|
-
(sameSlug.length === 0
|
|
681
|
-
? ""
|
|
682
|
-
: `Provisioned apps for this agent:\n${formatAppList(sameSlug)}`),
|
|
683
|
-
);
|
|
684
|
-
return 1;
|
|
685
|
-
}
|
|
686
|
-
if (candidates.length > 1) {
|
|
687
|
-
ctx.err(
|
|
688
|
-
`Multiple provisioned Slack apps match "${target.slug}" (${target.env}):\n` +
|
|
689
|
-
formatAppList(candidates) +
|
|
690
|
-
`Pass --slack-team <id> to pick one.\n`,
|
|
691
|
-
);
|
|
692
|
-
return 1;
|
|
693
|
-
}
|
|
694
|
-
return candidates[0]!;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
export async function cmdSlackDestroy(options: SlackCliOptions): Promise<number> {
|
|
698
|
-
const target = resolveSlackAppTarget(options, errStream(options));
|
|
699
|
-
if (typeof target === "number") {
|
|
700
|
-
return target;
|
|
701
|
-
}
|
|
702
|
-
const ctx = await prepareProvision(options);
|
|
703
|
-
if (typeof ctx === "number") {
|
|
704
|
-
return ctx;
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
const app = await resolveProvisionedApp(ctx, target, options);
|
|
708
|
-
if (typeof app === "number") {
|
|
709
|
-
return app;
|
|
710
|
-
}
|
|
711
|
-
try {
|
|
712
|
-
await ctx.client.deleteApp({
|
|
713
|
-
teamId: ctx.teamId,
|
|
714
|
-
slackAppId: app.slackAppId,
|
|
715
|
-
});
|
|
716
|
-
} catch (error) {
|
|
717
|
-
return renderSlackApiError(error, ctx.err);
|
|
718
|
-
}
|
|
719
|
-
if (ctx.json) {
|
|
720
|
-
ctx.out(
|
|
721
|
-
`${JSON.stringify(
|
|
722
|
-
{
|
|
723
|
-
ok: true,
|
|
724
|
-
deleted: true,
|
|
725
|
-
appId: app.slackAppId,
|
|
726
|
-
slackTeamId: app.slackTeamId,
|
|
727
|
-
slug: target.slug,
|
|
728
|
-
env: target.env,
|
|
729
|
-
},
|
|
730
|
-
null,
|
|
731
|
-
2,
|
|
732
|
-
)}\n`,
|
|
733
|
-
);
|
|
734
|
-
return 0;
|
|
735
|
-
}
|
|
736
|
-
ctx.out(
|
|
737
|
-
`Deleted the ${target.env} Slack app for ${target.slug} (app ${app.slackAppId}) from workspace ${app.slackTeamId}.\n` +
|
|
738
|
-
`Tokens in .env.local were left in place — ${target.envKeys.bot} / ${target.envKeys.app} are now inert; remove them whenever you like.\n`,
|
|
739
|
-
);
|
|
740
|
-
return 0;
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
export async function cmdSlackIcon(options: SlackCliOptions): Promise<number> {
|
|
744
|
-
const err = errStream(options);
|
|
745
|
-
if (options.iconSource === undefined) {
|
|
746
|
-
err(
|
|
747
|
-
`Usage: ${CLI} slack icon <https-url-or-file> [--dir .] [--slack-team T0123ABCD] [--prod] [--team <id>] [--json]\n`,
|
|
748
|
-
);
|
|
749
|
-
return 1;
|
|
750
|
-
}
|
|
751
|
-
const source = await resolveSlackIconSource(options.iconSource, err);
|
|
752
|
-
if (typeof source === "number") {
|
|
753
|
-
return source;
|
|
754
|
-
}
|
|
755
|
-
const target = resolveSlackAppTarget(options, err);
|
|
756
|
-
if (typeof target === "number") {
|
|
757
|
-
return target;
|
|
758
|
-
}
|
|
759
|
-
const ctx = await prepareProvision(options);
|
|
760
|
-
if (typeof ctx === "number") {
|
|
761
|
-
return ctx;
|
|
762
|
-
}
|
|
763
|
-
const app = await resolveProvisionedApp(ctx, target, options);
|
|
764
|
-
if (typeof app === "number") {
|
|
765
|
-
return app;
|
|
766
|
-
}
|
|
767
|
-
try {
|
|
768
|
-
await ctx.client.setAppIcon({
|
|
769
|
-
teamId: ctx.teamId,
|
|
770
|
-
slackAppId: app.slackAppId,
|
|
771
|
-
icon: toSlackAppIconInput(source),
|
|
772
|
-
});
|
|
773
|
-
} catch (error) {
|
|
774
|
-
return renderSlackApiError(error, ctx.err);
|
|
775
|
-
}
|
|
776
|
-
if (ctx.json) {
|
|
777
|
-
ctx.out(
|
|
778
|
-
`${JSON.stringify(
|
|
779
|
-
{
|
|
780
|
-
ok: true,
|
|
781
|
-
appId: app.slackAppId,
|
|
782
|
-
slackTeamId: app.slackTeamId,
|
|
783
|
-
slug: target.slug,
|
|
784
|
-
env: target.env,
|
|
785
|
-
iconStatus: "set",
|
|
786
|
-
},
|
|
787
|
-
null,
|
|
788
|
-
2,
|
|
789
|
-
)}\n`,
|
|
790
|
-
);
|
|
791
|
-
return 0;
|
|
792
|
-
}
|
|
793
|
-
ctx.out(
|
|
794
|
-
`Set the icon for the ${target.env} Slack app for ${target.slug} (app ${app.slackAppId}).\n`,
|
|
795
|
-
);
|
|
796
|
-
return 0;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
function formatAppList(
|
|
800
|
-
apps: ReadonlyArray<{
|
|
801
|
-
slackAppId: string;
|
|
802
|
-
slackTeamId: string;
|
|
803
|
-
env: string;
|
|
804
|
-
installStatus: string;
|
|
805
|
-
}>,
|
|
806
|
-
): string {
|
|
807
|
-
return apps
|
|
808
|
-
.map(
|
|
809
|
-
app =>
|
|
810
|
-
` - ${app.slackAppId} (${app.env}) in workspace ${app.slackTeamId} — ${app.installStatus}\n`,
|
|
811
|
-
)
|
|
812
|
-
.join("");
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* Scaffold the authored Slack channel when absent. Existing files are never
|
|
817
|
-
* overwritten: initSlackChannel writes with `wx`.
|
|
818
|
-
*/
|
|
819
|
-
async function scaffoldSlackChannelFiles(target: SlackAppTarget): Promise<string[]> {
|
|
820
|
-
const channelFile = projectPath(resolveProjectRoot(target.dir), "channels/slack.ts");
|
|
821
|
-
if (await fileExists(join(target.dir, channelFile))) {
|
|
822
|
-
return [];
|
|
823
|
-
}
|
|
824
|
-
try {
|
|
825
|
-
const result = await initSlackChannel({
|
|
826
|
-
dir: target.dir,
|
|
827
|
-
name: target.name,
|
|
828
|
-
envPrefix: target.envPrefix ?? "",
|
|
829
|
-
});
|
|
830
|
-
return result.files;
|
|
831
|
-
} catch (error) {
|
|
832
|
-
if (isErrnoException(error) && error.code === "EEXIST") {
|
|
833
|
-
return [];
|
|
834
|
-
}
|
|
835
|
-
throw error;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
function renderDoctorReport(result: SlackDoctorResult): string {
|
|
840
|
-
let text = `env: ${result.envKeys.bot} / ${result.envKeys.app}\n`;
|
|
841
|
-
for (const check of result.checks) {
|
|
842
|
-
text += `${check.ok ? "ok" : "!!"} ${check.id}: ${check.message}\n`;
|
|
843
|
-
}
|
|
844
|
-
text += result.ok ? "doctor: pass\n" : "doctor: fail\n";
|
|
845
|
-
for (const note of result.notes ?? []) {
|
|
846
|
-
text += `\nnote: ${note}\n`;
|
|
847
|
-
}
|
|
848
|
-
return text;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
function renderSlackApiError(error: unknown, err: (text: string) => void): number {
|
|
852
|
-
if (!(error instanceof SlackProvisionApiError)) {
|
|
853
|
-
throw error;
|
|
854
|
-
}
|
|
855
|
-
err(
|
|
856
|
-
error.code === "manager_reauth_required"
|
|
857
|
-
? `${error.message}\nRe-run \`${CLI} slack create\` and finish Slack consent in the dashboard.\n`
|
|
858
|
-
: `${error.message}\n`,
|
|
859
|
-
);
|
|
860
|
-
return 1;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
async function fileExists(path: string): Promise<boolean> {
|
|
864
|
-
try {
|
|
865
|
-
await access(path);
|
|
866
|
-
return true;
|
|
867
|
-
} catch {
|
|
868
|
-
return false;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
function isErrnoException(error: unknown): error is NodeJS.ErrnoException {
|
|
873
|
-
return error instanceof Error && "code" in error;
|
|
874
|
-
}
|