Skip to content

feat(slack): render progress as native progress task cards#87748

Merged
steipete merged 13 commits into
mainfrom
maint/pr-82258-slack-progress-cards
May 28, 2026
Merged

feat(slack): render progress as native progress task cards#87748
steipete merged 13 commits into
mainfrom
maint/pr-82258-slack-progress-cards

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Summary

  • Recreates feat(slack): render progress as native progress task cards #82258 from the contributor branch because the fork branch rejected maintainer pushes.
  • Adds opt-in Slack native progress task cards for progress streaming mode.
  • Caps native Slack progress plan titles to Slack chunk limits and merges Slack account streaming overrides field-by-field while preserving legacy scalar overrides.

Verification

  • pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts
  • .agents/skills/autoreview/scripts/autoreview --mode local
  • git diff --check

Real behavior proof

Behavior addressed: Slack progress mode can opt into native task cards without breaking fallback delivery or account-level streaming overrides.
Real environment tested: local OpenClaw checkout, focused Slack unit tests.
Exact steps or command run after this patch: pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts
Evidence after fix: 2 test files passed, 42 tests passed.
Observed result after fix: long native plan titles are capped before Slack stream chunks are built; account streaming object overrides inherit root streaming fields, while legacy scalar account overrides still replace the root object.
What was not tested: live Slack workspace delivery in this maintainer branch; original PR supplied real behavior proof and CI coverage.

Refs #82258.

Co-authored-by: Simon van Laak [email protected]

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: slack Channel integration: slack size: XL maintainer Maintainer-authored PR labels May 28, 2026
@clawsweeper

clawsweeper Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed May 28, 2026, 3:06 PM ET / 19:06 UTC.

Summary
This PR adds opt-in Slack native progress task cards, propagates progress item ids, extends Slack streaming config/schema/docs/tests, and adjusts Slack stream helpers to send structured chunks.

PR surface: Source +580, Tests +1208, Docs +20, Generated 0. Total +1808 across 22 files.

Reproducibility: yes. source-level reproduction is clear: buildPlanTasks slices to the visible task window and then derives idless fallback ids from index, so dropping an older idless line renumbers remaining task_update ids.

Review metrics: 1 noteworthy metric.

  • Slack config surface changes: 1 option added, 1 merge behavior changed. The new nativeTaskCards key and account streaming object merge affect upgrade and operator config behavior, so maintainers should review compatibility before merge.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

Mantis proof suggestion
A short Slack desktop smoke would directly show native progress cards updating and the final reply landing in the same thread. A maintainer can ask Mantis to capture proof by posting a new PR comment that starts with the OpenClaw Mantis account mention, followed by:

slack desktop smoke: verify opt-in Slack native progress task cards update during work and the final reply lands in the same thread.

Risk before merge

  • [P1] Idless native progress lines can still be renumbered after maxLines capping, which can update the wrong Slack task card or leave stale cards in the native plan.
  • [P1] The new Slack-only streaming.progress.nativeTaskCards option and account-level streaming object merge are upgrade-sensitive config surfaces even though the feature is default-off and legacy scalar overrides are tested.
  • [P1] This maintainer recreation and feat(slack): render progress as native progress task cards #82258 remain paired open branches, so maintainers should choose one canonical branch before landing.

Maintainer options:

  1. Fix idless task identity before merge (recommended)
    Stabilize fallback task ids for progress lines without upstream ids and add a regression covering maxLines capping before landing the native card path.
  2. Accept the config compatibility risk
    Maintainers can intentionally accept the new Slack-only config key and account streaming merge behavior after confirming upgrade behavior is acceptable.
  3. Pick one canonical branch
    Pause or close one of the paired Slack native progress-card PRs so review, proof, and follow-up fixes land through a single branch.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Stabilize Slack native progress fallback task ids for idless lines across maxLines capping, add focused regression tests for idless plan/approval or item events, and keep nativeTaskCards default-off with no unrelated changes.

Next step before merge

  • [P2] A focused automated repair can stabilize idless Slack task ids; maintainer review is still needed afterward for compatibility and paired-branch handling.

Security
Cleared: No concrete security or supply-chain regression was found; the diff does not change workflows, lockfiles, secrets handling, or dependency sources.

Review findings

  • [P2] Keep fallback task ids stable after capping — extensions/slack/src/progress-blocks.ts:141
Review details

Best possible solution:

Land one canonical branch after stabilizing idless task ids, preserving default-off behavior, and recording upgrade safety for Slack account streaming config.

Do we have a high-confidence way to reproduce the issue?

Yes, source-level reproduction is clear: buildPlanTasks slices to the visible task window and then derives idless fallback ids from index, so dropping an older idless line renumbers remaining task_update ids.

Is this the best way to solve the issue?

No, not yet: the opt-in Slack chunk approach is the right direction, but the implementation should stabilize idless fallback ids and get maintainer compatibility signoff before merge.

Full review comments:

  • [P2] Keep fallback task ids stable after capping — extensions/slack/src/progress-blocks.ts:141
    When a native progress line has no line.id, this fallback id is based on the line's current position after the rolling window is sliced. Once maxLines drops an older idless entry, remaining tasks get new ids, so Slack can update the wrong card or leave stale task cards in the plan. Derive a stable fallback from the line identity before/independent of capping, or otherwise persist ids for idless lines.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.84

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against a2595f16d486.

Label changes

Label justifications:

  • P2: This is a normal-priority Slack feature PR with a focused correctness blocker and limited blast radius.
  • merge-risk: 🚨 compatibility: The PR adds a Slack streaming config option and changes account-level streaming object merge behavior, which can affect existing Slack config upgrades.
  • merge-risk: 🚨 message-delivery: The new native Slack progress stream path can mis-associate task_update chunks for idless progress lines until fallback task ids are stable.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (recording): The linked original PR includes a Slack workspace recording and redacted stream evidence for native task cards, while this maintainer recreation adds focused post-change tests.
  • proof: sufficient: Contributor real behavior proof is sufficient. The linked original PR includes a Slack workspace recording and redacted stream evidence for native task cards, while this maintainer recreation adds focused post-change tests.
  • proof: 🎥 video: Contributor real behavior proof includes video or recording evidence. The linked original PR includes a Slack workspace recording and redacted stream evidence for native task cards, while this maintainer recreation adds focused post-change tests.
Evidence reviewed

PR surface:

Source +580, Tests +1208, Docs +20, Generated 0. Total +1808 across 22 files.

View PR surface stats
Area Files Added Removed Net
Source 12 650 70 +580
Tests 8 1255 47 +1208
Docs 1 20 0 +20
Config 0 0 0 0
Generated 1 7 7 0
Other 0 0 0 0
Total 22 1932 124 +1808

Acceptance criteria:

  • [P2] node scripts/run-vitest.mjs extensions/slack/src/progress-blocks.test.ts extensions/slack/src/monitor/message-handler/dispatch.preview-fallback.test.ts src/plugin-sdk/channel-streaming.test.ts.
  • [P1] git diff --check.

What I checked:

  • Current main lacks this feature: Current main only enables Slack native streaming for partial mode and has no native progress task-card chunk builder in progress-blocks, so this PR still carries unique feature work rather than being implemented on main. (extensions/slack/src/monitor/message-handler/dispatch.ts:167, a2595f16d486)
  • Opt-in gate is present on the PR head: The PR only enables native Slack streaming for progress mode when native transport is enabled and nativeProgressTaskCards is true. (extensions/slack/src/monitor/message-handler/dispatch.ts:172, 4803e98820b0)
  • Review finding source: buildPlanTasks still assigns idless native task ids from the post-capping array index, so older-line eviction can renumber remaining idless tasks even though Slack task_update chunks identify tasks by id. (extensions/slack/src/progress-blocks.ts:141, 4803e98820b0)
  • Slack dependency contract checked: Slack docs for chat.startStream/chat.appendStream/chat.stopStream document chunks, task_update ids, plan_update chunks, task_display_mode, and the 256-character task/plan chunk limit; the PR's structured chunk path targets that contract.
  • Configured Slack SDK versions: The Slack plugin depends on @slack/types 2.21.1 and @slack/web-api 7.16.0, matching the PR's AnyChunk and ChatStreamer usage surface. (extensions/slack/package.json:12, a2595f16d486)
  • Repository policy applied: Root and scoped AGENTS.md files mark config/default additions, plugin SDK surfaces, Slack channel behavior, and docs as compatibility-sensitive review areas. (AGENTS.md:12, a2595f16d486)

