A compliment gets a reaction drawn from a small warm set (❤️🥰😊👍🎉🙏😸) put on the compliment itself, and nothing in the group -- the one
answer that adds no line. Same cooldown as every other command.
The transport learns reactions: send_reaction on the Protocol, POST
/v1/reactions/<number> on the REST adapter with the four fields
api.SendReactionRequest requires (204 back), a recorded list on the fake.
CommandContext.react() names the target the way a quote does, and falls
back to the emoji as text for an envelope with no timestamp, so a shape
this bot has never seen is visible rather than swallowed.
The fake container gains the endpoint, strict about the schema, and
records reactions in order with the sends; a scenario can now expect
{kind: reaction, quotes: true}. First two-word trigger: fold() keeps the
inner space and the registry matches whole text first, so "!good bot"
resolves and "!good" does not; one-word spellings cover a double space.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>