@cursor/july 0.1.27 → 0.1.29

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.
Files changed (180) hide show
  1. package/dist/bin/agent-serve.js +32 -5
  2. package/dist/channels/slack/auth.d.ts +13 -13
  3. package/dist/channels/slack/auth.d.ts.map +1 -1
  4. package/dist/channels/slack/auth.js +19 -10
  5. package/dist/channels/slack/cursor-account.d.ts.map +1 -1
  6. package/dist/channels/slack/cursor-account.js +3 -1
  7. package/dist/channels/slack/defaults.d.ts +7 -4
  8. package/dist/channels/slack/defaults.d.ts.map +1 -1
  9. package/dist/channels/slack/defaults.js +14 -4
  10. package/dist/channels/slack/dispatch.d.ts +6 -0
  11. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  12. package/dist/channels/slack/dispatch.js +59 -21
  13. package/dist/channels/slack/external-policy.d.ts +27 -0
  14. package/dist/channels/slack/external-policy.d.ts.map +1 -0
  15. package/dist/channels/slack/external-policy.js +53 -0
  16. package/dist/channels/slack/index.d.ts +1 -0
  17. package/dist/channels/slack/index.d.ts.map +1 -1
  18. package/dist/channels/slack/index.js +1 -0
  19. package/dist/channels/slack/interactive.d.ts +6 -0
  20. package/dist/channels/slack/interactive.d.ts.map +1 -1
  21. package/dist/channels/slack/interactive.js +42 -15
  22. package/dist/channels/slack/slack-channel.d.ts +19 -1
  23. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  24. package/dist/channels/slack/slack-channel.js +48 -6
  25. package/dist/channels/slack/types.d.ts +10 -0
  26. package/dist/channels/slack/types.d.ts.map +1 -1
  27. package/dist/docs/404.html +2 -2
  28. package/dist/docs/ab.html +3 -3
  29. package/dist/docs/assets/{app.BICLoJYF.js → app.QdunVQKg.js} +1 -1
  30. package/dist/docs/assets/chunks/@localSearchIndexroot.DGe61XHA.js +1 -0
  31. package/dist/docs/assets/chunks/{VPLocalSearchBox.wN4Ko9dT.js → VPLocalSearchBox.B6EpUXYf.js} +1 -1
  32. package/dist/docs/assets/chunks/{theme.dnnTE-Co.js → theme.BOTJVqh7.js} +2 -2
  33. package/dist/docs/assets/{guides_slack.md.D_xFKlnF.js → guides_slack.md.CjmJSvZS.js} +8 -4
  34. package/dist/docs/assets/guides_slack.md.CjmJSvZS.lean.js +1 -0
  35. package/dist/docs/assets/guides_webhooks.md.wSOYas3X.js +183 -0
  36. package/dist/docs/assets/{guides_webhooks.md.B1EswtUu.lean.js → guides_webhooks.md.wSOYas3X.lean.js} +1 -1
  37. package/dist/docs/assets/{index.md.Dfv5ic9t.js → index.md.CH_s5uZe.js} +1 -1
  38. package/dist/docs/assets/{reference_channels.md.DdmiKgqf.js → reference_channels.md.CDhTRfUz.js} +2 -2
  39. package/dist/docs/assets/{reference_channels.md.DdmiKgqf.lean.js → reference_channels.md.CDhTRfUz.lean.js} +1 -1
  40. package/dist/docs/building-with-agents.html +3 -3
  41. package/dist/docs/concepts.html +3 -3
  42. package/dist/docs/deployment.html +3 -3
  43. package/dist/docs/evals.html +3 -3
  44. package/dist/docs/example-agents/approval-buddy.html +3 -3
  45. package/dist/docs/example-agents/benny.html +3 -3
  46. package/dist/docs/example-agents/bugbot.html +3 -3
  47. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  48. package/dist/docs/example-agents/codeowners-review.html +3 -3
  49. package/dist/docs/example-agents/concierge.html +3 -3
  50. package/dist/docs/example-agents/fsd.html +3 -3
  51. package/dist/docs/example-agents/index.html +3 -3
  52. package/dist/docs/example-agents/knowledge-base.html +3 -3
  53. package/dist/docs/example-agents/oncall.html +3 -3
  54. package/dist/docs/example-agents/security-reviewer.html +3 -3
  55. package/dist/docs/example-agents/slack-agent.html +3 -3
  56. package/dist/docs/example-agents/weather-agent.html +3 -3
  57. package/dist/docs/guides/agent-to-agent.html +3 -3
  58. package/dist/docs/guides/cloud-runtime.html +3 -3
  59. package/dist/docs/guides/github.html +3 -3
  60. package/dist/docs/guides/human-in-the-loop.html +3 -3
  61. package/dist/docs/guides/mcp-oauth.html +3 -3
  62. package/dist/docs/guides/slack.html +11 -7
  63. package/dist/docs/guides/webhooks.html +138 -5
  64. package/dist/docs/hashmap.json +1 -1
  65. package/dist/docs/hillclimbing.html +3 -3
  66. package/dist/docs/index.html +5 -5
  67. package/dist/docs/quickstart.html +3 -3
  68. package/dist/docs/reference/agent-config.html +3 -3
  69. package/dist/docs/reference/channels.html +5 -5
  70. package/dist/docs/reference/cli.html +3 -3
  71. package/dist/docs/reference/connections.html +3 -3
  72. package/dist/docs/reference/hooks.html +3 -3
  73. package/dist/docs/reference/http-api.html +3 -3
  74. package/dist/docs/reference/instructions.html +3 -3
  75. package/dist/docs/reference/playground.html +3 -3
  76. package/dist/docs/reference/project-layout.html +3 -3
  77. package/dist/docs/reference/prompt.html +3 -3
  78. package/dist/docs/reference/schedules.html +3 -3
  79. package/dist/docs/reference/sessions.html +3 -3
  80. package/dist/docs/reference/skills.html +3 -3
  81. package/dist/docs/reference/subagents.html +3 -3
  82. package/dist/docs/reference/tools.html +3 -3
  83. package/dist/docs/scaffolding-agents.html +3 -3
  84. package/dist/docs/storage.html +3 -3
  85. package/dist/docs/troubleshooting.html +3 -3
  86. package/dist/internal/cli-ax.d.ts +8 -0
  87. package/dist/internal/cli-ax.d.ts.map +1 -1
  88. package/dist/internal/cli-ax.js +116 -57
  89. package/dist/internal/cloud-turn-cost.d.ts +34 -0
  90. package/dist/internal/cloud-turn-cost.d.ts.map +1 -0
  91. package/dist/internal/cloud-turn-cost.js +106 -0
  92. package/dist/internal/cursor-slack-relay.d.ts +2 -0
  93. package/dist/internal/cursor-slack-relay.d.ts.map +1 -1
  94. package/dist/internal/cursor-slack-relay.js +1 -0
  95. package/dist/internal/deploy-client.d.ts +2 -0
  96. package/dist/internal/deploy-client.d.ts.map +1 -1
  97. package/dist/internal/deploy-client.js +1 -0
  98. package/dist/internal/discovery.d.ts.map +1 -1
  99. package/dist/internal/discovery.js +9 -2
  100. package/dist/internal/event-log.d.ts +6 -0
  101. package/dist/internal/event-log.d.ts.map +1 -1
  102. package/dist/internal/event-log.js +16 -0
  103. package/dist/internal/host-platforms.d.ts +13 -0
  104. package/dist/internal/host-platforms.d.ts.map +1 -1
  105. package/dist/internal/host-platforms.js +25 -16
  106. package/dist/internal/http-channel.d.ts.map +1 -1
  107. package/dist/internal/http-channel.js +3 -1
  108. package/dist/internal/local-control-plane.d.ts +25 -0
  109. package/dist/internal/local-control-plane.d.ts.map +1 -0
  110. package/dist/internal/local-control-plane.js +172 -0
  111. package/dist/internal/platform-schedule-sync.d.ts +17 -0
  112. package/dist/internal/platform-schedule-sync.d.ts.map +1 -0
  113. package/dist/internal/platform-schedule-sync.js +72 -0
  114. package/dist/internal/platform-timers.d.ts +28 -0
  115. package/dist/internal/platform-timers.d.ts.map +1 -0
  116. package/dist/internal/platform-timers.js +120 -0
  117. package/dist/internal/reminder-runner.d.ts +16 -12
  118. package/dist/internal/reminder-runner.d.ts.map +1 -1
  119. package/dist/internal/reminder-runner.js +112 -61
  120. package/dist/internal/reminder-store.d.ts +5 -4
  121. package/dist/internal/reminder-store.d.ts.map +1 -1
  122. package/dist/internal/reminder-store.js +5 -4
  123. package/dist/internal/sdk-runner.d.ts.map +1 -1
  124. package/dist/internal/sdk-runner.js +44 -1
  125. package/dist/internal/server.d.ts.map +1 -1
  126. package/dist/internal/server.js +115 -16
  127. package/dist/internal/session-engine.d.ts +22 -1
  128. package/dist/internal/session-engine.d.ts.map +1 -1
  129. package/dist/internal/session-engine.js +110 -4
  130. package/dist/internal/storage-coordinator.d.ts +4 -15
  131. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  132. package/dist/internal/storage-coordinator.js +4 -30
  133. package/dist/playground/assets/index-CquRB-l0.js +85 -0
  134. package/dist/playground/assets/{index-Bul1WfrB.css → index-Dj0bWpkn.css} +1 -1
  135. package/dist/playground/index.html +2 -2
  136. package/dist/storage.d.ts +0 -3
  137. package/dist/storage.d.ts.map +1 -1
  138. package/dist/storage.js +0 -3
  139. package/dist/types.d.ts +11 -2
  140. package/dist/types.d.ts.map +1 -1
  141. package/docs/README.md +1 -0
  142. package/docs/guides/slack.md +32 -7
  143. package/docs/guides/webhooks.md +183 -0
  144. package/docs/reference/channels.md +2 -1
  145. package/package.json +1 -1
  146. package/skills/setup-slack/SKILL.md +3 -0
  147. package/src/bin/agent-serve.ts +33 -5
  148. package/src/channels/slack/auth.ts +29 -22
  149. package/src/channels/slack/cursor-account.ts +2 -0
  150. package/src/channels/slack/defaults.ts +24 -4
  151. package/src/channels/slack/dispatch.ts +42 -1
  152. package/src/channels/slack/external-policy.ts +62 -0
  153. package/src/channels/slack/index.ts +1 -0
  154. package/src/channels/slack/interactive.ts +42 -10
  155. package/src/channels/slack/slack-channel.ts +66 -3
  156. package/src/channels/slack/types.ts +12 -0
  157. package/src/internal/cli-ax.ts +110 -34
  158. package/src/internal/cloud-turn-cost.ts +158 -0
  159. package/src/internal/cursor-slack-relay.ts +3 -0
  160. package/src/internal/deploy-client.ts +3 -0
  161. package/src/internal/discovery.ts +9 -1
  162. package/src/internal/event-log.ts +17 -0
  163. package/src/internal/host-platforms.ts +40 -18
  164. package/src/internal/http-channel.ts +3 -1
  165. package/src/internal/local-control-plane.ts +188 -0
  166. package/src/internal/platform-schedule-sync.ts +81 -0
  167. package/src/internal/platform-timers.ts +173 -0
  168. package/src/internal/reminder-runner.ts +131 -67
  169. package/src/internal/reminder-store.ts +5 -4
  170. package/src/internal/sdk-runner.ts +49 -1
  171. package/src/internal/server.ts +130 -11
  172. package/src/internal/session-engine.ts +138 -3
  173. package/src/internal/storage-coordinator.ts +4 -41
  174. package/src/storage.ts +0 -5
  175. package/src/types.ts +11 -2
  176. package/dist/docs/assets/chunks/@localSearchIndexroot.CQJytDwU.js +0 -1
  177. package/dist/docs/assets/guides_slack.md.D_xFKlnF.lean.js +0 -1
  178. package/dist/docs/assets/guides_webhooks.md.B1EswtUu.js +0 -50
  179. package/dist/playground/assets/index-BDCeW4uc.js +0 -86
  180. /package/dist/docs/assets/{index.md.Dfv5ic9t.lean.js → index.md.CH_s5uZe.lean.js} +0 -0
@@ -55,7 +55,7 @@ Usage:
55
55
  ${CLI} sessions [--url <baseUrl> | --prod] [--json]
56
56
  [--slug <slug>] [--team <id>] [--dir <path>]
57
57
  ${CLI} session <sessionId> [--url <baseUrl> | --prod]
58
- [--json | --text | --events]
58
+ [--json | --text | --events] [--out <file.ndjson>]
59
59
  [--slug <slug>] [--team <id>] [--dir <path>]
60
60
  ${CLI} cost [sessionId] [--url <baseUrl> | --prod] [--json]
61
61
  [--slug <slug>] [--team <id>] [--dir <path>]
@@ -80,11 +80,12 @@ Usage:
80
80
  [--tag <tag>]... [--verbose] [--timeout-ms <n>]
81
81
  [--strict] [--max-concurrency <n>]
82
82
  [--junit <path>] [--artifacts <dir>|--no-artifacts]
83
+ [--out <file.json>]
83
84
  [--skip-report] [--no-stream] [--no-wait]
84
85
  [--prod | --url <baseUrl>] [--slug <slug>]
85
86
  [--team <id>]
86
87
  ${CLI} eval status [runId] --prod|--url <baseUrl> [--dir <path>] [--json]
87
- [--slug <slug>] [--team <id>]
88
+ [--out <file.json>] [--slug <slug>] [--team <id>]
88
89
  ${CLI} eval cancel <runId> --prod|--url <baseUrl> [--dir <path>] [--json]
89
90
  [--slug <slug>] [--team <id>]
90
91
  ${CLI} info [--dir <path>] [--json]
@@ -269,6 +270,9 @@ Options:
269
270
  connections (defineConnection({ agent })) on cloud-runtime
270
271
  turns; local turns always use loopback.
271
272
  --no-schedules Disable the cron runner outside dev mode.
273
+ --no-control-plane serve: do not start the bundled control plane (schedule
274
+ and reminder clocks). Cursor hosting passes this so the
275
+ kit uses the Cursor backend instead.
272
276
  --team deploy/deployments/deployment/stop/rotate-token and
273
277
  chat/resume/run/call/eval/logs/sessions/session/playground
274
278
  --prod: Cursor team id. Defaults to the account's team when
@@ -362,8 +366,23 @@ Options:
362
366
  --comment github replay: comment body for comment events.
363
367
  --context github replay: commit-status context.
364
368
  --dry-run github replay: print synthesized payloads, don't POST.
365
- --out github replay: write synthesized payloads as fixtures.
369
+ --out eval / eval status <runId>: also write the full results
370
+ JSON to this path. session: write the raw NDJSON trace
371
+ there instead of printing (same format as run --events;
372
+ playground-openable). github replay: write synthesized
373
+ payloads as fixtures.
366
374
  `;
375
+ function writeStdout(text) {
376
+ return new Promise((resolve, reject) => {
377
+ process.stdout.write(text, (error) => {
378
+ if (error) {
379
+ reject(error);
380
+ return;
381
+ }
382
+ resolve();
383
+ });
384
+ });
385
+ }
367
386
  function main(argv) {
368
387
  return __awaiter(this, void 0, void 0, function* () {
369
388
  var _a, _b, _c, _d, _e, _f, _g;
@@ -373,11 +392,13 @@ function main(argv) {
373
392
  command === "help" ||
374
393
  command === "--help" ||
375
394
  command === "-h") {
376
- process.stdout.write(HELP);
395
+ // Await the write: HELP is larger than a pipe buffer, and process.exit
396
+ // after main() would otherwise truncate --help under execFile / CI.
397
+ yield writeStdout(HELP);
377
398
  return command === undefined ? 1 : 0;
378
399
  }
379
400
  if (command === "version" || command === "--version" || command === "-V") {
380
- process.stdout.write(`${CLI} ${packageVersion()}\n`);
401
+ yield writeStdout(`${CLI} ${packageVersion()}\n`);
381
402
  return 0;
382
403
  }
383
404
  // `session --events` means "dump raw events" (boolean). Rewrite so it does
@@ -403,6 +424,7 @@ function main(argv) {
403
424
  "allow-anonymous-cursor-account-mcp": { type: "boolean", default: false },
404
425
  "cursor-github-proxy": { type: "boolean", default: false },
405
426
  "no-schedules": { type: "boolean", default: false },
427
+ "no-control-plane": { type: "boolean", default: false },
406
428
  "no-playground": { type: "boolean", default: false },
407
429
  "no-docs": { type: "boolean", default: false },
408
430
  url: { type: "string" },
@@ -688,6 +710,7 @@ function main(argv) {
688
710
  apiKey: values["api-key"],
689
711
  slug: values.slug,
690
712
  bearerToken: values["bearer-token"],
713
+ out: values.out,
691
714
  }));
692
715
  }
693
716
  if (positionals[0] === "cancel" &&
@@ -725,6 +748,7 @@ function main(argv) {
725
748
  artifacts: values["no-artifacts"] ? false : values.artifacts,
726
749
  skipReport: values["skip-report"],
727
750
  maxConcurrency: parseMaxConcurrency(values["max-concurrency"]),
751
+ out: values.out,
728
752
  }));
729
753
  }
730
754
  case "chat": {
@@ -801,6 +825,7 @@ function main(argv) {
801
825
  json: values.json,
802
826
  text: values.text,
803
827
  rawEvents: values["raw-events"],
828
+ out: values.out,
804
829
  }));
805
830
  }
806
831
  case "cost": {
@@ -953,6 +978,7 @@ function main(argv) {
953
978
  : undefined,
954
979
  cursorGithubProxy: values["cursor-github-proxy"] === true ? true : undefined,
955
980
  schedules: values["no-schedules"] === true ? false : undefined,
981
+ noControlPlane: values["no-control-plane"] === true ? true : undefined,
956
982
  playground: values["no-playground"] === true ? false : undefined,
957
983
  docs: values["no-docs"] === true ? false : undefined,
958
984
  publicUrl: values["public-url"],
@@ -1080,6 +1106,7 @@ function axFromOptions(partial) {
1080
1106
  artifacts: partial.artifacts,
1081
1107
  skipReport: partial.skipReport,
1082
1108
  maxConcurrency: partial.maxConcurrency,
1109
+ out: partial.out,
1083
1110
  };
1084
1111
  }
1085
1112
  function loadMessages(messages, messagesFile) {
@@ -2,26 +2,25 @@
2
2
  * Slack auth helpers — AuthContext builders for thread-scoped sessions.
3
3
  */
4
4
  import type { AuthContext } from "../../types.js";
5
- import type { SlackBinding, SlackBlockAction, SlackMessage } from "./types.js";
6
- /**
7
- * Build a thread-scoped principal so any participant in the same Slack
8
- * thread can continue the session. The triggering user is preserved in
9
- * attributes for message context.
10
- */
11
- export declare function buildSlackAuthContext(args: {
5
+ import type { SlackBinding, SlackBlockAction, SlackMessage, SlackRespondTo } from "./types.js";
6
+ export type BuildSlackAuthArgs = {
12
7
  channelId: string;
13
8
  threadTs: string;
14
9
  teamId?: string;
15
10
  userId?: string;
16
11
  userName?: string;
17
12
  isBot?: boolean;
18
- /**
19
- * Engagement surface that started the session (e.g. `"channel_post"` for
20
- * the opt-in channel watch). Recorded as an attribute; the principal stays
21
- * thread-scoped so an @mention in the same thread continues the session.
22
- */
23
13
  engagement?: string;
24
- }): AuthContext;
14
+ /** Defaults to `"thread"`. `"author"` appends `:{userId}` to the principal. */
15
+ respondTo?: SlackRespondTo;
16
+ };
17
+ /**
18
+ * Build a Slack session principal.
19
+ *
20
+ * - `"thread"` (default): any participant can continue.
21
+ * - `"author"`: only the starter (`…:{userId}`), same shape approvals already honor.
22
+ */
23
+ export declare function buildSlackAuthContext(args: BuildSlackAuthArgs): AuthContext;
25
24
  /**
26
25
  * Auth for a Slack user clicking an interactive Approve/Deny button.
27
26
  * Uses the clicker's identity for {@link SessionEngine.resolveApproval},
@@ -42,5 +41,6 @@ export declare function buildSlackInteractiveApprovalAuth(args: {
42
41
  export declare function blockActionAuth(action: SlackBlockAction): AuthContext;
43
42
  export declare function defaultSlackAuth(message: SlackMessage, ctx: SlackBinding, options?: {
44
43
  engagement?: string;
44
+ respondTo?: SlackRespondTo;
45
45
  }): AuthContext | null;
46
46
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/E;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,WAAW,CA4Bd;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB,GAAG,WAAW,CAqBd;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAQrE;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAChC,WAAW,GAAG,IAAI,CAiBpB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,kBAAkB,GAAG,WAAW,CAiC3E;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB,GAAG,WAAW,CAqBd;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAQrE;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,YAAY,EACjB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,cAAc,CAAA;CAAE,GAC5D,WAAW,GAAG,IAAI,CAcpB"}
@@ -3,14 +3,18 @@
3
3
  */
4
4
  import { samePrincipal } from "../../internal/auth.js";
5
5
  /**
6
- * Build a thread-scoped principal so any participant in the same Slack
7
- * thread can continue the session. The triggering user is preserved in
8
- * attributes for message context.
6
+ * Build a Slack session principal.
7
+ *
8
+ * - `"thread"` (default): any participant can continue.
9
+ * - `"author"`: only the starter (`…:{userId}`), same shape approvals already honor.
9
10
  */
10
11
  export function buildSlackAuthContext(args) {
11
- var _a;
12
+ var _a, _b;
12
13
  const team = (_a = args.teamId) !== null && _a !== void 0 ? _a : "unknown";
13
- const principalId = `slack:${team}:${args.channelId}:${args.threadTs}`;
14
+ const respondTo = (_b = args.respondTo) !== null && _b !== void 0 ? _b : "thread";
15
+ const base = `slack:${team}:${args.channelId}:${args.threadTs}`;
16
+ const authorScoped = respondTo === "author" && args.userId !== undefined && args.userId !== "";
17
+ const principalId = authorScoped ? `${base}:${args.userId}` : base;
14
18
  const attributes = {
15
19
  channel_id: args.channelId,
16
20
  thread_ts: args.threadTs,
@@ -77,9 +81,14 @@ export function defaultSlackAuth(message, ctx, options) {
77
81
  if (message.author === undefined) {
78
82
  return null;
79
83
  }
80
- return buildSlackAuthContext(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ channelId: ctx.slack.channelId, threadTs: ctx.slack.threadTs }, (message.teamId === undefined ? {} : { teamId: message.teamId })), { userId: message.author.userId }), (message.author.userName === undefined
81
- ? {}
82
- : { userName: message.author.userName })), { isBot: message.author.isBot }), ((options === null || options === void 0 ? void 0 : options.engagement) === undefined
83
- ? {}
84
- : { engagement: options.engagement })));
84
+ return buildSlackAuthContext({
85
+ channelId: ctx.slack.channelId,
86
+ threadTs: ctx.slack.threadTs,
87
+ teamId: message.teamId,
88
+ userId: message.author.userId,
89
+ userName: message.author.userName,
90
+ isBot: message.author.isBot,
91
+ engagement: options === null || options === void 0 ? void 0 : options.engagement,
92
+ respondTo: options === null || options === void 0 ? void 0 : options.respondTo,
93
+ });
85
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-account.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/cursor-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAEhB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7C;AAED,wBAAgB,8BAA8B,IAAI,wBAAwB,CAezE;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,sEAAsE;AACtE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,0EAA0E;IAC1E,WAAW,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,wBAAwB,CAAC;IACpC,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,EAAE,mBAAmB,CAAC;IACrC,MAAM,EAAE,MAAM,QAAQ,CAAC;CACxB;AAID,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,yBAAyB,GACjC,IAAI,CAEN;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,GACjB,yBAAyB,GAAG,SAAS,CAEvC;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,yBAAyB,CAAC;IACnC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,YAAY,CAAC;IACxB,sBAAsB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,kBAAkB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,+BAA+B,CAAC,EAAE,CAChC,iBAAiB,EAAE,MAAM,KACtB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC,qBAAqB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEhB"}
1
+ {"version":3,"file":"cursor-account.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/cursor-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAEhB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7C;AAED,wBAAgB,8BAA8B,IAAI,wBAAwB,CAezE;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,sEAAsE;AACtE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,0EAA0E;IAC1E,WAAW,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,wBAAwB,CAAC;IACpC,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,EAAE,mBAAmB,CAAC;IACrC,MAAM,EAAE,MAAM,QAAQ,CAAC;CACxB;AAID,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,yBAAyB,GACjC,IAAI,CAEN;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,GACjB,yBAAyB,GAAG,SAAS,CAEvC;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,OAAO,EAAE,yBAAyB,CAAC;IACnC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,YAAY,CAAC;IACxB,sBAAsB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,kBAAkB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,+BAA+B,CAAC,EAAE,CAChC,iBAAiB,EAAE,MAAM,KACtB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC,qBAAqB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqEhB"}
@@ -83,7 +83,9 @@ export function dispatchCursorSlackEnvelope(args) {
83
83
  const handler = isDm ? runtime.onDirectMessage : runtime.onAppMention;
84
84
  yield dispatchInboundMessage(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind,
85
85
  message,
86
- handler, send: args.send, credentials: runtime.credentials, host: args.host, artifacts: args.artifacts, log, evalCommandsEnabled: runtime.options.evalCommands !== false, cursorAgentName: envelope.agentName }, (args.hasContinuationSession === undefined
86
+ handler, send: args.send, credentials: runtime.credentials, host: args.host, artifacts: args.artifacts, log, evalCommandsEnabled: runtime.options.evalCommands !== false, cursorAgentName: envelope.agentName,
87
+ // Backend router already refused externals for this envelope.
88
+ blockExternals: false }, (args.hasContinuationSession === undefined
87
89
  ? {}
88
90
  : { hasContinuationSession: args.hasContinuationSession })), (args.isContinuationBusy === undefined
89
91
  ? {}
@@ -3,17 +3,20 @@
3
3
  */
4
4
  import type { ChannelEventHandlers } from "../../types.js";
5
5
  import { type SlackLog } from "./log.js";
6
- import type { SlackChannelState, SlackCredentials, SlackMessageHandler, SlackSuggestedPrompt } from "./types.js";
6
+ import type { SlackAccessPolicy, SlackChannelState, SlackCredentials, SlackMessageHandler, SlackRespondTo, SlackSuggestedPrompt } from "./types.js";
7
+ export declare function resolveSlackRespondTo(policy: SlackAccessPolicy | undefined): SlackRespondTo;
8
+ /** Defaults to true when omitted. */
9
+ export declare function resolveSlackBlockExternals(policy: SlackAccessPolicy | undefined): boolean;
7
10
  /** Scrubbed turn.failed body for Slack (secrets / paths / URLs stripped). */
8
11
  export declare function formatSlackTurnFailureMessage(raw: string | undefined): string;
9
12
  /** Default mention/DM inbound handler (optional custom loading rotation). */
10
- export declare function createDefaultOnInbound(loadingMessages?: readonly string[]): SlackMessageHandler;
13
+ export declare function createDefaultOnInbound(loadingMessages?: readonly string[], policy?: SlackAccessPolicy): SlackMessageHandler;
11
14
  /**
12
15
  * Default watched-channel-post handler (optional custom loading rotation).
13
- * Same thread-scoped principal as mentions, tagged with
16
+ * Same principal policy as mentions, tagged with
14
17
  * `engagement: "channel_post"` for auth policies.
15
18
  */
16
- export declare function createDefaultOnChannelPost(loadingMessages?: readonly string[]): SlackMessageHandler;
19
+ export declare function createDefaultOnChannelPost(loadingMessages?: readonly string[], policy?: SlackAccessPolicy): SlackMessageHandler;
17
20
  export declare const defaultOnAppMention: SlackMessageHandler;
18
21
  export declare const defaultOnDirectMessage: SlackMessageHandler;
19
22
  export declare const defaultOnChannelPost: SlackMessageHandler;
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/defaults.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAe3D,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAMpB,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAS7E;AA0BD,6EAA6E;AAC7E,wBAAgB,sBAAsB,CACpC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAClC,mBAAmB,CAOrB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAClC,mBAAmB,CASrB;AAED,eAAO,MAAM,mBAAmB,EAAE,mBACR,CAAC;AAC3B,eAAO,MAAM,sBAAsB,EAAE,mBACX,CAAC;AAC3B,eAAO,MAAM,oBAAoB,EAAE,mBACL,CAAC;AAE/B,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mEAAmE;IACnE,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,QAAQ,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,oBAAoB,CAAC,iBAAiB,CAAC,CA8XzC"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/defaults.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAe3D,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAMpB,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GACpC,cAAc,CAEhB;AAED,qCAAqC;AACrC,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GACpC,OAAO,CAET;AAED,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAS7E;AA0BD,6EAA6E;AAC7E,wBAAgB,sBAAsB,CACpC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,EACnC,MAAM,CAAC,EAAE,iBAAiB,GACzB,mBAAmB,CAQrB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,EACnC,MAAM,CAAC,EAAE,iBAAiB,GACzB,mBAAmB,CAWrB;AAED,eAAO,MAAM,mBAAmB,EAAE,mBACR,CAAC;AAC3B,eAAO,MAAM,sBAAsB,EAAE,mBACX,CAAC;AAC3B,eAAO,MAAM,oBAAoB,EAAE,mBACL,CAAC;AAE/B,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mEAAmE;IACnE,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,QAAQ,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,oBAAoB,CAAC,iBAAiB,CAAC,CA8XzC"}
@@ -19,6 +19,13 @@ import { defaultSlackLog } from "./log.js";
19
19
  import { buildTaskChunkForResult, buildTaskChunksForCalls } from "./stream.js";
20
20
  const SLACK_TURN_FAILURE_FALLBACK = "I hit an error while handling your request. Please try again or rephrase.";
21
21
  const SLACK_TURN_FAILURE_MAX_CHARS = 400;
22
+ export function resolveSlackRespondTo(policy) {
23
+ return (policy === null || policy === void 0 ? void 0 : policy.respondTo) === "author" ? "author" : "thread";
24
+ }
25
+ /** Defaults to true when omitted. */
26
+ export function resolveSlackBlockExternals(policy) {
27
+ return (policy === null || policy === void 0 ? void 0 : policy.blockExternals) !== false;
28
+ }
22
29
  /** Scrubbed turn.failed body for Slack (secrets / paths / URLs stripped). */
23
30
  export function formatSlackTurnFailureMessage(raw) {
24
31
  var _a;
@@ -52,25 +59,28 @@ function resolveLoadingMessages(loadingMessages) {
52
59
  return [...SLACK_DEFAULT_LOADING_MESSAGES];
53
60
  }
54
61
  /** Default mention/DM inbound handler (optional custom loading rotation). */
55
- export function createDefaultOnInbound(loadingMessages) {
62
+ export function createDefaultOnInbound(loadingMessages, policy) {
56
63
  const rotating = resolveLoadingMessages(loadingMessages);
64
+ const respondTo = resolveSlackRespondTo(policy);
57
65
  return (ctx, message) => __awaiter(this, void 0, void 0, function* () {
58
66
  yield ctx.thread.startTyping("Thinking…", rotating);
59
- const auth = defaultSlackAuth(message, ctx);
67
+ const auth = defaultSlackAuth(message, ctx, { respondTo });
60
68
  return auth === null ? null : { auth };
61
69
  });
62
70
  }
63
71
  /**
64
72
  * Default watched-channel-post handler (optional custom loading rotation).
65
- * Same thread-scoped principal as mentions, tagged with
73
+ * Same principal policy as mentions, tagged with
66
74
  * `engagement: "channel_post"` for auth policies.
67
75
  */
68
- export function createDefaultOnChannelPost(loadingMessages) {
76
+ export function createDefaultOnChannelPost(loadingMessages, policy) {
69
77
  const rotating = resolveLoadingMessages(loadingMessages);
78
+ const respondTo = resolveSlackRespondTo(policy);
70
79
  return (ctx, message) => __awaiter(this, void 0, void 0, function* () {
71
80
  yield ctx.thread.startTyping("Thinking…", rotating);
72
81
  const auth = defaultSlackAuth(message, ctx, {
73
82
  engagement: "channel_post",
83
+ respondTo,
74
84
  });
75
85
  return auth === null ? null : { auth };
76
86
  });
@@ -38,6 +38,11 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
38
38
  evalCommandsEnabled?: boolean;
39
39
  /** cursorAccount agent name stripped before `eval` directive parsing. */
40
40
  cursorAgentName?: string;
41
+ /**
42
+ * Drop external senders before the handler. Defaults to `true`; pass
43
+ * `false` to admit them (or when an upstream gate already refused them).
44
+ */
45
+ blockExternals?: boolean;
41
46
  }
42
47
  export declare function dispatchInboundMessage(args: {
43
48
  kind: "app_mention" | "direct_message" | "channel_post" | "block_action";
@@ -59,6 +64,7 @@ export declare function dispatchInboundMessage(args: {
59
64
  * (`OncallBuddy eval list`).
60
65
  */
61
66
  cursorAgentName?: string;
67
+ blockExternals?: boolean;
62
68
  }): Promise<void>;
63
69
  /**
64
70
  * Parse an Events API body (or Socket Mode `events_api` payload) and dispatch
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/dispatch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EAEX,aAAa,EACd,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAK7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAO1D,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAM1D,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAEhB,YAAY,EACZ,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAIpB,uCAAuC;AACvC,wBAAgB,sBAAsB,CACpC,KAAK,GAAE,OAAO,CAAC,iBAAiB,CAAM,GACrC,iBAAiB,CAiBnB;AAED,MAAM,WAAW,wBAAyB,SAAQ,uBAAuB;IACvE,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAC/C,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,EAAE,mBAAmB,CAAC;IACrC,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,6EAA6E;IAC7E,SAAS,EAAE,YAAY,CAAC;IACxB,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,qDAAqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uDAAuD;IACvD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gEAAgE;IAChE,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAmBD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,IAAI,EAAE,aAAa,GAAG,gBAAgB,GAAG,cAAc,GAAG,cAAc,CAAC;IACzE,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,YAAY,CAAC;IACxB,sBAAsB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,kBAAkB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,+BAA+B,CAAC,EAAE,CAChC,iBAAiB,EAAE,MAAM,KACtB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC,qBAAqB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CA4QhB;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAgIT"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/dispatch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EAEX,aAAa,EACd,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAK7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQ1D,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAM1D,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAEhB,YAAY,EACZ,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAIpB,uCAAuC;AACvC,wBAAgB,sBAAsB,CACpC,KAAK,GAAE,OAAO,CAAC,iBAAiB,CAAM,GACrC,iBAAiB,CAiBnB;AAED,MAAM,WAAW,wBAAyB,SAAQ,uBAAuB;IACvE,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAC/C,YAAY,EAAE,mBAAmB,CAAC;IAClC,eAAe,EAAE,mBAAmB,CAAC;IACrC,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,6EAA6E;IAC7E,SAAS,EAAE,YAAY,CAAC;IACxB,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,qDAAqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uDAAuD;IACvD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gEAAgE;IAChE,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAmBD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,IAAI,EAAE,aAAa,GAAG,gBAAgB,GAAG,cAAc,GAAG,cAAc,CAAC;IACzE,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,YAAY,CAAC;IACxB,sBAAsB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,kBAAkB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,+BAA+B,CAAC,EAAE,CAChC,iBAAiB,EAAE,MAAM,KACtB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjC,qBAAqB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CA4ShB;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAkIT"}
@@ -13,6 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
13
13
  import { buildSlackBinding, slackContinuationKey } from "./api.js";
14
14
  import { firstLineTitle, maybeSetThreadTitle } from "./assistant.js";
15
15
  import { handleSlackEvalDirective, parseSlackEvalDirective, } from "./eval-directive.js";
16
+ import { isExternalSlackSender } from "./external-policy.js";
16
17
  import { formatSlackContextBlock, parseAppMentionEvent, parseChannelMessageEvent, parseDirectMessageEvent, } from "./inbound.js";
17
18
  import { defaultSlackLog } from "./log.js";
18
19
  import { isWholeMessageStop } from "./stop.js";
@@ -35,11 +36,19 @@ function triggeringMergeMessage(message) {
35
36
  }
36
37
  export function dispatchInboundMessage(args) {
37
38
  return __awaiter(this, void 0, void 0, function* () {
38
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
39
- var _m, _o, _p, _q, _r, _s, _t, _u, _v;
39
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
40
+ var _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
40
41
  const { message, kind } = args;
41
- const log = (_m = args.log) !== null && _m !== void 0 ? _m : defaultSlackLog;
42
- const binding = buildSlackBinding(Object.assign({ botToken: (_a = args.credentials) === null || _a === void 0 ? void 0 : _a.botToken, channelId: message.channelId, threadTs: message.threadTs, host: args.host, artifacts: args.artifacts, log }, (message.teamId === undefined ? {} : { teamId: message.teamId })));
42
+ const log = (_q = args.log) !== null && _q !== void 0 ? _q : defaultSlackLog;
43
+ const binding = buildSlackBinding({
44
+ botToken: (_a = args.credentials) === null || _a === void 0 ? void 0 : _a.botToken,
45
+ channelId: message.channelId,
46
+ threadTs: message.threadTs,
47
+ host: args.host,
48
+ artifacts: args.artifacts,
49
+ log,
50
+ teamId: message.teamId,
51
+ });
43
52
  log.info("inbound", {
44
53
  kind,
45
54
  event_id: args.eventId,
@@ -49,6 +58,35 @@ export function dispatchInboundMessage(args) {
49
58
  user: (_b = message.author) === null || _b === void 0 ? void 0 : _b.userId,
50
59
  team: message.teamId,
51
60
  });
61
+ if (args.blockExternals !== false && ((_c = message.author) === null || _c === void 0 ? void 0 : _c.isBot) !== true) {
62
+ const userId = (_r = (_d = message.author) === null || _d === void 0 ? void 0 : _d.userId) !== null && _r !== void 0 ? _r : "";
63
+ const teamId = message.teamId;
64
+ if (teamId === undefined || teamId === "") {
65
+ log.info("inbound dropped (missing team)", {
66
+ kind,
67
+ channel: message.channelId,
68
+ thread_ts: message.threadTs,
69
+ user: userId,
70
+ event_id: args.eventId,
71
+ });
72
+ return;
73
+ }
74
+ if (yield isExternalSlackSender({
75
+ botToken: (_e = args.credentials) === null || _e === void 0 ? void 0 : _e.botToken,
76
+ slackTeamId: teamId,
77
+ userId,
78
+ })) {
79
+ log.info("inbound dropped (external sender)", {
80
+ kind,
81
+ channel: message.channelId,
82
+ thread_ts: message.threadTs,
83
+ user: userId,
84
+ team: teamId,
85
+ event_id: args.eventId,
86
+ });
87
+ return;
88
+ }
89
+ }
52
90
  const continuation = slackContinuationKey(message.channelId, message.threadTs);
53
91
  // Whole-message stop: cancel active turn + clear nudges (Benny parity).
54
92
  if (isWholeMessageStop(message.text) ||
@@ -60,14 +98,14 @@ export function dispatchInboundMessage(args) {
60
98
  continuation,
61
99
  event_id: args.eventId,
62
100
  });
63
- yield (_c = args.host.slackNudges) === null || _c === void 0 ? void 0 : _c.clear(continuation);
101
+ yield (_f = args.host.slackNudges) === null || _f === void 0 ? void 0 : _f.clear(continuation);
64
102
  const interrupted = args.interruptContinuation === undefined
65
103
  ? false
66
104
  : yield args.interruptContinuation(continuation);
67
105
  try {
68
106
  yield binding.thread.startTyping(interrupted ? "Stopped." : "Nothing to stop.");
69
107
  }
70
- catch (_w) {
108
+ catch (_0) {
71
109
  // best-effort status
72
110
  }
73
111
  return;
@@ -78,7 +116,7 @@ export function dispatchInboundMessage(args) {
78
116
  ? undefined
79
117
  : { agentName: args.cursorAgentName };
80
118
  const evalDirective = evalCommandsEnabled && args.host.evals !== undefined
81
- ? ((_o = parseSlackEvalDirective(message.text, evalParseOptions)) !== null && _o !== void 0 ? _o : parseSlackEvalDirective(message.markdown, evalParseOptions))
119
+ ? ((_s = parseSlackEvalDirective(message.text, evalParseOptions)) !== null && _s !== void 0 ? _s : parseSlackEvalDirective(message.markdown, evalParseOptions))
82
120
  : null;
83
121
  if (evalDirective !== null && args.host.evals !== undefined) {
84
122
  log.info("eval directive", {
@@ -98,7 +136,7 @@ export function dispatchInboundMessage(args) {
98
136
  }
99
137
  if (message.ts === message.threadTs) {
100
138
  yield maybeSetThreadTitle({
101
- botToken: (_d = args.credentials) === null || _d === void 0 ? void 0 : _d.botToken,
139
+ botToken: (_g = args.credentials) === null || _g === void 0 ? void 0 : _g.botToken,
102
140
  channelId: message.channelId,
103
141
  threadTs: message.threadTs,
104
142
  title: firstLineTitle(message.markdown),
@@ -128,7 +166,7 @@ export function dispatchInboundMessage(args) {
128
166
  return;
129
167
  }
130
168
  // Reply-once / delayed parent: claim channel:ts after the handler accepts.
131
- const claimed = yield (_e = args.host.slackNudges) === null || _e === void 0 ? void 0 : _e.tryClaimAsk(message.channelId, message.ts);
169
+ const claimed = yield (_h = args.host.slackNudges) === null || _h === void 0 ? void 0 : _h.tryClaimAsk(message.channelId, message.ts);
132
170
  if (claimed === false) {
133
171
  log.info("inbound ask dedupe drop", {
134
172
  kind,
@@ -139,10 +177,10 @@ export function dispatchInboundMessage(args) {
139
177
  });
140
178
  return;
141
179
  }
142
- const userText = (_p = decision.message) !== null && _p !== void 0 ? _p : message.markdown;
180
+ const userText = (_t = decision.message) !== null && _t !== void 0 ? _t : message.markdown;
143
181
  const excludeThreadTimestamps = [
144
182
  message.ts,
145
- ...((_q = decision.excludeThreadTimestamps) !== null && _q !== void 0 ? _q : []),
183
+ ...((_u = decision.excludeThreadTimestamps) !== null && _u !== void 0 ? _u : []),
146
184
  ];
147
185
  const hasSession = args.hasContinuationSession === undefined
148
186
  ? false
@@ -154,10 +192,10 @@ export function dispatchInboundMessage(args) {
154
192
  // Cold start: full <slack_thread>. Warm: <slack_thread_delta> since last
155
193
  // agent post (session watermark), else last matching bot post in-thread.
156
194
  const threadContext = hasSession
157
- ? yield loadSlackThreadDeltaBlock(Object.assign(Object.assign({ botToken: (_f = args.credentials) === null || _f === void 0 ? void 0 : _f.botToken, channelId: message.channelId, threadTs: message.threadTs }, (afterTs === undefined ? {} : { afterTs })), { excludeTs: excludeThreadTimestamps, mergeMessages,
195
+ ? yield loadSlackThreadDeltaBlock(Object.assign(Object.assign({ botToken: (_j = args.credentials) === null || _j === void 0 ? void 0 : _j.botToken, channelId: message.channelId, threadTs: message.threadTs }, (afterTs === undefined ? {} : { afterTs })), { excludeTs: excludeThreadTimestamps, mergeMessages,
158
196
  log }))
159
197
  : yield loadSlackThreadContextBlock({
160
- botToken: (_g = args.credentials) === null || _g === void 0 ? void 0 : _g.botToken,
198
+ botToken: (_k = args.credentials) === null || _k === void 0 ? void 0 : _k.botToken,
161
199
  channelId: message.channelId,
162
200
  threadTs: message.threadTs,
163
201
  excludeTs: excludeThreadTimestamps,
@@ -168,11 +206,11 @@ export function dispatchInboundMessage(args) {
168
206
  log.info(hasSession ? "thread delta loaded" : "thread context loaded", Object.assign({ kind, channel: message.channelId, thread_ts: message.threadTs, chars: threadContext.length, event_id: args.eventId }, (afterTs === undefined ? {} : { after_ts: afterTs })));
169
207
  }
170
208
  const prompt = [
171
- formatSlackContextBlock(Object.assign(Object.assign({ userId: (_r = (_h = message.author) === null || _h === void 0 ? void 0 : _h.userId) !== null && _r !== void 0 ? _r : "", channelId: message.channelId, threadTs: message.threadTs }, (((_j = message.author) === null || _j === void 0 ? void 0 : _j.userName) === undefined
209
+ formatSlackContextBlock(Object.assign(Object.assign({ userId: (_v = (_l = message.author) === null || _l === void 0 ? void 0 : _l.userId) !== null && _v !== void 0 ? _v : "", channelId: message.channelId, threadTs: message.threadTs }, (((_m = message.author) === null || _m === void 0 ? void 0 : _m.userName) === undefined
172
210
  ? {}
173
211
  : { userName: message.author.userName })), (message.teamId === undefined ? {} : { teamId: message.teamId }))),
174
212
  ...(threadContext === undefined ? [] : [threadContext]),
175
- ...((_s = decision.context) !== null && _s !== void 0 ? _s : []),
213
+ ...((_w = decision.context) !== null && _w !== void 0 ? _w : []),
176
214
  "",
177
215
  userText,
178
216
  ]
@@ -186,10 +224,10 @@ export function dispatchInboundMessage(args) {
186
224
  state: emptySlackChannelState({
187
225
  channelId: message.channelId,
188
226
  threadTs: message.threadTs,
189
- teamId: (_t = message.teamId) !== null && _t !== void 0 ? _t : null,
190
- triggeringUserId: (_u = (_k = message.author) === null || _k === void 0 ? void 0 : _k.userId) !== null && _u !== void 0 ? _u : null,
227
+ teamId: (_x = message.teamId) !== null && _x !== void 0 ? _x : null,
228
+ triggeringUserId: (_y = (_o = message.author) === null || _o === void 0 ? void 0 : _o.userId) !== null && _y !== void 0 ? _y : null,
191
229
  }),
192
- title: (_v = decision.title) !== null && _v !== void 0 ? _v : `slack:${message.channelId}:${message.threadTs}`,
230
+ title: (_z = decision.title) !== null && _z !== void 0 ? _z : `slack:${message.channelId}:${message.threadTs}`,
193
231
  workspaceDir: decision.workspaceDir,
194
232
  workspaceFiles: decision.workspaceFiles,
195
233
  cloud: decision.cloud,
@@ -232,7 +270,7 @@ export function dispatchInboundMessage(args) {
232
270
  }
233
271
  }
234
272
  catch (error) {
235
- yield (_l = args.host.slackNudges) === null || _l === void 0 ? void 0 : _l.releaseAsk(message.channelId, message.ts);
273
+ yield (_p = args.host.slackNudges) === null || _p === void 0 ? void 0 : _p.releaseAsk(message.channelId, message.ts);
236
274
  log.error(`${kind} delivery failed: ${error instanceof Error ? error.message : String(error)}`, {
237
275
  channel: message.channelId,
238
276
  thread_ts: message.threadTs,
@@ -288,7 +326,7 @@ export function dispatchInboundFromEventBody(body, deps) {
288
326
  return false;
289
327
  }
290
328
  }
291
- deps.waitUntil(dispatchInboundMessage(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind: "app_mention", message: mention, handler: deps.onAppMention, send: deps.send, credentials: deps.credentials, host: deps.host, artifacts: deps.artifacts, log, evalCommandsEnabled: deps.evalCommandsEnabled, cursorAgentName: deps.cursorAgentName }, (deps.hasContinuationSession === undefined
329
+ deps.waitUntil(dispatchInboundMessage(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind: "app_mention", message: mention, handler: deps.onAppMention, send: deps.send, credentials: deps.credentials, host: deps.host, artifacts: deps.artifacts, log, evalCommandsEnabled: deps.evalCommandsEnabled, cursorAgentName: deps.cursorAgentName, blockExternals: deps.blockExternals }, (deps.hasContinuationSession === undefined
292
330
  ? {}
293
331
  : { hasContinuationSession: deps.hasContinuationSession })), (deps.isContinuationBusy === undefined
294
332
  ? {}
@@ -309,7 +347,7 @@ export function dispatchInboundFromEventBody(body, deps) {
309
347
  });
310
348
  return false;
311
349
  }
312
- deps.waitUntil(dispatchInboundMessage(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind: "direct_message", message: dm, handler: deps.onDirectMessage, send: deps.send, credentials: deps.credentials, host: deps.host, artifacts: deps.artifacts, log, evalCommandsEnabled: deps.evalCommandsEnabled, cursorAgentName: deps.cursorAgentName }, (deps.hasContinuationSession === undefined
350
+ deps.waitUntil(dispatchInboundMessage(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind: "direct_message", message: dm, handler: deps.onDirectMessage, send: deps.send, credentials: deps.credentials, host: deps.host, artifacts: deps.artifacts, log, evalCommandsEnabled: deps.evalCommandsEnabled, cursorAgentName: deps.cursorAgentName, blockExternals: deps.blockExternals }, (deps.hasContinuationSession === undefined
313
351
  ? {}
314
352
  : { hasContinuationSession: deps.hasContinuationSession })), (deps.isContinuationBusy === undefined
315
353
  ? {}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Workspace-membership checks for AgentKit Slack agents.
3
+ * Mirrors backend `isExternalSlackUser` (cloud-agent/slack/externalChannelPolicy).
4
+ */
5
+ import type { SlackBotToken } from "./types.js";
6
+ type SlackUserInfo = {
7
+ team_id?: string;
8
+ is_stranger?: boolean;
9
+ is_restricted?: boolean;
10
+ is_ultra_restricted?: boolean;
11
+ enterprise_user?: {
12
+ teams?: string[];
13
+ };
14
+ };
15
+ /** Pure classifier over a `users.info` user object. Fails open to external. */
16
+ export declare function classifySlackUserExternality(args: {
17
+ slackTeamId: string;
18
+ user: SlackUserInfo;
19
+ }): boolean;
20
+ /** Lookup + classify. Empty userId / API failure → external. */
21
+ export declare function isExternalSlackSender(args: {
22
+ botToken: SlackBotToken | undefined;
23
+ slackTeamId: string;
24
+ userId: string;
25
+ }): Promise<boolean>;
26
+ export {};
27
+ //# sourceMappingURL=external-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-policy.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/external-policy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACxC,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,aAAa,CAAC;CACrB,GAAG,OAAO,CAcV;AAED,gEAAgE;AAChE,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,QAAQ,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBnB"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Workspace-membership checks for AgentKit Slack agents.
3
+ * Mirrors backend `isExternalSlackUser` (cloud-agent/slack/externalChannelPolicy).
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ import { callSlackApi } from "./api.js";
15
+ /** Pure classifier over a `users.info` user object. Fails open to external. */
16
+ export function classifySlackUserExternality(args) {
17
+ var _a;
18
+ var _b;
19
+ const { slackTeamId, user } = args;
20
+ if (user.is_stranger === true ||
21
+ user.is_restricted === true ||
22
+ user.is_ultra_restricted === true) {
23
+ return true;
24
+ }
25
+ return (user.team_id !== undefined &&
26
+ user.team_id !== slackTeamId &&
27
+ !((_b = (_a = user.enterprise_user) === null || _a === void 0 ? void 0 : _a.teams) !== null && _b !== void 0 ? _b : []).includes(slackTeamId));
28
+ }
29
+ /** Lookup + classify. Empty userId / API failure → external. */
30
+ export function isExternalSlackSender(args) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ if (args.userId === "") {
33
+ return true;
34
+ }
35
+ try {
36
+ const result = yield callSlackApi({
37
+ botToken: args.botToken,
38
+ operation: "users.info",
39
+ body: { user: args.userId },
40
+ });
41
+ if (result.ok !== true || result.user === undefined) {
42
+ return true;
43
+ }
44
+ return classifySlackUserExternality({
45
+ slackTeamId: args.slackTeamId,
46
+ user: result.user,
47
+ });
48
+ }
49
+ catch (_a) {
50
+ return true;
51
+ }
52
+ });
53
+ }