todooo
全域、跨工作區的 TODO List。不管開哪個資料夾,看到的都是同一份清單。
原始碼:https://github.com/lazyjerry/todo-ext
使用方式
- 在底部 Panel 點 todooo 分頁(文件夾加筆的圖示),或點狀態列左側的 TODO 按鈕,或執行指令
todooo: Open TODO List。
- 頂列左邊是 Collection 下拉與四顆按鈕(新增、重新命名、刪除、保存位置),右邊是狀態篩選下拉(全部/未完成/結束/已完成/其他;「未完成」含待測試與待回覆,「結束」含已完成、失敗與擱置)與關鍵字搜尋框(搜標題或內容),兩者只影響左欄列表;子項目符合而父項目不符合時,父項目淡化留著當脈絡。最右邊的 ↻ 重新讀取磁碟上的 Collection 與最後一次變更的畫面狀態。
- 左欄按 + 新增 TODO,右欄會彈開細節、游標停在標題。新項目排在最上面。
- 點左欄任一項目,右欄切換到它的細節;按 展開 讓細節佔滿整個面板,再按 收合 回到兩欄。面板高度不夠時右欄可捲動,也可以把 Panel 往上拉高或最大化。
- 拖曳左右欄中間的分隔線調整比例(預設 6:4,可在 2:8 到 8:2 之間),比例會記住。
排序與子項目
- 拖曳排序:直接拖左欄的項目換位置,順序存進 JSON,重開一樣。
- 子項目:細節區按 + 子項目 在目前項目底下新增;或拖一個項目到另一個頂層項目的中段,它就變成那個項目的子項目。子項目縮排顯示、接在父項目後面,新的子項目排在父項目既有子項目的最後。
- 只有兩層:子項目底下不能再放子項目;帶著子項目的父項目不能拖進別人底下,只能在頂層換順序。
- 拖到頂層:把子項目拖到任一頂層項目的上緣或下緣,它就回到頂層、自己變成父項目。
- 父項目一起帶走:拖父項目時子項目跟著移動,關係不變。刪父項目時子項目一起刪,確認框會寫明幾個。
- 落點提示:上緣、下緣畫一條線(頂層項目的「下緣」是整組含子項目之後),中段畫一個框。
欄位
| 欄位 |
說明 |
| 標題 |
120 字內,右上角顯示字數。 |
| 狀態 |
固定六種:未完成、已完成、待測試、待回覆、失敗、擱置。一次一個,不可為空。 |
| 分類 |
每個 Collection 自訂,預設「未分類」。一次一個、不可為空、至少保留一個;刪掉分類時底下的項目改掛「未分類」。 |
| 標籤 |
Notion 風格的自訂標籤:多選下拉,九種顏色(灰、棕、橙、黃、綠、藍、紫、粉、紅)與文字自訂。欄位固定一行,塞不下的標籤收成「+N」。Collection 還沒有任何標籤時這個欄位不顯示,先從「分類」旁的「管理」建標籤。 |
| 內容 |
長文字,欄位隨面板高度伸展。 |
| 創建時間 |
預設建立當下(含時間),可改。 |
| 完成時間 |
狀態切成 已完成 或 失敗 時自動記下;切回其他狀態就清掉;已完成與失敗之間互切保留原時間。 |
分類與標籤共用一個管理區,按任一欄位旁的 管理 開啟:分類在上、標籤在下,改名稱後按 Enter 或移開焦點即生效,最後一列用來新增。
左欄每一列一行:狀態、標題、分類、創建時間;有標籤才多一行。
資料存放
- 預設在
~/.todooo/collections/,每個 Collection 一份 <id>.json,跨工作區、跨 VS Code profile 共用。
- 設定
todooo.dataFolder 可換資料夾(支援 ~ 開頭);只能在使用者設定層級設定,工作區設定不生效。
- 檔案可以手動編輯或用同步工具同步。讀取時逐欄檢查:認不得的狀態退回未完成、指向不存在的分類退回未分類、指向不存在父項目或疊到第三層的子項目升成頂層、壞掉的檔案略過並提示。
- 寫入採「先寫暫存檔再改名」,不會留下半份 JSON。
- 多個 VS Code 視窗同時開著面板時,以檔案裡的
updatedAt 當版本號:每次變更前先讀磁碟,發現這份 Collection 已被別的視窗改過或刪掉,就拒絕這次變更、跳出提示並重讀最新內容。焦點與正在打的字不動,下一次送出(再打一個字或移開焦點)就以新版本為基準,不必重做。面板分頁切回前景時也會重讀磁碟。
- 畫面狀態(開著的 Collection、選到的 TODO、狀態篩選、關鍵字、是否展開)存在同一個資料夾的
ui-state.json,所有視窗與 profile 共用、最後一次變更的視窗說了算:在別的視窗打開面板、或按頂列的 ↻,就切到那個狀態。這個檔案不做版本比對,壞掉就退回預設。
items 的陣列順序就是畫面順序:頂層項目依序排列,每個頂層項目後面緊接它的子項目(parentId 指向父項目,頂層為 null)。
個別 Collection 的保存位置
- 頂列的 📁 按鈕可以把目前這個 Collection 的 JSON 搬到指定資料夾(例如放進雲端同步的資料夾),檔名仍是
<id>.json;再按一次可以改回預設資料夾。目的地已有同 id 的檔案時拒絕,不覆蓋。
- 對照表存在使用者設定
todooo.collectionFolders(id → 資料夾,家目錄縮成 ~),只能在使用者設定層級設定,開哪個工作區都一樣。
- 另設位置的 Collection 只讀設定指向的那份;預設資料夾裡同 id 的殘留檔不讀。設定指向的檔案不存在時面板會提示,不會自己補一份空的。
- 換到另一台機器要接回同一份檔案:把同一組
todooo.collectionFolders 填進那台的使用者設定即可。
JSON 結構:
{
"version": 1,
"id": "col_…",
"name": "工作",
"title": "2026-09-26",
"categories": [{ "id": "cat_…", "name": "未分類" }],
"tags": [{ "id": "tag_…", "name": "緊急", "color": "red" }],
"items": [
{
"id": "todo_…",
"title": "寫 README",
"content": "…",
"status": "未完成",
"categoryId": "cat_…",
"tagIds": ["tag_…"],
"parentId": null,
"createdAt": "2026-09-26T01:02:03.000Z",
"completedAt": null,
"updatedAt": "2026-09-26T01:02:03.000Z"
}
],
"createdAt": "…",
"updatedAt": "…"
}
安全
- Webview 的 CSP 為
default-src 'none',腳本只認 nonce;畫面全部用 DOM API 組出,不用 innerHTML。
- Webview 送回擴充的訊息逐欄驗證型別,指令名稱走白名單。
- Collection id 只接受固定格式,拿來組檔名前再確認落在資料夾內。
- 本擴充不讀取工作區內容,受限模式(Restricted Mode)下照常可用。
開發
npm install
npm run check # lint + 建置 + 單元測試
./scripts/install-local.sh # 打包並安裝到本機 VS Code
./scripts/publish.sh patch # 發版第一階段(bump 版本、整理 CHANGELOG)
./scripts/publish.sh # 發版第二階段(打包、稽核、上傳)
授權
Apache-2.0