Skip to content

feat: add message revoke and forward commands#259

Merged
steipete merged 7 commits into
openclaw:mainfrom
dovocoder:feature/message-lifecycle
May 22, 2026
Merged

feat: add message revoke and forward commands#259
steipete merged 7 commits into
openclaw:mainfrom
dovocoder:feature/message-lifecycle

Conversation

@dovocoder
Copy link
Copy Markdown
Contributor

@dovocoder dovocoder commented May 21, 2026

Summary

  • Add explicit messages revoke command for deleting sent messages for everyone.
  • Add messages forward command for forwarding stored text and media/document messages to another recipient.
  • Support forwarding metadata such as media keys, direct paths, filenames, captions, mime types, and forwarding context.
  • Allow messages revoke to target an explicit --chat + --id even when the target is not present in the local message store.
  • Fix outgoing message sync for messages sent from another linked device: WhatsApp DeviceSentMessage wrappers are now parsed and stored in the actual destination chat with from_me=true, instead of being missed or associated with the wrong/self chat.
  • Update messages and sync docs plus changelog.

Why

This PR covers two connected message-lifecycle gaps:

  1. The CLI did not expose direct user-facing commands for revoking and forwarding messages.
  2. Outgoing messages sent from another linked WhatsApp device were not reliably represented in the local store. Those messages arrive wrapped as DeviceSentMessage; without unwrapping that metadata, wacli can miss the real destination chat and fail later workflows that depend on finding the outgoing message locally.

By fixing the outgoing-message import path and adding explicit lifecycle commands, wacli can now sync, find, forward, and revoke those messages more reliably.

Testing

  • pnpm format:check
  • pnpm lint
  • pnpm -s test:go
  • pnpm -s test:fts
  • pnpm -s test:windows-lock
  • pnpm -s test:cgo-required
  • pnpm build
  • git diff --check
  • Manual live smoke:
    • forwarded latest outbound Assistent image to Automator
    • revoked the forwarded message by explicit chat/id after loosening revoke lookup

Live behavior proof (redacted)

Run on 2026-05-22 against an authenticated local WhatsApp store. The recipient/source chat was the account's own WhatsApp JID so no third-party chat was targeted. Phone number, chat name, and message IDs are redacted.

$ ./dist/wacli --json send text --to <redacted-self>@s.whatsapp.net --message "wacli PR259 live proof <timestamp>" --post-send-wait 3s
{"success":true,"data":{"id":"<source-msg-id>","sent":true,"to":"<redacted-self>@s.whatsapp.net"},"error":null}

$ ./dist/wacli --json messages forward --chat <redacted-self>@s.whatsapp.net --id <source-msg-id> --to <redacted-self>@s.whatsapp.net --post-send-wait 3s
{"success":true,"data":{"forwarded":true,"id":"<forwarded-msg-id>","source":"<source-msg-id>","to":"<redacted-self>@s.whatsapp.net"},"error":null}

$ ./dist/wacli --read-only --json messages show --chat <redacted-self>@s.whatsapp.net --id <forwarded-msg-id>
{"success":true,"data":{"ChatJID":"<redacted-self>@s.whatsapp.net","ChatName":"<redacted-chat-name>","MsgID":"<forwarded-msg-id>","SenderJID":"","SenderName":"me","Timestamp":"2026-05-22T13:47:55Z","FromMe":true,"Text":"wacli PR259 live proof <timestamp>","DisplayText":"wacli PR259 live proof <timestamp>","IsForwarded":true,"ForwardingScore":1,"Revoked":false,"DeletedForMe":false},"error":null}

$ ./dist/wacli --json messages revoke --chat <redacted-self>@s.whatsapp.net --id <forwarded-msg-id> --post-send-wait 3s
{"success":true,"data":{"id":"<revoke-action-msg-id>","revoked":true,"target":"<forwarded-msg-id>","to":"<redacted-self>@s.whatsapp.net"},"error":null}

$ ./dist/wacli --read-only --json messages show --chat <redacted-self>@s.whatsapp.net --id <forwarded-msg-id>
{"success":true,"data":{"ChatJID":"<redacted-self>@s.whatsapp.net","ChatName":"<redacted-chat-name>","MsgID":"<forwarded-msg-id>","SenderJID":"","SenderName":"me","Timestamp":"2026-05-22T13:47:55Z","FromMe":true,"Text":"","DisplayText":"This message was deleted","IsForwarded":true,"ForwardingScore":1,"Revoked":true,"DeletedForMe":false},"error":null}

Validation after merge with current origin/main:

$ go test ./cmd/wacli ./internal/app ./internal/store ./internal/wa
ok  github.com/openclaw/wacli/cmd/wacli
ok  github.com/openclaw/wacli/internal/app
ok  github.com/openclaw/wacli/internal/store
ok  github.com/openclaw/wacli/internal/wa

$ pnpm format:check && pnpm lint && pnpm test && pnpm build && git diff --check
# passed

@dovocoder
Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 22, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 22, 2026

Codex review: needs maintainer review before merge.

Latest ClawSweeper review: 2026-05-22 13:55 UTC / May 22, 2026, 9:55 AM ET.

Workflow note: Future ClawSweeper reviews update this same comment in place.

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.

Summary
The branch adds messages revoke and messages forward, unwraps DeviceSentMessage wrappers into the destination chat during sync, and updates tests, docs, and the changelog.

Reproducibility: Do we have a high-confidence way to reproduce the issue? Partly: the DeviceSent sync gap is source-reproducible because current main lacks DeviceSent unwrapping, while the new commands are feature work now supported by redacted live terminal proof for text forward/revoke.

PR rating
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Summary: Normal good PR quality: source structure, tests, docs, and text/revoke live proof are present, with only media-forwarding proof depth left for maintainer judgment.

Rank-up moves:

  • Add a redacted media-forwarding terminal log, screenshot, or recording if maintainers want that path independently demonstrated before merge.
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.

Real behavior proof
Sufficient (terminal): The PR body includes redacted authenticated-store terminal output showing after-fix text send, forward, show, revoke, and show-revoked behavior, though it does not separately show media forwarding.

Risk before merge

  • The branch forwards and revokes real WhatsApp messages, so wrong targeting or payload construction could affect live chats even when unit tests pass.
  • The posted terminal proof covers text forwarding and revoke; media forwarding is supported by payload tests and a textual smoke note, but not by reviewer-visible media output.

Maintainer options:

  1. Proceed with maintainer review (recommended)
    Treat the redacted terminal proof for text forward/revoke plus the focused media payload tests as sufficient for this iteration, while reviewing the remote mutation paths carefully before merge.
  2. Ask for media proof too
    If maintainers want reviewer-visible coverage for the media path, ask for a redacted terminal log, screenshot, or recording showing a stored media message forwarded and rendered in the intended chat.

Next step before merge
No ClawSweeper repair is needed; the remaining action is ordinary maintainer review of a live WhatsApp message-delivery change.

Security
Cleared: No supply-chain, dependency, permission, or credential-handling concern was found; the new commands use the existing authenticated writable-store send path.

Review details

Best possible solution:

Land the lifecycle commands and DeviceSent import fix after maintainer review accepts the live-message delivery risk, with an extra media-forwarding proof requested only if maintainers want that path demonstrated separately.

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

Do we have a high-confidence way to reproduce the issue? Partly: the DeviceSent sync gap is source-reproducible because current main lacks DeviceSent unwrapping, while the new commands are feature work now supported by redacted live terminal proof for text forward/revoke.

Is this the best way to solve the issue?

Is this the best way to solve the issue? Yes from source review: the patch follows the existing writable-store, send, parser, store, docs, and test patterns; the main remaining question is maintainer comfort with the media-forwarding proof depth.

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes redacted authenticated-store terminal output showing after-fix text send, forward, show, revoke, and show-revoked behavior, though it does not separately show media forwarding.
  • add rating: 🐚 platinum hermit: Current PR rating is 🐚 platinum hermit because proof is 🐚 platinum hermit, patch quality is 🐚 platinum hermit, and Normal good PR quality: source structure, tests, docs, and text/revoke live proof are present, with only media-forwarding proof depth left for maintainer judgment.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes redacted authenticated-store terminal output showing after-fix text send, forward, show, revoke, and show-revoked behavior, though it does not separately show media forwarding.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority user-facing message lifecycle feature plus a targeted sync import fix with limited repository blast radius.
  • merge-risk: 🚨 message-delivery: The PR sends forwarded WhatsApp payloads and revoke messages to live chats, so incorrect targeting or payload construction would affect message delivery.
  • rating: 🐚 platinum hermit: Current PR rating is 🐚 platinum hermit because proof is 🐚 platinum hermit, patch quality is 🐚 platinum hermit, and Normal good PR quality: source structure, tests, docs, and text/revoke live proof are present, with only media-forwarding proof depth left for maintainer judgment.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes redacted authenticated-store terminal output showing after-fix text send, forward, show, revoke, and show-revoked behavior, though it does not separately show media forwarding.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes redacted authenticated-store terminal output showing after-fix text send, forward, show, revoke, and show-revoked behavior, though it does not separately show media forwarding.

What I checked:

  • Current main command surface: Current main wires messages subcommands through list/search/starred/show/context/export/delete/edit only, so messages revoke and messages forward are not already implemented on main. (cmd/wacli/messages.go:24, 9388460fd1e4)
  • Existing delete-for-everyone behavior: Current main already supports revoke semantics through messages delete, with writable/auth checks and RevokeMessage, which is relevant to the new explicit messages revoke alias and fallback behavior. (cmd/wacli/messages.go:469, 9388460fd1e4)
  • Current main DeviceSent gap: Current main parses live/history message wrappers without applying DeviceSentMeta or unwrapping DeviceSentMessage, so the sync fix is not already present on main. (internal/wa/messages.go:88, 9388460fd1e4)
  • PR diff inspection: The PR patch adds newMessagesRevokeCmd, newMessagesForwardCmd, DeviceSent parser handling, focused command/parser/sync tests, and docs/changelog entries. (cmd/wacli/messages.go:30, f9a78acf6364)
  • Live proof in PR body: The PR body now includes redacted authenticated-store terminal output showing a text message sent, forwarded, shown as forwarded, revoked, and then shown as revoked. (f9a78acf6364)
  • History routing: Git history shows Peter Steinberger introduced the existing message edit/delete and forwarded-metadata areas, while Dovocoder recently landed adjacent sync/send work before this PR. (9388460fd1e4)

Likely related people:

  • Peter Steinberger: Introduced the current message edit/delete path, forwarded-message metadata, and recently maintained the parser area touched by the PR. (role: feature-history owner; confidence: high; commits: da9134e6aead, 7533e4bef924, 9388460fd1e4; files: cmd/wacli/messages.go, internal/wa/messages.go, docs/messages.md)
  • Dovocoder: Recently contributed merged sync/send-adjacent WhatsApp work and authored the PR branch, making them relevant beyond only opening this PR. (role: recent adjacent contributor; confidence: medium; commits: 12c8d8a6a98a, 3613468d33b4, 95b6ee231403; files: internal/app/sync.go, cmd/wacli/send_file.go, cmd/wacli/messages.go)

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

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 message-delivery 🚨 Merging this PR could drop, duplicate, misroute, suppress, or wrongly target messages. labels May 22, 2026
@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 22, 2026

ClawSweeper PR egg

✨ Hatched: 🌱 uncommon Moonlit Patch Peep

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🌱 uncommon.
Trait: polishes edge cases.
Image traits: location workflow harbor; accessory little merge flag; palette moss green and polished brass; mood sparkly; pose leaning over a miniature review desk; shell starlit enamel shell; lighting soft underwater shimmer; background small review tokens.
Share on X: post this hatch
Copy: My PR egg hatched a 🌱 uncommon Moonlit Patch Peep in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@steipete
Copy link
Copy Markdown
Collaborator

Pushed maintainer updates in 4b09c8c.

What changed:

  • merged current main after fix: import completed call logs #261 landed
  • resolved the changelog conflict
  • fixed forwarded text to preserve leading/trailing whitespace instead of trimming message content
  • added a focused regression test for whitespace-preserving forwarded text

Local proof:

  • go test ./cmd/wacli ./internal/app ./internal/wa
  • pnpm format:check && pnpm lint && pnpm test && pnpm build && git diff --check
  • autoreview local patch clean: no accepted/actionable findings

Live proof status: blocked locally. The only local store at ~/.wacli currently reports authenticated:false, so I cannot honestly verify messages forward / messages revoke against WhatsApp from this machine yet.

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 22, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@dovocoder
Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 22, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. 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. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 22, 2026
…to feature/message-lifecycle

# Conflicts:
#	CHANGELOG.md
@steipete
Copy link
Copy Markdown
Collaborator

Maintainer update pushed after merging current main and fixing the new source --chat help text to match the implementation.

Proof:

  • go test ./cmd/wacli ./internal/app ./internal/store ./internal/wa
  • pnpm format:check && pnpm lint && pnpm test && pnpm build && git diff --check
  • /Users/steipete/Projects/agent-scripts/skills/autoreview/scripts/autoreview --mode branch --base origin/main
  • Live verified from clawmac with /tmp/wacli-pr259 --account molty to +436769770569:
    • send text succeeded: 3EB020026A3FE077BE0C2B
    • messages forward succeeded: 3EB034EE191C5A7A5E7F42
    • messages revoke succeeded for the original: revoke receipt 3EB06D3708CC7BBB37CA30
    • messages show confirmed the original is revoked locally and the forwarded copy is stored with IsForwarded=true.

@steipete steipete merged commit bb68ecc into openclaw:main May 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 message-delivery 🚨 Merging this PR could drop, duplicate, misroute, suppress, or wrongly target messages. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants