Skip to content

feat(gmail): add --include-attachments to messages search - #962

Open
ronny-rentner wants to merge 4 commits into
openclaw:mainfrom
ronny-rentner:feat/gmail-include-attachments
Open

feat(gmail): add --include-attachments to messages search#962
ronny-rentner wants to merge 4 commits into
openclaw:mainfrom
ronny-rentner:feat/gmail-include-attachments

Conversation

@ronny-rentner

Copy link
Copy Markdown
Contributor

Summary

Adds --include-attachments to gmail messages search. It lists each message's attachment metadata (filename, size, mimeType, attachmentId) next to the subject, without fetching message bodies.

Today the only way to see a message's attachments in search results is --include-body, which also decodes and returns the full body. --include-attachments gives just the attachment list.

  • New flag --include-attachments (env GOG_GMAIL_INCLUDE_ATTACHMENTS).
  • Emits the existing attachmentOutput shape (the same one --include-body already produces), so the JSON is purely additive — no existing field changes.
  • Cheap fetch: uses format=full with a fields mask that selects only the attachment part metadata — payload(headers,parts(filename,mimeType,body(size,attachmentId))) — so no body/data is transferred, just the attachment list.

Motivation

Lets a caller enumerate what a message carries — and grab the attachmentIds it needs to download — without pulling message bodies.

User-facing changes

  • New flag --include-attachments on gmail messages search.
  • New env var GOG_GMAIL_INCLUDE_ATTACHMENTS (mirrors the existing GOG_GMAIL_INLINE_MAX_BYTES pattern).
  • Additive attachments array in the JSON output, only when the flag is set.

Testing

  • New TestExecute_GmailMessagesSearch_IncludeAttachments: the flag lists attachments and does not include the body; the default search lists neither.
  • make fmt / make lint clean; command docs regenerated (make docs-commands).
  • Verified against a live account.

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

Copy link
Copy Markdown

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: 54c58df304

ℹ️ 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".

}

items, err := fetchMessageDetails(ctx, svc, messages, idToName, loc, c.IncludeBody, c.BodyFormat)
items, err := fetchMessageDetails(ctx, svc, messages, idToName, loc, c.IncludeBody, c.BodyFormat, c.IncludeAttachments)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Render attachments in non-JSON search output

When --include-attachments is used with the default table output or --plain, this path fetches and populates messageItem.Attachments, but the later call to gmailMessageColumns(c.IncludeBody, c.Full) never reads that field. The flag therefore performs the additional full-format API requests while producing exactly the same stdout as a search without the flag. Pass the option into the presentation layer and render the metadata, or explicitly restrict and document the flag as JSON-only.

Useful? React with 👍 / 👎.

@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: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Aug 7, 2026
@clawsweeper

clawsweeper Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed August 8, 2026, 1:26 AM ET / 05:26 UTC.

ClawSweeper review

What this changes

The PR adds --include-attachments and GOG_GMAIL_INCLUDE_ATTACHMENTS to Gmail message search, returning attachment metadata in JSON and table output.

Merge readiness

Blocked until real behavior proof is added - 9 items remain

Keep open: this is a useful opt-in Gmail feature, but attachment-only search currently retrieves full message payloads, including inline body data, and its text output truncates the attachment IDs needed for downloads.

Priority: P2
Reviewed head: eb83a8b88f3d7ef8af6ec926bcbe2a63b8f07177
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) The patch has useful scope and tests, but an unresolved privacy defect and absent inspectable real-behavior proof make it not merge-ready.
Proof confidence 🧂 unranked krab (1/6) Needs real behavior proof before merge: The PR claims a live-account verification but provides no inspectable redacted terminal output, trace, log, recording, or artifact showing the corrected real behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦪 silver shellfish (2/6) Security review found an item that needs attention.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The PR claims a live-account verification but provides no inspectable redacted terminal output, trace, log, recording, or artifact showing the corrected real behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 5 items Full-payload request contradicts the privacy contract: The attachment-only branch requests format=full with Fields(...,payload). Selecting the whole payload includes inline body data in the response even though it is not rendered, contrary to the PR's stated no-body-transfer behavior.
Text output loses the usable attachment identifier: The new table column emits only the first eight characters, while the existing download command requires the full opaque attachment ID and other attachment listings print it in full.
Prior P1 remains unresolved: The previous review identified raw-body retrieval; the current-head delta from that review changes only attachment/presentation helpers, not the message-detail request path.
Findings 2 actionable findings [P1] Avoid fetching raw bodies for attachment-only searches
[P2] Emit download-capable IDs in text output
Security Needs attention Attachment-only mode retrieves message bodies: The full-payload field selection can bring inline email body data into memory even when callers requested attachment metadata only, contradicting the feature's privacy boundary.

How this fits together

Gmail message search first lists matching messages, then fetches detail for each result to produce summaries, optional bodies, and attachments. The new path controls what Gmail data is requested and then emitted to JSON or tabular output.

flowchart LR
  Query[Search query] --> List[Matching message IDs]
  List --> Detail[Message detail request]
  Detail --> Decision{Requested detail}
  Decision --> Attachments[Attachment metadata collection]
  Attachments --> Output[JSON or table output]
  Decision --> Bodies[Message body data]
Loading

Decision needed

Question Recommendation
May attachment-only search retrieve raw Gmail body data to cover arbitrarily nested MIME parts, or must the feature preserve its advertised no-body-transfer boundary even if that constrains discovery? Preserve attachment-only minimization: Require a retrieval strategy that excludes body data and retain only behavior that can meet that contract.

Why: The current implementation cannot both request the entire payload and truthfully promise that bodies are not transferred; choosing that privacy boundary is maintainer policy, not a mechanical review choice.

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The PR claims a live-account verification but provides no inspectable redacted terminal output, trace, log, recording, or artifact showing the corrected real behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Avoid fetching raw bodies for attachment-only searches (P1) - Fields(...,payload) selects the complete payload, including inline body.data; not rendering it does not satisfy this PR's promise that body data is not transferred. Use a metadata-only retrieval strategy or obtain explicit approval to change that contract. This repeats the still-unfixed P1 from the prior review.
  • Emit download-capable IDs in text output (P2) - The new column reduces each opaque ID to eight characters, but gmail attachment requires the complete ID and existing attachment text listings expose it in full. Users of the default table/plain output therefore cannot use the value this feature advertises for downloads.
  • Resolve security concern: Attachment-only mode retrieves message bodies - The full-payload field selection can bring inline email body data into memory even when callers requested attachment metadata only, contradicting the feature's privacy boundary.
  • Resolve merge risk (P1) - Merging would make an attachment-only command fetch raw inline email bodies into the client process, weakening the stated data-minimization boundary; default table/plain output also exposes only unusable partial IDs.
  • Complete next step (P2) - A maintainer must choose the attachment-only privacy boundary before a safe implementation path can be selected.
  • Improve patch quality - Resolve the no-body-transfer contract and retain full IDs in text output.
  • Improve patch quality - Add redacted live terminal or request/response evidence showing attachment discovery without body data; update the PR body to trigger re-review.

Findings

  • [P1] Avoid fetching raw bodies for attachment-only searches — internal/cmd/gmail_messages.go:252-256
  • [P2] Emit download-capable IDs in text output — internal/cmd/gmail_presentation.go:53-56
  • [high] Attachment-only mode retrieves message bodies — internal/cmd/gmail_messages.go:256
Agent review details

Security

Needs attention: The new attachment-only path weakens data minimization by requesting full Gmail payloads containing body data.

Review metrics

Metric Value Why it matters
Production versus test delta production +59/-24, tests +133/-3, docs +1 The feature materially changes Gmail retrieval behavior and has substantial mock coverage, but still needs real after-fix proof.

Merge-risk options

Maintainer options:

  1. Restore the attachment-only data boundary (recommended)
    Before merge, avoid requesting the whole payload, emit full attachment IDs in text output, and add focused regression coverage plus redacted live proof.
  2. Explicitly accept full-payload semantics
    If full payloads are required for arbitrary MIME depth, approve that privacy tradeoff and change the user-facing claim before merge.

Technical review

Best possible solution:

Preserve the attachment-only privacy guarantee with a Gmail-supported metadata-only retrieval strategy, retain full download-capable IDs in text output, and demonstrate the corrected live request/result with redacted evidence.

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

Yes, from source: enable the new flag for a message with inline body content and the request selects the entire Gmail payload; the added HTTP test also supplies body data while checking only that it is not printed.

Is this the best way to solve the issue?

No: suppressing body output is not equivalent to avoiding body retrieval, and shortening an opaque identifier makes text results unusable for the existing download command.

Full review comments:

  • [P1] Avoid fetching raw bodies for attachment-only searches — internal/cmd/gmail_messages.go:252-256
    Fields(...,payload) selects the complete payload, including inline body.data; not rendering it does not satisfy this PR's promise that body data is not transferred. Use a metadata-only retrieval strategy or obtain explicit approval to change that contract. This repeats the still-unfixed P1 from the prior review.
    Confidence: 0.99
  • [P2] Emit download-capable IDs in text output — internal/cmd/gmail_presentation.go:53-56
    The new column reduces each opaque ID to eight characters, but gmail attachment requires the complete ID and existing attachment text listings expose it in full. Users of the default table/plain output therefore cannot use the value this feature advertises for downloads.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8fe3e7995d0b.

Labels

Label justifications:

  • P2: This is a bounded opt-in Gmail search feature with a merge-blocking privacy defect but limited blast radius before landing.
  • merge-risk: 🚨 security-boundary: The attachment-only branch requests the full Gmail payload, which includes body data the feature promises not to transfer.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR claims a live-account verification but provides no inspectable redacted terminal output, trace, log, recording, or artifact showing the corrected real behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

Security concerns:

  • [high] Attachment-only mode retrieves message bodies — internal/cmd/gmail_messages.go:256
    The full-payload field selection can bring inline email body data into memory even when callers requested attachment metadata only, contradicting the feature's privacy boundary.
    Confidence: 0.99

What I checked:

  • Full-payload request contradicts the privacy contract: The attachment-only branch requests format=full with Fields(...,payload). Selecting the whole payload includes inline body data in the response even though it is not rendered, contrary to the PR's stated no-body-transfer behavior. (internal/cmd/gmail_messages.go:256, eb83a8b88f3d)
  • Text output loses the usable attachment identifier: The new table column emits only the first eight characters, while the existing download command requires the full opaque attachment ID and other attachment listings print it in full. (internal/cmd/gmail_presentation.go:55, eb83a8b88f3d)
  • Prior P1 remains unresolved: The previous review identified raw-body retrieval; the current-head delta from that review changes only attachment/presentation helpers, not the message-detail request path. (internal/cmd/gmail_messages.go:256, 14ae95999438)
  • Current-main baseline: Current main has only the established body/detail flag and no attachment-only search mode, so the PR's feature is not already implemented. (internal/cmd/gmail_messages.go:102, 8fe3e7995d0b)
  • Feature-history routing: History shows chrischall recently changed message-listing fields in commit 3c9466a; Peter Steinberger has the largest sampled contribution count across the central Gmail message and attachment files. (internal/cmd/gmail_messages.go:102, 3c9466af5171)

Likely related people:

  • chrischall: Introduced the recent message-listing data-field change that the new detail-fetch path extends. (role: recent area contributor; confidence: high; commits: 3c9466af5171; files: internal/cmd/gmail_messages.go)
  • steipete: Sampled history shows Peter Steinberger has the most contributions across the central message-search and attachment implementation files. (role: frequent Gmail-area contributor; confidence: medium; commits: 8fe3e7995d0b; files: internal/cmd/gmail_messages.go, internal/cmd/gmail_attachments.go)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (9 earlier review cycles; latest 8 shown)
  • reviewed 2026-08-07T11:44:21.789Z sha 54c58df :: needs real behavior proof before merge. :: [P2] Render attachments in non-JSON search output | [P2] Include every attachment part in the Gmail fields mask
  • reviewed 2026-08-07T14:39:26.910Z sha d57234f :: needs real behavior proof before merge. :: [P2] Avoid silently omitting deeply nested attachments | [P2] Preserve attachment identifiers in text search output
  • reviewed 2026-08-07T16:44:47.342Z sha d57234f :: needs real behavior proof before merge. :: [P2] Do not silently omit deeply nested attachments | [P2] Keep attachment identifiers in text search output
  • reviewed 2026-08-07T19:27:02.648Z sha d57234f :: needs real behavior proof before merge. :: [P2] Render attachment identifiers and MIME types in text output | [P2] Avoid silently truncating attachment discovery at depth eight
  • reviewed 2026-08-07T22:01:46.611Z sha d57234f :: needs real behavior proof before merge. :: [P2] Do not silently omit deeply nested attachments | [P2] Expose MIME type and identifier in text output
  • reviewed 2026-08-08T03:01:07.784Z sha d57234f :: needs real behavior proof before merge. :: [P2] Avoid silently omitting deeply nested attachments | [P2] Render MIME type and identifier in text output
  • reviewed 2026-08-08T04:40:59.083Z sha d57234f :: needs real behavior proof before merge. :: [P2] Fetch attachment metadata at every MIME depth | [P2] Expose the advertised metadata in text output
  • reviewed 2026-08-08T04:48:33.173Z sha 14ae959 :: needs real behavior proof before merge. :: [P1] Avoid fetching raw bodies for attachment-only searches

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Aug 7, 2026
@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Aug 7, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. label Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant