Skip to content

tt msg send should accept body via --stdin/--body-file (shell substitution silently mangles messages) #52

Description

@mostlydev

Problem

tt msg send <recipient> "<body>" takes the message body as a shell argument. When the body contains shell metacharacters — most dangerously backticks or $(...) — the user's shell performs command substitution before tt ever sees the string, silently mangling (or breaking) the message.

Real repro from a dogfooding session

An agent composed a coordination message that referenced CLI commands in backticks, e.g.:

tt msg send codex:xxxx "Proposal: a `tt done` / `tt close` command, and use `tt wait` ..."

The shell executed the backticked segments as commands (tt doneUnknown command: done), and the message that would have been sent had those segments replaced by empty/garbage output. The first send effectively failed; the agent only noticed because the captured output was a stray {"error":"cli_error","message":"Unknown command: done"} instead of a send receipt.

For a coordination tool this is a quiet correctness problem: a handoff/coordination message can be silently truncated or corrupted, and the sender may not realize it.

Proposed direction (open to debate)

  • Add a stdin/body-file path for message bodies, mirroring what tt release/tt assign already support (--stdin):
    • tt msg send <recipient> --stdin (read body from stdin), and/or
    • tt msg send <recipient> --body-file <path>.
  • Document the shell-quoting footgun prominently in the skill/CLI help, recommending --stdin/--body-file (or single quotes) for any body that may contain backticks, $, or quotes.

This is the same ergonomic that makes tt release --stdin reliable for structured handoffs; message bodies deserve the same escape hatch.


Filed from a paired Claude+Codex dogfooding session, after the backtick footgun silently broke a coordination message.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions