Observed since 21 Oct, 09:20 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
One Agora per project: an architecture canvas shared with your own coding agent
每个项目自带一个 Agora:在项目的架构图上,和你自己选的 coding agent 讨论设计,再一键回到终端接着写代码。
A per-project architecture canvas where you and your own coding agent (Pi, Claude Code or Codex) discuss the design, then continue the very same session in the terminal.

在项目目录里运行 agora,就得到只属于这个项目的本地服务:架构图、评论、会话记录都存在项目的 .agora/ 里,跟着代码一起提交、克隆、切分支。
uv tool install git+https://github.com/arvakme/agora # 装成全局命令(需要 Node 22+ 构建前端,见「快速开始」)
cd ~/code/my-service && agora # 起本项目服务并打开浏览器
Agora 把这三件事放到同一张图上:图就在仓库里,agent 能读能改;它写代码时,图上的指针告诉你它正在动哪一块。
agora up 在当前目录初始化 .agora/ 并起本项目专属服务(只监听 127.0.0.1,不同项目各占一个端口)。画布是标准 .excalidraw 文件,评论是 JSON,键排序、内容不变就不重写,git diff 可读。会话记录、运行状态和分享记录默认不提交。格式见项目存储。

每个会话开始时从 Pi / Claude Code / Codex 里选一个,连同模型和强度一起锁定。会话就是这个 CLI 自己的原生会话,Agora 不另存对话,而是跟随 CLI 的会话日志。agent 通过 agora skill 调 agora canvas read / apply / link / anim 读图、改图,每次改图都是一批可撤销的修改。画布上的评论可以直接「交给 Agent」,答复会贴回评论线程。见 Agent 会话。

「在终端打开」用同一个原生会话 id 起交互式 CLI(claude --resume、pi --session-id、codex resume),在本项目专属的 tmux 服务器里起,再用 Ghostty(没有就 Kitty,再没有就 Terminal.app)打开窗口。你在终端里说的话、agent 的回复和工具调用都会出现在面板上;从面板发的消息会等 agent 这一轮结束、且没有人占着终端的输入(接管了,或挂着一个可写窗口)时粘贴进去,队列不丢。

给节点关联代码路径(glob,存在元素的 customData.codePaths 里,随图提交),可以手动设,也可以让 agent 按目录结构批量关联。agent 读写哪个文件,它的小人就走到这个文件所属的节点上干活(小人就是指针,见工位视图;两个节点之间有箭头直接相连时,小人沿箭头滑过去,否则蹲下、沿抛物线跳过去);不属于任何节点的文件在图外托盘。终端里发生的改动同样驱动它。映射规则见进度指针。

「对话 / 轨迹」两种视图(信息结构取自 DeepSeek Harness):每轮的模型、强度、输入 / 输出 / 缓存 tokens、耗时、花费;时间轴总览;每次工具调用可展开看完整输入、输出、改到的文件和起止时间。

