Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

code-chan: a physical companion for coding agents

Give your coding agent a body.

A coding agent works out of sight. You start a task, look away, and have no idea whether it is running, finished, stuck, or waiting to ask you something — so you keep checking the window. code-chan puts that state on a desk toy you can notice without looking straight at it, and lets you answer a permission request by touching it.

It runs on Stack-chan with an M5Stack CoreS3. A local host bridge turns the lifecycle hooks the coding app already invokes into a small device protocol; firmware owns the complete character response on the hardware.

video.mp4

The scene is original pixel art, but the states are not decorative: each one is driven by a hook the coding app emits, and no agent state is ever worked out from how much time has passed.

The device at rest showing the CLAUDE READY caption

At rest, connected to a coding app and waiting for a prompt. The caption names which app owns the device, because one program drives it at a time.

The device showing the WORKING caption while an agent turn runs

A task in progress. The character moves and the background scrolls while the agent works, and stops when it stops.

A permission request showing APPROVE and REJECT controls around the decision item

A permission request, answered on the hardware. The screen carries the tool's name and nothing else — never the command, the prompt, or the file path. Only an explicit labeled control produces an answer, and only while the waiting hook, the session that owns the device, its task, the current connection, and that request's ID all still match. Touching the floating item does not approve it.

Current implementation

  • You start one small Node.js 22 program for either the Codex desktop app or Claude Code. It checks the shape of the hook fields it reads, tells the device that app is ready, and follows one session at a time.
  • The first prompt sent while the device is ready takes it, and the screen changes to working before the hook returns. Prompts from other sessions are not queued or merged; they run normally in their own window and leave the device alone.
  • The first program to claim the local port owns the device. A second one cannot open the serial connection or add to what is on screen until the first stops or loses its connection.
  • Everything between the computer and the device travels over that one USB serial connection. Each connection is numbered, and the device accepts messages only from the current one, so an older connection cannot change what is on screen. Answers, acknowledgements, and touches come back only through the current connection.
  • The firmware checks every message against a fixed shape before acting on it, and keeps four things separate: whether it is connected, what the character is doing, the board's power state, and the agent's state.
  • Ready, working, waiting for you, finished, error, lost connection, no USB power, and sleep each map to the scene, head movement inside its checked range, the LEDs, and short sounds.
  • While a task is running or waiting for your answer, the screen stays awake. A permission request shows the tool's name and nothing else, with REJECT and APPROVE controls, and your choice goes back only to the hook that asked. A session that does not own the device keeps its coding app's usual permission prompt.
  • While a task runs the caption reads WORKING. On Claude Code's CLI, where a status line can report it, the caption shows how much context, five-hour, and seven-day usage is left instead. That changes the text only — no movement, no sound. Codex and everything else show WORKING.
  • Sleep and wake advance only when the screen and the motors actually report back, never because enough time has passed. A long press of the side button is a different operation: it shuts the board down, and if something fails or takes too long on the way, it keeps the first error and asks the power chip to cut power, once.
  • The character, drones, decision item, arrival effect, and layered background are original art, built into a 16-color image pack by a repeatable process. The firmware checks that pack before drawing from it and redraws the screen 24 times a second, in two horizontal strips. Whether that rate holds on real hardware is a separate check.

Touching Stack-chan's body is only character interaction. It does not wake the screen, choose which session owns the device, or approve anything. A permission answer needs a live matching request and an explicit labeled choice on screen; if it times out, your coding agent's normal flow stays in control.

Architecture

Hooks reach the program on your computer, which sends a small device protocol over USB serial to the firmware; a touchscreen choice returns as a permission decision

Everything specific to a particular coding app lives in the program on your computer. The firmware never reads anything about the app itself, and the transport layer does not change what a message means.

Get started

The current source-based installation requires Stack-chan with an M5Stack CoreS3, PlatformIO Core, Python 3, Node.js 22, and a macOS or Linux host.

  1. Clone this repository to a stable local path.
  2. Complete the spritekit setup, then generate the ignored package using the integrated-scene procedure.
  3. Build and install the LittleFS package before the matching firmware by following the firmware procedure.
  4. Install the host dependencies, connect the CoreS3 over USB, and configure either Codex or Claude Code hooks by following the host bridge setup.
  5. Start exactly one selected app bridge. Stop it before starting the other app's bridge.
  6. Submit a prompt. The first prompt received while ready takes the device and changes the ready screen straight to working.

The tracked hook files are repository-local development configuration. Using code-chan while coding in another repository requires the project-local or user-level hook installation described in the host bridge document.

To also show Claude Code CLI remaining usage in the working caption, install the optional status line described in the host bridge document. This step is Claude Code CLI only and needs Claude Code 2.1.196 or later.

Repository layout

assets/                 original art sources and manifests
docs/                   product and implementation specifications
firmware/stackchan/     CoreS3 firmware
packages/code-chan/     local Node.js host bridge
protocol/device.json    the list of messages the device understands
tools/                  deterministic protocol and asset builders

Start with the documentation map. The detailed product scene is defined in docs/PRODUCT.md, and current implemented boundaries are described by the architecture, host, firmware, protocol, security, and verification documents under docs/.

Security and privacy

code-chan runs entirely on one machine and one USB cable. It has no server, no account, and no telemetry. Its only listener is bound to loopback, and the host bridge has zero runtime dependencies.

Prompt text, file contents, command strings, and working directories never reach the device. The only text from the agent that the protocol can carry is a tool's name, at most 32 bytes. The optional Claude status line is reduced to two opaque ids and up to three numbers before anything leaves the local command.

docs/SECURITY.md owns the trust boundaries, what crosses each one, and how to report a vulnerability.

License

Apache License 2.0. See LICENSE.

About

Shows what your coding agent is doing, on a Stack-chan with an M5Stack CoreS3. Works with Codex and Claude Code.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages