@cursor/july 0.1.16 → 0.1.18
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/README.md +9 -4
- package/dist/bin/agent-serve.js +60 -2
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +13 -3
- package/dist/channels/slack/auth.d.ts +7 -1
- package/dist/channels/slack/auth.d.ts.map +1 -1
- package/dist/channels/slack/auth.js +14 -0
- package/dist/channels/slack/blocks.d.ts +61 -0
- package/dist/channels/slack/blocks.d.ts.map +1 -0
- package/dist/channels/slack/blocks.js +90 -0
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/defaults.d.ts +2 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +29 -3
- package/dist/channels/slack/dispatch.d.ts +3 -17
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +4 -1
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +6 -1
- package/dist/channels/slack/index.d.ts +2 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +2 -0
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +4 -1
- package/dist/channels/slack/interactive.d.ts +39 -3
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +153 -7
- package/dist/channels/slack/manifest.d.ts +13 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +36 -14
- package/dist/channels/slack/message-body.d.ts +13 -0
- package/dist/channels/slack/message-body.d.ts.map +1 -0
- package/dist/channels/slack/message-body.js +82 -0
- package/dist/channels/slack/setup.d.ts +4 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +16 -2
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +24 -3
- package/dist/channels/slack/thread-context.d.ts +0 -2
- package/dist/channels/slack/thread-context.d.ts.map +1 -1
- package/dist/channels/slack/thread-context.js +1 -65
- package/dist/channels/slack/types.d.ts +93 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +4 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +4 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.DjHC-Ggf.js → app.BR5EdVSq.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BOzkeUi8.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DwviwmIq.js → VPLocalSearchBox.CNCzfUKC.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BIpeYSon.js → theme.CwKvMSWv.js} +2 -2
- package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.js → example-agents_security-reviewer.md.Dhj_m7_B.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.DqmEOQY1.js → guides_mcp-oauth.md.Dd8EgSem.js} +3 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DqmEOQY1.lean.js → guides_mcp-oauth.md.Dd8EgSem.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.FWale6Ip.js → guides_slack.md.D_xFKlnF.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.CsSr3rDz.js → reference_connections.md.B9Q3TOve.js} +12 -5
- package/dist/docs/assets/{reference_connections.md.CsSr3rDz.lean.js → reference_connections.md.B9Q3TOve.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +3 -3
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +5 -5
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +6 -5
- package/dist/docs/guides/slack.html +5 -5
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +3 -3
- package/dist/docs/reference/connections.html +14 -7
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/evals/assertions.d.ts +190 -0
- package/dist/evals/assertions.d.ts.map +1 -0
- package/dist/evals/assertions.js +461 -0
- package/dist/evals/expect.d.ts +95 -0
- package/dist/evals/expect.d.ts.map +1 -0
- package/dist/evals/expect.js +194 -0
- package/dist/evals/judge.d.ts +133 -0
- package/dist/evals/judge.d.ts.map +1 -0
- package/dist/evals/judge.js +228 -0
- package/dist/evals/loaders.d.ts +51 -0
- package/dist/evals/loaders.d.ts.map +1 -0
- package/dist/evals/loaders.js +124 -0
- package/dist/evals/matchers.d.ts +95 -0
- package/dist/evals/matchers.d.ts.map +1 -0
- package/dist/evals/matchers.js +145 -0
- package/dist/evals/reporters.d.ts +70 -0
- package/dist/evals/reporters.d.ts.map +1 -0
- package/dist/evals/reporters.js +221 -0
- package/dist/evals/results.d.ts +103 -0
- package/dist/evals/results.d.ts.map +1 -0
- package/dist/evals/results.js +28 -0
- package/dist/evals/run-facts.d.ts +77 -0
- package/dist/evals/run-facts.d.ts.map +1 -0
- package/dist/evals/run-facts.js +187 -0
- package/dist/evals.d.ts +118 -31
- package/dist/evals.d.ts.map +1 -1
- package/dist/evals.js +46 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/builtin-tools/index.d.ts +10 -0
- package/dist/internal/builtin-tools/index.d.ts.map +1 -0
- package/dist/internal/builtin-tools/index.js +27 -0
- package/dist/internal/builtin-tools/reminders.d.ts +9 -0
- package/dist/internal/builtin-tools/reminders.d.ts.map +1 -0
- package/dist/internal/builtin-tools/reminders.js +138 -0
- package/dist/internal/cli-ax.d.ts +27 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +90 -12
- package/dist/internal/cli-mcp.d.ts +8 -0
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +98 -0
- package/dist/internal/cli-slack.d.ts +29 -1
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +799 -13
- package/dist/internal/cursor-event-relay.d.ts +30 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +37 -0
- package/dist/internal/deploy-client.d.ts +7 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +9 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +70 -9
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +2 -0
- package/dist/internal/eval-judge-model.d.ts +59 -0
- package/dist/internal/eval-judge-model.d.ts.map +1 -0
- package/dist/internal/eval-judge-model.js +131 -0
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +12 -20
- package/dist/internal/eval-runner.d.ts +31 -25
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +329 -126
- package/dist/internal/evals-client.d.ts.map +1 -1
- package/dist/internal/evals-client.js +4 -1
- package/dist/internal/local-env.d.ts +8 -0
- package/dist/internal/local-env.d.ts.map +1 -0
- package/dist/internal/local-env.js +47 -0
- package/dist/internal/playground/static.d.ts +3 -0
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/playground/static.js +3 -0
- package/dist/internal/reminder-runner.d.ts +7 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +21 -0
- package/dist/internal/run-client.d.ts +15 -0
- package/dist/internal/run-client.d.ts.map +1 -1
- package/dist/internal/run-client.js +3 -2
- package/dist/internal/sdk-runner.d.ts +51 -1
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +176 -36
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +11 -1
- package/dist/internal/session-engine.d.ts +18 -5
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +81 -19
- package/dist/internal/slack-provision-client.d.ts +133 -0
- package/dist/internal/slack-provision-client.d.ts.map +1 -0
- package/dist/internal/slack-provision-client.js +286 -0
- package/dist/playground/assets/cursor-icons-16-f_W_ogc-.woff2 +0 -0
- package/dist/playground/assets/index-DRjS5klQ.js +85 -0
- package/dist/playground/assets/index-TCDs-UhZ.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +98 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +26 -0
- package/docs/example-agents/security-reviewer.md +1 -1
- package/docs/guides/mcp-oauth.md +10 -5
- package/docs/guides/slack.md +3 -2
- package/docs/reference/connections.md +28 -18
- package/package.json +20 -2
- package/skills/create-agent/SKILL.md +15 -7
- package/skills/debug/SKILL.md +3 -1
- package/skills/mcp-auth/SKILL.md +1 -1
- package/skills/setup-slack/SKILL.md +177 -11
- package/src/bin/agent-serve.ts +63 -2
- package/src/channels/slack/api.ts +16 -3
- package/src/channels/slack/auth.ts +16 -1
- package/src/channels/slack/blocks.ts +139 -0
- package/src/channels/slack/cursor-account.ts +1 -0
- package/src/channels/slack/defaults.ts +32 -4
- package/src/channels/slack/dispatch.ts +6 -19
- package/src/channels/slack/inbound.ts +6 -1
- package/src/channels/slack/index.ts +2 -0
- package/src/channels/slack/init.ts +3 -0
- package/src/channels/slack/interactive.ts +184 -19
- package/src/channels/slack/manifest.ts +37 -6
- package/src/channels/slack/message-body.ts +90 -0
- package/src/channels/slack/setup.ts +16 -2
- package/src/channels/slack/slack-channel.ts +37 -6
- package/src/channels/slack/thread-context.ts +1 -69
- package/src/channels/slack/types.ts +105 -1
- package/src/connections.ts +4 -1
- package/src/evals/assertions.ts +704 -0
- package/src/evals/expect.ts +272 -0
- package/src/evals/judge.ts +346 -0
- package/src/evals/loaders.ts +113 -0
- package/src/evals/matchers.ts +246 -0
- package/src/evals/reporters.ts +274 -0
- package/src/evals/results.ts +132 -0
- package/src/evals/run-facts.ts +274 -0
- package/src/evals.ts +205 -42
- package/src/index.ts +2 -0
- package/src/internal/builtin-tools/index.ts +40 -0
- package/src/internal/builtin-tools/reminders.ts +158 -0
- package/src/internal/cli-ax.ts +134 -15
- package/src/internal/cli-mcp.ts +118 -5
- package/src/internal/cli-slack.ts +1017 -15
- package/src/internal/cursor-event-relay.ts +67 -0
- package/src/internal/deploy-client.ts +10 -0
- package/src/internal/discovery.ts +83 -5
- package/src/internal/distribution.ts +2 -0
- package/src/internal/eval-judge-model.ts +148 -0
- package/src/internal/eval-run-store.ts +10 -14
- package/src/internal/eval-runner.ts +460 -214
- package/src/internal/evals-client.ts +5 -0
- package/src/internal/local-env.ts +53 -0
- package/src/internal/playground/static.ts +3 -0
- package/src/internal/reminder-runner.ts +30 -0
- package/src/internal/run-client.ts +17 -1
- package/src/internal/sdk-runner.ts +234 -35
- package/src/internal/server.ts +12 -0
- package/src/internal/session-engine.ts +103 -21
- package/src/internal/slack-provision-client.ts +442 -0
- package/src/types.ts +125 -4
- package/dist/channels/slack/post-update-delivery.d.ts +0 -85
- package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DZtu0ZIc.js +0 -1
- package/dist/internal/json-dir-store.d.ts +0 -32
- package/dist/internal/json-dir-store.d.ts.map +0 -1
- package/dist/internal/persistence-coordinator.d.ts +0 -127
- package/dist/internal/persistence-coordinator.d.ts.map +0 -1
- package/dist/persistence.d.ts +0 -184
- package/dist/persistence.d.ts.map +0 -1
- package/dist/playground/assets/cursor-icons-16-CQ50JpfO.woff2 +0 -0
- package/dist/playground/assets/index-Bwl4Onx4.js +0 -85
- package/dist/playground/assets/index-ByV4nfch.css +0 -1
- /package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.lean.js → example-agents_security-reviewer.md.Dhj_m7_B.lean.js} +0 -0
- /package/dist/docs/assets/{guides_slack.md.FWale6Ip.lean.js → guides_slack.md.D_xFKlnF.lean.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,YAAY,CAAC"}
|
|
@@ -21,6 +21,7 @@ export * from "./api.js";
|
|
|
21
21
|
export * from "./approvals.js";
|
|
22
22
|
export * from "./assistant.js";
|
|
23
23
|
export * from "./auth.js";
|
|
24
|
+
export * from "./blocks.js";
|
|
24
25
|
export * from "./channel-watch.js";
|
|
25
26
|
export * from "./constants.js";
|
|
26
27
|
export * from "./credentials.js";
|
|
@@ -36,6 +37,7 @@ export * from "./interactive.js";
|
|
|
36
37
|
export * from "./links.js";
|
|
37
38
|
export * from "./log.js";
|
|
38
39
|
export * from "./manifest.js";
|
|
40
|
+
export * from "./message-body.js";
|
|
39
41
|
export * from "./nudge-carrier.js";
|
|
40
42
|
export * from "./nudge-store.js";
|
|
41
43
|
export * from "./pr-ref.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAkG1B"}
|
|
@@ -51,7 +51,10 @@ ${envPrefixLine} // Streaming and thinking steps default to true.
|
|
|
51
51
|
],
|
|
52
52
|
});
|
|
53
53
|
`);
|
|
54
|
-
const pair = buildSlackManifestPair(Object.assign(Object.assign({ name
|
|
54
|
+
const pair = buildSlackManifestPair(Object.assign(Object.assign({ name,
|
|
55
|
+
// Scaffolded for hand-import at api.slack.com; managed_app_settings is
|
|
56
|
+
// settable only with the manager app's user token.
|
|
57
|
+
managedByCursor: false }, (options.description === undefined
|
|
55
58
|
? {}
|
|
56
59
|
: { description: options.description })), (options.channelPosts === true ? { channelPosts: true } : {})));
|
|
57
60
|
yield write(".agent-serve/slack/manifest.dev.json", `${JSON.stringify(pair.dev, null, 2)}\n`);
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Socket Mode interactive payloads (Block Kit
|
|
2
|
+
* Socket Mode interactive payloads (Block Kit clicks).
|
|
3
|
+
*
|
|
4
|
+
* Built-in tool-approval Approve/Deny actions resolve parked calls
|
|
5
|
+
* ({@link dispatchInteractiveFromPayload}); everything else can be routed
|
|
6
|
+
* to an author handler ({@link dispatchBlockAction} via
|
|
7
|
+
* `slackChannel({ onBlockAction })`).
|
|
3
8
|
*/
|
|
4
|
-
import type { ApprovalDecision, AuthContext, ChannelSession, PendingApproval } from "../../types.js";
|
|
9
|
+
import type { ApprovalDecision, AuthContext, ChannelSession, HostContext, PendingApproval, SendMessageFn } from "../../types.js";
|
|
5
10
|
import { type SlackLog } from "./log.js";
|
|
6
|
-
import type { SlackCredentials } from "./types.js";
|
|
11
|
+
import type { SlackBlockAction, SlackBlockActionHandler, SlackBotToken, SlackContinuationProbes, SlackCredentials } from "./types.js";
|
|
7
12
|
export interface SlackInteractiveDispatchDeps {
|
|
8
13
|
credentials: SlackCredentials | undefined;
|
|
9
14
|
getSession: (sessionId: string) => Promise<ChannelSession | null>;
|
|
@@ -16,4 +21,35 @@ export interface SlackInteractiveDispatchDeps {
|
|
|
16
21
|
* an agent-serve approval action (handled or rejected with a reason).
|
|
17
22
|
*/
|
|
18
23
|
export declare function dispatchInteractiveFromPayload(payload: unknown, deps: SlackInteractiveDispatchDeps): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Parse a Socket Mode `block_actions` payload into a {@link SlackBlockAction}.
|
|
26
|
+
* Returns null for non-`block_actions` payloads (view submissions, shortcuts)
|
|
27
|
+
* and malformed bodies.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseSlackBlockAction(payload: unknown): SlackBlockAction | null;
|
|
30
|
+
/**
|
|
31
|
+
* Swap the clicked message's actions row for a context note (`chat.update`).
|
|
32
|
+
* Strips only the row the click came from (`action.blockId`); every other
|
|
33
|
+
* block survives. Soft: false when the payload carried no message blocks or
|
|
34
|
+
* the update failed — callers treat the dispatched turn as the durable
|
|
35
|
+
* record and the card as best-effort UI.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveBlockActionCard(args: {
|
|
38
|
+
botToken: SlackBotToken | undefined;
|
|
39
|
+
action: SlackBlockAction;
|
|
40
|
+
note: string;
|
|
41
|
+
}): Promise<boolean>;
|
|
42
|
+
export interface SlackBlockActionDispatchDeps extends SlackContinuationProbes {
|
|
43
|
+
handler: SlackBlockActionHandler;
|
|
44
|
+
send: SendMessageFn;
|
|
45
|
+
credentials: SlackCredentials | undefined;
|
|
46
|
+
host: HostContext;
|
|
47
|
+
log?: SlackLog;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Route a non-approval `block_actions` payload to the author handler and
|
|
51
|
+
* dispatch its decision as a turn on the click's thread. Returns true when
|
|
52
|
+
* the payload was a block action (dispatched or deliberately skipped).
|
|
53
|
+
*/
|
|
54
|
+
export declare function dispatchBlockAction(payload: unknown, deps: SlackBlockActionDispatchDeps): Promise<boolean>;
|
|
19
55
|
//# sourceMappingURL=interactive.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/interactive.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/interactive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,WAAW,EACX,eAAe,EACf,aAAa,EACd,MAAM,gBAAgB,CAAC;AAKxB,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAClE,eAAe,EAAE,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,EAAE,WAAW,GAAG,IAAI,KACrB,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAC/C,GAAG,CAAC,EAAE,QAAQ,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC,OAAO,CAAC,CAyFlB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,GACf,gBAAgB,GAAG,IAAI,CAuFzB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,QAAQ,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBnB;AAED,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC3E,OAAO,EAAE,uBAAuB,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,CAAC,EAAE,QAAQ,CAAC;CAChB;AAyBD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC,OAAO,CAAC,CA+ClB"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Socket Mode interactive payloads (Block Kit
|
|
2
|
+
* Socket Mode interactive payloads (Block Kit clicks).
|
|
3
|
+
*
|
|
4
|
+
* Built-in tool-approval Approve/Deny actions resolve parked calls
|
|
5
|
+
* ({@link dispatchInteractiveFromPayload}); everything else can be routed
|
|
6
|
+
* to an author handler ({@link dispatchBlockAction} via
|
|
7
|
+
* `slackChannel({ onBlockAction })`).
|
|
3
8
|
*/
|
|
4
9
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
10
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -10,8 +15,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
15
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
16
|
});
|
|
12
17
|
};
|
|
18
|
+
import { updateMessage } from "./api.js";
|
|
13
19
|
import { decisionFromActionId, parseApprovalActionValue } from "./approvals.js";
|
|
14
20
|
import { buildSlackInteractiveApprovalAuth } from "./auth.js";
|
|
21
|
+
import { dispatchInboundMessage } from "./dispatch.js";
|
|
15
22
|
import { defaultSlackLog } from "./log.js";
|
|
16
23
|
/**
|
|
17
24
|
* Handle a Socket Mode `interactive` body. Returns true when this was
|
|
@@ -22,7 +29,7 @@ export function dispatchInteractiveFromPayload(payload, deps) {
|
|
|
22
29
|
var _a;
|
|
23
30
|
var _b, _c, _d, _e;
|
|
24
31
|
const log = (_b = deps.log) !== null && _b !== void 0 ? _b : defaultSlackLog;
|
|
25
|
-
const parsed =
|
|
32
|
+
const parsed = parseSlackBlockAction(payload);
|
|
26
33
|
if (parsed === null) {
|
|
27
34
|
return false;
|
|
28
35
|
}
|
|
@@ -90,7 +97,12 @@ export function dispatchInteractiveFromPayload(payload, deps) {
|
|
|
90
97
|
return true;
|
|
91
98
|
});
|
|
92
99
|
}
|
|
93
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Parse a Socket Mode `block_actions` payload into a {@link SlackBlockAction}.
|
|
102
|
+
* Returns null for non-`block_actions` payloads (view submissions, shortcuts)
|
|
103
|
+
* and malformed bodies.
|
|
104
|
+
*/
|
|
105
|
+
export function parseSlackBlockAction(payload) {
|
|
94
106
|
if (typeof payload !== "object" || payload === null) {
|
|
95
107
|
return null;
|
|
96
108
|
}
|
|
@@ -107,8 +119,7 @@ function parseBlockActionsPayload(payload) {
|
|
|
107
119
|
return null;
|
|
108
120
|
}
|
|
109
121
|
const action = first;
|
|
110
|
-
if (typeof action.action_id !== "string"
|
|
111
|
-
typeof action.value !== "string") {
|
|
122
|
+
if (typeof action.action_id !== "string") {
|
|
112
123
|
return null;
|
|
113
124
|
}
|
|
114
125
|
const channel = typeof record.channel === "object" && record.channel !== null
|
|
@@ -120,6 +131,9 @@ function parseBlockActionsPayload(payload) {
|
|
|
120
131
|
const user = typeof record.user === "object" && record.user !== null
|
|
121
132
|
? record.user
|
|
122
133
|
: {};
|
|
134
|
+
const team = typeof record.team === "object" && record.team !== null
|
|
135
|
+
? record.team
|
|
136
|
+
: {};
|
|
123
137
|
const channelId = typeof channel.id === "string" ? channel.id : "";
|
|
124
138
|
const messageTs = typeof message.ts === "string" ? message.ts : "";
|
|
125
139
|
const threadTs = typeof message.thread_ts === "string"
|
|
@@ -131,12 +145,144 @@ function parseBlockActionsPayload(payload) {
|
|
|
131
145
|
? record.container.thread_ts
|
|
132
146
|
: messageTs;
|
|
133
147
|
const userId = typeof user.id === "string" ? user.id : "";
|
|
148
|
+
const userName = typeof user.username === "string"
|
|
149
|
+
? user.username
|
|
150
|
+
: typeof user.name === "string"
|
|
151
|
+
? user.name
|
|
152
|
+
: undefined;
|
|
153
|
+
const teamId = typeof team.id === "string"
|
|
154
|
+
? team.id
|
|
155
|
+
: typeof user.team_id === "string"
|
|
156
|
+
? user.team_id
|
|
157
|
+
: undefined;
|
|
158
|
+
const label = typeof action.text === "object" &&
|
|
159
|
+
action.text !== null &&
|
|
160
|
+
typeof action.text.text === "string"
|
|
161
|
+
? action.text.text
|
|
162
|
+
: undefined;
|
|
163
|
+
const actionTs = typeof action.action_ts === "string" ? action.action_ts : "";
|
|
164
|
+
const messageBlocks = Array.isArray(message.blocks)
|
|
165
|
+
? message.blocks
|
|
166
|
+
: undefined;
|
|
134
167
|
return {
|
|
135
168
|
actionId: action.action_id,
|
|
136
|
-
|
|
169
|
+
blockId: typeof action.block_id === "string" ? action.block_id : "",
|
|
170
|
+
value: typeof action.value === "string" ? action.value : "",
|
|
171
|
+
label,
|
|
137
172
|
channelId,
|
|
138
173
|
threadTs,
|
|
139
|
-
userId,
|
|
140
174
|
messageTs,
|
|
175
|
+
messageBlocks,
|
|
176
|
+
userId,
|
|
177
|
+
userName,
|
|
178
|
+
teamId,
|
|
179
|
+
actionTs,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Swap the clicked message's actions row for a context note (`chat.update`).
|
|
184
|
+
* Strips only the row the click came from (`action.blockId`); every other
|
|
185
|
+
* block survives. Soft: false when the payload carried no message blocks or
|
|
186
|
+
* the update failed — callers treat the dispatched turn as the durable
|
|
187
|
+
* record and the card as best-effort UI.
|
|
188
|
+
*/
|
|
189
|
+
export function resolveBlockActionCard(args) {
|
|
190
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
191
|
+
const { action, note } = args;
|
|
192
|
+
if (action.messageBlocks === undefined) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
const clicked = (block) => typeof block === "object" &&
|
|
196
|
+
block !== null &&
|
|
197
|
+
block.type === "actions" &&
|
|
198
|
+
block.block_id === action.blockId;
|
|
199
|
+
const result = yield updateMessage({
|
|
200
|
+
botToken: args.botToken,
|
|
201
|
+
channel: action.channelId,
|
|
202
|
+
ts: action.messageTs,
|
|
203
|
+
text: note,
|
|
204
|
+
blocks: [
|
|
205
|
+
...action.messageBlocks.filter((block) => !clicked(block)),
|
|
206
|
+
{ type: "context", elements: [{ type: "mrkdwn", text: note }] },
|
|
207
|
+
],
|
|
208
|
+
});
|
|
209
|
+
return result.ok;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* The click as an inbound-message stand-in: the synthetic ts is the click's
|
|
214
|
+
* `action_ts` (unique per click, never a real thread message), so ask-dedupe
|
|
215
|
+
* claims and `<slack_thread>` exclusions stay per-click.
|
|
216
|
+
*/
|
|
217
|
+
function blockActionAsMessage(action) {
|
|
218
|
+
var _a;
|
|
219
|
+
const text = `[clicked: ${(_a = action.label) !== null && _a !== void 0 ? _a : action.actionId}]`;
|
|
220
|
+
return {
|
|
221
|
+
text,
|
|
222
|
+
body: text,
|
|
223
|
+
markdown: text,
|
|
224
|
+
ts: action.actionTs,
|
|
225
|
+
threadTs: action.threadTs,
|
|
226
|
+
channelId: action.channelId,
|
|
227
|
+
teamId: action.teamId,
|
|
228
|
+
author: {
|
|
229
|
+
userId: action.userId,
|
|
230
|
+
userName: action.userName,
|
|
231
|
+
isBot: false,
|
|
232
|
+
},
|
|
141
233
|
};
|
|
142
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Route a non-approval `block_actions` payload to the author handler and
|
|
237
|
+
* dispatch its decision as a turn on the click's thread. Returns true when
|
|
238
|
+
* the payload was a block action (dispatched or deliberately skipped).
|
|
239
|
+
*/
|
|
240
|
+
export function dispatchBlockAction(payload, deps) {
|
|
241
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
242
|
+
var _a;
|
|
243
|
+
const log = (_a = deps.log) !== null && _a !== void 0 ? _a : defaultSlackLog;
|
|
244
|
+
const action = parseSlackBlockAction(payload);
|
|
245
|
+
if (action === null) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
if (action.channelId === "" || action.threadTs === "") {
|
|
249
|
+
log.warn("block action skipped (no conversation)", {
|
|
250
|
+
action_id: action.actionId,
|
|
251
|
+
user: action.userId,
|
|
252
|
+
});
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
// Slack stamps every real click; without one the synthetic message ts
|
|
256
|
+
// would alias another click's dedupe claim.
|
|
257
|
+
if (action.actionTs === "") {
|
|
258
|
+
log.warn("block action skipped (no action_ts)", {
|
|
259
|
+
action_id: action.actionId,
|
|
260
|
+
user: action.userId,
|
|
261
|
+
});
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
log.info("block action", {
|
|
265
|
+
action_id: action.actionId,
|
|
266
|
+
channel: action.channelId,
|
|
267
|
+
thread_ts: action.threadTs,
|
|
268
|
+
message_ts: action.messageTs,
|
|
269
|
+
user: action.userId,
|
|
270
|
+
});
|
|
271
|
+
yield dispatchInboundMessage({
|
|
272
|
+
kind: "block_action",
|
|
273
|
+
message: blockActionAsMessage(action),
|
|
274
|
+
handler: (ctx) => deps.handler(ctx, action),
|
|
275
|
+
send: deps.send,
|
|
276
|
+
credentials: deps.credentials,
|
|
277
|
+
host: deps.host,
|
|
278
|
+
log,
|
|
279
|
+
// Click text is synthetic — never treat it as a stop/eval directive.
|
|
280
|
+
evalCommandsEnabled: false,
|
|
281
|
+
hasContinuationSession: deps.hasContinuationSession,
|
|
282
|
+
isContinuationBusy: deps.isContinuationBusy,
|
|
283
|
+
getContinuationLastBotMessageTs: deps.getContinuationLastBotMessageTs,
|
|
284
|
+
interruptContinuation: deps.interruptContinuation,
|
|
285
|
+
});
|
|
286
|
+
return true;
|
|
287
|
+
});
|
|
288
|
+
}
|
|
@@ -3,8 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Import at https://api.slack.com/apps -> Create New App -> From a manifest.
|
|
5
5
|
* Always Socket Mode — no Events Request URL.
|
|
6
|
+
*
|
|
7
|
+
* Mirrored by backend/server/src/agentServe/agentServeSlackManifest.ts (the
|
|
8
|
+
* backend cannot import this published package); keep the twins in lockstep.
|
|
6
9
|
*/
|
|
7
10
|
import type { SlackManifestOptions } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Where Slack points users who open a Cursor-provisioned app's settings
|
|
13
|
+
* page. Manifest builders know neither the team slug nor the deployment
|
|
14
|
+
* id, so this is the dashboard tab root rather than a per-agent deep link.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SLACK_EXTERNAL_APP_MANAGEMENT_URL = "https://cursor.com/dashboard/deployed-agents";
|
|
8
17
|
export interface SlackAppManifest {
|
|
9
18
|
display_information: {
|
|
10
19
|
name: string;
|
|
@@ -44,6 +53,10 @@ export interface SlackAppManifest {
|
|
|
44
53
|
socket_mode_enabled: boolean;
|
|
45
54
|
token_rotation_enabled: boolean;
|
|
46
55
|
is_mcp_enabled: boolean;
|
|
56
|
+
managed_app_settings?: {
|
|
57
|
+
is_install_from_slack_disabled: boolean;
|
|
58
|
+
external_app_management_url: string;
|
|
59
|
+
};
|
|
47
60
|
};
|
|
48
61
|
}
|
|
49
62
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/manifest.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,iDACE,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE;YACR,YAAY,EAAE,MAAM,CAAC;YACrB,aAAa,EAAE,OAAO,CAAC;SACxB,CAAC;QACF,cAAc,CAAC,EAAE;YACf,qBAAqB,EAAE,MAAM,CAAC;YAC9B,iBAAiB,EAAE,KAAK,CAAC;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC9D,CAAC;QACF,QAAQ,CAAC,EAAE;YACT,gBAAgB,EAAE,OAAO,CAAC;YAC1B,oBAAoB,EAAE,OAAO,CAAC;YAC9B,8BAA8B,EAAE,OAAO,CAAC;SACzC,CAAC;KACH,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE;YACN,GAAG,EAAE,MAAM,EAAE,CAAC;SACf,CAAC;KACH,CAAC;IACF,QAAQ,EAAE;QACR,mBAAmB,EAAE;YACnB,UAAU,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC;QACF,aAAa,EAAE;YACb,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;QACF,kBAAkB,EAAE,OAAO,CAAC;QAC5B,mBAAmB,EAAE,OAAO,CAAC;QAC7B,sBAAsB,EAAE,OAAO,CAAC;QAChC,cAAc,EAAE,OAAO,CAAC;QACxB,oBAAoB,CAAC,EAAE;YACrB,8BAA8B,EAAE,OAAO,CAAC;YACxC,2BAA2B,EAAE,MAAM,CAAC;SACrC,CAAC;KACH,CAAC;CACH;AAuDD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,oBAAoB,GAC5B,gBAAgB,CA+ElB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,GACzC;IACD,GAAG,EAAE,gBAAgB,CAAC;IACtB,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAKA"}
|
|
@@ -3,7 +3,16 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Import at https://api.slack.com/apps -> Create New App -> From a manifest.
|
|
5
5
|
* Always Socket Mode — no Events Request URL.
|
|
6
|
+
*
|
|
7
|
+
* Mirrored by backend/server/src/agentServe/agentServeSlackManifest.ts (the
|
|
8
|
+
* backend cannot import this published package); keep the twins in lockstep.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Where Slack points users who open a Cursor-provisioned app's settings
|
|
12
|
+
* page. Manifest builders know neither the team slug nor the deployment
|
|
13
|
+
* id, so this is the dashboard tab root rather than a per-agent deep link.
|
|
6
14
|
*/
|
|
15
|
+
export const SLACK_EXTERNAL_APP_MANAGEMENT_URL = "https://cursor.com/dashboard/deployed-agents";
|
|
7
16
|
const BOT_SCOPES = [
|
|
8
17
|
"app_mentions:read",
|
|
9
18
|
"assistant:write",
|
|
@@ -20,6 +29,15 @@ const BOT_SCOPES = [
|
|
|
20
29
|
"users:read",
|
|
21
30
|
];
|
|
22
31
|
const BOT_EVENTS = ["app_mention", "message.im"];
|
|
32
|
+
/** Slack's display_information.description bound. */
|
|
33
|
+
const MAX_DESCRIPTION_LENGTH = 140;
|
|
34
|
+
const DESCRIPTION_SUFFIX = " — an AI agent built with Cursor";
|
|
35
|
+
/** Marketplace review rejects managed apps whose manifest omits a description. */
|
|
36
|
+
function defaultDescription(name) {
|
|
37
|
+
const room = MAX_DESCRIPTION_LENGTH - DESCRIPTION_SUFFIX.length;
|
|
38
|
+
// Spread splits by code point: truncation cannot halve a surrogate pair.
|
|
39
|
+
return `${[...name].slice(0, room).join("")}${DESCRIPTION_SUFFIX}`;
|
|
40
|
+
}
|
|
23
41
|
function appSlug(name) {
|
|
24
42
|
const base = name
|
|
25
43
|
.toLowerCase()
|
|
@@ -56,6 +74,7 @@ export function buildSlackManifest(options) {
|
|
|
56
74
|
? `${options.name} (dev)`
|
|
57
75
|
: options.name;
|
|
58
76
|
const botName = (_a = options.botDisplayName) !== null && _a !== void 0 ? _a : toBotDisplayName(options.name, env);
|
|
77
|
+
const description = (_b = options.description) !== null && _b !== void 0 ? _b : defaultDescription(options.name);
|
|
59
78
|
const includeAssistant = options.assistant !== false;
|
|
60
79
|
const botScopes = includeAssistant
|
|
61
80
|
? [...BOT_SCOPES]
|
|
@@ -65,9 +84,10 @@ export function buildSlackManifest(options) {
|
|
|
65
84
|
: [...BOT_EVENTS];
|
|
66
85
|
const suggested = options.suggestedPrompts !== undefined ? options.suggestedPrompts : [];
|
|
67
86
|
return {
|
|
68
|
-
display_information:
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
display_information: {
|
|
88
|
+
name: displayName,
|
|
89
|
+
description,
|
|
90
|
+
},
|
|
71
91
|
features: Object.assign({ bot_user: {
|
|
72
92
|
display_name: botName,
|
|
73
93
|
always_online: true,
|
|
@@ -78,7 +98,7 @@ export function buildSlackManifest(options) {
|
|
|
78
98
|
} }, (includeAssistant
|
|
79
99
|
? {
|
|
80
100
|
assistant_view: {
|
|
81
|
-
assistant_description:
|
|
101
|
+
assistant_description: description,
|
|
82
102
|
suggested_prompts: suggested,
|
|
83
103
|
},
|
|
84
104
|
}
|
|
@@ -88,21 +108,23 @@ export function buildSlackManifest(options) {
|
|
|
88
108
|
bot: botScopes,
|
|
89
109
|
},
|
|
90
110
|
},
|
|
91
|
-
settings: {
|
|
92
|
-
event_subscriptions: {
|
|
111
|
+
settings: Object.assign({ event_subscriptions: {
|
|
93
112
|
bot_events: botEvents,
|
|
94
|
-
},
|
|
95
|
-
interactivity: {
|
|
113
|
+
}, interactivity: {
|
|
96
114
|
is_enabled: options.interactivity === true,
|
|
97
|
-
},
|
|
115
|
+
},
|
|
98
116
|
// Benny installs org-wide in the Cursor FE & ADM workspace.
|
|
99
|
-
org_deploy_enabled: benny,
|
|
117
|
+
org_deploy_enabled: benny,
|
|
100
118
|
// Always Socket Mode — agent-serve has no Events Request URL path.
|
|
101
119
|
// (Do not set false even if Slack's empty-app stub defaults to off.)
|
|
102
|
-
socket_mode_enabled: true,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
120
|
+
socket_mode_enabled: true, token_rotation_enabled: false, is_mcp_enabled: false }, (options.managedByCursor === false
|
|
121
|
+
? {}
|
|
122
|
+
: {
|
|
123
|
+
managed_app_settings: {
|
|
124
|
+
is_install_from_slack_disabled: true,
|
|
125
|
+
external_app_management_url: SLACK_EXTERNAL_APP_MANAGEMENT_URL,
|
|
126
|
+
},
|
|
127
|
+
})),
|
|
106
128
|
};
|
|
107
129
|
}
|
|
108
130
|
export function buildSlackManifestPair(options) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flatten a Slack message payload into readable text.
|
|
3
|
+
*
|
|
4
|
+
* Works on both raw Events API payloads and `conversations.*` API records.
|
|
5
|
+
* Alert feeds (Datadog, PagerDuty, …) post with an empty top-level `text`
|
|
6
|
+
* and put the whole notification in `attachments` / Block Kit `blocks`, so
|
|
7
|
+
* anything reading `text` alone sees an empty message.
|
|
8
|
+
*/
|
|
9
|
+
type JsonRecord = Record<string, unknown>;
|
|
10
|
+
/** Pull readable text out of Slack attachment / Block Kit payloads. */
|
|
11
|
+
export declare function slackApiMessageBody(message: JsonRecord): string;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=message-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-body.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/message-body.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAa1C,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAkE/D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flatten a Slack message payload into readable text.
|
|
3
|
+
*
|
|
4
|
+
* Works on both raw Events API payloads and `conversations.*` API records.
|
|
5
|
+
* Alert feeds (Datadog, PagerDuty, …) post with an empty top-level `text`
|
|
6
|
+
* and put the whole notification in `attachments` / Block Kit `blocks`, so
|
|
7
|
+
* anything reading `text` alone sees an empty message.
|
|
8
|
+
*/
|
|
9
|
+
function asRecord(value) {
|
|
10
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function asString(value) {
|
|
16
|
+
return typeof value === "string" ? value : undefined;
|
|
17
|
+
}
|
|
18
|
+
/** Pull readable text out of Slack attachment / Block Kit payloads. */
|
|
19
|
+
export function slackApiMessageBody(message) {
|
|
20
|
+
const parts = [];
|
|
21
|
+
const text = asString(message.text);
|
|
22
|
+
if (text !== undefined && text.trim() !== "") {
|
|
23
|
+
parts.push(text);
|
|
24
|
+
}
|
|
25
|
+
const attachments = Array.isArray(message.attachments)
|
|
26
|
+
? message.attachments
|
|
27
|
+
: [];
|
|
28
|
+
for (const attachment of attachments) {
|
|
29
|
+
const rec = asRecord(attachment);
|
|
30
|
+
if (rec === null) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
for (const key of [
|
|
34
|
+
"pretext",
|
|
35
|
+
"title",
|
|
36
|
+
"text",
|
|
37
|
+
"fallback",
|
|
38
|
+
"footer",
|
|
39
|
+
]) {
|
|
40
|
+
const value = asString(rec[key]);
|
|
41
|
+
if (value !== undefined && value.trim() !== "") {
|
|
42
|
+
parts.push(value);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const titleLink = asString(rec.title_link);
|
|
46
|
+
if (titleLink !== undefined && titleLink.trim() !== "") {
|
|
47
|
+
parts.push(titleLink);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const blocks = Array.isArray(message.blocks) ? message.blocks : [];
|
|
51
|
+
for (const block of blocks) {
|
|
52
|
+
const rec = asRecord(block);
|
|
53
|
+
if (rec === null) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const blockText = asRecord(rec.text);
|
|
57
|
+
const blockTextValue = asString(blockText === null || blockText === void 0 ? void 0 : blockText.text);
|
|
58
|
+
if (blockTextValue !== undefined && blockTextValue.trim() !== "") {
|
|
59
|
+
parts.push(blockTextValue);
|
|
60
|
+
}
|
|
61
|
+
const fields = Array.isArray(rec.fields) ? rec.fields : [];
|
|
62
|
+
for (const field of fields) {
|
|
63
|
+
const fieldRec = asRecord(field);
|
|
64
|
+
const fieldText = asString(fieldRec === null || fieldRec === void 0 ? void 0 : fieldRec.text);
|
|
65
|
+
if (fieldText !== undefined && fieldText.trim() !== "") {
|
|
66
|
+
parts.push(fieldText);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Dedupe identical chunks (Datadog often repeats text/fallback across fields).
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
const deduped = [];
|
|
73
|
+
for (const part of parts) {
|
|
74
|
+
const trimmed = part.trim();
|
|
75
|
+
if (trimmed === "" || seen.has(trimmed)) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
seen.add(trimmed);
|
|
79
|
+
deduped.push(trimmed);
|
|
80
|
+
}
|
|
81
|
+
return deduped.join("\n");
|
|
82
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Slack setup guide printed by `agent-serve slack setup`.
|
|
3
3
|
*
|
|
4
|
-
* Mirrors the Cursor skill at skills/setup-slack/SKILL.md
|
|
4
|
+
* Mirrors the Cursor skill at skills/setup-slack/SKILL.md: connection
|
|
5
|
+
* decision first (Cursor-hosted vs dedicated Socket Mode app), then the
|
|
6
|
+
* dedicated-app phases. {@link SLACK_SETUP_PHASES} stays the dedicated-app
|
|
7
|
+
* checklist — its ids key `.agent-serve/slack/setup-status.json`.
|
|
5
8
|
*/
|
|
6
9
|
export interface SlackSetupPhase {
|
|
7
10
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/setup.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,eAAO,MAAM,kBAAkB,EAAE,eAAe,EA4D/C,CAAC;AAEF,wBAAgB,qBAAqB,IAAI,MAAM,CAgC9C"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Slack setup guide printed by `agent-serve slack setup`.
|
|
3
3
|
*
|
|
4
|
-
* Mirrors the Cursor skill at skills/setup-slack/SKILL.md
|
|
4
|
+
* Mirrors the Cursor skill at skills/setup-slack/SKILL.md: connection
|
|
5
|
+
* decision first (Cursor-hosted vs dedicated Socket Mode app), then the
|
|
6
|
+
* dedicated-app phases. {@link SLACK_SETUP_PHASES} stays the dedicated-app
|
|
7
|
+
* checklist — its ids key `.agent-serve/slack/setup-status.json`.
|
|
5
8
|
*/
|
|
6
9
|
export const SLACK_SETUP_PHASES = [
|
|
7
10
|
{
|
|
@@ -66,8 +69,19 @@ export const SLACK_SETUP_PHASES = [
|
|
|
66
69
|
];
|
|
67
70
|
export function formatSlackSetupGuide() {
|
|
68
71
|
const lines = [
|
|
69
|
-
"agent-serve — Slack setup
|
|
72
|
+
"agent-serve — Slack setup",
|
|
70
73
|
"",
|
|
74
|
+
"Two connections exist; decide before running the phases below.",
|
|
75
|
+
"",
|
|
76
|
+
" A) Cursor-hosted connection (recommended default, zero Slack admin):",
|
|
77
|
+
' slackChannel({ cursorAccount: true, agentName: "MyAgent" })',
|
|
78
|
+
" Sign in (agent-serve login / CURSOR_API_KEY), serve, then mention",
|
|
79
|
+
' "@Cursor MyAgent ..." in the linked workspace. No app, no tokens.',
|
|
80
|
+
" B) Dedicated Slack app (Socket Mode) — the phases below. Choose it",
|
|
81
|
+
" when you need your own bot user, channel watching",
|
|
82
|
+
" (engagement.channelPosts), or approval buttons / interactivity.",
|
|
83
|
+
"",
|
|
84
|
+
"Phases 0-5 cover connection B only.",
|
|
71
85
|
"Goal: importable dev + prod Slack apps over Socket Mode (no public URL).",
|
|
72
86
|
"App-Level Token (xapp-...) + Bot Token (xoxb-...) required.",
|
|
73
87
|
"",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-channel.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/slack-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EACV,iBAAiB,EAMlB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"slack-channel.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/slack-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EACV,iBAAiB,EAMlB,MAAM,gBAAgB,CAAC;AAyCxB,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,EAC7D,OAAO,GAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAAG;IAChD,SAAS,CAAC,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;CACnC,GACL,iBAAiB,CAAC,iBAAiB,CAAC,CAoatC"}
|