Skip to content

feat(amp-send,amp-reply): --body-file and --body-stdin for rich content#19

Open
joceqo wants to merge 1 commit into
agentmessaging:mainfrom
joceqo:feat/body-file-stdin-options
Open

feat(amp-send,amp-reply): --body-file and --body-stdin for rich content#19
joceqo wants to merge 1 commit into
agentmessaging:mainfrom
joceqo:feat/body-file-stdin-options

Conversation

@joceqo
Copy link
Copy Markdown

@joceqo joceqo commented May 1, 2026

Problem

amp-send and amp-reply take the message body as a positional shell
argument. This breaks for rich content even when the caller carefully
escapes things:

  • Backticks (interpreted as command substitution)
  • Fenced code blocks with embedded $var or \ sequences
  • Box-drawing characters (occasional Unicode handling issues)
  • Multi-line bodies with embedded quotes

Real-world failure mode

Observed in a multi-agent orchestration session: an AI agent was asked
to reply with a CLI UI mockup containing fenced code blocks with
backticks and box-drawing chars. The agent's
amp-reply <msg-id> "<rich content>" call entered a stuck loop in zsh.
The agent attempted multiple workarounds (writing the body to a temp
file, escaping backticks individually, switching quoting styles) and
never recovered. Other agents in the same swarm — sending plain text —
delivered fine. The friction is specifically rich content + positional
shell arg.

Fix

Both scripts now accept the message body via three mutually-exclusive
sources:

Source Flag Use case
Positional argument (default) Plain text, short messages
--body-file PATH new Pre-composed rich content (Markdown, mockups, code)
--body-stdin new Piped from another tool or heredoc

If more than one source is provided, the script errors with a clear
message. If none is provided, it falls through to the existing
"missing body" path with help shown.

Existing positional usage is unchanged — these options are purely
additive. No breaking changes.

Verified end-to-end

Rich content (backticks, fenced code blocks, box-drawing chars ┌──┐,
Unicode , and $var-looking sequences) preserved byte-for-byte at
the recipient via both --body-file and --body-stdin. Plain
positional usage continues to work.

amp-send alice "Subject" --body-file report.md
cat reply.md | amp-send alice "Subject" --body-stdin
amp-reply msg_xyz --body-file rich-reply.md

ShellCheck

Both patched scripts pass shellcheck. Only pre-existing info-level
warnings remain (SC1091 about following the helper file, SC2181
in amp-send.sh:293 about indirect $? check) — both unrelated to
this change.

Why this matters for AI-driven AMP

Multi-agent orchestrations (especially LLM agents writing bash) are
exactly the case where positional shell args fail unpredictably. A
file-based body is far easier for an agent to compose reliably:
write to /tmp/reply-$$.md, then call amp-reply <msg-id> --body-file /tmp/reply-$$.md.
This makes amp-reply / amp-send safe to use as a target API for
agent code generation.

🤖 Generated with Claude Code

…ch content

Both scripts take the message body as a positional shell argument. This
breaks for rich content — backticks (command substitution), fenced code
blocks, box-drawing characters, multi-line content with embedded quotes
or `$var` references — even when the caller carefully escapes things.

Observed in real multi-agent orchestration: an AI agent was asked to
reply with a CLI UI mockup containing fenced code blocks with
backticks and box-drawing chars. The agent's
`amp-reply <msg-id> "<rich content>"` call entered a stuck loop in zsh —
the agent attempted multiple workarounds (writing to a file, escaping
backticks individually, switching quoting styles) and never recovered.

Both scripts now accept the body via three mutually-exclusive sources:

  - Positional argument (existing, unchanged)
  - `--body-file PATH`   read body from a file
  - `--body-stdin`       read body from stdin

If more than one is provided, the script errors clearly. Existing
positional usage is unchanged — purely additive.

Verified with rich content end-to-end: backticks, fenced code blocks,
box-drawing chars (┌──┐ │ │ └──┘), Unicode (★), and $var-looking
sequences all preserved byte-for-byte at the recipient.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant