<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thoughtbot="https://thoughtbot.com/feeds/">
  <title>Giant Robots Smashing Into Other Giant Robots</title>
  <subtitle>Written by thoughtbot, your expert partner for design and development.
</subtitle>
  <id>https://robots.thoughtbot.com/</id>
  <link href="https://thoughtbot.com/blog"/>
  <link href="https://feed.thoughtbot.com" rel="self"/>
  <updated>2026-04-23T00:00:00+00:00</updated>
  <author>
    <name>thoughtbot</name>
  </author>
<entry>
  <title>Seven commands and the communication layer that emerged</title>
  <link rel="alternate" href="https://thoughtbot.com/blog/seven-commands-and-the-communication-layer-that-emerged"/>
  <author>
    <name>Rob Whittaker</name>
  </author>
  <id>https://thoughtbot.com/blog/seven-commands-and-the-communication-layer-that-emerged</id>
  <published>2026-04-23T00:00:00+00:00</published>
  <updated>2026-04-22T10:22:30Z</updated>
  <content type="html">&lt;p&gt;On Tuesday, 11 February, I made seventeen commits to my
management system. That is more than any other day in the
project so far. The previous two weeks had been about
structure. Daily routines. Meeting sync. Project tracking.
This week was about communication.&lt;/p&gt;

&lt;p&gt;The trigger was simple. I ran &lt;code&gt;/inbox&lt;/code&gt; and spotted the
pattern. Every time: fetch the item, decide what to do,
place it somewhere, move on. The first version of the
command automated that loop:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Inbox Command&lt;/span&gt;

Process the Things inbox one item at a time, newest first.

&lt;span class="gu"&gt;## Instructions&lt;/span&gt;

&lt;span class="gu"&gt;### Step 1: Load Context&lt;/span&gt;

Fetch in parallel:
&lt;span class="p"&gt;
1.&lt;/span&gt; Call &lt;span class="sb"&gt;`mcp__things__get_inbox`&lt;/span&gt; to get all inbox items
&lt;span class="p"&gt;1.&lt;/span&gt; Call &lt;span class="sb"&gt;`mcp__things__get_projects`&lt;/span&gt; to get project names

Sort inbox items newest first (by creation date).

If the inbox is empty, report "Inbox is empty" and stop.

&lt;span class="gu"&gt;### Step 2: Present the Next Item&lt;/span&gt;

For each inbox item, present:
&lt;span class="p"&gt;
-&lt;/span&gt; Title
&lt;span class="p"&gt;-&lt;/span&gt; Age
&lt;span class="p"&gt;-&lt;/span&gt; Tags (if any)
&lt;span class="p"&gt;-&lt;/span&gt; Notes (truncated if long)
&lt;span class="p"&gt;-&lt;/span&gt; Related project (fuzzy-match title against project names)

Then wait for the user to say what they want to do.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Within thirty minutes, that command went through three
revisions. The loop version advanced on its own. I changed
it to single-item mode because I wanted control. Then I
added reading detection: if the notes contain a URL, fetch
the page title and suggest a tag. I created three commits,
three lessons about how I process information.&lt;/p&gt;
&lt;h3 id="the-one-day-command"&gt;
  
    The one-day command
  
&lt;/h3&gt;

&lt;p&gt;The same morning, I created &lt;code&gt;/reply&lt;/code&gt; for Slack DMs. It
standardised the flow: find the user, open the DM, fetch
the history, draft the reply, and send.&lt;/p&gt;

&lt;p&gt;It lasted twenty-four hours.&lt;/p&gt;

&lt;p&gt;By Wednesday, I had split it into &lt;code&gt;/dm&lt;/code&gt; for direct messages
and &lt;code&gt;/thread&lt;/code&gt; for channel thread replies. Both shared a
patterns file that held the common steps:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# DM Command&lt;/span&gt;

Send a direct message on Slack to $ARGUMENTS.

Follow shared patterns from
&lt;span class="sb"&gt;`.claude/commands/slack-patterns.md`&lt;/span&gt;.

&lt;span class="gu"&gt;## Instructions&lt;/span&gt;

&lt;span class="gu"&gt;### Step 1: Setup and Find User&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; &lt;span class="gs"&gt;**Rube Session Setup**&lt;/span&gt; (see &lt;span class="sb"&gt;`slack-patterns.md`&lt;/span&gt;)
&lt;span class="p"&gt;1.&lt;/span&gt; &lt;span class="gs"&gt;**Find User**&lt;/span&gt; (see &lt;span class="sb"&gt;`slack-patterns.md`&lt;/span&gt;)

&lt;span class="gu"&gt;### Step 2: Open DM and Fetch History&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Use &lt;span class="sb"&gt;`SLACK_OPEN_DM`&lt;/span&gt; with the user's ID
&lt;span class="p"&gt;1.&lt;/span&gt; &lt;span class="gs"&gt;**Fetch History**&lt;/span&gt; on the DM channel
   (see &lt;span class="sb"&gt;`slack-patterns.md`&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The split happened because DMs and threads are different
conversations. A DM is private, one-to-one, with full
history. A thread is public, anchored to a specific message,
with context that the whole channel can see. The same “reply”
verb hid two different communication patterns.&lt;/p&gt;
&lt;h3 id="the-communication-stack"&gt;
  
    The communication stack
  
&lt;/h3&gt;

&lt;p&gt;That refactoring revealed something. Each command I built
that week mapped to a communication channel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/dm&lt;/code&gt; — Slack direct messages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/thread&lt;/code&gt; — Slack channel threads&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/slack&lt;/code&gt; — new channel messages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/email&lt;/code&gt; — Gmail replies and composition&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/hub&lt;/code&gt; — reading saved Hub pages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/draft&lt;/code&gt; — anything else (LinkedIn, talking points,
Hub replies)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Six commands. Six ways I talk to people at work. The &lt;code&gt;/draft&lt;/code&gt;
command became the catch-all for channels without an API:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Draft Command&lt;/span&gt;

Draft a reply or message for any context. Does not send.

Use this for LinkedIn messages, in-person talking points,
Hub replies, or any situation where &lt;span class="sb"&gt;`/dm`&lt;/span&gt;, &lt;span class="sb"&gt;`/thread`&lt;/span&gt;, and
&lt;span class="sb"&gt;`/email`&lt;/span&gt; don't apply.

&lt;span class="gu"&gt;## Pattern: Voice&lt;/span&gt;

Blend the user's natural tone with DHH and Nicholas Lezard:
&lt;span class="p"&gt;
-&lt;/span&gt; Direct and opinionated, but not abrasive
&lt;span class="p"&gt;-&lt;/span&gt; Concise sentences that carry weight
&lt;span class="p"&gt;-&lt;/span&gt; Avoid corporate filler
&lt;span class="p"&gt;-&lt;/span&gt; Match the formality of the channel
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The voice pattern is the part I did not expect to matter. I
had assumed Claude would write in a generic assistant tone.
Instead, by defining a voice, every draft came back in a
register I recognised as mine. Not perfect. Close enough to
edit rather than rewrite.&lt;/p&gt;
&lt;h3 id="plan-mode-and-command-boundaries"&gt;
  
    Plan mode and command boundaries
  
&lt;/h3&gt;

&lt;p&gt;Not everything went well. On Tuesday, I hit a bug where
plan mode leaked between commands. When I ran &lt;code&gt;/waiting&lt;/code&gt;,
it accumulated a state that bled into &lt;code&gt;/retro&lt;/code&gt;. That broke
both commands.&lt;/p&gt;

&lt;p&gt;The fix took two commits and a revert. The first attempt
added “Never use EnterPlanMode” to every command. That was
wrong. The real fix was removing the auto-advance loop from
&lt;code&gt;/waiting&lt;/code&gt;. Each command invocation stayed self-contained.
Commands are not functions. They are conversations. And
conversations should end clean.&lt;/p&gt;
&lt;h3 id="what-i-learned"&gt;
  
    What I learned
  
&lt;/h3&gt;

&lt;p&gt;Building these commands showed me something. My job as a
director is communication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write messages&lt;/li&gt;
&lt;li&gt;Respond to threads&lt;/li&gt;
&lt;li&gt;Follow up on waiting items&lt;/li&gt;
&lt;li&gt;Process my inbox&lt;/li&gt;
&lt;li&gt;Draft replies&lt;/li&gt;
&lt;li&gt;Read Hub posts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The actual management decisions happen in the gaps between
those conversations.&lt;/p&gt;

&lt;p&gt;The system I built in the first two weeks gave me structure:
routines, meeting sync, and project files. This week gave me
flow. The difference is that structure tells you what to do.
Flow tells you how to do it without thinking about the
mechanics.&lt;/p&gt;

&lt;p&gt;I am not faster. I am less distracted. Each command removes
one decision about where to go and what to type. That
compounds over a day of fifty small conversations.&lt;/p&gt;
&lt;h3 id="try-it-yourself"&gt;
  
    Try it yourself
  
&lt;/h3&gt;

&lt;p&gt;Pick one communication pattern you repeat daily. Write a
command for it. Not a script. A conversation. Define the
steps, the voice, the context. Then run it and see what
breaks. The breaking is where the learning is.&lt;/p&gt;

&lt;aside class="related-articles"&gt;&lt;h2&gt;If you enjoyed this post, you might also like:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thoughtbot.com/blog/a-bullet-in-your-programs-head"&gt;A bullet in your programs head&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thoughtbot.com/blog/internbot-chronicles-2"&gt;Internbot Chronicles #2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thoughtbot.com/blog/retrospective-fashionopoly"&gt;Retrospective: Fashionopoly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/aside&gt;
</content>
  <summary>Week three of building a management system with Claude Code. Seventeen commits in one day, a command that lasted 24 hours, and the realisation that commands are conversations.</summary>
  <thoughtbot:auto_social_share>true</thoughtbot:auto_social_share>
</entry>
</feed>
