npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ember-assist

v0.1.1

Published

Local MCP bridge and ESP32 mock for Ember physical expressions.

Readme

Ember

Ember is a global CLI for expressing Codex task state through a small display. It installs a Codex hook runner, stores global runtime config, auto-detects a serial device when possible, and optionally exposes an MCP tool for advanced control.

The default transport is a built-in ESP32 mock, so the project can be developed and tested without hardware connected.

Features

  • Global CLI: ember
  • Interactive setup: ember setup
  • Health checks: ember doctor
  • Hook install/uninstall: ember hooks install --global
  • MCP tool: set_expression via ember mcp serve
  • Mock and USB serial transports
  • Global config with serial-path persistence and hook mappings
  • Validated expression names
  • Simple serial protocol: EXPR <name>\n
  • ESP32 mock for local tests and development

Supported Expressions

| Expression | Display behavior | | --- | --- | | idle | calm neutral face | | thinking | animated thinking face | | success | happy check face | | error | sad error face | | working | typing cat keyboard scene | | warning | alert face with warning marker | | approval | waiting for approval face | | happy | celebratory face with sparkles |

Requirements

  • Node.js 22.14.0 or newer
  • npm
  • Optional hardware:
    • ESP32-C3 dev board
    • GME12864-41 v3 128x64 I2C OLED
    • USB serial connection
    • PlatformIO CLI for firmware build/upload

Install

npm install
npm install -g .

Publish target package name:

ember-assist

For a full system setup from installing Codex CLI through flashing the ESP32-C3 and enabling hooks, see docs/system-setup.md.

Quick Start

  1. Install the CLI globally:
npm install -g ember-assist
  1. Run one-time setup:
ember setup
  1. Validate the installation and send a test expression:
ember doctor
  1. Send an expression directly:
ember expr thinking

Legacy compatibility is still available:

ember-led happy

Usage

Common flows

Set up Ember on a new machine:

ember setup
ember doctor

Send a single expression with saved config:

ember expr working

Send a single expression with explicit serial settings:

ember expr success --transport serial --serial-path /dev/tty.usbserial-0001

Test without hardware:

ember expr happy --transport mock

Install global Codex hooks:

ember hooks install --global

Remove Ember-managed Codex hooks:

ember hooks uninstall --global

Start the optional MCP server:

ember mcp serve

Command reference

Show help:

ember --help

Run one-time setup:

ember setup

Run health checks:

ember doctor

Send an expression:

ember expr <expression>

Send an expression through the legacy compatibility alias:

ember-led <expression>

Install or update global Codex hooks:

ember hooks install --global

Remove Ember-managed hooks:

ember hooks uninstall --global

Start the MCP stdio server:

ember mcp serve

CLI options

These options work with commands that resolve runtime config such as expr, doctor, and mcp serve:

--transport mock|serial
--serial-path <path>
--baud-rate <baud>
--config <path>

Examples:

ember doctor --transport mock
ember expr thinking --serial-path /dev/cu.usbmodem12101
ember mcp serve --config /tmp/ember-config.json

Runtime Config

ember setup writes global config to:

~/.config/ember/config.json

The config stores:

  • selected transport
  • selected serial device path and metadata
  • baud rate
  • hook event mappings
  • throttle window

Resolution precedence is:

  1. CLI flags such as --serial-path
  2. Environment variables
  3. Saved global config
  4. Auto-detected serial device

Serial Transport

ember setup will prefer a detected serial device and persist it. You can still override runtime behavior explicitly:

ember expr thinking --transport serial --serial-path /dev/tty.usbserial-0001

The baud rate defaults to 115200 and can be overridden with --baud-rate or EMBER_BAUD_RATE.

If no serial device is configured, Ember falls back to the mock transport only when the saved config or explicit flags request it. Otherwise it asks you to run ember setup.

Codex Hooks

Global hooks are installed into:

~/.codex/hooks.json

The managed hook runner is invoked through:

ember hook-runner

Default hook mappings are:

| Hook event | Expression | Purpose | | --- | --- | --- | | UserPromptSubmit | thinking | Shows that Codex is considering the prompt | | PreToolUse | working | Shows that Codex is about to run a tool | | PermissionRequest | approval | Shows that Codex is paused for approval | | Stop | happy | Shows a completion celebration when the response ends |

The hook runner keeps runtime state under:

~/.config/ember/

Behavior guarantees:

  • hook failures still return exit code 0
  • a global throttle suppresses high-frequency duplicate sends
  • approval bypasses throttle by default
  • hook execution never prompts the user interactively

Hook behavior can be overridden with environment variables:

EMBER_HOOK_ON_PROMPT=thinking
EMBER_HOOK_ON_TOOL_START=working
EMBER_HOOK_ON_PERMISSION=approval
EMBER_HOOK_ON_STOP=happy
EMBER_HOOK_THROTTLE_SECONDS=1
EMBER_HOOK_THROTTLE_BYPASS=approval,error

MCP Server

The MCP server is optional. Start it when you want an external model client to call set_expression directly:

ember mcp serve

The server registers one tool:

set_expression({ name: "thinking" })

It uses the same runtime resolution stack as the CLI and hook runner, so global config, environment overrides, and auto-detection behave the same way.

Serial Protocol

Ember sends newline-terminated commands:

EXPR thinking
EXPR success
EXPR error
EXPR idle
EXPR working
EXPR warning
EXPR approval
EXPR happy

Invalid commands or unsupported expressions are ignored by the mock and should be ignored by firmware.

Development

Run the test suite:

npm test

Type-check the project:

npm run typecheck

Build the ESP32-C3 firmware:

npm run firmware:build

Upload firmware:

npm run firmware:upload

Open the serial monitor:

npm run firmware:monitor

Run firmware tests on a connected board:

npm run firmware:test

Project Structure

src/cli.ts          CLI entry point
src/mcp-server.ts   MCP stdio server and tool registration
src/service.ts      Expression validation and transport orchestration
src/protocol.ts     Serial command encoder/parser
src/transports.ts   Mock and serial transports
src/esp32-mock.ts   Local ESP32 behavior mock
firmware/           ESP32-C3 PlatformIO firmware
tests/              Vitest tests
bin/ember-led       Executable CLI wrapper
.codex/hooks.json   Codex hook configuration

Hardware Notes

Current firmware defaults target an ESP32-C3 dev module with a GME12864-41 v3 128x64 I2C OLED:

OLED VCC -> ESP32-C3 3.3V
OLED GND -> ESP32-C3 GND
OLED SDA -> ESP32-C3 GPIO8
OLED SCL -> ESP32-C3 GPIO9

Use 3.3V unless the OLED module explicitly supports 5V logic and power.

Firmware defaults live in firmware/include/config.h:

constexpr uint8_t EMBER_DISPLAY_WIDTH = 128;
constexpr uint8_t EMBER_DISPLAY_HEIGHT = 64;
constexpr uint8_t EMBER_DISPLAY_SDA_PIN = 8;
constexpr uint8_t EMBER_DISPLAY_SCL_PIN = 9;
constexpr uint8_t EMBER_DISPLAY_I2C_ADDRESS = 0x3C;

If the display does not light, try address 0x3D, verify the controller is SSD1306-compatible, and confirm SDA/SCL wiring.