Work in progress · BAT UI on a Paseo daemon開發中 · 跑在 Paseo daemon 上的 BAT 介面

Everyone sees the run. One client drives.

人人看得到,一人說了算。

BAT Cowork puts the Better Agent Terminal desktop UI on a daemon derived from Paseo and keeps the task rules inside that daemon. It is early: one of seven work packages is accepted, nothing is released, and it must not touch a production daemon.

BAT Cowork 把 Better Agent Terminal 的桌面介面接到衍生自 Paseo 的 daemon,任務規則也放在這個 daemon 裡。目前還很早期:七個工作包只通過一個,沒有任何正式版本,也不能接到正式環境的 daemon。

Not a release非正式版本Derived from Paseo衍生自 PaseoNot official Paseo or BAT非 Paseo 或 BAT 官方版本
docs/cowork/RELEASE-GATE.mdNot a release非正式版本
Release gate
發行關卡
No signing key · no staging host沒有簽章金鑰 · 不連 staging 主機
W0 · BaselineW0 · 基準快照W0-REPORT.mdaccepted已通過
W1 · Desktop readW1 · 桌面端讀取w1-session.e2e.test.tsnot accepted未通過
W2 · Task loopW2 · 任務流程w2-same-run.e2e.test.tsnot accepted未通過
W3 · Rework and restartW3 · 重做與重啟task-w3.e2e.test.tslocal evidence僅本機證據
W4 · Shared controlW4 · 多人控制w4-control.e2e.test.tsnot accepted未通過
W5 · UI parityW5 · 介面對等w5-history.test.tsnot accepted未通過
W6 · Journal and cutoverW6 · 帳本與切換w6-journal.test.tsnot accepted未通過
1 / 7Work packages accepted (W0)已通過的工作包(W0)
0Agent providers admitted for dispatch獲准派工的供應者
2 / 90Paseo write messages behind the send gate接上關卡的寫入訊息
7Upstream Paseo files changed改動的上游檔案
The problem要解決的問題

One agent, several clients, nobody in charge.

客戶端一多,就沒人主導。

When a desktop app owns the agent processes, closing it stops the work. When several clients reach the same agent, any of them can send, pause, or resend, and nothing records who decided what. BAT Cowork keeps BAT's interface, drops its local sidecar and agent spawning, and lets a Paseo daemon own agents, worktrees, and task state, with the task rules next to the sessions they guard.

如果 agent 程式綁在桌面 app 上,關掉 app,工作就停了。好幾個客戶端連到同一個 agent 時,誰都能送指令、暫停或重送,也沒有地方記錄是誰決定了什麼。BAT Cowork 保留 BAT 的介面,拿掉它在本機的 sidecar 與啟動 agent 的部分,改由 Paseo daemon 管理 agent、worktree 與任務狀態,任務規則就放在它要把關的 session 旁邊。

Viewers can comment. Only the driver gives instructions.
旁觀者可以留言,主導者才能下指令。
What exists現有功能

What is in the tree today, tested only locally.

目前做好的部分,都只在本機測過。

Everything below ran against a local test daemon with an in-process fake Claude client. None of it has driven a real agent yet.

以下每一項都只在本機測試 daemon 上、搭配程式內的假 Claude 客戶端跑過,還沒有驅動過真正的 agent。

01

BAT's interface, with its notice

沿用 BAT 介面,保留授權聲明

The renderer is imported from Better Agent Terminal at 41ea2b1 under MIT, with TonyQ's copyright notice kept. A new Tauri crate uses its own app id, dev.teddashh.bat-cowork, with no updater and no BAT update endpoint.

介面程式碼從 Better Agent Terminal 的 41ea2b1 匯入,採 MIT 授權並保留 TonyQ 的版權聲明。新的 Tauri crate 使用自己的 app id(dev.teddashh.bat-cowork),沒有自動更新,也不連 BAT 的更新端點。

apps/bat-desktop
02

A read-only view of a daemon

唯讀連上 daemon

The browser shell takes the daemon's WebSocket address as a query parameter and reads workspaces, files, diff, branch, and commit history. The read port has no create or send method, and PTY writes throw.

瀏覽器版用網址參數指定 daemon 的 WebSocket 位址,讀取工作區、檔案、diff、分支與 commit 紀錄。讀取埠沒有建立或送出的方法,PTY 寫入一律丟出錯誤。

DaemonWorkspaceReadPort
03

One driver per task

每個任務一位主導者

