Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,21 @@ it shipped into a `## [x.y.z] - date` section of their own; the tag's

### Changed

- RBAC: REST `GET /history` and `GET /usb/acl` need `read_data`; a `viewer`
token gets 403 there. MCP `resources/read`, `resources/list` and
`resources/subscribe` are gated the same way: `autocontrol://history` and
`autocontrol://files/...` need `read_data`, and a resource URI the server
does not recognise is treated as stored data.
- Slack bot: `/run` runs on a worker thread and its reply arrives when the
script ends; a second `/run` while one is going is refused instead of queued.
`SlackBot.stop()` also stops the running command and returns `bool`.
- `execute_action` takes `result_callback=`; it is called after every command
that returned, nested ones included.
- Script Builder: every secret-named field of a command's result is masked at
any depth, flagged or not (`AC_lease_secret`, `AC_lease_active`,
`AC_rest_api_start`, `AC_rest_api_status` were shown in plain text). The
executor's result log leaves a secret-named field that is `None` or empty
as it is.
- RBAC: 29 MCP tools that return stored records or configuration (run history,
costs, traces, heal logs, journals, the USB ACL, lease tokens, mobile
clipboards) now need `read_data` instead of `read_screen`. The built-in
Expand Down
24 changes: 10 additions & 14 deletions Progress.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 跨平台與 GUI 全面改版

`WIP` — 計畫 A–H 的程式都已交付(A 在 U-20261009-01…14,B–H 在 U-20261009-15…26,留下的缺口在 U-20261009-27…38);還沒做到的是**實機驗證**、要維護者決定的幾件事,與下面各節列的少數缺口
`WIP` — 計畫 A–H 的程式都已交付(A 在 U-20261009-01…14,B–H 在 U-20261009-15…26,留下的缺口在 U-20261009-27…40);還沒做到的是**實機驗證**、要維護者決定的幾件事,與下面各節列的少數缺口

核准設計:[跨平台自動化與 GUI 改版](docs/superpowers/specs/2026-10-02-platform-gui-modernization-design.md)。
實作計畫:[分階段交付計畫](docs/superpowers/plans/2026-10-02-modernization-index.md)。
Expand Down Expand Up @@ -226,14 +226,7 @@ U-20261009-06 與 -04 的 macOS 部分是在 Windows 上對假的 pyobjc/Quart

## 安全與伺服器:留下的缺口

`TODO` — U-20261009-29、-30、-34、-35、-37 之後還開著的

**要維護者過目或決定的:**

- **`DECIDE`:REST 的 `GET /history` 與 `GET /usb/acl` 仍只要 `read_screen`**(`REST_ROUTE_CAPABILITIES`;REST 文件寫 viewer 可以用「除了兩個以外的所有 GET」)。
MCP 那邊同樣的資料已改成要 `read_data`(`DATA_TOOLS` 42 → 71),所以 viewer 的 token 經 MCP 讀不到執行歷史與 USB ACL,經 REST 仍讀得到。
- **`DECIDE`:`AC_lease_secret`/`AC_lease_active` 回傳的租約 token 在 Script Builder 仍以明文顯示**(後者巢狀在 `leases` 底下,遮蔽與一次性顯示都只看最上層欄位)。
`AC_rest_api_start`/`AC_rest_api_status` 回傳共用的 REST bearer token,沒有 Script Builder schema,從 raw JSON 檢視執行時明文顯示。
`TODO` — U-20261009-29、-30、-34、-35、-37、-39 之後還開著的

**還沒做的:**

Expand All @@ -246,6 +239,8 @@ U-20261009-06 與 -04 的 macOS 部分是在 Windows 上對假的 pyobjc/Quart
- **MCP 路徑根目錄**管不到的:執行動作清單的工具、自由格式物件裡的路徑、沒標註的外掛工具、`ac_launch_process` 的 `argv` 與 `ac_shell` 的 `command`(刻意不管)。
`path-or-other` 有已知的誤判:開了根目錄時,像 `/help` 這種文字目標或剛好對到根目錄外既有檔案的值會被拒絕。
檔案 symlink 的跳脫在這台機器上建不出來;POSIX 的 `file:` URL、`:` 分隔與 `~` 沒在 Linux/macOS 跑。
- **REST 與 dashboard**:`GET /jobs`(腳本路徑與間隔)與 `GET /usb/passthrough/status` 可以被看成「設定」,目前和對應的 MCP 工具一樣留在 `read_screen`;要搬就要兩邊一起搬。
REST 與 MCP 的一致性測試只配對 `GET` 路由與唯讀工具,經由不同呼叫讀同一份資料的(例如 `/commands`)配不到。dashboard 的 403 訊息(`app.js`)沒有在任何 JS runtime 或瀏覽器裡執行過。
- **MCP 漸進揭露**:沒對任何真的 client 跑過;`tools/list` 的分頁游標與 `-32602` 是憑對規格的記憶寫的。
- **USB passthrough**:沒對真的舊版 host、真的 WebRTC 通道或真的 USB 裝置跑過。`usb_acl.json` 改成單一檔案(簽章內嵌)之後,**舊版讀不了新檔、會全部拒絕**;
沒有對真的舊版安裝做過降版測試。
Expand Down Expand Up @@ -297,18 +292,19 @@ U-20261009-18 的每一個裝置面呼叫都只對假的 ADB/uiautomator2/WD

