# 檔案工具

尋找、讀取、編輯、開啟與追蹤檔案的工具。

| 工具 | 說明 |
|---|---|
| `find_files` | 尋找檔案（`queries: [{dir, pattern, file_pattern, recursive}]`）。`mode=list` 回傳目錄內容（依字母排序），`mode=glob` 以檔名 pattern 比對路徑，自 v1.0.23 起依最近修改時間由新到舊排序，`mode=search` 以 RE2 regex grep 檔案內容。省略 mode 時自動推斷：`pattern` + `file_pattern` → search、只有 `pattern` → glob、兩者皆無 → list。glob pattern 必須含字面字元，全萬用字元（`**/*`）會被拒絕。多筆 query 的結果會合併去重。`mode=list` 與 `mode=glob` 上限為總計 128 KiB，截斷時結尾會說明丟棄了幾筆。`mode=search` 自 v1.0.11 起改為分頁而非截斷：`output=files`（預設）每個命中檔案回一列 `{path, count, lines}` —— 自 v1.0.23 起 `lines` 帶前五個匹配的行號，可直接交給 `read_files` 的 `around` —— `output=content` 回帶行號的匹配行，`multiline=true`（v1.0.23）改以整份檔案比對 regex，讓 `.` 可跨越換行，並回報匹配涵蓋的每一行；`offset` / `limit`（預設 256）翻頁，`context` 附上前後文行數 —— 標記 `context: true` 且不計入 `offset` / `limit`。單一匹配行超過 512 bytes 會被截短。每頁結尾帶 `[files a-b of N ...]` / `[lines a-b of N ...]` 說明下一個 `offset`，或標示 `last page`；翻頁期間 query 與 `output` 必須維持不變 |
| `read_files` | 批次讀取一個或多個檔案（`files: [{path, offset, limit, around, context}]`）；支援文字、PDF、DOCX、PPTX、CSV/TSV、圖片，以及音訊 / 影片 —— 媒體檔會經由已設定的 speech-to-text 模型回傳逐字稿，因此不再有獨立的轉錄工具。預設最多讀 2048 行（文件上限 1 MiB、圖片 10 MiB），超過時以 `offset`/`limit` 分頁 —— PDF 以頁、PPTX 以投影片、CSV 以列為單位。自 v1.0.23 起 `around` 接受純文字檔的 1-based 行號，並在每行前後各讀 `context` 行（預設 20，`0` = 只讀該行），重疊的區段會合併、略過的內容以 `...` 行標示（此時忽略 `offset`/`limit`）；同一路徑可在 `files` 中出現多次，結果依序串接。自 v1.0.11 起被截斷的文字讀取會在結尾附上 `[lines a-b of N; call again with offset=... for more]`，接續的 offset 不必用猜的。文字行以 `"<row>\t<line>"` 形式回傳，行號由讀取端加上、不存在於檔案中，拿該行當 `edit_file` anchor 前必須先去除。`edit_file` 修改既有檔案前必須先呼叫：自 v1.0.23 起，檔案須在本次執行中讀過、且讀取後修改時間未變，編輯才會被接受。**敏感檔案防護**：SSH keys、`.pem`、`.key`、`.env` 一律需要確認，無論是否處於 sudo 或 allowlist |
| `edit_file` | 對磁碟上檔案的所有變更。`mode=write` 建立首版或刻意整份覆寫；`mode=patch` 透過 `targets` 陣列做區域編輯 —— 每個 target 為 `{old_string, new_string}` 加上選用的 `replace_all`，所有 anchor 都在套用任何變更前對原始檔案內容定位。兩個 target 覆蓋同一區域，或某 target 的 `old_string` 出現在較早 target 的 `new_string` 內時，整次呼叫被拒絕、不寫入任何內容。`new_string` 留空即為刪除；插入的寫法是把 `old_string` 原樣放在 `new_string` 開頭。以行號定位的 `row` / `insert_string` 形式已移除 —— 行號會把同一次呼叫中先前的 target 一併算入，而那些內容尚未寫入磁碟；`mode=remove` 將檔案移置一旁，仍可還原；`mode=restore` 以 `version` id 還原單一版本，或以 `task_id` 回滾整個任務動過的所有檔案（`current` = 當前執行中的任務）。省略 mode 時：有 `content` → write、有 `targets` → patch；remove 與 restore 永不自動推斷。自 v1.0.23 起，覆寫既有檔案的 `write` 與每一次 `patch` 都要通過讀取新鮮度檢查：檔案須在本次執行中以 `read_files` 讀過，且之後未在磁碟上被變更（使用者、formatter 或其他指令），否則不寫入任何內容，錯誤訊息要求重新讀取；成功寫入後即視為已重新讀取，可接著編輯。`patch` 的 anchor 若只在彎引號與直引號上與檔案不同仍可命中，取代內容會沿用檔案原本的引號樣式。工具描述會把未指定位置、為使用者產生的檔案導向輸出目錄 |
| `file_history` | 工具動過的每個檔案的版本紀錄 —— 何時變更、當時任務目標為何、內容是什麼。`mode=list` 由新到舊列出版本，可用 `path`、`task_id`、`from`/`to` 本地時間與 `limit`（上限 24）過濾；`mode=read` 將每個路徑的最新紀錄版本與磁碟現況做 diff。這是 `edit_file(mode=restore)` 還原時所依據的快照層 |
| `open_file` | 以 OS 預設應用程式開啟檔案（播放影片、檢視圖片、開啟 PDF 閱讀器）。取代沙箱無法觸及的 `run_command` `open`/`xdg-open`。上限 10 秒 |
