From Clawd Mochi
Connect this machine's Claude Code to a Clawd Mochi desk companion — discover the device, write the config, wire the statusLine bridge, smoke-test.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mochi:setup [optional host/IP][optional host/IP]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Wire this machine's Claude Code to a Clawd Mochi (ESP32-C3 display). The
Wire this machine's Claude Code to a Clawd Mochi (ESP32-C3 display). The
plugin already registers the hook bridge by itself (hooks/hooks.json runs
scripts/mochi-hook straight from the installed plugin, so it follows plugin
updates). What is left for this skill, in order:
In the commands below $SKILL_DIR means this skill's base directory (shown
when the skill loads) — set it first in each shell you use. All commands are
POSIX shell: Claude Code runs them in bash on macOS/Linux and in Git Bash on
Windows; the same commands work in both, including ~-paths.
If the user passed a host/IP as $ARGUMENTS, skip discovery (step 3) and use
it directly as <host>.
Detailed config schema, event mapping, toggles, debug and Windows notes live in reference.md — read it only if tuning or debugging.
~/.config/clawd-mochi/bin/,
not from the plugin: settings.json cannot expand ${CLAUDE_PLUGIN_ROOT},
and the plugin's cache path changes on every update. Hooks need no copy —
the plugin resolves its own path.~/.claude/settings.json, not a project one — the
companion should react in every project.~/.claude/settings.json, preserve all existing keys and emit
valid JSON. Never overwrite the file blindly.PY=$(command -v python3 || command -v python || command -v py); echo "PY=$PY"
command -v curl >/dev/null && echo "curl ok" || echo "MISSING curl"
If PY is empty, stop and tell the user to install Python 3 (macOS:
brew install python3; Windows: the python.org installer — and Claude Code on
Windows also needs Git for Windows, whose Git Bash runs the bridges). curl
ships with macOS and Windows 10+; if missing, stop likewise. Use "$PY" for
every Python invocation below.
mkdir -p ~/.config/clawd-mochi/bin
[ -f ~/.config/clawd-mochi/config.json ] || cp "$SKILL_DIR/templates/config.json" ~/.config/clawd-mochi/config.json
cp "$SKILL_DIR/scripts/mochi-statusline" "$SKILL_DIR/scripts/mochi-statusline.py" ~/.config/clawd-mochi/bin/
chmod +x ~/.config/clawd-mochi/bin/mochi-statusline 2>/dev/null || true
echo "installed -> $HOME/.config/clawd-mochi"
An existing config is kept — it holds the user's event→emotion mapping; only
device.host gets updated below. Re-run this step after plugin updates to
refresh the bridge copy.
Skip if the user supplied a host in $ARGUMENTS.
"$PY" "$SKILL_DIR/scripts/find-mochi.py" --write
clawd-mochi.local or an IP) and wrote
it into the config. Use that as <host>.ClaWD-Mochi Wi-Fi and the host is always 192.168.4.1.
Then verify: curl -s http://<ip>/state must return JSON containing
roboLively. If it does, set device.host to <ip> in
~/.config/clawd-mochi/config.json and use <ip> as <host>.curl -s --ipv4 --max-time 2 "http://<host>/state" | head -c 200; echo
curl -s --ipv4 --max-time 2 "http://<host>/robo?shot=blink&caption=hi%20:)" >/dev/null
The device should blink and show a small caption. If /state fails, the host
is wrong or the device is offline — fix that before continuing.
Check statusLine in ~/.claude/settings.json:
statusLine.command points at a script): open that
script. If it already pipes to a mochi-statusline (even an old path), just
fix that path to $HOME/.config/clawd-mochi/bin/mochi-statusline.
Otherwise, right after it captures stdin (e.g. input=$(cat)), add:
printf '%s' "$input" | "$HOME/.config/clawd-mochi/bin/mochi-statusline" &
If the script does not capture stdin into a variable, adapt minimally so both
the status line and the bridge get the JSON. Don't duplicate the line if present.cp "$SKILL_DIR/scripts/statusline-command.sh" ~/.claude/statusline-command.sh
chmod +x ~/.claude/statusline-command.sh 2>/dev/null || true
then set in ~/.claude/settings.json:
"statusLine": { "type": "command", "command": "bash ~/.claude/statusline-command.sh" }.Older setups (before this plugin existed) merged Mochi hooks into
~/.claude/settings.json by hand. Read that file: if any hooks entry
command references mochi-hook (a repo path or
~/.config/clawd-mochi/bin/mochi-hook), remove those entries — the plugin
registers its own now, and stale ones double-fire every event. Keep all
non-Mochi hooks intact. Also delete a leftover
~/.config/clawd-mochi/bin/mochi-hook* if present (only the statusLine bridge
belongs there now). If nothing references mochi-hook, skip this step.
End-to-end dry-run through the real config:
echo '{"hook_event_name":"Stop"}' | sh "$SKILL_DIR/scripts/mochi-hook"
The device should play the Stop animation (default mapping: laugh, then relax after 5 s). Then tell the user, concisely:
/mochi:setup after an update to
refresh it.export CLAWD_MOCHI_DISABLED=1 (per-shell kill switch),
"enabled": false in the config (mute all), "statusline":{"enabled":false}
(mute bar)./mochi:setup.
(Prefer clawd-mochi.local as the host on mDNS firmware; it never drifts.)npx claudepluginhub npokc123/clawd-mochi-companion --plugin mochiGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Resolves in-progress git merge or rebase conflicts by analyzing history, understanding intent, and preserving both changes where possible. Runs automated checks after resolution.