@openclaw/slack 2026.7.2-beta.1 → 2026.7.2-beta.2

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 (42) hide show
  1. package/dist/{action-runtime-p6M2ULpv.js → action-runtime-Cee2ih0s.js} +9 -6
  2. package/dist/action-runtime.runtime-DZfd7IFr.js +2 -0
  3. package/dist/{actions-DkTcWmpT.js → actions-BZiuSTIq.js} +4 -8
  4. package/dist/{actions.runtime-BSxpwgUc.js → actions.runtime-DoD0-gxw.js} +1 -1
  5. package/dist/api.js +9 -9
  6. package/dist/{approval-handler.runtime-UGbnz9OC.js → approval-handler.runtime-CUPtIM4k.js} +2 -2
  7. package/dist/{channel-B0_j6C6z.js → channel-DaIiGUOp.js} +20 -18
  8. package/dist/channel-config-api.js +1 -1
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel-type-BpeTezY4.js → channel-type-Cfm6_6n1.js} +2 -2
  11. package/dist/{channel.setup-BQFut21T.js → channel.setup-C-mLz50O.js} +3 -3
  12. package/dist/{client-D2F6m8CP.js → client-WIPAS3Yr.js} +9 -1
  13. package/dist/{config-schema-DYI01PV2.js → config-schema-xPSnK2VK.js} +12 -0
  14. package/dist/{directory-live-DX7yFsM-.js → directory-live-D_yZhjgp.js} +1 -1
  15. package/dist/{group-policy-C-b2ZnSl.js → group-policy-85UWiriS.js} +28 -15
  16. package/dist/{monitor-BN_uuvrQ.js → monitor-CalGciTs.js} +3 -3
  17. package/dist/{outbound-adapter-ECl0go7d.js → outbound-adapter-BiLKcnyH.js} +2 -2
  18. package/dist/{pipeline.runtime-f0eJJoJL.js → pipeline.runtime-DofAvTtb.js} +176 -54
  19. package/dist/{policy-f8b0edSi.js → policy-BVs4LiSa.js} +7 -7
  20. package/dist/{probe-CfALk0l4.js → probe-CN0ssfLN.js} +2 -2
  21. package/dist/{provider-Ds-y-imP.js → provider-CmeoUiIM.js} +282 -47
  22. package/dist/{relay-source-B-6LFUdz.js → relay-source-DMmgtvg4.js} +1 -1
  23. package/dist/{replies-BMvf3ihj.js → replies-CJJCp6qz.js} +3 -3
  24. package/dist/{resolve-channels-DOMgNCWb.js → resolve-channels-Rfts6POK.js} +1 -1
  25. package/dist/{resolve-users-aL6-Ssee.js → resolve-users-y6wAxR8E.js} +1 -1
  26. package/dist/{runtime-CauEvswP.js → runtime-JSVZSWAj.js} +2 -2
  27. package/dist/{runtime-api-CVb6CQjX.js → runtime-api-BGDyOt1D.js} +1 -1
  28. package/dist/runtime-api.js +11 -11
  29. package/dist/runtime-setter-api.js +1 -1
  30. package/dist/{scopes-Dw8wbU0j.js → scopes-CuxNQZ6v.js} +2 -2
  31. package/dist/{send-NEfJ0GvM.js → send-DYp8ca-l.js} +4 -4
  32. package/dist/{send.runtime-BkKpitPu.js → send.runtime-CJLxAt26.js} +1 -1
  33. package/dist/{setup-core-fGd6Gquy.js → setup-core-CkwVLzFO.js} +15 -21
  34. package/dist/setup-plugin-api.js +1 -1
  35. package/dist/{setup-surface-BN2WeG5c.js → setup-surface-oSd3NX9J.js} +4 -4
  36. package/dist/{shared-BLnB9R1T.js → shared-D9yz5Otg.js} +12 -35
  37. package/dist/{slash-dispatch.runtime-C0Otuf_T.js → slash-dispatch.runtime-CSja9VuD.js} +1 -1
  38. package/npm-shrinkwrap.json +3 -3
  39. package/openclaw.plugin.json +68 -0
  40. package/package.json +5 -7
  41. package/dist/action-runtime.runtime-DQstDkHG.js +0 -2
  42. package/dist/configured-state.js +0 -11
@@ -1,17 +1,17 @@
1
1
  import { u as resolveSlackReplyToMode } from "./accounts-BOJJiHSr.js";
2
2
  import { i as parseSlackTarget } from "./target-parsing-N6lHogYZ.js";
3
3
  import "./targets-KmjP2E8s.js";
4
- import { C as hasSlackNativeDataBlock, F as SLACK_TEXT_LIMIT, K as escapeSlackMrkdwn, N as SLACK_EDIT_TEXT_LIMIT, O as normalizeSlackOutboundText, _ as resolveSlackReplyRenderPlan, c as normalizeSlackAllowOwnerEntry, k as buildSlackBlocksFallbackText, r as formatSlackError, s as normalizeAllowListLower, u as resolveSlackAllowListMatch, z as truncateSlackText } from "./group-policy-C-b2ZnSl.js";
4
+ import { A as buildSlackBlocksFallbackText, B as truncateSlackText, I as SLACK_TEXT_LIMIT, P as SLACK_EDIT_TEXT_LIMIT, c as normalizeAllowListLower, d as resolveSlackAllowListMatch, i as formatSlackError, k as normalizeSlackOutboundText, l as normalizeSlackAllowOwnerEntry, q as escapeSlackMrkdwn, v as resolveSlackReplyRenderPlan, w as hasSlackNativeDataBlock } from "./group-policy-85UWiriS.js";
5
5
  import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-BilWUdcI.js";
6
6
  import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode, t as mapStreamingModeToSlackLegacyDraftStreamMode } from "./streaming-compat-3_X-21wW.js";
7
- import { C as buildSlackEditTextPayload, S as formatSlackFileReference, _ as resolveSlackThreadHistory, b as resolveSlackBlocksText, f as removeSlackReaction, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage, v as resolveSlackThreadStarter, y as chooseSlackPrimaryText } from "./actions-DkTcWmpT.js";
8
- import { c as recordSlackThreadParticipation, l as buildSlackNativeDataDeliveryPlan, r as sendMessageSlack, s as hasSlackThreadParticipationWithPersistence } from "./send-NEfJ0GvM.js";
9
- import { S as updateLastRoute, _ as resolveSlackChatType, b as resolveChannelResetConfig, d as authorizeSlackBotRoomMessage, f as resolveSlackCommandIngress, g as normalizeSlackChannelType, h as parseSlackAssistantThreadMetadata, l as recordInboundSession, m as buildSlackAssistantThreadMetadata, o as authorizeSlackDirectMessage, p as resolveSlackEffectiveAllowFrom, r as resolveSlackRoomContextHints, u as resolveConversationLabel$1, v as readSessionUpdatedAt, w as stripSlackMentionsForCommandDetection, x as resolveStorePath, y as resolveChannelContextVisibilityMode } from "./provider-Ds-y-imP.js";
10
- import { n as resolveSlackChannelConfig } from "./policy-f8b0edSi.js";
11
- import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, s as emitSlackMessageSentHooks, t as createSlackReplyDeliveryPlan } from "./replies-BMvf3ihj.js";
7
+ import { S as buildSlackEditTextPayload, _ as resolveSlackThreadHistory, b as resolveSlackBlocksText, f as removeSlackReaction, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage, v as resolveSlackThreadStarter, x as formatSlackFileReference, y as chooseSlackPrimaryText } from "./actions-BZiuSTIq.js";
8
+ import { c as recordSlackThreadParticipation, l as buildSlackNativeDataDeliveryPlan, r as sendMessageSlack, s as hasSlackThreadParticipationWithPersistence } from "./send-DYp8ca-l.js";
9
+ import { S as updateLastRoute, _ as resolveSlackChatType, b as resolveChannelResetConfig, d as authorizeSlackBotRoomMessage, f as resolveSlackCommandIngress, g as normalizeSlackChannelType, h as parseSlackAssistantThreadMetadata, l as recordInboundSession, m as buildSlackAssistantThreadMetadata, o as authorizeSlackDirectMessage, p as resolveSlackEffectiveAllowFrom, r as resolveSlackRoomContextHints, u as resolveConversationLabel$1, v as readSessionUpdatedAt, w as stripSlackMentionsForCommandDetection, x as resolveStorePath, y as resolveChannelContextVisibilityMode } from "./provider-CmeoUiIM.js";
10
+ import { n as resolveSlackChannelConfig } from "./policy-BVs4LiSa.js";
11
+ import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, s as emitSlackMessageSentHooks, t as createSlackReplyDeliveryPlan } from "./replies-CJJCp6qz.js";
12
12
  import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
13
13
  import { resolveAgentRoute, resolveInboundLastRouteSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
14
- import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftGate, createDraftStreamLoop, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, resolveAgentOutboundIdentity, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelProgressDraftConfig, resolveChannelProgressDraftMaxLineChars, resolveChannelProgressDraftMaxLines, resolveChannelProgressDraftRender, resolveChannelStreamingBlockEnabled, resolveChannelStreamingNativeTransport, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingProgressCommentary, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-outbound";
14
+ import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftGate, createDraftStreamLoop, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, formatChannelProgressDraftText, formatPlanChecklistLines, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, resolveAgentOutboundIdentity, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelProgressDraftConfig, resolveChannelProgressDraftMaxLineChars, resolveChannelProgressDraftMaxLines, resolveChannelProgressDraftRender, resolveChannelStreamingBlockEnabled, resolveChannelStreamingNativeTransport, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingProgressCommentary, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-outbound";
15
15
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
16
16
  import { danger, logVerbose, shouldLogVerbose, sleep } from "openclaw/plugin-sdk/runtime-env";
17
17
  import { stripReasoningTagsFromText } from "openclaw/plugin-sdk/text-chunking";
@@ -221,6 +221,11 @@ function stableTaskIdPart(value) {
221
221
  return `${slugTaskIdPart(value)}_${suffix}`;
222
222
  }
223
223
  function buildPlanTasks(params) {
224
+ if (params.plan) return params.plan.slice(-50).map((entry, index) => ({
225
+ id: `plan_step_${index + 1}`,
226
+ title: compactTitle(entry.step),
227
+ status: entry.status === "completed" ? "complete" : entry.status
228
+ }));
224
229
  const maxLineChars = resolveMaxLineChars(params.maxLineChars, DEFAULT_SLACK_PROGRESS_TASK_DETAIL_MAX_CHARS);
225
230
  return params.lines.slice(-50).map((line, index) => ({
226
231
  id: line.id ? stableTaskIdPart(line.id) : `${slugTaskIdPart(line.toolName ?? line.kind ?? line.label)}_${index + 1}`,
@@ -234,6 +239,7 @@ function resolvePlanTitle(params) {
234
239
  function buildSlackProgressStreamChunks(params) {
235
240
  const tasks = buildPlanTasks({
236
241
  lines: params.lines,
242
+ plan: params.plan,
237
243
  maxLineChars: params.maxLineChars
238
244
  });
239
245
  if (tasks.length === 0) return;
@@ -254,15 +260,63 @@ function buildSlackProgressStreamChunks(params) {
254
260
  function buildSlackProgressDraftBlocks(params) {
255
261
  const label = params.label?.trim() || params.title?.trim();
256
262
  const maxLineChars = resolveMaxLineChars(params.maxLineChars, DEFAULT_SLACK_PROGRESS_DETAIL_MAX_CHARS);
257
- const renderedBlocks = [...label ? [{
258
- type: "section",
259
- text: field(`*${escapeSlackMrkdwn(label)}*`)
260
- }] : [], ...params.lines.map((line) => ({
263
+ const planLines = formatPlanChecklistLines(params.plan ?? [], {
264
+ maxLines: 50,
265
+ maxLineChars
266
+ });
267
+ const narration = params.narration?.replace(/\s+/g, " ").trim();
268
+ const headBlocks = [
269
+ ...label ? [{
270
+ type: "section",
271
+ text: field(`*${escapeSlackMrkdwn(label)}*`)
272
+ }] : [],
273
+ ...narration ? [{
274
+ type: "section",
275
+ text: field(`_${escapeSlackMrkdwn(narration)}_`)
276
+ }] : [],
277
+ ...planLines.length > 0 ? [{
278
+ type: "section",
279
+ text: field(planLines.map((line) => escapeSlackMrkdwn(line)).join("\n"))
280
+ }] : []
281
+ ].slice(0, 50);
282
+ const lineBudget = Math.max(0, 50 - headBlocks.length);
283
+ const renderedBlocks = [...headBlocks, ...params.lines.slice(-lineBudget).map((line) => ({
261
284
  type: "section",
262
285
  fields: [field(legacyLineTitle(line)), field(legacyLineDetail(line, maxLineChars))]
263
- }))].slice(-50);
286
+ }))];
264
287
  return renderedBlocks.length ? renderedBlocks : void 0;
265
288
  }
289
+ /**
290
+ * Slack native streams key task rows by persistent id with no removal chunk.
291
+ * When the task source switches representation (tool lines <-> typed plan) or
292
+ * a snapshot drops ids, previously emitted non-terminal rows must receive a
293
+ * final update or they linger in_progress forever.
294
+ */
295
+ function reconcileSlackNativeTaskChunks(params) {
296
+ const nextTasks = /* @__PURE__ */ new Map();
297
+ for (const chunk of params.chunks ?? []) if (chunk.type === "task_update") nextTasks.set(chunk.id, {
298
+ title: chunk.title,
299
+ status: chunk.status
300
+ });
301
+ const terminalized = [...params.previousTasks].filter(([id, task]) => !nextTasks.has(id) && task.status !== "complete" && task.status !== "error").map(([id, task]) => {
302
+ const entry = {
303
+ title: task.title,
304
+ status: "complete"
305
+ };
306
+ nextTasks.set(id, entry);
307
+ return {
308
+ type: "task_update",
309
+ id,
310
+ title: task.title,
311
+ status: "complete"
312
+ };
313
+ });
314
+ for (const [id, task] of params.previousTasks) if (!nextTasks.has(id)) nextTasks.set(id, task);
315
+ return {
316
+ chunks: params.chunks?.length ? [...params.chunks, ...terminalized] : terminalized.length ? terminalized : params.chunks,
317
+ tasks: nextTasks
318
+ };
319
+ }
266
320
  function buildSlackProgressStreamStartChunks(params) {
267
321
  return buildSlackProgressStreamChunks(params);
268
322
  }
@@ -1130,7 +1184,7 @@ async function dispatchPreparedSlackMessage(prepared) {
1130
1184
  delivery.outcome = "success";
1131
1185
  }
1132
1186
  };
1133
- const deliveryTracker = createSlackEventDeliveryTracker();
1187
+ let deliveryTracker = createSlackEventDeliveryTracker();
1134
1188
  const markPreviewPayloadDelivered = (params) => {
1135
1189
  deliveryTracker.markDelivered(params);
1136
1190
  const nextThreadTs = replyPlan.peekThreadTs();
@@ -1357,12 +1411,16 @@ async function dispatchPreparedSlackMessage(prepared) {
1357
1411
  logVerbose("slack-stream: suppressed duplicate append payload");
1358
1412
  return;
1359
1413
  }
1360
- const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent && previewToolProgressLines.length > 0 ? buildSlackProgressStreamCompletionChunks({
1361
- title: explicitProgressTitle,
1362
- lines: previewToolProgressLines,
1363
- maxLineChars: progressDraftMaxLineChars,
1364
- finalInProgressStatus: params.payload.isError ? "error" : "complete"
1365
- }) : void 0;
1414
+ const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent && (previewToolProgressLines.length > 0 || Boolean(latestPlan?.length) || Boolean(latestPlanExplanation) || [...nativeTaskState.values()].some((task) => task.status !== "complete" && task.status !== "error")) ? reconcileSlackNativeTaskChunks({
1415
+ previousTasks: nativeTaskState,
1416
+ chunks: buildSlackProgressStreamCompletionChunks({
1417
+ title: resolveNativeProgressTitle(),
1418
+ lines: resolveNativeProgressLines(),
1419
+ plan: resolveNativeProgressPlan(),
1420
+ maxLineChars: progressDraftMaxLineChars,
1421
+ finalInProgressStatus: params.payload.isError ? "error" : "complete"
1422
+ })
1423
+ }).chunks : void 0;
1366
1424
  if (useNativeProgressStreaming) {
1367
1425
  if (completionChunks?.length) {
1368
1426
  await appendSlackStream({
@@ -1641,6 +1699,9 @@ async function dispatchPreparedSlackMessage(prepared) {
1641
1699
  let previewToolProgressSuppressed = false;
1642
1700
  let previewToolProgressLines = [];
1643
1701
  let lastNonEmptyPreviewToolProgressLines = [];
1702
+ let latestPlan;
1703
+ let latestPlanExplanation;
1704
+ let nativeTaskState = /* @__PURE__ */ new Map();
1644
1705
  let appendRenderedText = "";
1645
1706
  let appendSourceText = "";
1646
1707
  let reasoningProgressRawText = "";
@@ -1658,12 +1719,16 @@ async function dispatchPreparedSlackMessage(prepared) {
1658
1719
  entry: account.config,
1659
1720
  lines: progressLines,
1660
1721
  seed: progressSeed,
1661
- formatLine: escapeSlackMrkdwn
1722
+ formatLine: escapeSlackMrkdwn,
1723
+ narration: latestPlanExplanation,
1724
+ plan: latestPlan
1662
1725
  });
1663
1726
  if (!previewText) return;
1664
1727
  const richProgressBlocks = useRichProgressDraft ? buildSlackProgressDraftBlocks({
1665
1728
  title: explicitProgressTitle,
1666
1729
  lines: progressLines,
1730
+ plan: latestPlan,
1731
+ narration: latestPlanExplanation,
1667
1732
  maxLineChars: resolveChannelProgressDraftMaxLineChars(account.config)
1668
1733
  }) : void 0;
1669
1734
  draftStream.update(useRichProgressDraft && richProgressBlocks ? {
@@ -1682,13 +1747,26 @@ async function dispatchPreparedSlackMessage(prepared) {
1682
1747
  }
1683
1748
  return !streamFailed;
1684
1749
  };
1750
+ const resolveNativeProgressPlan = () => latestPlan?.length ? latestPlan : void 0;
1751
+ const resolveNativeProgressLines = () => {
1752
+ if (latestPlan?.length || !latestPlanExplanation) return previewToolProgressLines;
1753
+ const explanationLine = buildChannelProgressDraftLine({
1754
+ event: "plan",
1755
+ phase: "update",
1756
+ explanation: latestPlanExplanation
1757
+ });
1758
+ return explanationLine ? [...previewToolProgressLines, explanationLine] : previewToolProgressLines;
1759
+ };
1760
+ const resolveNativeProgressTitle = () => explicitProgressTitle && latestPlanExplanation ? `${explicitProgressTitle} — ${latestPlanExplanation}` : explicitProgressTitle ?? latestPlanExplanation;
1685
1761
  const buildNativeProgressChunks = () => streamSession ? buildSlackProgressStreamUpdateChunks({
1686
- title: explicitProgressTitle,
1687
- lines: previewToolProgressLines,
1762
+ title: resolveNativeProgressTitle(),
1763
+ lines: resolveNativeProgressLines(),
1764
+ plan: resolveNativeProgressPlan(),
1688
1765
  maxLineChars: progressDraftMaxLineChars
1689
1766
  }) : buildSlackProgressStreamStartChunks({
1690
- title: explicitProgressTitle,
1691
- lines: previewToolProgressLines,
1767
+ title: resolveNativeProgressTitle(),
1768
+ lines: resolveNativeProgressLines(),
1769
+ plan: resolveNativeProgressPlan(),
1692
1770
  maxLineChars: progressDraftMaxLineChars
1693
1771
  });
1694
1772
  const markNativeProgressDelivered = (session, threadTs) => {
@@ -1746,24 +1824,51 @@ async function dispatchPreparedSlackMessage(prepared) {
1746
1824
  nativeProgressChunkKey = chunkKey;
1747
1825
  };
1748
1826
  const updateNativeProgressStream = async () => {
1749
- if (!useNativeProgressStreaming || streamFailed || previewToolProgressLines.length === 0) return;
1827
+ const hasRetirableNativeTasks = [...nativeTaskState.values()].some((task) => task.status !== "complete" && task.status !== "error");
1828
+ if (!useNativeProgressStreaming || streamFailed || previewToolProgressLines.length === 0 && !latestPlan?.length && !latestPlanExplanation && !hasRetirableNativeTasks) return;
1750
1829
  if (!await waitForNativeProgressStreamStart()) return;
1751
- const chunks = buildNativeProgressChunks();
1830
+ const reconciled = reconcileSlackNativeTaskChunks({
1831
+ previousTasks: nativeTaskState,
1832
+ chunks: buildNativeProgressChunks()
1833
+ });
1834
+ const chunks = reconciled.chunks;
1752
1835
  if (!chunks?.length) return;
1753
1836
  const chunkKey = JSON.stringify(chunks);
1754
1837
  if (chunkKey === nativeProgressChunkKey) return;
1755
1838
  try {
1756
- if (!streamSession) {
1757
- await startNativeProgressStream(chunks, chunkKey);
1758
- return;
1759
- }
1760
- await appendNativeProgressStream(chunks, chunkKey);
1839
+ if (!streamSession) await startNativeProgressStream(chunks, chunkKey);
1840
+ else await appendNativeProgressStream(chunks, chunkKey);
1841
+ nativeTaskState = reconciled.tasks;
1761
1842
  } catch (err) {
1762
1843
  runtime.error?.(danger(`slack-stream: native progress stream failed: ${formatSlackError(err)}, falling back`));
1763
1844
  streamFailed = true;
1764
1845
  }
1765
1846
  };
1766
1847
  const progressDraftGate = createChannelProgressDraftGate({ onStart: useNativeProgressStreaming ? updateNativeProgressStream : renderProgressDraft });
1848
+ const pushPlanProgress = async (steps, explanation) => {
1849
+ if (previewToolProgressSuppressed) return;
1850
+ latestPlan = steps ? steps.map((entry) => ({ ...entry })) : void 0;
1851
+ latestPlanExplanation = explanation?.replace(/\s+/g, " ").trim() || void 0;
1852
+ if (!draftStream && !useNativeProgressStreaming) return;
1853
+ if (streamMode !== "status_final" && !useNativeProgressStreaming) {
1854
+ const text = formatChannelProgressDraftText({
1855
+ entry: account.config,
1856
+ lines: previewToolProgressLines,
1857
+ seed: progressSeed,
1858
+ formatLine: escapeSlackMrkdwn,
1859
+ narration: latestPlanExplanation,
1860
+ plan: latestPlan
1861
+ });
1862
+ if (text) {
1863
+ draftStream?.update(text);
1864
+ hasStreamedMessage = true;
1865
+ }
1866
+ return;
1867
+ }
1868
+ const alreadyStarted = progressDraftGate.hasStarted;
1869
+ await progressDraftGate.startNow();
1870
+ if (alreadyStarted && progressDraftGate.hasStarted) await refreshStartedProgressDraft();
1871
+ };
1767
1872
  const refreshStartedProgressDraft = async () => {
1768
1873
  if (useNativeProgressStreaming) await updateNativeProgressStream();
1769
1874
  else renderProgressDraft();
@@ -1854,18 +1959,36 @@ async function dispatchPreparedSlackMessage(prepared) {
1854
1959
  label: "Reasoning"
1855
1960
  });
1856
1961
  };
1857
- const onDraftBoundary = !shouldUseDraftStream ? void 0 : async () => {
1858
- if (hasStreamedMessage && streamMode !== "status_final") {
1859
- draftStream?.forceNewMessage();
1860
- hasStreamedMessage = false;
1861
- appendRenderedText = "";
1862
- appendSourceText = "";
1863
- statusUpdateCount = 0;
1864
- }
1962
+ const resetDraftDeliveryState = () => {
1963
+ hasStreamedMessage = false;
1964
+ appendRenderedText = "";
1965
+ appendSourceText = "";
1966
+ statusUpdateCount = 0;
1967
+ };
1968
+ const resetDraftProgressState = () => {
1865
1969
  reasoningProgressRawText = "";
1866
1970
  previewToolProgressSuppressed = false;
1867
1971
  previewToolProgressLines = [];
1868
1972
  };
1973
+ const onDraftBoundary = !shouldUseDraftStream ? void 0 : async () => {
1974
+ if (hasStreamedMessage && streamMode !== "status_final") {
1975
+ draftStream?.forceNewMessage();
1976
+ resetDraftDeliveryState();
1977
+ }
1978
+ resetDraftProgressState();
1979
+ };
1980
+ const onQueuedFollowupAdmitted = !shouldUseDraftStream ? void 0 : async () => {
1981
+ await draftStream?.flush();
1982
+ draftStream?.forceNewMessage();
1983
+ draftPreviewCommitted = false;
1984
+ observedFinalReplyDelivery = false;
1985
+ deliveryTracker = createSlackEventDeliveryTracker();
1986
+ resetDraftDeliveryState();
1987
+ resetDraftProgressState();
1988
+ latestPlan = void 0;
1989
+ latestPlanExplanation = void 0;
1990
+ nativeTaskState = /* @__PURE__ */ new Map();
1991
+ };
1869
1992
  let dispatchError;
1870
1993
  let queuedFinal = false;
1871
1994
  let counts = {};
@@ -1910,6 +2033,7 @@ async function dispatchPreparedSlackMessage(prepared) {
1910
2033
  },
1911
2034
  onAssistantMessageStart: onDraftBoundary,
1912
2035
  onReasoningEnd: onDraftBoundary,
2036
+ onQueuedFollowupAdmitted,
1913
2037
  onReasoningStream: statusReactionsEnabled || previewToolProgressEnabled ? async (payload) => {
1914
2038
  await pushReasoningProgress(payload);
1915
2039
  if (!statusReactionsEnabled) return;
@@ -1943,13 +2067,7 @@ async function dispatchPreparedSlackMessage(prepared) {
1943
2067
  },
1944
2068
  onPlanUpdate: async (payload) => {
1945
2069
  if (payload.phase !== "update") return;
1946
- await pushPreviewProgress(buildChannelProgressDraftLine({
1947
- event: "plan",
1948
- phase: payload.phase,
1949
- title: payload.title,
1950
- explanation: payload.explanation,
1951
- steps: payload.steps
1952
- }));
2070
+ await pushPlanProgress(payload.planSteps, payload.explanation);
1953
2071
  },
1954
2072
  onApprovalEvent: async (payload) => {
1955
2073
  if (payload.phase !== "requested") return;
@@ -2006,12 +2124,16 @@ async function dispatchPreparedSlackMessage(prepared) {
2006
2124
  let streamFallbackDelivered = false;
2007
2125
  const finalStream = streamSession;
2008
2126
  if (finalStream && !finalStream.stopped) try {
2009
- const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent && previewToolProgressLines.length > 0 ? buildSlackProgressStreamCompletionChunks({
2010
- title: explicitProgressTitle,
2011
- lines: previewToolProgressLines,
2012
- maxLineChars: progressDraftMaxLineChars,
2013
- finalInProgressStatus: dispatchError ? "error" : "complete"
2014
- }) : void 0;
2127
+ const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent && (previewToolProgressLines.length > 0 || Boolean(latestPlan?.length) || Boolean(latestPlanExplanation) || [...nativeTaskState.values()].some((task) => task.status !== "complete" && task.status !== "error")) ? reconcileSlackNativeTaskChunks({
2128
+ previousTasks: nativeTaskState,
2129
+ chunks: buildSlackProgressStreamCompletionChunks({
2130
+ title: resolveNativeProgressTitle(),
2131
+ lines: resolveNativeProgressLines(),
2132
+ plan: resolveNativeProgressPlan(),
2133
+ maxLineChars: progressDraftMaxLineChars,
2134
+ finalInProgressStatus: dispatchError ? "error" : "complete"
2135
+ })
2136
+ }).chunks : void 0;
2015
2137
  if (completionChunks?.length) nativeProgressCompletionSent = true;
2016
2138
  const stopResult = await stopSlackStream({
2017
2139
  session: finalStream,
@@ -2199,7 +2321,7 @@ async function discardSlackPreflightMedia(media) {
2199
2321
  const SLACK_MENTION_RESOLUTION_CONCURRENCY = 4;
2200
2322
  const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
2201
2323
  const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
2202
- const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-DkTcWmpT.js").then((n) => n.g));
2324
+ const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-BZiuSTIq.js").then((n) => n.g));
2203
2325
  function collectUniqueSlackMentionIds$1(texts) {
2204
2326
  const seen = /* @__PURE__ */ new Set();
2205
2327
  const mentionIds = [];
@@ -2621,7 +2743,7 @@ function formatSlackThreadLabelSnippet(text) {
2621
2743
  }
2622
2744
  //#endregion
2623
2745
  //#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
2624
- const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-DkTcWmpT.js").then((n) => n.g));
2746
+ const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-BZiuSTIq.js").then((n) => n.g));
2625
2747
  const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
2626
2748
  function resolveSlackThreadSessionFreshness(params) {
2627
2749
  return params.ctx.channelRuntime?.session?.resolveEntryResetFreshness?.({
@@ -1,6 +1,6 @@
1
- import { l as normalizeSlackSlug } from "./group-policy-C-b2ZnSl.js";
1
+ import { t as buildSlackChannelPolicyScope, u as normalizeSlackSlug } from "./group-policy-85UWiriS.js";
2
2
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
3
- import { applyChannelMatchMeta, buildChannelKeyCandidates, resolveChannelEntryMatchWithFallback } from "openclaw/plugin-sdk/channel-targets";
3
+ import { applyChannelMatchMeta, buildChannelKeyCandidates } from "openclaw/plugin-sdk/channel-targets";
4
4
  import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
5
5
  //#region extensions/slack/src/monitor/channel-config.ts
6
6
  function firstDefined(...values) {
@@ -23,10 +23,9 @@ function resolveSlackChannelConfig(params) {
23
23
  const channelTarget = `channel:${channelId}`;
24
24
  const channelTargetLower = `channel:${channelIdLower}`;
25
25
  const channelTargetUpper = `channel:${channelIdUpper}`;
26
- const match = resolveChannelEntryMatchWithFallback({
27
- entries,
28
- keys: buildChannelKeyCandidates(channelId, channelIdLower !== channelId ? channelIdLower : void 0, channelIdUpper !== channelId ? channelIdUpper : void 0, channelTarget, channelTargetLower !== channelTarget ? channelTargetLower : void 0, channelTargetUpper !== channelTarget ? channelTargetUpper : void 0, allowNameMatching ? channelName ? `#${directName}` : void 0 : void 0, allowNameMatching ? directName : void 0, allowNameMatching ? normalizedName : void 0),
29
- wildcardKey: "*"
26
+ const match = buildSlackChannelPolicyScope({
27
+ channels: entries,
28
+ candidates: buildChannelKeyCandidates(channelId, channelIdLower !== channelId ? channelIdLower : void 0, channelIdUpper !== channelId ? channelIdUpper : void 0, channelTarget, channelTargetLower !== channelTarget ? channelTargetLower : void 0, channelTargetUpper !== channelTarget ? channelTargetUpper : void 0, allowNameMatching ? channelName ? `#${directName}` : void 0 : void 0, allowNameMatching ? directName : void 0, allowNameMatching ? normalizedName : void 0)
30
29
  });
31
30
  const { entry: matched, wildcardEntry: fallback } = match;
32
31
  const requireMentionDefault = defaultRequireMention ?? true;
@@ -52,7 +51,8 @@ function resolveSlackChannelConfig(params) {
52
51
  botLoopProtection: mergePairLoopGuardConfig(fallback?.botLoopProtection, matched?.botLoopProtection),
53
52
  users: firstDefined(resolved.users, fallback?.users),
54
53
  skills: firstDefined(resolved.skills, fallback?.skills),
55
- systemPrompt: firstDefined(resolved.systemPrompt, fallback?.systemPrompt)
54
+ systemPrompt: firstDefined(resolved.systemPrompt, fallback?.systemPrompt),
55
+ presenceEvents: firstDefined(resolved.presenceEvents, fallback?.presenceEvents)
56
56
  }, match);
57
57
  }
58
58
  //#endregion
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { d as formatSlackBotTokenIdentityWarning } from "./accounts-BOJJiHSr.js";
3
- import { r as formatSlackError } from "./group-policy-C-b2ZnSl.js";
4
- import { i as createSlackWebClient } from "./client-D2F6m8CP.js";
3
+ import { i as formatSlackError } from "./group-policy-85UWiriS.js";
4
+ import { a as createSlackWebClient } from "./client-WIPAS3Yr.js";
5
5
  import { withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
6
6
  //#region extensions/slack/src/probe.ts
7
7
  var probe_exports = /* @__PURE__ */ __exportAll({ probeSlack: () => probeSlack });