View source

NemaRoom

Keep your project aligned, from discussion to delivery.

Hammershøi, White Doors: two white doors stand open in an empty room, showing the room beyond.
Hammershøi, Interior, Strandgade 30: through an open door, another room and a figure seen from behind.

Notes and tradeoffs scatter, and one requirement can be read two ways.

Keep one sourced reading, then bring commit evidence back into the discussion.

Chat becomes entries

Below is a discussion about exporting bills. Turn on a message and Nema files it as entries, noting whether someone stated it, someone decided it, or the agent inferred it.

Stated
Someone said it in the discussion
Decided
Someone settled it
Inferred
The agent proposed it; waiting for you
Knowledge · Bill export Requirements 1 · Decisions 1 · Questions 1
    Messages in the discussion

    One reading, with its sources

    Who said what

    Stated, decided and inferred are labeled apart. An agent’s guess never passes for your decision.

    Decision D-2Decided

    Exported files include a UTF-8 BOM

    “Yes, or non-English text comes out garbled.”Zhou · 10:12 · answers Q-1
    1. a41c0e2D-2 added: export with BOM
    2. 7be19f0Q-1 status: open → answered
    3. e03d551R-2 changed: yen rounded
    4. 19ac7d4D-1 added: CSV only for v1

    Every change is in Git

    The knowledge base is a Git repository. What changed, why, and what it said before are all on record.

    It reads your code

    Bind a local repository and the agent reads a snapshot of main and searches it, so the discussion knows what already exists.

    Repo~/code/ledger-app
    Branchmain @ 5d2e8a1
    Snapshot2 min ago
    src/billing/export.ts:48
    src/billing/export.test.ts:12
    Bill export call graphCode changed; may be stale
    BillingPage exportCsv BillRepo tz.ts

    Diagrams say when they’re stale

    A diagram drawn from code remembers which commit it came from. When the code moves on, the diagram says so.

    Ask before building

    Unclear points, and a statement that conflicts with an active decision, become questions. Nema asks and waits for you. Only what needs your answer is marked red.

    • Q-3Export an empty file for months with no bills?Open
    • Q-2Recalculate old bills in the new time zone?Open
    • Q-1Include a UTF-8 BOM in the CSVAnswered
    Interface
    中文English日本語
    Knowledge
    Follow discussionFixed
    Night mode

    Three interface languages

    Switch between Chinese, English and Japanese at any time. The language entries are written in is a separate setting.

    Back into the discussion

    Work package · Bill CSV exportDrafting
    • 3 requirements
    • 1 decision
    • 2 questions open

    First, talk it through. Entries file themselves.

    Work package · Bill CSV exportClarified
    • 3 requirements
    • 3 decisions
    • 0 questions open

    Then answer the open questions, one by one.

    Work package · Bill CSV exportApproved
    • Spec and plan generated
    • Handed to Claude Code
    • Approved by Zhou

    Next, approve the work package for a coding agent.

    Work package · Bill CSV exportDone
    • 3 commits, merged into main
    • 6 files changed
    • Linked to 3 requirements

    Commit reports come back into the discussion.

    Database
    PGlite on your local disk
    Data folder
    ~/.nema/desktop
    Network
    Listens on loopback only

    Runs only on your computer

    The desktop app packs the whole stack into one program: the database, the local core, and Node. It uses Git 2.31 or later already installed on your machine. On a Mac, an app opened from the Finder also finds Homebrew and MacPorts Git. No Docker, and no database server. Discussion text goes only to the model provider you choose, and Nema never touches your GitHub token.

    Status

    • Windows x64 desktoplatest installer or ZIP
    • macOS desktoplatest, Apple Silicon
    • LinuxWeb / Compose version
    • Installer signingNot yet signed
    • Auto-updateNone yet
    • ChatGPT subscriptionBrowser sign-in
    • Claude subscriptionClaude Code token
    • API keyResponses API compatible
    • Coding agentsCodex, Claude Code
    • LicenseMIT

    Questions

    Can I download it now?

    Yes. The latest release has a Windows x64 installer, a Windows portable ZIP, and an Apple Silicon disk image. The ZIP is the unpacked app: unzip it and run Nema.exe. It has no shortcuts or uninstaller. The installer and the ZIP both use ~/.nema/desktop. Pick one. Installers are unsigned, so Windows shows “Windows protected your PC” the first time, and macOS asks you to open it from Privacy & Security. The app also needs Git 2.31 or later on the machine. Intel Macs have no desktop build. On Linux, use the linux/amd64 hub and web images, or build from source.

    Does it cost anything?

    Nema Room itself is open source under the MIT license. Filing entries calls a model, so cost or quota depends on your provider: a ChatGPT or Claude subscription, or your own API key.

    Where does my discussion go?

    The database and knowledge base stay on your computer. Only when entries are generated is the relevant text sent to the model provider you chose. Services listen on your machine only; don’t expose them to the internet.

    How do coding agents report progress?

    Run nema report install to add report hooks to Codex or Claude Code. Each commit notifies Nema; if Nema isn’t running, reports wait locally and go out next time.

    Can a team use it together?

    The first release is for one person on one machine. Multi-device sync, backups and read-only team access come after the local core is done.

    Why Nema?

    The name comes from nemawashi (根回し): understanding before a decision. Disagreements stay visible, and the decision keeps its evidence.

    Hammershøi, Interior, Strandgade 30: a door stands open and a woman sits at a table with her back turned.

    Download

    Windows x64 and Apple Silicon builds are on the latest release. On Windows, pick the installer or the portable ZIP. The ZIP unzips to Nema.exe, with no shortcuts or uninstaller. Both use ~/.nema/desktop. The app needs Git 2.31 or later already on the machine.

    The host command is nema, from npm i -g @nema-project/nema@<locked version>. That number is the version both image: pins in the docker-compose.yml you fetched carry. Hub and web images are linux/amd64. docker-compose.yml is a fixed-name asset of the latest release, rendered with both images pinned to that release's version. Fetch it, check that both pins print the same version, write NEMA_IMAGE_TAG=<that version> into .env (keep an existing value and fetch releases/download/v<locked>/docker-compose.yml instead), then start them. The v0.1.6 file still opens with the template's "not an installable version" comment; the two pinned image: lines are what count. A lock older than v0.1.6 has no release asset; take raw.githubusercontent.com/Nema-Project/nema-room/v<locked>/docker-compose.yml instead. On Linux and macOS, export NEMA_UID and NEMA_GID first. To develop this repository, clone it and run the setup wizard.

    # Hub and web, linux/amd64. The compose file is a fixed-name asset of the latest release; an existing NEMA_IMAGE_TAG in .env keeps its own version.
    NEMA_FETCHED= NEMA_LOCKED= NEMA_UP= NEMA_INSTALLED=
    NEMA_PIN=$(sed -n 's/^NEMA_IMAGE_TAG=//p' .env 2>/dev/null | tail -1)
    NEMA_URL=https://github.com/Nema-Project/nema-room/releases/latest/download/docker-compose.yml
    test -n "$NEMA_PIN" \
      && NEMA_URL=https://github.com/Nema-Project/nema-room/releases/download/v$NEMA_PIN/docker-compose.yml
    { curl -fsSL -o docker-compose.yml.download "$NEMA_URL" \
      || { test -n "$NEMA_PIN" && curl -fsSL -o docker-compose.yml.download \
        "https://raw.githubusercontent.com/Nema-Project/nema-room/v$NEMA_PIN/docker-compose.yml"; }; } \
      && mv docker-compose.yml.download docker-compose.yml && NEMA_FETCHED=1
    # Prints the version only when hub and web agree, then locked when .env holds it. Stop if either is missing.
    NEMA_VERSION=$(grep -o 'nema-room-hub:[0-9.]*' docker-compose.yml | head -1 | cut -d: -f2)
    WEB_VERSION=$(grep -o 'nema-room-web:[0-9.]*' docker-compose.yml | head -1 | cut -d: -f2)
    test -n "$NEMA_FETCHED" && test -n "$NEMA_VERSION" && test "$NEMA_VERSION" = "$WEB_VERSION" \
      && echo "$NEMA_VERSION"
    test -n "$NEMA_FETCHED" && test -n "$NEMA_VERSION" && test "$NEMA_VERSION" = "$WEB_VERSION" \
      && { test -n "$NEMA_PIN" || printf '\nNEMA_IMAGE_TAG=%s\n' "$NEMA_VERSION" >> .env; } \
      && test "$(sed -n 's/^NEMA_IMAGE_TAG=//p' .env | tail -1)" = "$NEMA_VERSION" \
      && NEMA_LOCKED=$NEMA_VERSION && echo "locked $NEMA_LOCKED"
    # Each step runs only if the one before it succeeded. Export NEMA_HUB_PORT and NEMA_DATA_HOST_DIR first if .env sets them.
    export NEMA_UID="$(id -u)" NEMA_GID="$(id -g)"   # Linux and macOS only
    NEMA_DIR=${NEMA_DATA_HOST_DIR:-$HOME/.nema/data}
    test -n "$NEMA_LOCKED" && mkdir -p -m 700 "$NEMA_DIR" && test -w "$NEMA_DIR" \
      && NEMA_IMAGE_TAG=$NEMA_LOCKED docker compose up -d --wait && NEMA_UP=1
    test -n "$NEMA_UP" && npm i -g "@nema-project/nema@$NEMA_LOCKED" && NEMA_INSTALLED=1
    # Compose does not run the daemon; keep it running.
    test -n "$NEMA_INSTALLED" \
      && NEMA_DATA_DIR=$NEMA_DIR nema daemon --hub "http://127.0.0.1:${NEMA_HUB_PORT:-4400}"
    
    # Or build this repository from source
    git clone https://github.com/Nema-Project/nema-room.git
    cd nema-room
    node scripts/setup.mjs --lang en
    Download latest