# 檔案與憑證端點

檔案、已存金鑰與即時語音的端點。

| Method | 路徑 | 說明 |
|---|---|---|
| `GET` `PUT` | `/v1/file` | **local** — `GET ?path=` 回傳檔案並附 `X-Content-SHA256` 標頭（目錄回 400，不存在回 404）。`PUT` `{path, content \| content_base64, base_sha256}` 寫入並回 `{sha256, path}`；檔案在 `base_sha256` 之後已被改動、或已不存在時回 409（附 `current_sha256`）。路徑以家目錄解析且不得離開家目錄；敏感路徑回 403 |
| `GET` | `/v1/file/open` | **local** — `?path=`。以作業系統預設程式開啟檔案並回傳 `{result}`。與 `/v1/file` 相同的僅限家目錄與敏感路徑規則；此端點不接受 URL |
| `GET` | `/v1/file/locate` | **local** — 依裸檔名尋找候選路徑並回傳 `{paths}`。`name` 必須是裸檔名；未帶 `dir=1` 時 `size` 必填（否則回 400）；`child`（可重複，僅限目錄）與 `mtime`（毫秒，誤差 1 秒內）進一步過濾。依序搜尋 `Desktop`、`Downloads`、`Documents`、`Pictures`、`Movies`、`Music`、`Library/Mobile Documents`，最後是家目錄其餘部分，在第一個有命中的根目錄停止（時間預算 8 秒） |
| `GET` | `/v1/workdir` | **local** — 解析並驗證工作目錄（`?path=`，空值為家目錄），回傳 `{path}`；無法解析、不存在或不是目錄時回 400 |
| `DELETE` | `/v1/key` | **local** — `?key=`。從 keychain 與 `config.json` 的 key 清單刪除單一憑證。回傳已存值的 `GET` 已於 v1.0.23 移除 |
| `GET` `POST` | `/v1/keys` | **local** — `GET` 回傳 `keys`，即 `config.json` 中登記的名稱（不含值）。`POST` `{key, value}`（皆必填）寫入 keychain 並登記名稱 |
| `GET` | `/v1/voice/live` | **local** — v1.1.1 新增。WebSocket upgrade，以 keychain 中的 `GEMINI_API_KEY` 將儀表板的語音模式中繼到 Gemini Live（`gemini-3.8-live`）。setup 由 daemon 自行送出 —— 依設定回覆語言產生的語音 system prompt、`send_to_chat` / `read_history` / `read_task` 三個 function declaration、輸入與輸出逐字稿 —— 之後雙向轉送 frame。缺少 key 時以 close code `4401` 關閉，上游連線或 setup 失敗時以 `1011` 關閉 |
