cli-jaw 2.17.43 → 2.17.44

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 (223) hide show
  1. package/README.md +13 -2
  2. package/dist/bin/commands/slack.js +73 -7
  3. package/dist/bin/commands/slack.js.map +1 -1
  4. package/dist/server.js +46 -1
  5. package/dist/server.js.map +1 -1
  6. package/dist/src/agent/calendar-context.js +23 -0
  7. package/dist/src/agent/calendar-context.js.map +1 -0
  8. package/dist/src/agent/claude-runtime-run.js +10 -1
  9. package/dist/src/agent/claude-runtime-run.js.map +1 -1
  10. package/dist/src/agent/cursor-acp-models.js +139 -0
  11. package/dist/src/agent/cursor-acp-models.js.map +1 -0
  12. package/dist/src/agent/events/cursor.js +28 -4
  13. package/dist/src/agent/events/cursor.js.map +1 -1
  14. package/dist/src/agent/lifecycle-handler.js +8 -2
  15. package/dist/src/agent/lifecycle-handler.js.map +1 -1
  16. package/dist/src/agent/native-runtime-run.js +22 -1
  17. package/dist/src/agent/native-runtime-run.js.map +1 -1
  18. package/dist/src/agent/runtime/acp/config.js +76 -11
  19. package/dist/src/agent/runtime/acp/config.js.map +1 -1
  20. package/dist/src/agent/runtime/acp/cursor-session.js +6 -1
  21. package/dist/src/agent/runtime/acp/cursor-session.js.map +1 -1
  22. package/dist/src/agent/runtime/liveness.js +24 -0
  23. package/dist/src/agent/runtime/liveness.js.map +1 -0
  24. package/dist/src/agent/runtime/start-failure.js +61 -0
  25. package/dist/src/agent/runtime/start-failure.js.map +1 -0
  26. package/dist/src/agent/spawn/queue.js +11 -6
  27. package/dist/src/agent/spawn/queue.js.map +1 -1
  28. package/dist/src/agent/spawn.js +59 -17
  29. package/dist/src/agent/spawn.js.map +1 -1
  30. package/dist/src/cli/api-auth.js +6 -0
  31. package/dist/src/cli/api-auth.js.map +1 -1
  32. package/dist/src/manager/design/watcher.js +10 -2
  33. package/dist/src/manager/design/watcher.js.map +1 -1
  34. package/dist/src/memory/heartbeat.js +6 -0
  35. package/dist/src/memory/heartbeat.js.map +1 -1
  36. package/dist/src/messaging/channel-validate.js +5 -3
  37. package/dist/src/messaging/channel-validate.js.map +1 -1
  38. package/dist/src/messaging/redact.js +30 -8
  39. package/dist/src/messaging/redact.js.map +1 -1
  40. package/dist/src/messaging/send.js +7 -0
  41. package/dist/src/messaging/send.js.map +1 -1
  42. package/dist/src/orchestrator/collect.js +5 -3
  43. package/dist/src/orchestrator/collect.js.map +1 -1
  44. package/dist/src/orchestrator/gateway.js +10 -3
  45. package/dist/src/orchestrator/gateway.js.map +1 -1
  46. package/dist/src/orchestrator/pipeline.js +21 -9
  47. package/dist/src/orchestrator/pipeline.js.map +1 -1
  48. package/dist/src/orchestrator/request-registry.js +2 -0
  49. package/dist/src/orchestrator/request-registry.js.map +1 -1
  50. package/dist/src/prompt/builder.js +74 -6
  51. package/dist/src/prompt/builder.js.map +1 -1
  52. package/dist/src/prompt/templates/a1-system.md +22 -5
  53. package/dist/src/routes/messaging.js +105 -27
  54. package/dist/src/routes/messaging.js.map +1 -1
  55. package/dist/src/routes/settings.js +20 -8
  56. package/dist/src/routes/settings.js.map +1 -1
  57. package/dist/src/routes/slack-tools.js +176 -0
  58. package/dist/src/routes/slack-tools.js.map +1 -0
  59. package/dist/src/slack/action-rate.js +43 -0
  60. package/dist/src/slack/action-rate.js.map +1 -0
  61. package/dist/src/slack/action-runtime.js +243 -0
  62. package/dist/src/slack/action-runtime.js.map +1 -0
  63. package/dist/src/slack/action-store.js +84 -0
  64. package/dist/src/slack/action-store.js.map +1 -0
  65. package/dist/src/slack/action-types.js +6 -0
  66. package/dist/src/slack/action-types.js.map +1 -0
  67. package/dist/src/slack/actions-canvas.js +108 -0
  68. package/dist/src/slack/actions-canvas.js.map +1 -0
  69. package/dist/src/slack/actions-channel.js +88 -0
  70. package/dist/src/slack/actions-channel.js.map +1 -0
  71. package/dist/src/slack/actions-interactions.js +204 -0
  72. package/dist/src/slack/actions-interactions.js.map +1 -0
  73. package/dist/src/slack/actions-lists.js +308 -0
  74. package/dist/src/slack/actions-lists.js.map +1 -0
  75. package/dist/src/slack/actions-message.js +117 -0
  76. package/dist/src/slack/actions-message.js.map +1 -0
  77. package/dist/src/slack/actions-resources.js +62 -0
  78. package/dist/src/slack/actions-resources.js.map +1 -0
  79. package/dist/src/slack/actions-rts.js +88 -0
  80. package/dist/src/slack/actions-rts.js.map +1 -0
  81. package/dist/src/slack/actions-schedule.js +214 -0
  82. package/dist/src/slack/actions-schedule.js.map +1 -0
  83. package/dist/src/slack/actions.js +17 -0
  84. package/dist/src/slack/actions.js.map +1 -0
  85. package/dist/src/slack/api.js +56 -9
  86. package/dist/src/slack/api.js.map +1 -1
  87. package/dist/src/slack/blocks.js +162 -0
  88. package/dist/src/slack/blocks.js.map +1 -0
  89. package/dist/src/slack/bot.js +562 -378
  90. package/dist/src/slack/bot.js.map +1 -1
  91. package/dist/src/slack/commands.js +24 -5
  92. package/dist/src/slack/commands.js.map +1 -1
  93. package/dist/src/slack/context.js +15 -4
  94. package/dist/src/slack/context.js.map +1 -1
  95. package/dist/src/slack/conversation.js +135 -33
  96. package/dist/src/slack/conversation.js.map +1 -1
  97. package/dist/src/slack/events.js +41 -17
  98. package/dist/src/slack/events.js.map +1 -1
  99. package/dist/src/slack/format.js +181 -0
  100. package/dist/src/slack/format.js.map +1 -1
  101. package/dist/src/slack/history.js +133 -8
  102. package/dist/src/slack/history.js.map +1 -1
  103. package/dist/src/slack/ingress.js +26 -9
  104. package/dist/src/slack/ingress.js.map +1 -1
  105. package/dist/src/slack/interaction-store.js +56 -0
  106. package/dist/src/slack/interaction-store.js.map +1 -0
  107. package/dist/src/slack/manifest.js +3 -0
  108. package/dist/src/slack/manifest.js.map +1 -1
  109. package/dist/src/slack/message-content.js +132 -0
  110. package/dist/src/slack/message-content.js.map +1 -0
  111. package/dist/src/slack/message.js +58 -0
  112. package/dist/src/slack/message.js.map +1 -0
  113. package/dist/src/slack/notice-transport.js +49 -19
  114. package/dist/src/slack/notice-transport.js.map +1 -1
  115. package/dist/src/slack/operator-auth.js +62 -0
  116. package/dist/src/slack/operator-auth.js.map +1 -0
  117. package/dist/src/slack/progress-activity.js +210 -0
  118. package/dist/src/slack/progress-activity.js.map +1 -0
  119. package/dist/src/slack/progress-detail.js +473 -0
  120. package/dist/src/slack/progress-detail.js.map +1 -0
  121. package/dist/src/slack/progress-files.js +70 -0
  122. package/dist/src/slack/progress-files.js.map +1 -0
  123. package/dist/src/slack/progress-lifecycle.js +223 -0
  124. package/dist/src/slack/progress-lifecycle.js.map +1 -0
  125. package/dist/src/slack/progress-restore.js +81 -0
  126. package/dist/src/slack/progress-restore.js.map +1 -0
  127. package/dist/src/slack/progress.js +325 -143
  128. package/dist/src/slack/progress.js.map +1 -1
  129. package/dist/src/slack/quote.js +227 -0
  130. package/dist/src/slack/quote.js.map +1 -0
  131. package/dist/src/slack/render-features.js +105 -0
  132. package/dist/src/slack/render-features.js.map +1 -0
  133. package/dist/src/slack/reply-delivery.js +110 -0
  134. package/dist/src/slack/reply-delivery.js.map +1 -0
  135. package/dist/src/slack/rts-output-store.js +143 -0
  136. package/dist/src/slack/rts-output-store.js.map +1 -0
  137. package/dist/src/slack/scope-status.js +17 -3
  138. package/dist/src/slack/scope-status.js.map +1 -1
  139. package/dist/src/slack/search-quote.js +70 -0
  140. package/dist/src/slack/search-quote.js.map +1 -0
  141. package/dist/src/slack/search.js +54 -0
  142. package/dist/src/slack/search.js.map +1 -0
  143. package/dist/src/slack/send-handler.js +11 -7
  144. package/dist/src/slack/send-handler.js.map +1 -1
  145. package/dist/src/slack/send-only-client.js +116 -79
  146. package/dist/src/slack/send-only-client.js.map +1 -1
  147. package/dist/src/slack/table-content.js +253 -0
  148. package/dist/src/slack/table-content.js.map +1 -0
  149. package/dist/src/slack/table-verification.js +64 -0
  150. package/dist/src/slack/table-verification.js.map +1 -0
  151. package/dist/src/slack/task-input.js +55 -0
  152. package/dist/src/slack/task-input.js.map +1 -0
  153. package/dist/src/slack/tool-access.js +127 -0
  154. package/dist/src/slack/tool-access.js.map +1 -0
  155. package/dist/src/slack/tool-capabilities.js +47 -0
  156. package/dist/src/slack/tool-capabilities.js.map +1 -0
  157. package/dist/src/slack/tool-context.js +91 -0
  158. package/dist/src/slack/tool-context.js.map +1 -0
  159. package/dist/src/slack/verified-workspace.js +17 -6
  160. package/dist/src/slack/verified-workspace.js.map +1 -1
  161. package/dist/src/trace/redact.js +2 -1
  162. package/dist/src/trace/redact.js.map +1 -1
  163. package/package.json +1 -1
  164. package/public/dist/.vite/manifest.json +102 -102
  165. package/public/dist/assets/{Agent-CQ4EBgY8.js → Agent-CNad_A6t.js} +1 -1
  166. package/public/dist/assets/{ChannelEnablementControl-JsYvNMlM.js → ChannelEnablementControl-DwUDKjX9.js} +4 -4
  167. package/public/dist/assets/{ChannelSetupEntry-BpyRWEUE.js → ChannelSetupEntry-DH0AuNNX.js} +1 -1
  168. package/public/dist/assets/{ChannelsDiscord-DNfvz1jn.js → ChannelsDiscord-7NmoTjR7.js} +1 -1
  169. package/public/dist/assets/{ChannelsSlack-DzpxIdgW.js → ChannelsSlack-Ba0ax6iT.js} +1 -1
  170. package/public/dist/assets/{ChannelsTelegram-CUhFc5s6.js → ChannelsTelegram-DKA9atf2.js} +1 -1
  171. package/public/dist/assets/{app-Q0prKOFx.js → app-9OQNfmqw.js} +4 -4
  172. package/public/dist/assets/{bgtask-badge-DAcWaUfS.js → bgtask-badge-BvxHqMGi.js} +1 -1
  173. package/public/dist/assets/bgtask-badge-DeSZJGNN.js +1 -0
  174. package/public/dist/assets/{employees-CWS3Juca.js → employees-CkUqN4oh.js} +1 -1
  175. package/public/dist/assets/{iframe-renderer-DCDKBMb7.js → iframe-renderer-C2gchtOj.js} +2 -2
  176. package/public/dist/assets/iframe-renderer-DfvACXIn.js +1 -0
  177. package/public/dist/assets/{manager-v6GYfoPB.js → manager-rb5X-4DJ.js} +1 -1
  178. package/public/dist/assets/{memory-DhNdKZLO.js → memory-BiWzpoBq.js} +1 -1
  179. package/public/dist/assets/memory-Ckp1Eq5a.js +1 -0
  180. package/public/dist/assets/message-history-Bv0l_t7O.js +1 -0
  181. package/public/dist/assets/{message-history-DbRTl1P0.js → message-history-CuFefS02.js} +1 -1
  182. package/public/dist/assets/{render-DP8SJtdZ.js → render-DUGqq9Mu.js} +1 -1
  183. package/public/dist/assets/{settings-85n9NjvX.js → settings-BqUHavbH.js} +1 -1
  184. package/public/dist/assets/settings-C81Kf9uX.js +1 -0
  185. package/public/dist/assets/{settings-C9_D-pn0.js → settings-DQ1fLygB.js} +31 -30
  186. package/public/dist/assets/{settings-core-BcVD2FgV.js → settings-core-CzdXfoOK.js} +1 -1
  187. package/public/dist/assets/settings-core-DO_5M7Lv.js +1 -0
  188. package/public/dist/assets/{settings-embedding-BSpq785l.js → settings-embedding-BAKFrVLV.js} +1 -1
  189. package/public/dist/assets/{settings-types-B09BmpYe.js → settings-types-D3cd6SWy.js} +1 -1
  190. package/public/dist/assets/{sidebar-BVhLb5Ft.js → sidebar-CvGbp9x5.js} +3 -3
  191. package/public/dist/assets/skills-DFpPmMUR.js +1 -0
  192. package/public/dist/assets/{skills-X7qxmHka.js → skills-abLMqY5_.js} +1 -1
  193. package/public/dist/assets/slash-commands-BU58xYih.js +1 -0
  194. package/public/dist/assets/{slash-commands-BnDH4IU_.js → slash-commands-D8o9pqOS.js} +1 -1
  195. package/public/dist/assets/{trace-drawer-DasaS1z4.js → trace-drawer-C6RvkUAd.js} +1 -1
  196. package/public/dist/assets/{ui-BtiBTXng.js → ui-Bxapl_Eu.js} +1 -1
  197. package/public/dist/assets/ui-CUB4iwz3.js +1 -0
  198. package/public/dist/index.html +1 -1
  199. package/public/dist/manager/index.html +1 -1
  200. package/public/dist/settings/index.html +1 -1
  201. package/public/js/features/settings-cli-status.ts +11 -1
  202. package/public/js/features/settings-types.ts +21 -0
  203. package/public/locales/en.json +34 -1
  204. package/public/locales/ja.json +34 -1
  205. package/public/locales/ko.json +34 -1
  206. package/public/locales/zh.json +34 -1
  207. package/scripts/check-native-load.cjs +17 -4
  208. package/scripts/release-gates.mjs +84 -3
  209. package/scripts/service-artifact.mjs +157 -0
  210. package/scripts/service-shell/zsh/.zlogin +23 -0
  211. package/scripts/service-shell/zsh/.zlogout +23 -0
  212. package/scripts/service-shell/zsh/.zprofile +23 -0
  213. package/scripts/service-shell/zsh/.zshenv +23 -0
  214. package/scripts/service-shell/zsh/.zshrc +23 -0
  215. package/public/dist/assets/bgtask-badge-DHA2OQm8.js +0 -1
  216. package/public/dist/assets/iframe-renderer-RpvBly2x.js +0 -1
  217. package/public/dist/assets/memory-4YH8sz0L.js +0 -1
  218. package/public/dist/assets/message-history-lVcLpAw8.js +0 -1
  219. package/public/dist/assets/settings--EGy3_B9.js +0 -1
  220. package/public/dist/assets/settings-core-8wBl1mg-.js +0 -1
  221. package/public/dist/assets/skills-6GFkHTlQ.js +0 -1
  222. package/public/dist/assets/slash-commands-qu8fPAZ3.js +0 -1
  223. package/public/dist/assets/ui-BucJ1zMA.js +0 -1
@@ -0,0 +1,243 @@
1
+ import { slackDataForAgent } from './history.js';
2
+ import { getRtsOutputStore, isRtsOutput } from './rts-output-store.js';
3
+ import { createHash } from 'node:crypto';
4
+ import { SlackActionRateLimiter } from './action-rate.js';
5
+ import { slackApi, addSlackReaction, removeSlackReaction, deleteSlackMessage, readBoundedResponse } from './api.js';
6
+ import { readSlackAuthSnapshot } from './verified-workspace.js';
7
+ import { slackCredentialKey } from './tool-context.js';
8
+ import { slackToolDenied, withSlackToolAccess } from './tool-access.js';
9
+ import { redactOutboundPayload } from '../messaging/redact.js';
10
+ import { validateSlackDownloadUrl } from './inbound-url.js';
11
+ const WRITE_METHODS = new Set(['reactions.add', 'reactions.remove', 'chat.update', 'chat.delete', 'chat.postMessage', 'chat.scheduleMessage', 'chat.deleteScheduledMessage', 'pins.add', 'pins.remove', 'bookmarks.add', 'bookmarks.edit', 'bookmarks.remove', 'canvases.create', 'canvases.edit', 'canvases.access.set', 'slackLists.create', 'slackLists.items.create', 'slackLists.items.update', 'slackLists.access.set']);
12
+ const SAFE_ERRORS = new Set(['missing_scope', 'invalid_auth', 'not_authed', 'not_in_channel', 'channel_not_found', 'message_not_found', 'invalid_scheduled_message_id', 'already_reacted', 'no_reaction', 'not_pinned', 'already_pinned', 'bookmark_not_found', 'invalid_arguments', 'invalid_name', 'permission_denied', 'restricted_action', 'list_not_found', 'row_not_found', 'canvas_not_found']);
13
+ export class SlackActionRuntime {
14
+ options;
15
+ rate;
16
+ constructor(options) {
17
+ this.options = options;
18
+ this.rate = options.rateLimiter ?? new SlackActionRateLimiter();
19
+ }
20
+ async execute(definition, raw, principal, requestSignal) {
21
+ if (principal.kind === 'turn' && definition.mutates) {
22
+ const thread = principal.grant.destination.threadId ?? '';
23
+ if (raw['threadTs'] !== undefined && raw['threadTs'] !== thread)
24
+ throw slackToolDenied('slack_destination_thread_mismatch');
25
+ if (['schedule.create', 'schedule.update', 'interaction.url', 'interaction.choice'].includes(definition.operation) && thread)
26
+ raw = { ...raw, threadTs: thread };
27
+ }
28
+ const prepared = definition.prepare(raw);
29
+ const args = prepared.args;
30
+ const token = this.options.getToken();
31
+ if (!token)
32
+ throw slackToolDenied('slack_unavailable', 503);
33
+ if (definition.requiresInbound && !this.options.inboundReady?.())
34
+ throw slackToolDenied('slack_interaction_inbound_unavailable', 409);
35
+ if (definition.mutates && !args.invocationId)
36
+ throw slackToolDenied('slack_invocation_required', 400);
37
+ if (definition.mutates && principal.kind === 'turn' && args.channel !== principal.grant.destination.targetId)
38
+ throw slackToolDenied('slack_destination_mismatch');
39
+ const identity = await readSlackAuthSnapshot(token, { ...(this.options.fetchImpl ? { fetchImpl: this.options.fetchImpl } : {}), ...(requestSignal ? { signal: requestSignal } : {}) });
40
+ if (!identity?.userId)
41
+ throw slackToolDenied('slack_bot_identity_unverified', 409);
42
+ if (definition.scopes.length && identity.scopes === null)
43
+ throw slackToolDenied('slack_action_scopes_unverified', 403);
44
+ if (definition.scopes.some(scope => !identity.scopes?.includes(scope)))
45
+ throw slackToolDenied('slack_action_scopes_missing', 403);
46
+ const workspace = identity.teamId;
47
+ const actor = principal.kind === 'turn' ? principal.grant.actorId : 'operator';
48
+ const credentialKey = slackCredentialKey(token);
49
+ const store = this.options.store;
50
+ const hash = createHash('sha256').update(JSON.stringify({ credentialKey, operation: definition.operation, args: prepared.canonical })).digest('hex');
51
+ const existing = definition.mutates ? store.invocation(workspace, actor, args.invocationId) : undefined;
52
+ const ids = new Set();
53
+ let dispatched = false;
54
+ const base = (verification, data, resourceIds = [...ids]) => {
55
+ const projected = data === undefined ? undefined : slackDataForAgent(data);
56
+ const state = projected?.truncated && verification === 'verified' ? 'partial' : verification;
57
+ return { ok: state === 'verified', operation: definition.operation, verification: state, retryable: false, resourceIds,
58
+ ...(projected ? { data: projected.value } : {}), ...(state === 'partial' ? { partial: true } : {}) };
59
+ };
60
+ return withSlackToolAccess(token, principal, args.channel, async (grantSignal) => {
61
+ const signal = requestSignal ? (grantSignal ? AbortSignal.any([requestSignal, grantSignal]) : requestSignal) : grantSignal;
62
+ const checkCurrent = () => {
63
+ if (signal?.aborted)
64
+ throw slackToolDenied('slack_action_cancelled', 499);
65
+ if (this.options.getToken() !== token)
66
+ throw slackToolDenied('slack_credential_changed', 409);
67
+ };
68
+ checkCurrent();
69
+ if (principal.kind === 'turn' && /^(canvas|list)\./.test(definition.operation)) {
70
+ // File ACLs describe the requester, not every recipient in a group.
71
+ // Until a complete audience ACL proof is available, resource tools
72
+ // run only in the freshly verified requester/bot DM.
73
+ const conversation = await slackApi(token, 'conversations.info', { channel: args.channel }, {
74
+ ...(this.options.fetchImpl ? { fetchImpl: this.options.fetchImpl } : {}), ...(signal ? { signal } : {}), sensitiveResponse: true, form: true,
75
+ });
76
+ checkCurrent();
77
+ if (!conversation.ok || conversation.data?.channel?.id !== args.channel || conversation.data.channel.is_im !== true
78
+ || conversation.data.channel.user !== actor)
79
+ throw slackToolDenied('slack_resource_requester_dm_required');
80
+ }
81
+ if (existing) {
82
+ if (existing.request_hash !== hash || !['completed', 'failed'].includes(existing.status) || !existing.receipt_json)
83
+ throw slackToolDenied('slack_invocation_conflict_or_unknown', 409);
84
+ const receipt = JSON.parse(existing.receipt_json);
85
+ if (!receipt || typeof receipt !== 'object' || Array.isArray(receipt))
86
+ throw slackToolDenied('slack_invocation_receipt_invalid', 409);
87
+ return receipt;
88
+ }
89
+ if (definition.mutates && !store.reserve(workspace, actor, args.invocationId, hash))
90
+ throw slackToolDenied('slack_invocation_capacity_or_conflict', 409);
91
+ let calls = 0;
92
+ const context = {
93
+ token, workspace, botUserId: identity.userId, actor, channel: args.channel, credentialKey, operator: principal.kind === 'operator', ...(signal ? { signal } : {}),
94
+ checkCurrent, now: this.options.now ?? (() => Date.now()),
95
+ api: async (method, body, beforeDispatch) => {
96
+ checkCurrent();
97
+ if (!definition.methods.includes(method) || ++calls > 100 || (WRITE_METHODS.has(method) && !definition.mutates))
98
+ throw slackToolDenied('slack_action_method_contract', 500);
99
+ for (const key of ['channel', 'channel_id'])
100
+ if (body[key] !== undefined && body[key] !== args.channel)
101
+ throw slackToolDenied('slack_action_target_contract', 400);
102
+ if (Array.isArray(body['channel_ids']) && body['channel_ids'].some(value => value !== args.channel))
103
+ throw slackToolDenied('slack_action_target_contract', 400);
104
+ await this.rate.admit(workspace, method, signal);
105
+ checkCurrent();
106
+ if (WRITE_METHODS.has(method)) {
107
+ if (principal.kind === 'turn') {
108
+ const thread = principal.grant.destination.threadId ?? '';
109
+ if (['chat.postMessage', 'chat.scheduleMessage'].includes(method)) {
110
+ if (body['thread_ts'] !== undefined && body['thread_ts'] !== thread)
111
+ throw slackToolDenied('slack_destination_thread_mismatch');
112
+ body = { ...body, ...(thread ? { thread_ts: thread } : {}) };
113
+ }
114
+ const protectedResource = method === 'chat.update' || method === 'chat.delete' ? ['message', body['ts']]
115
+ : method === 'bookmarks.edit' || method === 'bookmarks.remove' ? ['bookmark', body['bookmark_id']]
116
+ : method === 'pins.remove' ? ['pin', body['timestamp']] : undefined;
117
+ if (protectedResource) {
118
+ const owned = context.resource(protectedResource[0], String(protectedResource[1]));
119
+ if (!owned || owned.status !== 'active' || owned.credentialKey !== credentialKey)
120
+ throw slackToolDenied('slack_resource_ownership_unverified');
121
+ }
122
+ }
123
+ await withSlackToolAccess(token, principal, args.channel, async () => true, this.options.fetchImpl, undefined, true);
124
+ if (beforeDispatch)
125
+ await beforeDispatch();
126
+ checkCurrent();
127
+ store.dispatched(workspace, actor, args.invocationId);
128
+ dispatched = true;
129
+ }
130
+ if (!WRITE_METHODS.has(method) && beforeDispatch) {
131
+ await beforeDispatch();
132
+ checkCurrent();
133
+ }
134
+ const options = { ...(this.options.fetchImpl ? { fetchImpl: this.options.fetchImpl } : {}), ...(signal ? { signal } : {}), sensitiveResponse: true, maxResponseBytes: 1048576, timeoutMs: 10000 };
135
+ const result = method === 'reactions.add' ? await addSlackReaction(token, String(body['channel']), String(body['timestamp']), String(body['name']), options)
136
+ : method === 'reactions.remove' ? await removeSlackReaction(token, String(body['channel']), String(body['timestamp']), String(body['name']), options)
137
+ : method === 'chat.delete' ? await deleteSlackMessage(token, String(body['channel']), String(body['ts']), options)
138
+ : await slackApi(token, method, body, { ...options, form: !WRITE_METHODS.has(method) && !method.startsWith('slackLists.') });
139
+ if (result.ok && WRITE_METHODS.has(method) && result.data && typeof result.data === 'object') {
140
+ const data = result.data;
141
+ const nestedId = (value) => value && typeof value === 'object' ? value['id'] : undefined;
142
+ for (const id of [data['ts'], data['scheduled_message_id'], data['canvas_id'], data['list_id'], nestedId(data['bookmark']), nestedId(data['item'])]) {
143
+ if ((typeof id === 'string' || typeof id === 'number') && /^[A-Za-z0-9_.:-]{1,128}$/.test(String(id)))
144
+ ids.add(String(id));
145
+ }
146
+ }
147
+ if (result.ok && principal.kind === 'turn') {
148
+ const data = result.data;
149
+ if (method === 'chat.postMessage' && typeof data?.['ts'] === 'string')
150
+ context.remember('message', data['ts']);
151
+ if (method === 'pins.add' && typeof body['timestamp'] === 'string')
152
+ context.remember('pin', body['timestamp']);
153
+ }
154
+ if (!WRITE_METHODS.has(method))
155
+ checkCurrent();
156
+ if (result.error === 'ratelimited' || result.error === 'rate_limited')
157
+ throw Object.assign(slackToolDenied('slack_action_rate_limited', 429), { retryAfterMs: result.retryAfterMs });
158
+ if (!WRITE_METHODS.has(method) && definition.operation !== 'rts.reconcile' && result.data !== undefined)
159
+ return { ...result, data: maskRtsActionMessages(workspace, args.channel, result.data) };
160
+ return result;
161
+ },
162
+ remember(kind, id, metadata = {}) {
163
+ ids.add(id);
164
+ store.remember({ workspace, kind, id, actor, channel: args.channel, botUserId: identity.userId, credentialKey, metadata: redactOutboundPayload({ ...metadata, ...(principal.kind === 'turn' ? { threadTs: principal.grant.destination.threadId ?? '' } : {}) }) });
165
+ },
166
+ resource(kind, id) {
167
+ const row = store.resource(workspace, kind, id);
168
+ if (!row || row.channel !== args.channel || row.botUserId !== identity.userId || (principal.kind !== 'operator' && row.actor !== actor))
169
+ return undefined;
170
+ if (principal.kind === 'turn' && (row.metadata['threadTs'] ?? '') !== (principal.grant.destination.threadId ?? ''))
171
+ return undefined;
172
+ if (kind === 'schedule' && row.credentialKey !== credentialKey)
173
+ throw slackToolDenied('slack_schedule_credential_changed', 409);
174
+ return row;
175
+ },
176
+ resources: kind => store.resources(workspace, kind, args.channel, principal.kind === 'operator' ? undefined : actor).filter(row => row.botUserId === identity.userId),
177
+ retire(kind, id) { if (!context.resource(kind, id))
178
+ throw slackToolDenied('slack_resource_ownership_unverified'); store.retire(workspace, kind, id); ids.add(id); },
179
+ download: async (url) => {
180
+ let next = url;
181
+ for (let hop = 0; hop <= 3; hop++) {
182
+ checkCurrent();
183
+ const safe = await validateSlackDownloadUrl(next, this.options.resolveHost ? { resolveHost: this.options.resolveHost } : {});
184
+ checkCurrent();
185
+ const downloadSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(10000)]) : AbortSignal.timeout(10000);
186
+ const response = await (this.options.fetchImpl ?? fetch)(safe, { headers: { Authorization: `Bearer ${token}` }, redirect: 'manual', signal: downloadSignal });
187
+ if (response.status >= 300 && response.status < 400) {
188
+ const location = response.headers.get('location');
189
+ void response.body?.cancel().catch(() => { });
190
+ if (!location)
191
+ throw slackToolDenied('slack_download_redirect_invalid', 502);
192
+ next = new URL(location, safe).href;
193
+ continue;
194
+ }
195
+ if (!response.ok)
196
+ throw slackToolDenied('slack_download_failed', 502);
197
+ const content = await readBoundedResponse(response, 1048576, downloadSignal);
198
+ checkCurrent();
199
+ return { content: redactOutboundPayload(content), contentType: response.headers.get('content-type') ?? '' };
200
+ }
201
+ throw slackToolDenied('slack_download_redirect_limit', 502);
202
+ },
203
+ result: base,
204
+ fail: (code, status = 409, resourceIds = [...ids]) => ({ ...base(dispatched ? 'unknown' : 'failed', undefined, resourceIds), error: code, status: status >= 400 && status <= 599 ? status : 502 }),
205
+ };
206
+ let result;
207
+ try {
208
+ result = await prepared.execute(context);
209
+ checkCurrent();
210
+ }
211
+ catch (error) {
212
+ const code = error.code;
213
+ result = { ...base(dispatched ? 'unknown' : 'failed'), error: typeof code === 'string' && (code.startsWith('slack_') || SAFE_ERRORS.has(code)) ? code : 'slack_action_failed', status: error.statusCode ?? 502 };
214
+ }
215
+ if (definition.mutates && Buffer.byteLength(JSON.stringify(result)) > 15000) {
216
+ // Durable replay must retain acknowledged addresses even when a
217
+ // provider's readback is larger than the receipt budget.
218
+ result = { ...result, ok: false, verification: result.verification === 'verified' ? 'partial' : result.verification,
219
+ partial: true, data: { omitted: true, reason: 'receipt_byte_limit' } };
220
+ }
221
+ if (result.verification === 'verified' && this.options.evidenceSource === 'slack_api')
222
+ store.recordVerified(workspace, credentialKey, definition.operation);
223
+ if (definition.mutates)
224
+ store.finish(workspace, actor, args.invocationId, result.verification === 'unknown' || result.verification === 'partial' ? 'unknown' : result.ok ? 'completed' : 'failed', result);
225
+ return result;
226
+ }, this.options.fetchImpl, result => ({ ...result, ok: false, verification: 'unknown', error: 'slack_action_cancelled_after_dispatch' }), true);
227
+ }
228
+ }
229
+ function maskRtsActionMessages(workspace, channel, value, depth = 0) {
230
+ if (depth > 16)
231
+ throw slackToolDenied('slack_action_response_depth', 502);
232
+ if (Array.isArray(value))
233
+ return value.map(item => maskRtsActionMessages(workspace, channel, item, depth + 1));
234
+ if (!value || typeof value !== 'object')
235
+ return value;
236
+ const item = value;
237
+ const store = getRtsOutputStore();
238
+ if (typeof item['ts'] === 'string' && (!store || isRtsOutput(item['blocks']) || store.held(workspace, channel) || store.contains(workspace, channel, item['ts']))) {
239
+ return { ts: item['ts'], user: item['user'], bot_id: item['bot_id'], reactions: item['reactions'], contentExcluded: true, text: '[검색 응답 내용 제외]', blocks: [] };
240
+ }
241
+ return Object.fromEntries(Object.entries(item).filter(([key]) => !['__proto__', 'constructor', 'prototype'].includes(key)).map(([key, child]) => [key, maskRtsActionMessages(workspace, channel, child, depth + 1)]));
242
+ }
243
+ //# sourceMappingURL=action-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-runtime.js","sourceRoot":"","sources":["../../../src/slack/action-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ const INVOCATION_CAP = 100000;
2
+ const RESOURCE_CAP = 10000;
3
+ export class SlackActionStore {
4
+ database;
5
+ constructor(database) {
6
+ this.database = database;
7
+ database.exec(`CREATE TABLE IF NOT EXISTS slack_tool_invocations (
8
+ workspace TEXT NOT NULL, actor TEXT NOT NULL, invocation_id TEXT NOT NULL,
9
+ request_hash TEXT NOT NULL, status TEXT NOT NULL, receipt_json TEXT,
10
+ created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL,
11
+ PRIMARY KEY(workspace,actor,invocation_id));
12
+ CREATE TABLE IF NOT EXISTS slack_tool_resources (
13
+ workspace TEXT NOT NULL, kind TEXT NOT NULL, resource_id TEXT NOT NULL,
14
+ actor TEXT NOT NULL, channel TEXT NOT NULL, bot_user_id TEXT NOT NULL,
15
+ credential_key TEXT NOT NULL, status TEXT NOT NULL, metadata_json TEXT NOT NULL,
16
+ PRIMARY KEY(workspace,kind,resource_id));
17
+ CREATE TABLE IF NOT EXISTS slack_tool_verified (
18
+ workspace TEXT NOT NULL, credential_key TEXT NOT NULL, operation TEXT NOT NULL,
19
+ verified_at INTEGER NOT NULL, PRIMARY KEY(workspace,credential_key,operation));`);
20
+ }
21
+ invocation(workspace, actor, id) {
22
+ return this.database.prepare('SELECT request_hash,status,receipt_json FROM slack_tool_invocations WHERE workspace=? AND actor=? AND invocation_id=?').get(workspace, actor, id);
23
+ }
24
+ reserve(workspace, actor, id, hash) {
25
+ return this.database.transaction(() => {
26
+ const count = this.database.prepare('SELECT count(*) AS n FROM slack_tool_invocations').get();
27
+ if (count.n >= INVOCATION_CAP)
28
+ return false;
29
+ const now = Date.now();
30
+ return this.database.prepare('INSERT OR IGNORE INTO slack_tool_invocations VALUES (?,?,?,?,?,?,?,?)').run(workspace, actor, id, hash, 'reserved', null, now, now).changes === 1;
31
+ })();
32
+ }
33
+ dispatched(workspace, actor, id) {
34
+ this.database.prepare("UPDATE slack_tool_invocations SET status='dispatched',updated_at=? WHERE workspace=? AND actor=? AND invocation_id=? AND status IN ('reserved','dispatched')").run(Date.now(), workspace, actor, id);
35
+ }
36
+ finish(workspace, actor, id, status, receipt) {
37
+ const json = JSON.stringify(receipt);
38
+ if (Buffer.byteLength(json) > 16384)
39
+ throw new Error('slack_action_receipt_too_large');
40
+ this.database.prepare('UPDATE slack_tool_invocations SET status=?,receipt_json=?,updated_at=? WHERE workspace=? AND actor=? AND invocation_id=?').run(status, json, Date.now(), workspace, actor, id);
41
+ }
42
+ resource(workspace, kind, id) {
43
+ const row = this.database.prepare('SELECT workspace,kind,resource_id,actor,channel,bot_user_id,credential_key,status,metadata_json FROM slack_tool_resources WHERE workspace=? AND kind=? AND resource_id=?').get(workspace, kind, id);
44
+ if (!row)
45
+ return undefined;
46
+ const metadata = JSON.parse(String(row['metadata_json']));
47
+ if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata) || !['active', 'retired'].includes(String(row['status'])))
48
+ throw new Error('slack_action_resource_invalid');
49
+ return { workspace: String(row['workspace']), kind: String(row['kind']), id: String(row['resource_id']), actor: String(row['actor']), channel: String(row['channel']), botUserId: String(row['bot_user_id']), credentialKey: String(row['credential_key']), status: row['status'], metadata: metadata };
50
+ }
51
+ resources(workspace, kind, channel, actor) {
52
+ const rows = (actor === undefined
53
+ ? this.database.prepare('SELECT resource_id FROM slack_tool_resources WHERE workspace=? AND kind=? AND channel=? LIMIT 1001').all(workspace, kind, channel)
54
+ : this.database.prepare('SELECT resource_id FROM slack_tool_resources WHERE workspace=? AND kind=? AND channel=? AND actor=? LIMIT 1001').all(workspace, kind, channel, actor));
55
+ if (rows.length > 1000)
56
+ throw new Error('slack_action_resource_list_incomplete');
57
+ return rows.map(row => this.resource(workspace, kind, row.resource_id));
58
+ }
59
+ remember(value) {
60
+ const metadata = JSON.stringify(value.metadata);
61
+ if (Buffer.byteLength(metadata) > 262144)
62
+ throw new Error('slack_action_resource_too_large');
63
+ const existing = this.resource(value.workspace, value.kind, value.id);
64
+ if (existing && (existing.actor !== value.actor || existing.channel !== value.channel || existing.botUserId !== value.botUserId
65
+ || (value.kind === 'schedule' && existing.credentialKey !== value.credentialKey)))
66
+ throw new Error('slack_action_resource_collision');
67
+ const count = this.database.prepare('SELECT count(*) AS n FROM slack_tool_resources').get();
68
+ if (!existing && count.n >= RESOURCE_CAP)
69
+ throw new Error('slack_action_resource_capacity');
70
+ this.database.prepare(`INSERT INTO slack_tool_resources VALUES (?,?,?,?,?,?,?,?,?)
71
+ ON CONFLICT(workspace,kind,resource_id) DO UPDATE SET metadata_json=excluded.metadata_json,status='active'`).run(value.workspace, value.kind, value.id, value.actor, value.channel, value.botUserId, value.credentialKey, 'active', metadata);
72
+ }
73
+ retire(workspace, kind, id) {
74
+ this.database.prepare("UPDATE slack_tool_resources SET status='retired',metadata_json='{}' WHERE workspace=? AND kind=? AND resource_id=?").run(workspace, kind, id);
75
+ }
76
+ verified(workspace, credentialKey, operation) {
77
+ const row = this.database.prepare('SELECT verified_at FROM slack_tool_verified WHERE workspace=? AND credential_key=? AND operation=?').get(workspace, credentialKey, operation);
78
+ return row?.verified_at ?? null;
79
+ }
80
+ recordVerified(workspace, credentialKey, operation) {
81
+ this.database.prepare('INSERT INTO slack_tool_verified VALUES (?,?,?,?) ON CONFLICT(workspace,credential_key,operation) DO UPDATE SET verified_at=excluded.verified_at').run(workspace, credentialKey, operation, Date.now());
82
+ }
83
+ }
84
+ //# sourceMappingURL=action-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-store.js","sourceRoot":"","sources":["../../../src/slack/action-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export function defineAction(definition) {
2
+ return { operation: definition.operation, scopes: definition.scopes, methods: definition.methods, mutates: definition.mutates,
3
+ ...(definition.requiresInbound ? { requiresInbound: true } : {}),
4
+ prepare(raw) { const args = definition.parse(raw); return { args, canonical: args, execute: ctx => definition.execute(ctx, args) }; } };
5
+ }
6
+ //# sourceMappingURL=action-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-types.js","sourceRoot":"","sources":["../../../src/slack/action-types.ts"],"names":[],"mappings":"AAqBA,MAAM,UAAU,YAAY,CAAuB,UAGlD;IACG,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO;QACzH,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAChJ,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { defineAction } from './action-types.js';
2
+ import { baseAction, enumValue, opaqueId, requiredText } from './task-input.js';
3
+ import { acknowledgedFailure, fileAccess, preserve, responseId } from './actions-resources.js';
4
+ import { redactOutboundText } from '../messaging/redact.js';
5
+ import { slackToolDenied } from './tool-access.js';
6
+ const aclMethods = ['files.info', 'users.info'];
7
+ const aclScopes = ['files:read', 'users:read'];
8
+ async function readCanvas(ctx, id, expected) {
9
+ const file = await fileAccess(ctx, 'canvas', id, false);
10
+ if (!file)
11
+ return ctx.fail('resource_requester_access_denied', 403, [id]);
12
+ const url = file['url_private_download'] ?? file['url_private'];
13
+ const metadata = { id, title: typeof file['title'] === 'string' ? redactOutboundText(file['title']).slice(0, 512) : undefined };
14
+ if (typeof url !== 'string')
15
+ return ctx.result('partial', { ...metadata, content: 'not_checked', requesterView: 'not_checked' }, [id]);
16
+ const exported = await ctx.download(url);
17
+ ctx.checkCurrent();
18
+ if (!await fileAccess(ctx, 'canvas', id, false))
19
+ return ctx.fail('resource_requester_access_denied', 403, [id]);
20
+ // The file endpoint supplies no documented completeness/version receipt for Canvas.
21
+ // A bounded supported export may be displayed, but is never labelled a full snapshot.
22
+ const mime = exported.contentType.split(';')[0]?.trim().toLowerCase();
23
+ if (!['text/markdown', 'text/plain'].includes(mime ?? '') || Buffer.byteLength(exported.content) > 1048576) {
24
+ return ctx.result('partial', { ...metadata, content: 'not_checked', export: 'unsupported_format', requesterView: 'not_checked' }, [id]);
25
+ }
26
+ return ctx.result('partial', { ...metadata, content: 'partial', exportText: redactOutboundText(exported.content).slice(0, 8000),
27
+ exportTruncated: exported.content.length > 8000, ...(expected !== undefined ? { exportMatchesRequested: exported.content === expected } : {}), requesterView: 'not_checked' }, [id]);
28
+ }
29
+ export const canvasActions = [
30
+ defineAction({ operation: 'canvas.create', scopes: ['canvases:write', ...aclScopes], methods: ['canvases.create', 'canvases.access.set', ...aclMethods], mutates: true,
31
+ parse(raw) { return { ...baseAction(raw, ['title', 'markdown'], true), title: requiredText(raw['title'], 256), markdown: redactOutboundText(requiredText(raw['markdown'], 64000)) }; },
32
+ async execute(ctx, args) {
33
+ const ids = [];
34
+ return preserve(ctx, ids, async () => {
35
+ const direct = args.channel.startsWith('D');
36
+ if (args.channel !== ctx.channel)
37
+ return ctx.fail('canvas_destination_mismatch', 403);
38
+ if (direct && (ctx.operator || !/^[UW][A-Z0-9]+$/.test(ctx.actor)))
39
+ return ctx.fail('canvas_requester_identity_required', 403);
40
+ ctx.checkCurrent();
41
+ const created = await ctx.api('canvases.create', { title: redactOutboundText(args.title), document_content: { type: 'markdown', markdown: args.markdown }, ...(direct ? {} : { channel_id: args.channel }) });
42
+ const id = responseId(created.data?.['canvas_id']);
43
+ if (id) {
44
+ ids.push(id);
45
+ ctx.remember('canvas', id);
46
+ }
47
+ ctx.checkCurrent();
48
+ if (!created.ok || !id) {
49
+ if (ids.length)
50
+ return acknowledgedFailure(ctx, ids, 'create_unconfirmed');
51
+ if (['free_teams_cannot_create_standalone_canvases', 'free_teams_cannot_create_non_tabbed_canvases', 'invalid_arguments', 'canvas_disabled_user_team', 'missing_scope'].includes(created.error ?? ''))
52
+ return ctx.fail(created.error, created.status ?? 400);
53
+ return ctx.result('unknown', { creation: 'unconfirmed' });
54
+ }
55
+ let sharing = 'not_requested';
56
+ if (direct) {
57
+ // Slack may require prior direct sharing; failure remains partial, never a wider share fallback.
58
+ const shared = await ctx.api('canvases.access.set', { canvas_id: id, access_level: 'write', user_ids: [ctx.actor] });
59
+ ctx.checkCurrent();
60
+ if (!shared.ok)
61
+ return acknowledgedFailure(ctx, ids, 'canvas_sharing_unconfirmed');
62
+ sharing = 'acknowledged';
63
+ if (!await fileAccess(ctx, 'canvas', id, true))
64
+ return acknowledgedFailure(ctx, ids, 'requester_write_unverified');
65
+ }
66
+ const read = await readCanvas(ctx, id, args.markdown);
67
+ if (!read.ok)
68
+ return acknowledgedFailure(ctx, ids, 'requester_visibility_unverified');
69
+ return ctx.result('partial', { creation: 'acknowledged', sharing, readback: read.data, requesterView: 'not_checked' }, ids);
70
+ });
71
+ } }),
72
+ defineAction({ operation: 'canvas.read', scopes: aclScopes, methods: aclMethods, mutates: false,
73
+ parse(raw) { return { ...baseAction(raw, ['canvasId'], false), canvasId: opaqueId(raw['canvasId']) }; },
74
+ execute(ctx, args) { return preserve(ctx, [], () => readCanvas(ctx, args.canvasId)); } }),
75
+ defineAction({ operation: 'canvas.edit', scopes: ['canvases:write', ...aclScopes], methods: ['canvases.edit', ...aclMethods], mutates: true,
76
+ parse(raw) {
77
+ const base = baseAction(raw, ['canvasId', 'mode', 'markdown', 'sectionId', 'replaceAll'], true);
78
+ const mode = enumValue(raw['mode'], ['append', 'replace']);
79
+ const sectionId = raw['sectionId'] === undefined ? undefined : opaqueId(raw['sectionId']);
80
+ const replaceAll = raw['replaceAll'] === undefined ? false : raw['replaceAll'];
81
+ if (typeof replaceAll !== 'boolean' || (mode === 'append' && (sectionId || replaceAll))
82
+ || (mode === 'replace' && (!!sectionId === replaceAll))) {
83
+ throw slackToolDenied('invalid_canvas_edit', 400);
84
+ }
85
+ return { ...base, canvasId: opaqueId(raw['canvasId']), mode, sectionId, replaceAll, markdown: redactOutboundText(requiredText(raw['markdown'], 64000)) };
86
+ },
87
+ async execute(ctx, args) {
88
+ const ids = [];
89
+ return preserve(ctx, ids, async () => {
90
+ if (!await fileAccess(ctx, 'canvas', args.canvasId, true))
91
+ return ctx.fail('resource_requester_write_denied', 403);
92
+ ctx.checkCurrent();
93
+ ids.push(args.canvasId);
94
+ const edited = await ctx.api('canvases.edit', { canvas_id: args.canvasId, changes: [{ operation: args.mode === 'append' ? 'insert_at_end' : 'replace',
95
+ document_content: { type: 'markdown', markdown: args.markdown }, ...(args.sectionId ? { section_id: args.sectionId } : {}) }] }, async () => {
96
+ if (!await fileAccess(ctx, 'canvas', args.canvasId, true))
97
+ throw slackToolDenied('resource_requester_write_denied', 403);
98
+ ctx.checkCurrent();
99
+ });
100
+ ctx.checkCurrent();
101
+ if (!edited.ok)
102
+ return ctx.result('unknown', { edit: 'unconfirmed' }, ids);
103
+ const read = await readCanvas(ctx, args.canvasId, args.replaceAll ? args.markdown : undefined);
104
+ return read.ok ? ctx.result('partial', { edit: 'acknowledged', readback: read.data, requesterView: 'not_checked' }, ids) : acknowledgedFailure(ctx, ids, 'readback_unavailable');
105
+ });
106
+ } }),
107
+ ];
108
+ //# sourceMappingURL=actions-canvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions-canvas.js","sourceRoot":"","sources":["../../../src/slack/actions-canvas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import { defineAction } from './action-types.js';
2
+ import { baseAction, messageTs, opaqueId, requiredText, optionalText } from './task-input.js';
3
+ import { redactChannelSecrets } from '../messaging/redact.js';
4
+ import { slackToolDenied } from './tool-access.js';
5
+ function safeLink(value) {
6
+ const link = requiredText(value, 2048);
7
+ let url;
8
+ try {
9
+ url = new URL(link);
10
+ }
11
+ catch {
12
+ throw slackToolDenied('slack_link_invalid', 400);
13
+ }
14
+ if (url.protocol !== 'https:' || url.username || url.password || redactChannelSecrets(link) !== link)
15
+ throw slackToolDenied('slack_link_unsafe', 400);
16
+ return link;
17
+ }
18
+ export const channelActions = [];
19
+ for (const operation of ['pin.add', 'pin.remove', 'pin.list']) {
20
+ const mutates = operation !== 'pin.list';
21
+ channelActions.push(defineAction({ operation, scopes: mutates ? ['pins:write', 'pins:read'] : ['pins:read'],
22
+ methods: mutates ? [operation === 'pin.add' ? 'pins.add' : 'pins.remove', 'pins.list'] : ['pins.list'], mutates,
23
+ parse(raw) { return { ...baseAction(raw, mutates ? ['ts'] : [], mutates), ...(mutates ? { ts: messageTs(raw['ts']) } : {}) }; },
24
+ async execute(ctx, args) {
25
+ if (mutates) {
26
+ const changed = await ctx.api(operation === 'pin.add' ? 'pins.add' : 'pins.remove', { channel: args.channel, timestamp: args.ts });
27
+ const converged = operation === 'pin.add' ? changed.error === 'already_pinned' : changed.error === 'not_pinned';
28
+ if (!changed.ok && !converged)
29
+ return ctx.fail(changed.error ?? 'slack_pin_failed', changed.status);
30
+ }
31
+ const read = await ctx.api('pins.list', { channel: args.channel });
32
+ if (!read.ok || !Array.isArray(read.data?.items) || read.data.items.length > 1000)
33
+ return ctx.fail('slack_pins_readback_failed', 502, mutates ? [args.ts] : []);
34
+ if (read.data.items.some(item => item.channel && item.channel !== args.channel))
35
+ return ctx.fail('slack_pins_target_mismatch', 502, mutates ? [args.ts] : []);
36
+ const items = read.data.items.filter(item => item.type === 'message' && typeof item.message?.ts === 'string').map(item => ({ ts: item.message.ts, text: item.message?.text ?? '', contentExcluded: item.message?.contentExcluded === true }));
37
+ if (mutates && items.some(item => item.ts === args.ts) !== (operation === 'pin.add'))
38
+ return ctx.fail('slack_pin_state_mismatch', 409, [args.ts]);
39
+ return ctx.result(read.data.items.length !== items.length ? 'partial' : 'verified', { items, scope: 'conversation' }, mutates ? [args.ts] : []);
40
+ },
41
+ }));
42
+ }
43
+ for (const operation of ['bookmark.add', 'bookmark.edit', 'bookmark.remove', 'bookmark.list']) {
44
+ const mutates = operation !== 'bookmark.list';
45
+ channelActions.push(defineAction({ operation, scopes: mutates ? ['bookmarks:write', 'bookmarks:read'] : ['bookmarks:read'],
46
+ methods: mutates ? [operation.replace('bookmark.', 'bookmarks.'), 'bookmarks.list'] : ['bookmarks.list'], mutates,
47
+ parse(raw) {
48
+ const allowed = operation === 'bookmark.add' ? ['title', 'link', 'emoji'] : operation === 'bookmark.edit' ? ['bookmarkId', 'title', 'link', 'emoji'] : operation === 'bookmark.remove' ? ['bookmarkId'] : [];
49
+ const base = baseAction(raw, allowed, mutates);
50
+ const title = operation === 'bookmark.add' ? requiredText(raw['title'], 100) : optionalText(raw['title'], 100);
51
+ const link = raw['link'] !== undefined || operation === 'bookmark.add' ? safeLink(raw['link']) : undefined;
52
+ const emoji = optionalText(raw['emoji'], 100);
53
+ if (operation === 'bookmark.edit' && title === undefined && link === undefined && emoji === undefined)
54
+ throw slackToolDenied('slack_bookmark_edit_empty', 400);
55
+ return { ...base, ...(title !== undefined ? { title: redactChannelSecrets(title) } : {}), ...(link ? { link } : {}), ...(emoji ? { emoji } : {}),
56
+ ...(['bookmark.edit', 'bookmark.remove'].includes(operation) ? { bookmarkId: opaqueId(raw['bookmarkId']) } : {}) };
57
+ },
58
+ async execute(ctx, args) {
59
+ let id = args.bookmarkId;
60
+ if (mutates) {
61
+ const changed = await ctx.api(operation.replace('bookmark.', 'bookmarks.'), { channel_id: args.channel,
62
+ ...(id ? { bookmark_id: id } : {}), ...(operation === 'bookmark.add' ? { type: 'link' } : {}),
63
+ ...(args.title !== undefined ? { title: args.title } : {}), ...(args.link ? { link: args.link } : {}), ...(args.emoji ? { emoji: args.emoji } : {}) });
64
+ if (!changed.ok)
65
+ return ctx.fail(changed.error ?? 'slack_bookmark_failed', changed.status, id ? [id] : []);
66
+ if (operation === 'bookmark.add') {
67
+ id = changed.data?.bookmark?.id;
68
+ if (!id || changed.data?.bookmark?.channel_id !== args.channel)
69
+ return ctx.fail('slack_bookmark_id_unverified');
70
+ ctx.remember('bookmark', id);
71
+ }
72
+ }
73
+ const read = await ctx.api('bookmarks.list', { channel_id: args.channel });
74
+ if (!read.ok || !Array.isArray(read.data?.bookmarks) || read.data.bookmarks.length > 100)
75
+ return ctx.fail('slack_bookmark_readback_failed', 502, id ? [id] : []);
76
+ if (read.data.bookmarks.some(bookmark => bookmark.channel_id !== args.channel || typeof bookmark.id !== 'string')
77
+ || new Set(read.data.bookmarks.map(bookmark => bookmark.id)).size !== read.data.bookmarks.length)
78
+ return ctx.fail('slack_bookmark_response_invalid', 502, id ? [id] : []);
79
+ const bookmark = read.data.bookmarks.find(item => item.id === id);
80
+ if (operation === 'bookmark.remove' && bookmark)
81
+ return ctx.fail('slack_bookmark_still_present', 409, [id]);
82
+ if ((operation === 'bookmark.add' || operation === 'bookmark.edit') && (!bookmark || bookmark.type !== 'link' || (args.title !== undefined && bookmark.title !== args.title) || (args.link !== undefined && bookmark.link !== args.link) || (args.emoji !== undefined && bookmark.emoji !== args.emoji)))
83
+ return ctx.fail('slack_bookmark_content_mismatch', 409, id ? [id] : []);
84
+ return ctx.result('verified', { bookmarks: read.data.bookmarks.map(item => ({ id: item.id, title: item.title, link: item.link, type: item.type })) }, id ? [id] : []);
85
+ },
86
+ }));
87
+ }
88
+ //# sourceMappingURL=actions-channel.js.map