## GUI:留下的缺口

`TODO` — U-20261009-27、-28、-34、-36、-38 之後還開著的
`TODO` — U-20261009-27、-28、-34、-36、-38、-40 之後還開著的

- **Windows UIA 後端的執行緒模型完全沒對真的 COM 驗過**:現在每個呼叫執行緒各有一個自動化物件(`accessibility/backends/windows_automation.py`;
主執行緒 STA、其他執行緒進 MTA),Accessibility 分頁與 A11y Audit 已移出 GUI 執行緒。開發環境沒裝 `comtypes`,CI 也沒有同時有 `comtypes` 與桌面的 job,
測試全是假 COM 物件。未驗證的假設:MTA 工作執行緒上的 UIA 呼叫可用;焦點事件 callback 不需要 message pump;
`import comtypes` 第一次發生在已經是 MTA 的執行緒上會丟 `OSError`(憑記憶,沒處理)。`AC_wait_for_focus_change` 的原生 `Queue.get` 仍不會被 stop 叫醒。
- **Script Builder 的一次性值**:在區塊指令(`AC_loop`、`AC_try`、`AC_if_*`)裡產生的 token 拿不到——區塊只記錄自己的摘要,巢狀指令的結果不在任何紀錄裡(結果畫面會說明並列出指令)。
要補需要 executor 的結果掛鉤(`utils/executor/action_executor.py` 的 `_run_one_action` 與 `gui/script_builder/step_model.py::nested_sensitive_commands`)。
對話框開過之後結果畫面仍顯示「有值可看」那一行;複製到系統剪貼簿的 token 關閉時不清除;對話框從未實際顯示過。
- **Script Builder 的一次性值**:一次執行最多保留 200 個(`MAX_ONE_TIME_VALUES`,留前面的);`AC_parallel` 分支裡產生的值不經結果掛鉤回報,
只能從區塊的結果裡取得(標成 `results[0].…`)。結果裡內嵌的動作清單以「參數」規則遮蔽,那些欄位不提供一次性顯示。
對話框從未在真的螢幕上顯示過,真的系統剪貼簿(`QClipboard.clear()`/`text()`)在測試裡是假物件。
`AC_approval_request` 的 `token`(請求編號)在結果畫面保持可見,但在 log 裡仍被遮蔽。
- **stop 還叫不醒的**:已經進到後端的單一指令(一次影像搜尋、OCR、HTTP 請求、shell 指令)、單一手勢內的節奏 sleep、`AC_wait_for_focus_change`;
MCP 自己的輪詢(`ac_wait_for_image`/`ac_wait_for_pixel`)不在可停止的執行裡。非腳本的分頁工作在後端無法取消,只是結果被丟掉。
ChatOps:`SlackBot.poll_once` 在輪詢執行緒上依序分派,所以同一個 bot 自己的 `/run` 還在跑時貼的 `/stop` 要等它結束才會被讀到(不帶參數的 `/stop` 因此只停 `chatops-` 開頭的執行);沒對真的 Slack workspace 跑過。
ChatOps 的 Slack bot:`/run` 現在在工作執行緒上跑,`/stop` 的反應受輪詢間隔限制(預設 5 秒);卡在不可中斷的後端呼叫裡的執行仍停不掉,`stop()` 逾時後回 `False`;在輪詢執行緒上的指令 handler 裡呼叫 `stop()` 也會等到逾時。沒對真的 Slack workspace 跑過。
新轉成可停止的等待裡,`AC_handle_file_dialog`、`AC_wait_until_app_idle`、`AC_wait_for_composition_commit`、`AC_wait_for_unlock` 與行動裝置的 `wait_for_app` 只對假探針測過。
- **WebRTC**:`StatsPoller.start()` 會在 GUI 執行緒上最多等 2 秒(`future.result(timeout=2.0)`,是啟動路徑,沒動)。LAN 廣播的註冊與取消已移出 GUI 執行緒,
但真的 zeroconf 的時間與名稱衝突行為只對假物件測過。
Expand Down
Loading
Loading