Likely related people:

  • steipete: Current-main blame on the Slack dispatch streaming block points at Peter Steinberger's recent Slack work, and the PR head includes hardening commits by steipete on the same files. (role: recent area contributor and maintainer-branch author; confidence: high; commits: a2595f16d486, 57c8e91e13a5, a9d860603959; files: extensions/slack/src/monitor/message-handler/dispatch.ts, extensions/slack/src/accounts.ts, extensions/slack/src/progress-blocks.ts)
  • simonvanlaak: The linked original PR and most commits in this recreated branch were authored by simonvanlaak, including the Slack native task-card config, streaming, tests, and progress identity changes. (role: original feature branch author; confidence: medium; commits: 35c455d97a06, 55c45b2fa777, 713c73f33d29; files: extensions/slack/src/progress-blocks.ts, extensions/slack/src/monitor/message-handler/dispatch.ts, src/channels/streaming.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59025447f5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +139 to +141
id: line.id
? stableTaskIdPart(line.id)
: `${slugTaskIdPart(line.toolName ?? line.kind ?? line.label)}_${index + 1}`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep fallback task ids stable across progress updates

When Slack-native progress is enabled and a progress line has no line.id (for example plan/approval events or provider item events that omit itemId), this fallback id is based on the line's current position in the capped progress array. Once streaming.progress.maxLines drops an older entry, every remaining idless task can be renumbered, so Slack task_update chunks update the wrong cards or leave stale cards in the plan instead of preserving the rolling-window behavior the draft preview had. Use a stable fallback derived from the line identity, or otherwise preserve per-line ids before slicing.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 28, 2026
@steipete
steipete force-pushed the maint/pr-82258-slack-progress-cards branch from 08801a0 to 4803e98 Compare May 28, 2026 19:00

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4803e98820

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +105 to +106
...(baseConfig.preview || accountConfig.preview
? { preview: { ...baseConfig.preview, ...accountConfig.preview } }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve preview chunk defaults when merging accounts

When a Slack account overrides only part of streaming.preview.chunk, this shallow preview merge replaces the whole chunk object, so top-level defaults such as minChars or breakPreference are dropped even though the rest of this helper now inherits account streaming settings field-by-field. resolveChannelStreamingPreviewChunk() consumes that nested object as-is, so an account config like top-level preview.chunk: { minChars, maxChars, breakPreference } plus account preview.chunk: { maxChars } silently changes the chunking behavior for that account; merge preview.chunk the same way block.coalesce is merged.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor Author

Verification before merge:

Behavior addressed: Slack progress-mode streaming can render native task-card progress updates while preserving draft fallback behavior; account-level streaming config now deep-merges canonical nested defaults without breaking legacy scalar overrides; plugin SDK fetch runtime import stays lightweight.
Real environment tested: local macOS checkout plus GitHub Actions for PR #87748 at 4803e98.
Exact steps or command run after this patch: pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts src/plugin-sdk/fetch-runtime.test.ts; pnpm lint --threads=8; git diff --check; .agents/skills/autoreview/scripts/autoreview --mode local; GitHub PR checks for #87748.
Evidence after fix: local focused tests passed with 43 tests total; oxlint shards passed; autoreview reported no accepted/actionable findings; GitHub PR checks show 100 statuses with no non-green statuses.
Observed result after fix: #87748 is mergeable and all required checks are green.
What was not tested: live Slack workspace delivery was not exercised in this pass.

@steipete
steipete merged commit 7c4601e into main May 28, 2026
100 checks passed
@steipete
steipete deleted the maint/pr-82258-slack-progress-cards branch May 28, 2026 19:08
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 29, 2026
Render Slack progress-mode updates as native task-card progress blocks, with bounded Slack chunk text and stable fallback behavior.

Also deep-merge Slack account streaming objects over top-level defaults while preserving legacy scalar account overrides, and keep the plugin SDK fetch runtime import path from evaluating guarded-fetch dispatcher code.

Verification:
- pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts src/plugin-sdk/fetch-runtime.test.ts
- pnpm lint --threads=8
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local
- GitHub PR checks green on openclaw#87748 at 4803e98

Refs openclaw#82258

Co-authored-by: Simon van Laak <[email protected]>
steipete added a commit that referenced this pull request May 29, 2026
Render Slack progress-mode updates as native task-card progress blocks, with bounded Slack chunk text and stable fallback behavior.

Also deep-merge Slack account streaming objects over top-level defaults while preserving legacy scalar account overrides, and keep the plugin SDK fetch runtime import path from evaluating guarded-fetch dispatcher code.

Verification:
- pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts src/plugin-sdk/fetch-runtime.test.ts
- pnpm lint --threads=8
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local
- GitHub PR checks green on #87748 at 4803e98

Refs #82258

Co-authored-by: Simon van Laak <[email protected]>
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
Render Slack progress-mode updates as native task-card progress blocks, with bounded Slack chunk text and stable fallback behavior.

Also deep-merge Slack account streaming objects over top-level defaults while preserving legacy scalar account overrides, and keep the plugin SDK fetch runtime import path from evaluating guarded-fetch dispatcher code.

Verification:
- pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts src/plugin-sdk/fetch-runtime.test.ts
- pnpm lint --threads=8
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local
- GitHub PR checks green on openclaw#87748 at 4803e98

Refs openclaw#82258

Co-authored-by: Simon van Laak <[email protected]>
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
Render Slack progress-mode updates as native task-card progress blocks, with bounded Slack chunk text and stable fallback behavior.

Also deep-merge Slack account streaming objects over top-level defaults while preserving legacy scalar account overrides, and keep the plugin SDK fetch runtime import path from evaluating guarded-fetch dispatcher code.

Verification:
- pnpm test extensions/slack/src/progress-blocks.test.ts extensions/slack/src/accounts.test.ts src/plugin-sdk/fetch-runtime.test.ts
- pnpm lint --threads=8
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local
- GitHub PR checks green on openclaw#87748 at 4803e98

Refs openclaw#82258

Co-authored-by: Simon van Laak <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: slack Channel integration: slack docs Improvements or additions to documentation feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants