feat(gmail): add bounded inline attachment output#919
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 14, 2026, 10:32 AM ET / 14:32 UTC. Summary Reproducibility: not applicable. This PR fills a remote-client capability gap rather than fixing a violation of an existing documented contract. Current main’s path-only response clearly establishes the motivation. Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the bounded Do we have a high-confidence way to reproduce the issue? Not applicable: this PR fills a remote-client capability gap rather than fixing a violation of an existing documented contract. Current main’s path-only response clearly establishes the motivation. Is this the best way to solve the issue? Unclear: bounded inline bytes are the narrowest maintainable solution to the remote-path problem, while built-in text extraction is a larger optional parsing surface whose value depends on maintainer product and security intent. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against e4239f8c57a5. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
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
Review history (5 earlier review cycles)
|
|
@clawsweeper re-review — pushed 5e4cd61 fixing the --text --plain TSV contract (Go-quoted single field + regression test) and bounding PDF extraction with a 10s timeout + adversarial corrupt-PDF fixture; the PR body now includes redacted live CLI and MCP transcripts for default/--inline/--text and the fixed --plain output. |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review — 1d59b5b replaces the goroutine timeout with a killable subprocess boundary: PDF parsing re-execs gog as a hidden |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
gog gmail attachment previously only wrote the attachment to a local file
and returned the path — a dead end for remote callers (MCP clients) that
cannot read the host filesystem.
- --inline: returns the content base64-encoded in a contentBase64 field
(JSON) for attachments up to 3 MiB; larger ones keep the path-only
behavior with an explanatory `reason` instead of failing silently.
- --text: returns extracted text in a `text` field — PDFs via a pure-Go
text extractor (with a `note` when the PDF is scanned/image-only),
HTML with tags stripped, plain text verbatim. Unsupported types return
a clear `reason`. Mutually exclusive with --inline.
- Both modes resolve filename/mimeType from the message payload, with a
single-attachment fallback (Gmail attachment IDs are not stable across
API responses) and content sniffing when metadata is unavailable.
- Default behavior (no new flags) is unchanged: {path, cached, bytes}.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Address review on the --inline/--text attachment modes: - --plain output stays a stable one-record-per-line TSV: values containing tabs/newlines (extracted text) are emitted as a single Go-quoted field, with a regression test that round-trips multiline text via strconv.Unquote. - PDF parsing of attacker-controlled attachments is now bounded: a 10s timeout (on top of the existing 3 MiB input cap and panic recovery) so a pathological PDF cannot hang the command or a long-lived MCP server. - Adversarial fixture test: corrupt PDF input surfaces a clear reason instead of text, without panicking. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Address the remaining review P1: a goroutine timeout cannot terminate parser work, so repeated hostile PDFs could leave CPU/memory work behind in a long-lived MCP server. - gmail attachment --text now re-execs the gog binary as a hidden `gmail pdf-extract` child (PDF bytes on stdin, text on stdout) under exec.CommandContext, so the 10s timeout SIGKILLs the parser outright. - Child re-checks the input size cap; parent caps extracted-text output at 4 MiB (compressed streams can inflate past the input cap) and surfaces child stderr as the failure reason. - Tests spawn the real subprocess boundary (test binary dispatches via a TestMain hook): extraction through the child, a hung child killed on timeout, corrupt-PDF error propagation, direct child-command IO, and oversized-input rejection. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Chris Hall <chris.c.hall@gmail.com>
1d59b5b to
6401d19
Compare
Summary
gog gmail attachment --inlinefor base64 content in JSON and plain output.Safety and compatibility
{path, cached, bytes}JSON remains unchanged.Proof
make ci: lint, deadcode, all Go and Node tests, generated command docs, docs coverage, and agent-skills checks pass.6401d196bfb24c0225e4fdb1d6ae4eb3dacef201: help, credential-free dry-run, small inline round-trip, unchanged default shape, invalid-ID cache rejection, same-size stale-file refresh, and oversized fallback all pass. Temporary drafts and files were deleted; post-check found zero drafts.