PTY 與行程監督計畫
1. 問題與目標
我們需要一套可靠的生命週期機制,涵蓋所有長時間執行的指令執行:
exec前景執行exec背景執行process後續操作(poll、log、send-keys、paste、submit、kill、remove)- CLI 代理 runner 子行程
目標不僅是支援 PTY,而是具備可預測的擁有權、取消、逾時和清理,不使用不安全的行程比對啟發式方法。
2. 範圍與邊界
- 實作內部維護在
src/process/supervisor。 - 不為此建立新套件。
- 在可行處保持現行行為的相容性。
- 不擴展範圍至終端機重播或 tmux 風格的 session 持久性。
3. 本分支已實作
Supervisor 基線已就位
- Supervisor 模組已在
src/process/supervisor/*下就位。 - Exec 執行時和 CLI runner 已透過 supervisor spawn 和 wait 路由。
- Registry 最終化為冪等的。
本次完成
- 明確的 PTY 指令合約
SpawnInput現在是src/process/supervisor/types.ts中的判別聯集。- PTY 執行需要
ptyCommand而非重用泛用的argv。 - Supervisor 不再在
src/process/supervisor/supervisor.ts中從 argv join 重建 PTY 指令字串。 - Exec 執行時現在在
src/agents/bash-tools.exec-runtime.ts中直接傳遞ptyCommand。
- 行程層型別解耦
- Supervisor 型別不再從 agents 匯入
SessionStdin。 - 行程本地的 stdin 合約位於
src/process/supervisor/types.ts(ManagedRunStdin)。 - 轉接器現在僅依賴行程層級型別:
src/process/supervisor/adapters/child.tssrc/process/supervisor/adapters/pty.ts
- 行程工具生命週期擁有權改善
src/agents/bash-tools.process.ts現在先透過 supervisor 請求取消。process kill/remove現在在 supervisor 查詢未命中時使用行程樹回退終止。remove透過在請求終止後立即丟棄執行中的 session 項目來保持確定性的 remove 行為。
- 單一來源看門狗預設值
- 在
src/agents/cli-watchdog-defaults.ts新增共用預設值。 src/agents/cli-backends.ts使用共用預設值。src/agents/cli-runner/reliability.ts使用相同的共用預設值。
- 無用輔助函式清理
- 從
src/agents/bash-tools.shared.ts移除未使用的killSession輔助路徑。
- 直接 supervisor 路徑測試
- 新增
src/agents/bash-tools.process.supervisor.test.ts覆蓋透過 supervisor 取消的 kill 和 remove 路由。
- 可靠性缺口修復已完成
src/agents/bash-tools.process.ts現在在 supervisor 查詢未命中時回退至真正的 OS 層級行程終止。src/process/supervisor/adapters/child.ts現在對預設的取消/逾時 kill 路徑使用行程樹終止語義。- 在
src/process/kill-tree.ts新增共用的行程樹工具。
- PTY 合約邊緣案例覆蓋
- 新增
src/process/supervisor/supervisor.pty-command.test.ts用於逐字 PTY 指令轉發和空指令拒絕。 - 新增
src/process/supervisor/adapters/child.test.ts用於 child adapter 取消中的行程樹 kill 行為。
4. 剩餘缺口與決策
可靠性狀態
本次要求的兩個可靠性缺口現已關閉:
process kill/remove現在在 supervisor 查詢未命中時有真正的 OS 終止回退。- child 取消/逾時現在對預設 kill 路徑使用行程樹 kill 語義。
- 兩個行為都新增了回歸測試。
持久性與啟動調和
重啟行為現在明確定義為僅記憶體生命週期。
reconcileOrphans()在src/process/supervisor/supervisor.ts中刻意保持為 no-op。- 行程重啟後不復原活躍的執行。
- 此邊界在本次實作中是刻意的,以避免部分持久化的風險。
可維護性後續
src/agents/bash-tools.exec-runtime.ts中的runExecProcess仍處理多項職責,可在後續分割為聚焦的輔助函式。
5. 實作計畫
必要的可靠性和合約項目的實作已完成。
已完成:
process kill/remove回退的真正終止- child adapter 預設 kill 路徑的行程樹取消
- 回退 kill 和 child adapter kill 路徑的回歸測試
- 明確
ptyCommand下的 PTY 指令邊緣案例測試 - 明確的記憶體重啟邊界,
reconcileOrphans()刻意為 no-op
選用後續:
- 將
runExecProcess分割為聚焦的輔助函式且不改變行為
6. 檔案對照
行程 supervisor
src/process/supervisor/types.ts更新為判別式 spawn input 和行程本地 stdin 合約。src/process/supervisor/supervisor.ts更新為使用明確的ptyCommand。src/process/supervisor/adapters/child.ts和src/process/supervisor/adapters/pty.ts與代理型別解耦。src/process/supervisor/registry.ts冪等最終化保持不變。
Exec 與 process 整合
src/agents/bash-tools.exec-runtime.ts更新為明確傳遞 PTY 指令並保留回退路徑。src/agents/bash-tools.process.ts更新為透過 supervisor 取消並搭配真正的行程樹回退終止。src/agents/bash-tools.shared.ts移除直接 kill 輔助路徑。
CLI 可靠性
src/agents/cli-watchdog-defaults.ts新增為共用基線。src/agents/cli-backends.ts和src/agents/cli-runner/reliability.ts現在使用相同預設值。
7. 本次驗證執行
單元測試:
pnpm vitest src/process/supervisor/registry.test.tspnpm vitest src/process/supervisor/supervisor.test.tspnpm vitest src/process/supervisor/supervisor.pty-command.test.tspnpm vitest src/process/supervisor/adapters/child.test.tspnpm vitest src/agents/cli-backends.test.tspnpm vitest src/agents/bash-tools.exec.pty-cleanup.test.tspnpm vitest src/agents/bash-tools.process.poll-timeout.test.tspnpm vitest src/agents/bash-tools.process.supervisor.test.tspnpm vitest src/process/exec.test.ts
端對端目標:
pnpm vitest src/agents/cli-runner.test.tspnpm vitest run src/agents/bash-tools.exec.pty-fallback.test.ts src/agents/bash-tools.exec.background-abort.test.ts src/agents/bash-tools.process.send-keys.test.ts
型別檢查說明:
- 使用
pnpm build(以及pnpm check進行完整的 lint/docs 閘門)。舊筆記中提到pnpm tsgo的已過時。
8. 保留的操作保證
- Exec 環境強化行為不變。
- 核准和白名單流程不變。
- 輸出清理和輸出上限不變。
- PTY adapter 仍保證在強制 kill 時的 wait 完成和監聽器處置。
9. 完成定義
- Supervisor 是受管理執行的生命週期擁有者。
- PTY spawn 使用明確的指令合約,不進行 argv 重建。
- 行程層對 supervisor stdin 合約不依賴代理層型別。
- 看門狗預設值為單一來源。
- 目標的單元和端對端測試維持綠色。
- 重啟持久性邊界已明確記載或完全實作。
10. 總結
本分支現在具備連貫且更安全的監督架構:
- 明確的 PTY 合約
- 更乾淨的行程分層
- supervisor 驅動的行程操作取消路徑
- supervisor 查詢未命中時的真正回退終止
- child-run 預設 kill 路徑的行程樹取消
- 統一的看門狗預設值
- 明確的記憶體重啟邊界(本次不跨重啟進行孤兒調和)