agora share create --for 1d(或顶栏「分享」)经 Cloudflare Tunnel 给一块画布(或 --whole-project 整个项目,之后新建的画布也自动可见)开一个独立子域名,访客只能看图、读评论、发评论和回复;改图、会话、终端、代码路径和本地路径都不下发。到期或撤销后 DNS 记录和隧道一起删除。域名来自你自己的 Cloudflare zone(作者本机用的是 quietharbor.de)。没有账号也行:agora share create --quick 用 cf tunnels quick-start 开一个临时 trycloudflare.com 地址(一次一个分享,撤销或 agora down 即失效)。想把画布交给别的开发者:agora share export 导出分享包(访客页也有「导入到我的 Agora」),对方 agora import 就成了他项目里的新画布,评论作为只读历史;分享包一旦给出去就收不回来。见分享。
| 作者:选画布和有效期 | 访客:只读画布,可评论 |
|---|---|
![]() | ![]() |
flowchart LR
subgraph browser [浏览器]
UI[Agora 页面<br/>Excalidraw 画布 · 会话 · 轨迹 · 指针]
end
subgraph project [你的项目目录]
Server[本项目的 agora 服务<br/>127.0.0.1:随机端口]
Files[(.agora/<br/>canvases · threads · sessions · config)]
subgraph tmux [tmux -L agora-项目哈希]
TUI[交互式 CLI<br/>claude / pi / codex]
end
Headless[无头续接<br/>claude -p · pi -p · codex exec]
Logs[(CLI 原生会话日志<br/>~/.claude · ~/.pi · ~/.codex)]
end
subgraph share [分享]
Guest[访客浏览器<br/>子域名.quietharbor.de]
CF[cf tunnels run<br/>Cloudflare Tunnel]
Gateway[分享网关<br/>白名单路由]
end
UI <-->|HTTP + SSE| Server
Server <-->|原子写 + 版本校验| Files
Server -->|发消息| Headless
Server -->|粘贴 / 托管| TUI
Headless -->|agora skill<br/>agora canvas read/apply/link| Server
TUI -->|agora skill| Server
Headless --> Logs
TUI --> Logs
Logs -->|每 0.4s 跟随| Server
Server -->|改图请求| UI
Guest -->|HTTPS| CF --> Gateway -->|一块画布 + 评论| Files
agora canvas apply 经服务转给最近连接的页面执行(校验 schema、引用和新鲜度),结果写回 .agora/。依赖:
| 依赖 | 用途 |
|---|---|
| uv(Python 3.12+,没有时 uv 自己装) | 安装和运行 agora 命令 |
Node 22+ 与 npm(从源码安装或开发时;开发用 Node 24,写在 web/mise.toml,装了 mise 会自动选用) | 构建前端 |
| tmux | 「在终端打开」 |
至少一个已登录的 agent CLI:claude、pi 或 codex | 会话 |
可选:cf(没装时自动用 npx cf@1.0.0-beta.5,AGORA_CF_VERSION 可改;先 npx cf auth login)+ 自己的 Cloudflare 域名 | 分享 |
安装成全局命令(不需要留着仓库):
uv tool install git+https://github.com/arvakme/agora # 安装时构建前端,需要 Node 和 npm
cd ~/code/my-service # 你的项目(.agora/ 建在当前目录)
agora # 不带子命令等于 agora open:初始化 .agora/,起本项目服务并打开浏览器
agora open --no-browser # 只起服务、打印地址
agora status # 在跑就打印地址、端口、pid
agora down # 停掉服务和本项目的 tmux
agora doctor [--fix] # 检查本机数据;--fix 从备份和本机注册表放回丢了的东西
装好后提示找不到 agora 时运行一次 uv tool update-shell 再重开终端;which agora 能看到跑的是哪一份(以前把 ~/code/agora/bin 加进过 PATH 的话,记得删掉)。升级用 uv tool upgrade agora-canvas(或重新 uv tool install --force git+https://github.com/arvakme/agora),卸载用 uv tool uninstall agora-canvas。推 v* 标签后,GitHub Release 里会有带好前端的 wheel,装它不需要 Node(目前还没有发布过版本)。发行包名是 agora-canvas(PyPI 上 agora、agora-cli 都已被占用),命令名仍是 agora;发布到 PyPI 后可以 uv tool install agora-canvas,或不安装直接 uvx --from agora-canvas agora open(目前还没发布)。
从源码运行(开发 Agora 本身时用;改代码立即生效,还能走 vite 热更新):
git clone https://github.com/arvakme/agora.git ~/code/agora
cd ~/code/agora
uv sync
cd web && npm ci && npm run build && cd .. # 用 mise 时:mise exec -- npm ci,以此类推
cd ~/code/my-service
~/code/agora/bin/agora open # 与上面的 agora 相同,跑的是这份仓库的代码
~/code/agora/bin/agora open --dev # 前端走 vite 热更新(只有源码仓库能用)
一边改 Agora 一边在别的项目里用:uv tool install --editable ~/code/agora。全局的 agora 直接跑这份仓库的代码,改完不用重装,agora open --dev 也能用。
删除的画布和会话进「回收站」,30 天内可恢复(刷新、重启后也行);「所有画布」底部还有「会话历史」,可以按时间、agent、主题、画布找会话,也能把本机找到的原生会话重新导入。
仓库移动、cp -r 复制、重新 clone 都有处理:移动后 Pi 会话的日志跟着挪;副本里的会话只读、可分叉继续;别的机器建的会话显示成只读卡片。git clean -fdx 删掉的本机数据(会话绑定、改图记录、回收站)由仓库外的每日备份和本机注册表兜底:agora doctor --fix。见项目存储。
首次打开会建一块以项目命名的空画布和一个会话;会话里的「画出这个项目的架构」按钮让推荐的 agent 看一遍项目、把架构画上去(也可以自己选 agent、自己写第一句话);「看一个示例」会把示例图作为另一张画布打开。
绑定会话时会自动为该 agent 安装 agora skill(旧的 agora-canvas 链接会被换掉);也可以手动 agora skill install --agent claude|codex|pi|all(Claude Code 链接到 .claude/skills/,Codex 链接到 .agents/skills/,Pi 每次启动带 --skill;链接写进 .git/info/exclude,不改全局配置)。
agora up 只起服务并打印地址。从源码运行时把 ~/code/agora/bin 加进 PATH 也能直接用 agora。同时开着几个 worktree 的服务时,agora dev status 列出本机所有服务和各自跑的 git SHA(安装版显示包版本),agora dev gc 清掉已退出的记录。
分享需要 cf(Cloudflare CLI;没装就用固定版本的 npx cf),并已 npx cf auth login(凭据归 cf 管,Agora 不存也不读);AGORA_SHARE_DOMAIN 指定分享用的域名(账号里只有一个域名时可省):
agora share create --for 1d # 默认分享聚焦的画布;--canvas <id|名字>;--for 10m|2h|1d|7d|forever
agora share list
agora share revoke <id> # 或 --all
固定的 7 类改图任务,每类跑 3 次,逐次检查:通过 schema 校验、新鲜度、改对元素、没有误伤、撤销后完全还原。最近一次(2026-09-28,claude-sonnet-5):
| 任务 | 通过 | 平均耗时 | 平均花费 |
|---|---|---|---|
| T1 改名 | 3/3 | 5.7 s | $0.0088 |
| T2 新增节点并连线 | 3/3 | 8.7 s | $0.0092 |
| T3 给箭头加标签 | 3/3 | 4.6 s | $0.0039 |
| T4 对齐两个节点 | 3/3 | 26.2 s | $0.0232 |
| T5 删除节点并重连 | 3/3 | 4.8 s | $0.0050 |
| T6 从素材库插入 Kafka | 3/3 | 18.9 s | $0.0213 |
| T7 画一个普通 TODO 方框 | 3/3 | 6.3 s | $0.0057 |
| 合计 | 21/21(100%) | 10.7 s | $0.0110(总 $0.2312) |
评测基线是一次性的 claude -p --json-schema,在中性的空临时目录里运行,不继承仓库或项目上下文,也不经过 Agent 会话,只衡量「看图 + 评论 → 类型化改图操作」这一步。明细见 web/eval/latest-report.md,原始记录在 web/eval/runs/。
cd web
npm run eval -- --runs 3 # 真模型,写 eval/runs/*.jsonl 与 eval/latest-report.md
npm run eval:replay # 离线回放最近一轮的模型输出(validate → apply → check → undo),不调模型
agora_cli/ agora 命令:init / up / open / status / down / canvas / skill / share
bin/agora 在任意项目目录里调用上面的命令:源码仓库里经 uv run --project <仓库>,安装版里用安装环境自己的 Python
bin/agora-state CLI 钩子向服务回报状态的脚本
server/canvas/ 本项目服务:项目存储、三个 agent 后端、会话跟随与终端、画布桥接、分享与网关
server/paths.py 非 Python 文件(前端、素材库、skill、bin/)的唯一定位:源码里是仓库根,安装后是包内 server/_bundle/
hatch_build.py 打包钩子:没有 web/dist 时先构建,再把上述文件放进 wheel
skills/agora/ 给 Pi / Claude Code / Codex 的 skill:SKILL.md 是入口路由,references/ 按领域放细节(改图、动画、子图、关联代码、评论、派活)
web/ 前端(React + Excalidraw);web/docs/ 是各功能规格,web/eval/ 是评测
web/libraries/ vendored 素材库(约 6k 个组件,来源与许可见其 NOTICE.md)
tests/ Python 测试
docs/ 开发协作与测试说明
.agora/ 文件,靠版本校验发现冲突,由你选择载入磁盘版本或覆盖;外部改动不会主动推送到已打开的页面。agora canvas apply 返回退出码 3。AGORA_TURN_IDLE_TIMEOUT_S / AGORA_TURN_MAX_S 改秒数,0 = 不设。/model 无法禁止(Pi 用 --models 把轮换限制在选定模型);下一次无头续接仍按绑定的模型启动。sed -i、cat > x 这类 shell 写入不会被识别;读文件、跑测试不移动指针;一个文件只属于最具体的那个节点。AGORA_TERMINAL=ghostty|kitty|terminal|auto 可指定);都没有时面板给出 tmux attach 命令;下拉里的「复制打开命令」给出可在任意终端里运行的命令。可能的方向(未排期):多人实时协同编辑、Linux 上的终端窗口、进度指针识别更多写入方式。
uv run pytest tests/test_project_store.py tests/test_agent_sessions.py tests/test_share.py # 画布相关,免外部服务
cd web && npx tsc -p . && npx vitest run && npm run build && npm run eval:replay
打包:uv build 在 dist/ 生成 sdist 和 wheel(没有 web/dist 时先在 web/ 里 npm ci && npm run build;AGORA_SKIP_WEB_BUILD=1 跳过前端)。推 v* 标签时 .github/workflows/release.yml 构建并附到 GitHub Release,不发布到 PyPI。
仓库目前不跑 CI,提交前在本地跑上面的检查;.github/workflows/test.yml 还在(全部 Python 测试,以及前端的类型检查、单测、构建、离线评测回放和素材库校验),需要时在 GitHub 上重新启用 Actions 即可。开发协作见 docs/development.md,测试说明见 docs/testing.md,后端编排(Agent 生命周期、派发与恢复)见 docs/orchestration.md,一页面试讲法见 docs/orchestration-interview.md。
本项目以 MIT 许可发布。第三方内容:
web/libraries/):来自 excalidraw-libraries 等来源的组件。各自的作者、许可和原始地址见 NOTICE.md 与 SOURCES.md,许可全文在 web/libraries/licenses/。其中的产品名称和标志归各自所有者,仅用于在图中指代对应产品。@unlocalhosted/dither-icons,MIT,© 2026 Unlocalhosted):界面图标。web/src/app/dither-extra/):本项目作者为 Marginalia 按 Dither Icons 的构造规则绘制的 17 个补充图标(eye-off 复用 Dither Icons 的眼睛几何),随本项目以 MIT 发布,并附 Dither Icons 的许可原文(LICENSE-dither-icons.txt)。web/src/app/agents/,随应用打包、不在运行时外链):Pi 取自 pi.dev Press Kit 的方形徽标(Badge SVG,pi.dev/favicon.svg,单色,亮色 #111111、暗色 #f6f6f6),以矢量路径内联;Claude Code 取自官方文档站 code.claude.com/docs 的矢量标志(橙色星芒 #D97757),以矢量路径内联;Codex 取自 OpenAI 签名的 Codex 桌面应用(bundle id com.openai.codex,26.908.70816)自带的 1024px 图标 Contents/Resources/icon-codex-light.png 与 icon-codex-dark-color.png:用两张图做差分抠图去掉应用底板与投影,只留中间的云形标志,导出 64px 与 128px 两档;Grok 取自 xAI 官网 x.ai 自己发布的站点图标 https://x.ai/icon.png(512px 位图,黑底白标;官方没有公开矢量,grok.com 拒绝抓取),2026-09-29 取得,缩成 64px 与 128px 两档;Cursor 取自 cursor.com 的 https://cursor.com/favicon.svg(矢量,自带深色圆角底板 #14120b 与浅色立方体 #edecec,两种主题下原样使用,以矢量路径内联),2026-09-29 取得;Devin 取自 devin.ai 的 https://devin.ai/favicon.svg(单色矢量,原色黑 #000000,内联时改用主题墨色:亮色 #111111、暗色 #f6f6f6),2026-09-29 取得。web/src/app/terminals/):Kitty 取自本机 kitty.app(0.48.2)的 Contents/Resources/kitty.icns,Kitty 为 Kovid Goyal 的作品(kovidgoyal/kitty);取 32px 与 64px 两档,未改动图形。Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 19 Oct 2026 | 5 |
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 09:20 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:e200c931135662045c785c071162a797ae9b92fef2681f3aa364417823c91a08