Only the driver can instruct, pause, cancel, or release a paused task. Viewers can comment and propose. The daemon stamps each event with the connection's client id, and a takeover holds sends until the current writer settles.

只有主導者能下指令、暫停、取消,或讓暫停的任務繼續;旁觀者可以留言與提案。daemon 會在每個事件蓋上該連線的 client id;有人接手時,會先暫停送出,等目前的寫入者收尾。

cowork-core/task-core.ts
04

A gate on sends

送出前的關卡

Sends to a managed agent go through authorizeCoworkWrite. A stale revision, an old epoch, a paused task, the wrong writer, or a repeated message id is refused. Unmanaged agents keep the stock Paseo path.

送給受管 agent 的訊息都要先通過 authorizeCoworkWrite。revision 過時、epoch 舊了、任務暫停中、寫入者不對,或 message id 重複,一律拒絕。未受管的 agent 照走 Paseo 原本的路徑。

server/cowork/mutation-gate.ts
05

A journal that survives restarts

重啟後還在的任務帳本

Tasks are written to {paseoHome}/cowork/tasks.json and restored when the daemon starts. Each write goes to a synced temp file that is then renamed over the journal, so a crash leaves the old copy or the new one, never half of each. A paused task stays held. A command that was in flight becomes unknown until the driver acknowledges it, and it is not resent.

任務寫在 {paseoHome}/cowork/tasks.json,daemon 啟動時還原。每次寫入都先寫到同步到磁碟的暫存檔,再改名蓋過帳本,所以中途當掉時留下的是舊版或新版,不會是各一半。暫停中的任務維持暫停;重啟前還在執行的指令會標成 unknown,要等主導者確認,而且不會重送。

server/cowork/journal.ts
06

Done means a new commit

有新 commit 才算完成

When a managed turn ends, the task is verified only if HEAD moved past the last verified commit and the tree is clean. Each failed check counts a rework attempt, and after two the task becomes a blocker. No test result feeds this yet.

受管的回合結束時,只有 HEAD 越過上一個已驗證的 commit、而且工作目錄是乾淨的,任務才算 verified。每次檢查沒過就記一次重做,滿兩次後任務就標成卡關。目前還沒有接上測試結果。

verifyTask

Viewers can talk, not pause

旁觀能說,不能暫停

Who drives is decided by the connection, not by a name written in the message.

誰在主導,看的是這條連線,不是訊息裡寫的名字。

  1. Comment

    You can leave a note, or suggest a change.

  2. Driver

    Pause and cancel work only from the driving connection. Someone else can take over, and that freezes sends.

  • a viewer can leave a note
  • pause needs the driver
  • you cannot send an instruction
  • Watching
  • Client id
  • Driving
The original driver can send again only after the work in flight finishes and the takeover is released.
  1. 留言提案

    你可以留一句話,也可以提一個建議。

  2. 主導者

    只有主導的連線能暫停或取消。別人可以接手,接手會先凍結送出。

  • 旁觀者可以留言
  • 暫停要是主導者
  • 不能下指令
  • 在旁邊
  • 連線 id
  • 在主導
還沒跑完的工作做完,接手也放開了,原本的主導者才能再送出。

Most writes skip the gate

多數寫入不進關卡

Sending a message and creating an agent have to clear this gate first.

送出訊息和建立 agent,都要先過這一關。

  1. Too old

    If the task has already moved on, the write is refused.

  2. Wrong writer

    The wrong person, a paused task, or a takeover that has not settled is refused.

  3. Repeated

    The same command does not start a second turn.

  4. Send gate

    An agent this daemon is not managing is allowed through, and Paseo continues as before.

  • an old write is refused
  • a repeated command stops
  • only two kinds are checked
Of 90 kinds of writes, 88 never reach this check.
  1. 寫太舊

    任務已經往下走了,這個寫入就不收。

  2. 人不對

    不是主導者寫的、任務暫停中,或接手還沒完成,都不收。

  3. 又來一次

    同一個指令不會再開始一輪。

  4. 送出關卡

    daemon 沒在管的 agent 會放行,然後還是走 Paseo 原來的路。

  • 太舊的寫入會拒
  • 重複的指令會停
  • 只有兩種會檢查
90 種寫入裡,有 88 種到不了這個檢查。

Git decides, not the tests

看 git,不看測試

When a turn ends, the check looks only at HEAD and the work tree.

回合結束時,檢查只看 HEAD 和工作樹。

  1. Turn ends

    When a managed turn ends, this check runs. A paused or finished task is skipped.

  2. Check HEAD

    HEAD has to be a different commit from the last one recorded, and the work tree has to be clean.

  3. Record it

    A pass stores that commit. After two failures, the third marks the task blocked.

  • HEAD must differ
  • the tree must be clean
  • the repair is not sent
The first check compares against where HEAD was when the task opened.
  1. 回合結束

    daemon 管的回合一結束就檢查。暫停或已經結束的任務會跳過。

  2. 檢查 HEAD

    HEAD 得跟上一次記下的 commit 不同,工作樹也要乾淨。

  3. 記下結果

    通過就記下這個 commit。失敗兩次以後,第三次會標成卡關。

  • HEAD 得不一樣
  • 工作樹必須乾淨
  • 修復不會送出去
第一次檢查時,拿任務開始時的 HEAD 來比。
Architecture系統架構

BAT on the outside, Paseo underneath.

外面是 BAT,底下是 Paseo。

The desktop is a client. The daemon owns agents, worktrees, and task state, and the cowork rules run inside it. Paseo's server, client, protocol, and CLI stay on their upstream paths, and the cowork code is wired in through seven upstream files: 237 lines added, one removed.

桌面端只是客戶端。agent、worktree 與任務狀態都歸 daemon 管,協作規則也在 daemon 裡執行。Paseo 的 server、client、協定與 CLI 都留在上游原本的路徑,協作程式碼只透過七個上游檔案接進來:新增 237 行,刪除 1 行。

Desktop → daemon → agents桌面端 → daemon → agent
BAT desktop UIBAT 桌面介面Renderer from BAT, MITBAT 的 renderer,MIT 授權Tauri shell does not compile yetTauri 版還編譯不過Browser shell reads瀏覽器版能讀取
Paseo daemonPaseo daemonPaseo 0.11.0-beta.4 · cf2b3f4Task journal, send gate任務帳本、送出關卡cowork.tasks.list / append
AgentsAgentClaude, Codex, Grok: not admittedClaude、Codex、Grok:未獲准Tests use a fake Claude client測試用假的 Claude 客戶端Worktrees made by the daemon由 daemon 建立的 worktree
{paseoHome}/cowork/tasks.json

The daemon does the work

活是 daemon 在做

BAT draws the screen. Agents, worktrees, and the cowork rules stay in the Paseo daemon.

BAT 畫畫面。agent、worktree 和協作規則,都在 Paseo 的 daemon 裡。

  1. BAT UI

    The desktop shell has not compiled yet.

  2. Browser read

    It can only read workspaces, files, diffs, and commits.

  3. Daemon

    The task journal and the send check both live in this process.

  4. Cannot run

    Claude, Codex, and Grok cannot run yet.

  • no desktop window yet
  • the browser cannot send
  • no provider can run
The upstream change is small: seven files, 237 lines added, one removed, and Paseo's own code stays where it was.
  1. BAT 介面

    桌面殼還沒編譯成功。

  2. 瀏覽器讀取

    它只能讀工作區、檔案、diff 和 commit。

  3. daemon

    任務帳本和送出檢查,都在這個行程裡。

  4. 不能跑

    Claude、Codex、Grok 都還不能跑。

  • 還沒有桌面視窗
  • 瀏覽器不能送出
  • 沒有供應者能跑
上游的改動很小:七個檔案,加了 237 行,刪了 1 行。Paseo 自己的程式還在原來的地方。

The journal outlives a crash

當掉了,帳本還在

The next process reads the same file. A command that was still running is not sent again.

下一個行程讀的是同一個檔。當時還在跑的指令,不會再送一次。

  1. Task event

    Saves wait in line, so an older one can't overwrite a newer one.

  2. Rename file

    The new body is synced to a temp file beside the journal, then renamed over it.

  3. Read back

    On the next start, a command that was still running is marked unfinished, and new work waits.

  • the temp file is synced first
  • rename is the actual swap
  • in flight is not resent
A crash leaves either the old file or the new one, never a half-written journal.
  1. 任務事件

    存檔依呼叫順序排隊。較舊的快照不會蓋到較新的上面。

  2. 改名寫入

    新內容先同步寫到帳本旁邊的暫存檔,再改名蓋過去。

  3. 重啟讀回

    下次啟動時,當時還在跑的指令會標成未完成,新的工作先等著。

  • 暫存檔先同步
  • 改名才換掉帳本
  • 執行中的不會重送
中途當掉的話,留下的不是舊檔就是新檔,不會寫到一半。
Design decisions設計取捨

Why it is built this way.

為什麼這樣做。

01

Fork the daemon, keep its paths

沿用 daemon,不搬動路徑

Paseo's server, client, protocol, and CLI stay where upstream keeps them, and the cowork code lives in new folders, so upstream changes stay easy to compare. The cost: the rules hook into Paseo's Session handler instead of owning the flow.

Paseo 的 server、client、協定與 CLI 都留在上游原本的位置,協作程式碼放在新的資料夾,和上游比對差異比較容易。代價是協作規則得掛在 Paseo 的 Session 處理流程上,而不是自己掌控整個流程。

02

Rules in the daemon, not a second service

規則放在 daemon 裡,不另開服務

Task rules run in the same process as the sessions they guard. bat-agent-connector's Python task daemon is a behavior reference only and is not vendored, so there is one owner of task state and no second ledger to reconcile.

任務規則和它要把關的 session 跑在同一個程式裡。bat-agent-connector 的 Python 任務服務只當行為參考,沒有複製進來,所以任務狀態只有一個擁有者,不會有第二本帳要對。

03

Refuse instead of pretend

寧可拒絕,不要假裝

BAT host calls that are not ported throw UNSUPPORTED_CAPABILITY, every provider is marked not admitted, and ungated ingress throws. The UI shows less, but nothing quietly half works.

還沒移植的 BAT 主機呼叫一律丟出 UNSUPPORTED_CAPABILITY,每個供應者都標成未獲准,沒有關卡的入口也直接丟錯。介面能顯示的東西變少,但不會有功能悄悄只做一半。

04

The gate is a file a test reads

發行關卡是一個由測試把關的檔案

RELEASE-GATE.md is plain text. w6-release-gate.test.ts fails if it stops saying Not a release, if cutover opens, or if any package other than W0 is marked accepted, so changing the status means changing a test too.

RELEASE-GATE.md 是純文字檔。只要它不再寫著 Not a release、切換被打開,或 W0 以外的工作包被標成 accepted,w6-release-gate.test.ts 就會失敗,所以要改狀態,也得一起改測試。

Nobody is allowed to run

沒有一家准跑

A catalog row, or an adapter sitting on disk, is not permission to run one.

目錄裡有一列,或磁碟上有 adapter,都不代表可以讓它跑。

  1. Admit check

    Claude, Codex, Grok, and Antigravity are all refused.

  2. Test fake

    Tests use a fake Claude inside the process, not a real login.

  • no provider is admitted
  • a catalog row is not a yes
  • tests use a fake client
A provider that is not on the list is refused too.
  1. 准入檢查

    Claude、Codex、Grok 和 Antigravity,一律不准跑。

  2. 測試替身

    測試用的是行程裡的假 Claude,不是真的登入。

  • 沒有供應者獲准
  • 目錄有列也不算准
  • 測試用假的客戶端
表上沒有的供應者,一樣會被拒。
Try it動手試試

Read the gate, then run the tests.

先看關卡,再跑測試。

There is nothing to install as a product. In a clone of the repo, the task rule and desktop host suites need only Node (24 was used here) and no npm install. The client boundary tests and the server-side cowork tests run under Vitest and need the Paseo workspace install (npm ci at the repo root).

目前沒有可以安裝的產品。在 clone 下來的 repo 裡,任務規則與桌面主機這兩組測試只需要 Node(這裡用的是 24 版),不用 npm install。客戶端邊界測試與 server 端的協作測試跑在 Vitest 上,要先在 repo 根目錄執行 npm ci,裝好整個 Paseo workspace。

Task rules: 17 tests

任務規則:17 個測試

The reducer, dispatch policy, ingress table, and UI parity rows.

涵蓋 reducer、派工規則、ingress 對照表與介面對等清單。

cd packages/cowork-core
npm test

Read-only client boundary: 7 tests

唯讀客戶端邊界:7 個測試

From the repo root, after npm ci. Runs under Vitest and checks that writes are not reachable and auth headers stay in one module.

從 repo 根目錄執行,要先跑過 npm ci。測試跑在 Vitest 上,確認寫入方法拿不到,驗證標頭也只在一個模組裡處理。

cd packages/client
npx vitest run src/cowork

Desktop host refusals: 5 tests

桌面主機的拒絕行為:5 個測試

From the repo root. Unported BAT calls must throw, and reads must go through the daemon port.

從 repo 根目錄執行。還沒移植的 BAT 呼叫必須丟出錯誤,讀取也必須經過 daemon 的讀取埠。

cd apps/bat-desktop
npm test
Honest status誠實的現況

Where it stands.

目前的樣子。

Work began on 2026-09-30, and the tree is still changing quickly. There are no tags or releases. CI on main runs Paseo's suites and the cowork tests; a few tests inherited from Paseo fail now and then and pass on a rerun. Paseo is by Mohamed Boudra and contributors; BAT is by TonyQ. This is not an official build of either.

2026 年 9 月 30 日才開始,程式碼還在快速變動。沒有任何 tag 或正式版本。main 的 CI 會跑 Paseo 原有的測試與協作測試;有幾個從 Paseo 帶來的測試偶爾失敗,重跑就會通過。Paseo 的作者是 Mohamed Boudra 與其貢獻者,BAT 的作者是 TonyQ;本專案不是兩者的官方版本。

Works on a local test daemon

在本機測試 daemon 上可用

  • W0 accepted the original Paseo snapshot at 53ee9cd, upstream-lock.json, third-party notices, and the inventories in cowork-core. This tree now follows cf2b3f4
  • W0 已通過原本的 Paseo 53ee9cd 快照、upstream-lock.json、第三方聲明,以及 cowork-core 裡的各項清單。目前這棵樹跟到 cf2b3f4
  • Two clients see one run; a repeated message id does not start a second turn; a daemon-made worktree receives the commit
  • 兩個客戶端看到同一次執行;重複的 message id 不會開第二輪;commit 落在 daemon 建立的 worktree
  • Pause, takeover, rework, and restart paths in the task reducer, with a journal that survives a daemon restart
  • 任務 reducer 的暫停、接手、重做與重啟流程,帳本在 daemon 重啟後仍在
  • A browser shell that reads workspaces, files, diff, and commit history from a local daemon
  • 瀏覽器版可以從本機 daemon 讀取工作區、檔案、diff 與 commit 紀錄
  • 29 cowork tests pass in a local run and in CI: 17 task core and 5 desktop host that need no install, plus 7 client boundary under Vitest
  • 29 個協作測試在本機與 CI 都通過:不需安裝的任務核心 17 個、桌面主機 5 個,加上跑在 Vitest 上的客戶端邊界 7 個

Not done, and not safe yet

還沒完成,也還不安全

  • Not a release: no tags, no signing key, no updater. Do not point it at a production daemon or an existing BAT session
  • 不是正式版本:沒有 tag、沒有簽章金鑰、沒有自動更新。不要把它接到正式環境的 daemon 或既有的 BAT session
  • The Tauri shell has not been built: the one compile attempt stopped in glib-sys because pkg-config was missing, so there is no desktop window yet
  • Tauri 版還沒建置成功:唯一一次編譯在 glib-sys 就失敗了(環境裡沒有 pkg-config),所以還沒有桌面視窗
  • No agent provider is admitted: Claude, Codex, and Grok stay closed, and every turn in the tests comes from a fake Claude client
  • 沒有任何 agent 供應者獲准:Claude、Codex、Grok 都還關著,測試裡的每一輪都來自假的 Claude 客戶端
  • Only 2 of Paseo's 90 inbound write messages pass the cowork gate; the other 88 are not wired
  • Paseo 的 90 種寫入訊息裡,只有 2 種經過協作關卡,其餘 88 種還沒接上
  • No client message opens a task or sends an instruction yet, the terminal is refused, and the journal is still one JSON file rewritten in full on every event
  • 還沒有客戶端訊息能開任務或下指令,終端機也被拒絕;帳本仍是一個每次事件都整份重寫的 JSON 檔
  • Workspace scope is an upstream gap: Paseo grants are daemon-wide, and file preview accepts any file the daemon can read
  • 工作區範圍是上游的缺口:Paseo 的授權是整個 daemon 層級,檔案預覽也接受 daemon 讀得到的任何檔案
Version版本
Unreleased未發行
Based on基礎
Paseo 0.11.0-beta.4 · cf2b3f4
License授權
Apache 2.0 · BAT UI MITApache 2.0 · BAT 介面 MIT
Stack技術
TypeScript · Node · Tauri
Release gate發行關卡
1 of 7 accepted7 個通過 1 個
Verified查核日期
2026-10-06

More from Ted Huang. Every public project has a page like this one, in English and Traditional Chinese.

Ted Huang 的其他作品。每個公開專案都有一頁像這樣的中英雙語介紹。

All projects →全部專案 →