查看源码

NemaRoom

让项目保持对齐,从讨论直到交付。

Hammershøi 画作《白门》:空房间里两扇白色的门向内敞开,能看到后面的房间。
Hammershøi 画作《斯特兰德街 30 号室内》:一扇门开着,穿过门洞是另一个房间和一个背影。

需求容易散落,同一件事也会被理解成两样。

收成同一份有来源的理解,提交证据再回到讨论。

讨论怎样落地

下面是一次关于“账单导出”的讨论。打开一条消息,Nema 会把它整理成条目,并注明这条是谁说的、谁定的,还是 Agent 推断的。

用户陈述
有人在讨论里说过
用户决定
有人拍板定下
Agent 推断
Agent 提出,等你确认
知识库 · 账单导出 需求 1 · 决策 1 · 问题 1
    讨论中的消息

    同一份理解,每条都有出处

    分清谁说的

    用户陈述、用户决定、Agent 推断分开标注。Agent 的推断不会冒充你的决定。

    决策 D-2用户决定

    导出文件带 UTF-8 BOM

    “要带,不然中文会乱码。”周 · 10:12 · 回答了 Q-1
    1. a41c0e2D-2 新增:导出文件带 BOM
    2. 7be19f0Q-1 状态:待澄清 → 已回答
    3. e03d551R-2 修改:日元改为取整
    4. 19ac7d4D-1 新增:首版只做 CSV

    改动都在 Git 里

    知识库本身是一个 Git 仓库。哪条被改了、为什么改、改之前是什么,都能翻出来。

    读得到你的代码

    绑定本地仓库后,Agent 读取 main 分支快照、搜索代码,讨论时就知道现有实现。

    仓库~/code/ledger-app
    分支main @ 5d2e8a1
    快照2 分钟前
    src/billing/export.ts:48
    src/billing/export.test.ts:12
    账单导出调用图代码已变更,图可能过期
    BillingPage exportCsv BillRepo tz.ts

    代码图会提醒过期

    从代码生成的图记住了它基于哪次提交。代码一变,图上就标出来,不会悄悄过时。

    先问清楚再动手

    没说清的地方,以及和已有决策冲突的说法,会变成问题。Nema 提问并等你来定。需要你回答的地方用红色标出。

    • Q-3空账单月份要导出空文件吗?待回答
    • Q-2旧账单是否也按新时区重算?待回答
    • Q-1CSV 是否带 UTF-8 BOM已回答
    界面语言
    中文English日本語
    知识语言
    跟随讨论固定
    夜间模式

    三种界面语言

    中文、英文、日文界面随时切换。条目用什么语言记,可以单独设置。

    回到讨论

    工作包 · 账单 CSV 导出整理中
    • 需求 3
    • 决策 1
    • 问题 2 待回答

    先在房间里讨论,条目随讨论归档。

    工作包 · 账单 CSV 导出已澄清
    • 需求 3
    • 决策 3
    • 问题 0 待回答

    再把没说清的问题逐个问清楚。

    工作包 · 账单 CSV 导出已批准
    • 规格与计划已生成
    • 交给 Claude Code
    • 批准人:周

    然后生成工作包,批准后交给编码 Agent。

    工作包 · 账单 CSV 导出已完成
    • 提交 3 个,已进入 main
    • 改动 6 个文件
    • 关联回 3 条需求

    提交回报回到讨论里。

    数据库
    本机磁盘上的 PGlite
    数据目录
    ~/.nema/desktop
    网络
    只监听本机回环地址

    只在你的电脑上运行

    桌面版把整套服务装进一个程序:数据库、本地核心和 Node 随附。它使用你电脑上已经装好的 Git(2.31 或更新)。在 Mac 上,从访达打开时也会找到 Homebrew 和 MacPorts 的 Git。不需要 Docker,也不需要数据库服务器。讨论内容只发给你选的模型服务商,GitHub 令牌 Nema 不碰。

    现状

    • Windows x64 桌面版最新安装包或 ZIP
    • macOS 桌面版最新,Apple 芯片
    • LinuxWeb / Compose 版
    • 安装包签名暂未签名
    • 自动更新暂无
    • ChatGPT 订阅浏览器登录
    • Claude 订阅Claude Code 令牌
    • API Key兼容 Responses API
    • 编码 AgentCodex、Claude Code
    • 许可证MIT

    常见问题

    现在能下载吗?

    可以。最新发布提供 Windows x64 安装包、Windows 便携 ZIP,以及 Apple 芯片 Mac 的磁盘镜像。ZIP 是解压即可运行的程序目录:解压后运行 Nema.exe,没有快捷方式,也没有卸载程序。安装包和 ZIP 都使用 ~/.nema/desktop。选其中一个。安装包未签名,Windows 首次打开会提示“已保护你的电脑”,macOS 需要在“隐私与安全性”里打开。应用还需要本机已安装 Git 2.31 或更新版本。Intel Mac 没有桌面安装包。Linux 使用 linux/amd64 的 hub 与 web 镜像,或从源码构建。

    要花钱吗?

    Nema Room 本身以 MIT 许可开源。整理条目需要调用模型,费用或额度由你选的服务商决定:ChatGPT 或 Claude 订阅,或者你自己的 API Key。

    讨论内容会上传到哪里?

    数据库和知识库都在你的电脑上。只有生成条目时,相关内容会发给你选择的模型服务商。服务默认只监听本机,不要直接暴露到公网。

    编码 Agent 怎么回报进度?

    用 nema report install 给 Codex 或 Claude Code 装上回报钩子。提交时它会通知 Nema;Nema 没在运行时,回报先存在本地,下次再发。

    能多人一起用吗?

    首版是一个人在本机使用。多设备同步、备份和团队只读访问,会在本地核心完成之后再做。

    为什么叫 Nema?

    名字来自日语「根回し」(nemawashi):决定之前先把理解理清。不同意见留在明处,决定则带着证据。

    Hammershøi 画作《斯特兰德街 30 号室内》:门开着,一位女子背对观者坐在桌前。

    下载

    Windows x64 和 Apple 芯片的构建在最新发布页。Windows 上在安装包和便携 ZIP 里选一个。ZIP 解压后运行 Nema.exe,没有快捷方式,也没有卸载程序。两者都使用 ~/.nema/desktop。本机需要已经装好 Git 2.31 或更新版本。

    宿主机命令是 nema,用 npm i -g @nema-project/nema@<locked version> 安装。这个数字是你取到的 docker-compose.yml 里两个 image: 钉的那个版本。hub 和 web 镜像是 linux/amd64。docker-compose.yml 是最新 Release 的固定名资产,渲染时双镜像都钉在该 Release 的版本上。取到后确认两处钉的版本相同,把 NEMA_IMAGE_TAG=<该版本> 写进 .env(已有值就沿用,并改取 releases/download/v<locked>/docker-compose.yml),再启动。v0.1.6 的文件开头仍是模板那条「不是可安装的版本」注释,以两行钉住版本的 image: 为准。v0.1.6 之前的锁定版本没有发布资产,改取 raw.githubusercontent.com/Nema-Project/nema-room/v<locked>/docker-compose.yml。Linux 和 macOS 上先导出 NEMA_UID 和 NEMA_GID。开发本仓库则克隆后运行安装向导。

    # hub 与 web,仅 linux/amd64。compose 文件是最新 Release 的固定名资产;.env 里已有 NEMA_IMAGE_TAG 时沿用它的版本。
    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
    # hub 和 web 版本一致才打印版本,.env 锁的正是它才打印 locked。缺一个就停下。
    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"
    # 每一步只在上一步成功后执行。.env 设了 NEMA_HUB_PORT 或 NEMA_DATA_HOST_DIR 时先 export 同样的值。
    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 不会替你启动 daemon,请让它一直运行。
    test -n "$NEMA_INSTALLED" \
      && NEMA_DATA_DIR=$NEMA_DIR nema daemon --hub "http://127.0.0.1:${NEMA_HUB_PORT:-4400}"
    
    # 或从源码构建本仓库
    git clone https://github.com/Nema-Project/nema-room.git
    cd nema-room
    node scripts/setup.mjs
    下载最新版