文件整理 #4

Merged
admin merged 12 commits from feat/文件整理 into develop 2026-08-07 16:49:29 +00:00
Member

What changed

  • 整理文件與工作流程相關內容。
  • 將分支上的變更整合為可審查的單一 PR。

Validation

  • 已確認分支與 develop 之間存在提交差異。

Commit

### What changed - 整理文件與工作流程相關內容。 - 將分支上的變更整合為可審查的單一 PR。 ### Validation - 已確認分支與 `develop` 之間存在提交差異。 ### Commit - 0eb30cf
jiantw83 added 1 commit 2026-08-07 06:09:38 +00:00
refresh review pipeline
CI / 1. BUILD (pull_request) Successful in 2s
CI / 2. TEST (pull_request) Failing after 19s
CI / 3. RESULT (pull_request) Skipped
0eb30cf9d4
jiantw83 added 1 commit 2026-08-07 06:16:50 +00:00
allow proxy auto model selection
CI / 1. BUILD (pull_request) Successful in 2s
CI / 2. TEST (pull_request) Successful in 2s
CI / 3. RESULT (pull_request) Successful in 0s
651e221e90
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
admin reviewed 2026-08-07 07:09:39 +00:00
admin left a comment
Owner

AI Code Review 統計

類型 🔴 嚴重 🟡 警告 🔵 建議 ⚪ 無法標示
新問題 0 筆 6 筆 2 筆 0 筆
舊問題 0 筆 0 筆 0 筆 0 筆

🤖 AI 助理使用量

本次審查(cliproxyapi / auto,共 7 次呼叫)

提示 token 回應 token 合計
100,155 1,563 101,718

剩餘可用

剩餘可用:無法計算百分比(CLIProxyAPI 不提供帳號額度資訊)

## AI Code Review 統計 | 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 | ⚪ 無法標示 | | --- | --- | --- | --- | --- | | 新問題 | 0 筆 | 6 筆 | 2 筆 | 0 筆 | | 舊問題 | 0 筆 | 0 筆 | 0 筆 | 0 筆 | ## 🤖 AI 助理使用量 **本次審查**(cliproxyapi / auto,共 7 次呼叫) | 提示 token | 回應 token | 合計 | | --- | --- | --- | | 100,155 | 1,563 | 101,718 | **剩餘可用** 剩餘可用:無法計算百分比(CLIProxyAPI 不提供帳號額度資訊)
@@ -11,1 +11,4 @@
model:
description: '使用的 AI 模型'
required: false
runs:
Owner

嚴重等級:🟡 警告
審查員:Assassin
問題:AI 模型參數(model)為使用者輸入但未驗證。攻擊者可透過 PR workflow 傳入任意字符串,縱然後續經 JSON 序列化理論上應轉義,仍增加了攻擊面且難以追蹤輸入來源。
建議:在 action.yml 中對 model 輸入進行描述性限制(說明只接受特定格式),並在 src/config.js 的 getLLMConfig() 加上白名單驗證或正則表達式檢查,拒絕包含特殊字符的模型名稱(如單引號、反斜線、括號等)。例:/^[a-zA-Z0-9._-]+$/。

**嚴重等級**:🟡 警告 **審查員**:Assassin **問題**:AI 模型參數(`model`)為使用者輸入但未驗證。攻擊者可透過 PR workflow 傳入任意字符串,縱然後續經 JSON 序列化理論上應轉義,仍增加了攻擊面且難以追蹤輸入來源。 **建議**:在 action.yml 中對 `model` 輸入進行描述性限制(說明只接受特定格式),並在 src/config.js 的 `getLLMConfig()` 加上白名單驗證或正則表達式檢查,拒絕包含特殊字符的模型名稱(如單引號、反斜線、括號等)。例:`/^[a-zA-Z0-9._-]+$/`。
admin marked this conversation as resolved
entrypoint.sh Outdated
@@ -1,4 +1,11 @@
#!/bin/sh
# ============================================================================
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:進入點腳本一開頭就塞入固定更新時間與裝飾性框線,資訊價值很低,卻會讓每次重生產都留下無意義的 diff 雜訊。
建議:移除這種會過期的時間戳註解,只保留真正需要提醒讀者的簡短說明即可。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:進入點腳本一開頭就塞入固定更新時間與裝飾性框線,資訊價值很低,卻會讓每次重生產都留下無意義的 diff 雜訊。 **建議**:移除這種會過期的時間戳註解,只保留真正需要提醒讀者的簡短說明即可。
admin marked this conversation as resolved
@@ -0,0 +1,1703 @@
# AI Code Review
更新時間:2026/08/07 13:51:53
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:這份 README 已經長成機械化的 API 編目,還把時間戳與大量硬編碼連結一起寫進來,讓主文件變得又厚又脆,讀者很難快速抓到重點。
建議:把 README 收斂成專案摘要、安裝方式與使用入口;細部 API 文件另放獨立文件或改成可生成的 docs,避免主文件膨脹成資料堆。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:這份 README 已經長成機械化的 API 編目,還把時間戳與大量硬編碼連結一起寫進來,讓主文件變得又厚又脆,讀者很難快速抓到重點。 **建議**:把 README 收斂成專案摘要、安裝方式與使用入口;細部 API 文件另放獨立文件或改成可生成的 docs,避免主文件膨脹成資料堆。
admin marked this conversation as resolved
@@ -213,10 +235,28 @@ function toReviewComment(f) {
}
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:postFindingsReview 這段 JSDoc 太像流程筆記,不像 API 說明。@param、@remarks、使用情境 與多層降級敘事一路堆疊,重點被枝節埋掉,閱讀節奏很不乾淨。
建議:把註解壓縮回最必要的契約說明:用途、參數、回傳與例外即可;降級順序和測試注入細節留給實作內的短註解。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:`postFindingsReview` 這段 JSDoc 太像流程筆記,不像 API 說明。`@param`、`@remarks`、`使用情境` 與多層降級敘事一路堆疊,重點被枝節埋掉,閱讀節奏很不乾淨。 **建議**:把註解壓縮回最必要的契約說明:用途、參數、回傳與例外即可;降級順序和測試注入細節留給實作內的短註解。
admin marked this conversation as resolved
@@ -371,7 +413,14 @@ function extractFileDiff(diff, file) {
/**
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:resolveMissingLineNumbers 的註解把行為、邊界條件、併發設定與人工備註全揉成一段,語氣也從說明一路滑到審查心得,讀起來有點散、有點吵。
建議:把說明拆短,保留輸入、輸出與副作用三件事即可;如果某些設計值得提醒,也應縮成一句附註,不要塞進主體敘述。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:`resolveMissingLineNumbers` 的註解把行為、邊界條件、併發設定與人工備註全揉成一段,語氣也從說明一路滑到審查心得,讀起來有點散、有點吵。 **建議**:把說明拆短,保留輸入、輸出與副作用三件事即可;如果某些設計值得提醒,也應縮成一句附註,不要塞進主體敘述。
admin marked this conversation as resolved
src/llm.js Outdated
@@ -111,0 +170,4 @@
{ role: 'user', content: prompt },
],
temperature: 0,
stream: false,
Owner

嚴重等級:🔵 建議
審查員:Assassin
問題:HTTP request body 中的 model 欄位現在允許為 null(由上游 getLLMConfig() 傳入),導致該欄位的存在性由輸入決定。若 API 伺服器對缺少 model 欄位與 model: null 的處理邏輯不同,可能產生非預期的行為切換(例如自動選擇與使用者預期模型不符的模型版本)。
建議:在 src/llm.js 的 runProxyAPI() 中明確文檔化 model: null 時的 API 行為,或在構造 body 前透過 getLLMConfig() 的驗證確保 model 值的一致性。若允許自動選擇,應於 log 與回應中清楚標示使用了自動選擇(目前已在 main.js 中以 modelLabel 處理,但建議同步至 API 層確認)。

**嚴重等級**:🔵 建議 **審查員**:Assassin **問題**:HTTP request body 中的 `model` 欄位現在允許為 null(由上游 `getLLMConfig()` 傳入),導致該欄位的存在性由輸入決定。若 API 伺服器對缺少 `model` 欄位與 `model: null` 的處理邏輯不同,可能產生非預期的行為切換(例如自動選擇與使用者預期模型不符的模型版本)。 **建議**:在 src/llm.js 的 `runProxyAPI()` 中明確文檔化 `model: null` 時的 API 行為,或在構造 body 前透過 `getLLMConfig()` 的驗證確保 model 值的一致性。若允許自動選擇,應於 log 與回應中清楚標示使用了自動選擇(目前已在 main.js 中以 `modelLabel` 處理,但建議同步至 API 層確認)。
admin marked this conversation as resolved
src/log.js Outdated
@@ -3,0 +5,4 @@
* @param {Date} [date] - 要格式化的時間點;省略時使用呼叫當下的系統時間。
* @returns {string} 例如 `2026/08/07 12:39:43`。
*/
function formatTimestamp(date = new Date()) {
Owner

嚴重等級:🔵 建議
審查員:Bard
問題:這裡用 en-CA 來拼台灣時區時間字串,技法不算錯,但對讀者很不直觀。看到 Asia/Taipei 卻搭配 en-CA,第一眼會先懷疑這是不是某種繞路寫法。
建議:改用更直白的格式化方式,例如手動補零組字串,或至少把這個 locale 選擇的用意明講,讓 helper 的意圖一眼可懂。

**嚴重等級**:🔵 建議 **審查員**:Bard **問題**:這裡用 `en-CA` 來拼台灣時區時間字串,技法不算錯,但對讀者很不直觀。看到 `Asia/Taipei` 卻搭配 `en-CA`,第一眼會先懷疑這是不是某種繞路寫法。 **建議**:改用更直白的格式化方式,例如手動補零組字串,或至少把這個 locale 選擇的用意明講,讓 helper 的意圖一眼可懂。
admin marked this conversation as resolved
@@ -54,1 +56,4 @@
* 目前程式碼中有 3 個 exit 1 呼叫點(未設定 CLIProxyAPI、取 diff 失敗、所有角色分析皆失敗)
* 退出前未呼叫 `section('Pipeline 結束')`,與其餘 exit 點不一致,會少一行收尾分隔線,
* 是否為刻意設計尚需人工確認。
*/
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:這段註解直接寫出『目前程式碼中有 3 個 exit 1 呼叫點』,把瞬時的實作現況硬塞進長期註解,過幾次重構就會先壞掉,徒增維護負擔。
建議:刪掉這種會隨流程變動而失真的數量型描述;若真要提醒收尾差異,改成更穩定的概念性說明即可。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:這段註解直接寫出『目前程式碼中有 3 個 exit 1 呼叫點』,把瞬時的實作現況硬塞進長期註解,過幾次重構就會先壞掉,徒增維護負擔。 **建議**:刪掉這種會隨流程變動而失真的數量型描述;若真要提醒收尾差異,改成更穩定的概念性說明即可。
admin marked this conversation as resolved
admin added 1 commit 2026-08-07 07:09:41 +00:00
chore: update ai-review findings [ai-review-bot][success]
CI / 1. BUILD (pull_request) Successful in 2s
CI / 2. TEST (pull_request) Successful in 2s
CI / 3. RESULT (pull_request) Successful in 1s
5e9bd86bbc
jiantw83 added 3 commits 2026-08-07 08:49:40 +00:00
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
admin reviewed 2026-08-07 08:55:57 +00:00
admin left a comment
Owner

AI Code Review 統計

類型 🔴 嚴重 🟡 警告 🔵 建議 ⚪ 無法標示
新問題 0 筆 9 筆 8 筆 0 筆
舊問題 0 筆 1 筆 0 筆 0 筆

🤖 AI 助理使用量

本次審查(cliproxyapi / auto,共 21 次呼叫)

提示 token 回應 token 合計
144,981 4,277 149,258

剩餘可用

剩餘可用:無法計算百分比(CLIProxyAPI 不提供帳號額度資訊)

## AI Code Review 統計 | 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 | ⚪ 無法標示 | | --- | --- | --- | --- | --- | | 新問題 | 0 筆 | 9 筆 | 8 筆 | 0 筆 | | 舊問題 | 0 筆 | 1 筆 | 0 筆 | 0 筆 | ## 🤖 AI 助理使用量 **本次審查**(cliproxyapi / auto,共 21 次呼叫) | 提示 token | 回應 token | 合計 | | --- | --- | --- | | 144,981 | 4,277 | 149,258 | **剩餘可用** 剩餘可用:無法計算百分比(CLIProxyAPI 不提供帳號額度資訊)
@@ -11,1 +11,4 @@
model:
description: '使用的 AI 模型,僅允許英數字、點、底線與連字號'
required: false
runs:
Owner

嚴重等級:🟡 警告
審查員:Assassin
問題:action.yml 中新增的 inputs.model 沒有在 GitHub Actions 層面進行輸入驗證。雖然描述寫著「僅允許英數字、點、底線與連字號」,但使用者可以提供任意字符(如 gpt-4; rm -rf /),這些惡意輸入會先被寫入環境變數 CLI_PROXY_API_MODEL,才在 Node.js 代碼中被驗證。違反了「最小信任原則」。
建議:在 action.yml 中的 inputs.model 新增驗證限制(GitHub Actions 層面無原生驗證機制,但可在文檔中強調風險,並確保 Node.js 驗證實作完備)。或改為使用 choices 列表限制可選值。目前的 Node.js 驗證雖然有效,但應在 GitHub Actions 文檔中明確說明:只有英數字、點、底線、連字號的 model 值才會被接受,其他值會被拒絕並導致工作流失敗。

**嚴重等級**:🟡 警告 **審查員**:Assassin **問題**:action.yml 中新增的 inputs.model 沒有在 GitHub Actions 層面進行輸入驗證。雖然描述寫著「僅允許英數字、點、底線與連字號」,但使用者可以提供任意字符(如 `gpt-4; rm -rf /`),這些惡意輸入會先被寫入環境變數 `CLI_PROXY_API_MODEL`,才在 Node.js 代碼中被驗證。違反了「最小信任原則」。 **建議**:在 action.yml 中的 inputs.model 新增驗證限制(GitHub Actions 層面無原生驗證機制,但可在文檔中強調風險,並確保 Node.js 驗證實作完備)。或改為使用 `choices` 列表限制可選值。目前的 Node.js 驗證雖然有效,但應在 GitHub Actions 文檔中明確說明:只有英數字、點、底線、連字號的 model 值才會被接受,其他值會被拒絕並導致工作流失敗。
admin marked this conversation as resolved
@@ -11,2 +12,4 @@
description: '使用的 AI 模型,僅允許英數字、點、底線與連字號'
required: false
runs:
using: 'docker'
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:把 Docker Action 的 image 參照改成小寫 dockerfile,讓原本業界慣用的 Dockerfile 檔名失去辨識度;這種大小寫改動會讓人讀配置時多停一下,也讓專案風格顯得不一致。
建議:把檔名與 action.yml 的 runs.image 都改回慣用的 Dockerfile,維持 Docker 生態的標準寫法。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:把 Docker Action 的 image 參照改成小寫 `dockerfile`,讓原本業界慣用的 `Dockerfile` 檔名失去辨識度;這種大小寫改動會讓人讀配置時多停一下,也讓專案風格顯得不一致。 **建議**:把檔名與 `action.yml` 的 `runs.image` 都改回慣用的 `Dockerfile`,維持 Docker 生態的標準寫法。
admin marked this conversation as resolved
@@ -0,0 +1,1703 @@
# AI Code Review
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:新文件採用小寫 readme.md,和倉庫中常見的 README.md 命名慣例不合。這種只差大小寫的命名,最容易在查找與瀏覽時破壞一致感。
建議:改名為 README.md,讓入口文件維持一眼可辨的標準名稱。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:新文件採用小寫 `readme.md`,和倉庫中常見的 `README.md` 命名慣例不合。這種只差大小寫的命名,最容易在查找與瀏覽時破壞一致感。 **建議**:改名為 `README.md`,讓入口文件維持一眼可辨的標準名稱。
admin marked this conversation as resolved
@@ -33,2 +34,4 @@
* {@link postNewCriticalComments} 組裝 comment 內文使用。
* 使用情境:任何要把一批 findings 呈現成單一 Markdown 表格的地方,先篩好要顯示的子集合再呼叫本函式。
*/
function buildTable(findings) {
Owner

嚴重等級:🟡 警告
審查員:Mage
問題:buildTable 函式在呼叫 findings.map() 前無防呆檢查,若 findings 為 null/undefined 會拋出 TypeError。文件已提及此問題但函式本體未修正
建議:在 .map() 呼叫前加入 if (!Array.isArray(findings)) findings = []; 或改用可選鏈語法,確保即使傳入無效值也能優雅降級

**嚴重等級**:🟡 警告 **審查員**:Mage **問題**:buildTable 函式在呼叫 findings.map() 前無防呆檢查,若 findings 為 null/undefined 會拋出 TypeError。文件已提及此問題但函式本體未修正 **建議**:在 .map() 呼叫前加入 `if (!Array.isArray(findings)) findings = [];` 或改用可選鏈語法,確保即使傳入無效值也能優雅降級
admin marked this conversation as resolved
@@ -77,0 +87,4 @@
/**
* 產生單一 finding 的行內(inline)review comment 內文:等級/審查員/建議三行。
*
* @param {{ level?: string, role?: string, suggestion?: string }} f 單筆審查問題物件。
Owner

嚴重等級:🟡 警告
審查員:Mage
問題:inlineCommentBody 函式若 f.role 或 f.suggestion 為 undefined,會直接內嵌 undefined 字樣到輸出字串,產生 '等級:xxx\n審查員:undefined\n建議:undefined' 的破損註解
建議:在組字前加檢查:const role = f.role || 'AI Review'; const suggestion = f.suggestion || ''; 確保回傳值不含 undefined 字面值

**嚴重等級**:🟡 警告 **審查員**:Mage **問題**:inlineCommentBody 函式若 f.role 或 f.suggestion 為 undefined,會直接內嵌 undefined 字樣到輸出字串,產生 '**等級**:xxx\n**審查員**:undefined\n**建議**:undefined' 的破損註解 **建議**:在組字前加檢查:`const role = f.role || 'AI Review'; const suggestion = f.suggestion || '';` 確保回傳值不含 undefined 字面值
admin marked this conversation as resolved
@@ -273,1 +312,3 @@
* 發布所有舊問題 comment(一次發布,依等級排序)
* 發布所有舊問題的彙總 comment(一次性發布一則一般 comment,不含行內標註)。
*
* @param {Array<{ is_new?: boolean, level?: string }>} findings 審查問題陣列;
Owner

嚴重等級:🟡 警告
審查員:Bard
問題:這段 JSDoc 連到不存在的 newFindingsOnly,斷鏈的 {@link} 會讓文件閱讀時突然失聲;同時還把判定差異寫得過於旁白化,讓主註解變得冗長。
建議:把 cross-reference 換成實際存在的符號,或直接刪掉;差異說明則濃縮成一句話,保留重點即可。

**嚴重等級**:🟡 警告 **審查員**:Bard **問題**:這段 JSDoc 連到不存在的 `newFindingsOnly`,斷鏈的 `{@link}` 會讓文件閱讀時突然失聲;同時還把判定差異寫得過於旁白化,讓主註解變得冗長。 **建議**:把 cross-reference 換成實際存在的符號,或直接刪掉;差異說明則濃縮成一句話,保留重點即可。
admin marked this conversation as resolved
@@ -43,3 +43,4 @@
export const FINDINGS_PATH = '.gitea/ai-review/findings.json';
export const EXCLUSIONS_PATH = '.gitea/ai-review/exclusions.json';
const MODEL_NAME_RE = /^[A-Za-z0-9._-]+$/;
Owner

嚴重等級:🔵 建議
審查員:Assassin
問題:正則表達式 MODEL_NAME_RE = /^[A-Za-z0-9._-]+$/ 不允許 / 字符。某些合法的模型名稱格式(如 openrouter/openai/gpt-4o 或 providers/openai/models/gpt-4o)會被拒絕,導致功能受限。雖然不是直接的安全漏洞,但可能造成合法請求被誤判為異常。
建議:評估是否需要在正則表達式中允許 / 字符。若允許,應同時確保不會引入新的安全風險(例如路徑穿越攻擊)。改為 /^[A-Za-z0-9._/-]+$/ 並增加單元測試確認邊界情況。

**嚴重等級**:🔵 建議 **審查員**:Assassin **問題**:正則表達式 `MODEL_NAME_RE = /^[A-Za-z0-9._-]+$/` 不允許 `/` 字符。某些合法的模型名稱格式(如 `openrouter/openai/gpt-4o` 或 `providers/openai/models/gpt-4o`)會被拒絕,導致功能受限。雖然不是直接的安全漏洞,但可能造成合法請求被誤判為異常。 **建議**:評估是否需要在正則表達式中允許 `/` 字符。若允許,應同時確保不會引入新的安全風險(例如路徑穿越攻擊)。改為 `/^[A-Za-z0-9._/-]+$/` 並增加單元測試確認邊界情況。
admin marked this conversation as resolved
src/findings.js Outdated
@@ -330,14 +348,25 @@ export function mergeFindings(oldFindings, newFindings) {
}
Owner

嚴重等級:🔵 建議
審查員:Mage
問題:mergeFindings 用 suggestion 前 50 字作為 key 的一部分進行去重。若兩個 findings 的 role 與 location 相同但 suggestion 在第 50 字之後才出現差異,會被誤判為重複而遭移除
建議:考慮是否改用完整 suggestion 或增加其他識別字段(如 problem)來組成 key,確保去重不會誤刪本質不同的問題

**嚴重等級**:🔵 建議 **審查員**:Mage **問題**:mergeFindings 用 suggestion 前 50 字作為 key 的一部分進行去重。若兩個 findings 的 role 與 location 相同但 suggestion 在第 50 字之後才出現差異,會被誤判為重複而遭移除 **建議**:考慮是否改用完整 suggestion 或增加其他識別字段(如 problem)來組成 key,確保去重不會誤刪本質不同的問題
admin marked this conversation as resolved
src/findings.js Outdated
@@ -338,3 +361,3 @@
/**
* AI 呼叫失敗時的統一降級處理
* AI 呼叫失敗時的統一降級處理:記錄警告訊息後原樣回傳 findings(不做任何篩選),
Owner

嚴重等級:🔵 建議
審查員:Mage
問題:sortByLevel 使用 LEVELS.indexOf() 排序,級別不在 ['critical','warning','info'] 中的項目因 indexOf 回傳 -1 而被排到 critical 之前(最前面),此邊界行為是否為預期設計不明確
建議:在文件或代碼中明確說明未知級別項目的預期排序位置,或改用顯式的條件判斷以提升代碼可讀性

**嚴重等級**:🔵 建議 **審查員**:Mage **問題**:sortByLevel 使用 LEVELS.indexOf() 排序,級別不在 ['critical','warning','info'] 中的項目因 indexOf 回傳 -1 而被排到 critical 之前(最前面),此邊界行為是否為預期設計不明確 **建議**:在文件或代碼中明確說明未知級別項目的預期排序位置,或改用顯式的條件判斷以提升代碼可讀性
admin marked this conversation as resolved
@@ -571,8 +656,13 @@ async function judgeFindingIsFalsePositive(finding, defender, exclusionHint, cha
}
/**
Owner

嚴重等級:🟡 警告
審查員:Mage
問題:applyExclusions 的比對邏輯在 (locationMatches && roleMatches && (textMatches || ...)) 中,若排除規則只指定 filePath 不指定 role,會產生「該檔案內所有角色的問題都被排除」的非預期行為;若只指定 role 不指定 filePath,則「該角色所有檔案的問題都被排除」。此為對稱性缺陷
建議:重新檢視比對邏輯意圖:若欲實現「指定 filePath 時自動不檢查 role」的設計,需在文件中明確說明此為刻意設計;若非刻意,應改為 (locationMatches || !exclusion.filePath) && (roleMatches || !exclusion.role) && (textMatches || ...),確保每個維度皆能獨立篩選

**嚴重等級**:🟡 警告 **審查員**:Mage **問題**:applyExclusions 的比對邏輯在 (locationMatches && roleMatches && (textMatches || ...)) 中,若排除規則只指定 filePath 不指定 role,會產生「該檔案內所有角色的問題都被排除」的非預期行為;若只指定 role 不指定 filePath,則「該角色所有檔案的問題都被排除」。此為對稱性缺陷 **建議**:重新檢視比對邏輯意圖:若欲實現「指定 filePath 時自動不檢查 role」的設計,需在文件中明確說明此為刻意設計;若非刻意,應改為 (locationMatches || !exclusion.filePath) && (roleMatches || !exclusion.role) && (textMatches || ...),確保每個維度皆能獨立篩選
admin marked this conversation as resolved
@@ -26,6 +30,26 @@ export async function mapWithConcurrency(items, limit, fn) {
const n = Number(limit);
const workers = (!Number.isFinite(n) || n <= 0) ? list.length : Math.min(n, list.length);
Owner

嚴重等級:🔵 建議
審查員:Bard
問題:mapWithConcurrency 內部工作者 run() 的註解太像設計文件,對 cursor、Promise.all 行為、背景工作都展開長篇解釋,視覺重量遠超過程式本身。
建議:把這段縮成一兩句重點註解,保留「限制併發、保序寫入」即可,其餘執行細節交回外層函式說明。

**嚴重等級**:🔵 建議 **審查員**:Bard **問題**:`mapWithConcurrency` 內部工作者 `run()` 的註解太像設計文件,對 `cursor`、`Promise.all` 行為、背景工作都展開長篇解釋,視覺重量遠超過程式本身。 **建議**:把這段縮成一兩句重點註解,保留「限制併發、保序寫入」即可,其餘執行細節交回外層函式說明。
admin marked this conversation as resolved
src/llm.js Outdated
@@ -105,0 +151,4 @@
* 僅使用 `apiKeys[0]`;`model` 可省略,省略時交由 CLIProxyAPI 自動選擇。
* @param {string} prompt - 送給 API 的完整 prompt 內容,會作為 user 訊息內容;
* HTTP 層的 system 訊息為固定的通用指示,與 prompt 內可能內嵌的 `<system>` 內容無關。
* @returns {Promise<any>} API 回應的原始資料物件(`resp.data`),並非純文字;
Owner

嚴重等級:🔵 建議
審查員:Rogue
問題:runProxyAPI() 中 body 物件先建立後再條件性添加 model 屬性;若此函式在併發量大的場景反覆呼叫,每次都會新建完整物件結構
建議:改用 Object.assign() 或 const body = { messages: [...], temperature: 0, stream: false, ...(model && { model }) },減少不必要的中間物件建立步驟

**嚴重等級**:🔵 建議 **審查員**:Rogue **問題**:runProxyAPI() 中 body 物件先建立後再條件性添加 model 屬性;若此函式在併發量大的場景反覆呼叫,每次都會新建完整物件結構 **建議**:改用 Object.assign() 或 const body = { messages: [...], temperature: 0, stream: false, ...(model && { model }) },減少不必要的中間物件建立步驟
admin marked this conversation as resolved
src/llm.js Outdated
@@ -105,1 +158,4 @@
* @remarks 逾時與輸出上限由環境變數 `AI_ASSISTANT_TIMEOUT_MS`/`AI_ASSISTANT_MAX_BUFFER`
* 控制,預設值為 15 分鐘/20 MB。
* @remarks 使用 `getInsecureHttpsAgent()`(停用 TLS 憑證驗證),適用內部自簽憑證環境。
*/
Owner

嚴重等級:🟡 警告
審查員:Mage
問題:summarizeApiError 函式內存取 e.stderr 與 e.stdout 時未使用可選鏈,若 e 為 null 或 undefined,會拋出 TypeError 而非優雅容錯
建議:改用可選鏈:const stderr = e?.stderr || '' 與 const stdout = e?.stdout || '',或在函式開頭加入 if (!e) return String(e); 早期退出

**嚴重等級**:🟡 警告 **審查員**:Mage **問題**:summarizeApiError 函式內存取 e.stderr 與 e.stdout 時未使用可選鏈,若 e 為 null 或 undefined,會拋出 TypeError 而非優雅容錯 **建議**:改用可選鏈:`const stderr = e?.stderr || ''` 與 `const stdout = e?.stdout || ''`,或在函式開頭加入 `if (!e) return String(e);` 早期退出
admin marked this conversation as resolved
src/log.js Outdated
@@ -3,0 +4,4 @@
*
* @param {Date} [date] - 要格式化的時間點;省略時使用呼叫當下的系統時間。
* @returns {string} 例如 `2026/08/07 12:39:43`。
*/
Owner

嚴重等級:🟡 警告
審查員:Rogue
問題:formatTimestamp() 每次調用都新建 Intl.DateTimeFormat 實例,加上 formatToParts() 與 Object.fromEntries() 轉換,高頻日誌場景下重複成本大;而日誌函式會在 section/step/line/input/output/result/ok/warn/error 等多處調用,累積開銷明顯
建議:將 Intl.DateTimeFormat 快取為模組層級單例(const formatter = new Intl.DateTimeFormat(...)),或改用更輕量的時間格式化方式(例如直接用 Date 方法),避免每條日誌都重複實例化

**嚴重等級**:🟡 警告 **審查員**:Rogue **問題**:formatTimestamp() 每次調用都新建 Intl.DateTimeFormat 實例,加上 formatToParts() 與 Object.fromEntries() 轉換,高頻日誌場景下重複成本大;而日誌函式會在 section/step/line/input/output/result/ok/warn/error 等多處調用,累積開銷明顯 **建議**:將 Intl.DateTimeFormat 快取為模組層級單例(const formatter = new Intl.DateTimeFormat(...)),或改用更輕量的時間格式化方式(例如直接用 Date 方法),避免每條日誌都重複實例化
admin marked this conversation as resolved
@@ -3,0 +15,4 @@
minute: '2-digit',
second: '2-digit',
hourCycle: 'h23',
}).formatToParts(date);
Owner

嚴重等級:🔵 建議
審查員:Rogue
問題:formatToParts() 後用 Object.fromEntries(parts.map(...)) 進行雙次陣列與物件轉換,再拼字串;格式化操作偏複雜,對日誌輸出這種高頻操作成本偏高
建議:改用 reduce() 直接在一次遍歷內組出 map 物件,或改寫為單一模板字符串拼接,避免中間陣列轉換

**嚴重等級**:🔵 建議 **審查員**:Rogue **問題**:formatToParts() 後用 Object.fromEntries(parts.map(...)) 進行雙次陣列與物件轉換,再拼字串;格式化操作偏複雜,對日誌輸出這種高頻操作成本偏高 **建議**:改用 reduce() 直接在一次遍歷內組出 map 物件,或改寫為單一模板字符串拼接,避免中間陣列轉換
admin marked this conversation as resolved
@@ -3,0 +16,4 @@
second: '2-digit',
hourCycle: 'h23',
}).formatToParts(date);
const map = Object.fromEntries(parts.map((p) => [p.type, p.value]));
Owner

嚴重等級:🔵 建議
審查員:Assassin
問題:formatTimestamp 函數依賴 Intl.DateTimeFormat.formatToParts 的實現細節。若回應結構不符預期,map.year、map.month 等會是 undefined,導致日誌中顯示 undefined 字樣。雖然不影響安全性,但可能造成日誌混亂及除錯困難。
建議:加強容錯處理。在存取 map.year 等屬性前先驗證其存在性;或改用更穩定的日期格式化方式(如 new Date().toISOString())。同時增加單元測試,確保在異常情況下(例如不同的語言環境或舊版本瀏覽器)仍能產生正確的日誌格式。

**嚴重等級**:🔵 建議 **審查員**:Assassin **問題**:formatTimestamp 函數依賴 Intl.DateTimeFormat.formatToParts 的實現細節。若回應結構不符預期,`map.year`、`map.month` 等會是 `undefined`,導致日誌中顯示 `undefined` 字樣。雖然不影響安全性,但可能造成日誌混亂及除錯困難。 **建議**:加強容錯處理。在存取 `map.year` 等屬性前先驗證其存在性;或改用更穩定的日期格式化方式(如 `new Date().toISOString()`)。同時增加單元測試,確保在異常情況下(例如不同的語言環境或舊版本瀏覽器)仍能產生正確的日誌格式。
admin marked this conversation as resolved
@@ -94,5 +94,5 @@
}
return [...groups.values()].map(g => ({ ...g, thread: g.bodies.join('\n---\n') }));
}
/** codeWindow 預設的上下文行數(目標行上下各取幾行)。 */
Owner

嚴重等級:🔵 建議
審查員:Mage
問題:groupConversations 在設置 botFinding 時用 botFindings[0],若該對話的 botFindings 陣列為空,botFinding 會為 undefined。此設計雖有文件說明是為相容舊邏輯,但下游代碼仍需確保可安全處理 undefined 值
建議:在文件中明確註記 botFinding 可為 undefined,並在此函式或其呼叫端加入明確的 null 檢查,或改用 botFinding: botFindings.length > 0 ? botFindings[0] : null 以更清晰地表達意圖

**嚴重等級**:🔵 建議 **審查員**:Mage **問題**:groupConversations 在設置 botFinding 時用 `botFindings[0]`,若該對話的 botFindings 陣列為空,botFinding 會為 undefined。此設計雖有文件說明是為相容舊邏輯,但下游代碼仍需確保可安全處理 undefined 值 **建議**:在文件中明確註記 botFinding 可為 undefined,並在此函式或其呼叫端加入明確的 null 檢查,或改用 `botFinding: botFindings.length > 0 ? botFindings[0] : null` 以更清晰地表達意圖
admin marked this conversation as resolved
admin added 1 commit 2026-08-07 08:56:00 +00:00
chore: update ai-review findings [ai-review-bot][success]
CI / 1. BUILD (pull_request) Successful in 2s
CI / 2. TEST (pull_request) Successful in 2s
CI / 3. RESULT (pull_request) Successful in 1s
605d557455
jiantw83 added 4 commits 2026-08-07 16:42:51 +00:00
Owner

🤖 AI Code Review 團隊

👤 角色 🎯 面向 🧠 個性
🗡️ Assassin security 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用
🎼 Bard style 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版
🧰 Leo maintainability 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來
🔮 Mage logic 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」
🧪 Maya testing 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑
⚡ Rogue efficiency 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」

🔍 服務:cliproxyapi 模型:auto

## 🤖 AI Code Review 團隊 | 👤 角色 | 🎯 面向 | 🧠 個性 | |--------|--------|--------| | **🗡️ Assassin** | security | 多疑偏執、以攻擊者視角看世界,假設每筆輸入都是惡意的,每個信任都會被濫用 | | **🎼 Bard** | style | 唯美龜毛、追求優雅,把可讀性與一致性當作旋律,最受不了走調的命名與排版 | | **🧰 Leo** | maintainability | 有遠見、重視長期維護成本,凡事先問「六個月後的自己還看得懂嗎?」,討厭把債留給未來 | | **🔮 Mage** | logic | 嚴謹冷靜、滴水不漏,凡事推演到最壞情況,深信「沒驗證過的假設都是 bug」 | | **🧪 Maya** | testing | 對測試覆蓋率有執念,深信「沒有測試的程式碼等於沒寫完」,溫和但堅持,最在意邊界與失敗路徑 | | **⚡ Rogue** | efficiency | 急性子、講求速度,最痛恨被浪費的 CPU 週期與記憶體,凡事先問「這能不能更快、更省」 | > 🔍 服務:cliproxyapi 模型:auto
admin approved these changes 2026-08-07 16:45:04 +00:00
admin reviewed 2026-08-07 16:46:03 +00:00
admin left a comment
Owner

AI Code Review 統計

類型 🔴 嚴重 🟡 警告 🔵 建議 ⚪ 無法標示
新問題 0 筆 1 筆 1 筆 0 筆
舊問題 0 筆 1 筆 2 筆 0 筆

🤖 AI 助理使用量

本次審查(cliproxyapi / auto,共 9 次呼叫)

提示 token 回應 token 合計
50,034 1,291 51,325

剩餘可用

剩餘可用:無法計算百分比(CLIProxyAPI 不提供帳號額度資訊)

## AI Code Review 統計 | 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 | ⚪ 無法標示 | | --- | --- | --- | --- | --- | | 新問題 | 0 筆 | 1 筆 | 1 筆 | 0 筆 | | 舊問題 | 0 筆 | 1 筆 | 2 筆 | 0 筆 | ## 🤖 AI 助理使用量 **本次審查**(cliproxyapi / auto,共 9 次呼叫) | 提示 token | 回應 token | 合計 | | --- | --- | --- | | 50,034 | 1,291 | 51,325 | **剩餘可用** 剩餘可用:無法計算百分比(CLIProxyAPI 不提供帳號額度資訊)
@@ -0,0 +6,4 @@
| 專案名稱 | 專案描述 |
| --- | --- |
| [AI Code Review](https://gitea.jsc.idv.tw/actions/ai-code-review/src/branch/develop/src) | Gitea Docker 容器 action:對 PR 的 diff 派多個角色進行 AI 程式碼審查,產生 findings 並依對話收斂、排除規則與 AI 誤報裁決收斂結果;負責 Gitea PR API(diff/comment/review/resolve)串接、CLIProxyAPI 對話與 usage/額度統計、git clone/commit/push 持久化 findings,以及執行前的 token/LLM/git 遠端前置驗證。 |
Owner

嚴重等級:🔵 建議
審查員:Assassin
問題:這份新增文件把內部 Gitea 網域與完整倉庫路徑直接寫進專案內容。只要文件被外部看見,攻擊者就能先掌握內部服務命名、URL 模式與專案結構,降低枚舉、釣魚與後續橫向移動的成本。
建議:如果這份文件有外部可見的可能,請把內網主機名與完整路徑改成相對路徑或 placeholder,並把只限內部使用的操作細節移到不對外公開的位置。

**嚴重等級**:🔵 建議 **審查員**:Assassin **問題**:這份新增文件把內部 Gitea 網域與完整倉庫路徑直接寫進專案內容。只要文件被外部看見,攻擊者就能先掌握內部服務命名、URL 模式與專案結構,降低枚舉、釣魚與後續橫向移動的成本。 **建議**:如果這份文件有外部可見的可能,請把內網主機名與完整路徑改成相對路徑或 placeholder,並把只限內部使用的操作細節移到不對外公開的位置。
@@ -42,23 +42,28 @@ export const LLM_PROVIDER = 'cliproxyapi';
export const FINDINGS_PATH = '.gitea/ai-review/findings.json';
export const EXCLUSIONS_PATH = '.gitea/ai-review/exclusions.json';
Owner

嚴重等級:🟡 警告
審查員:Assassin
問題:這裡只限制字元種類,卻還放行 . 與 /,因此像 ../foo、foo/../../bar 這類路徑式字串仍可通過。攻擊者只要能控制 inputs.model 或 CLI_PROXY_API_MODEL,就能把惡意 model 值送進 CLIProxyAPI;若後端拿 model 名稱去拼路徑、呼叫指令或做檔名查找,這個輸入就可能被拿來做路徑穿越或指令注入。
建議:不要只做字元白名單,應改成明確白名單比對可用模型 slug,並額外拒絕 ..、前導/結尾 /、連續 /、反斜線與控制字元;如果可行,直接用 /v1/models 回傳清單做嚴格選擇,而不是接受任意形狀的字串。

**嚴重等級**:🟡 警告 **審查員**:Assassin **問題**:這裡只限制字元種類,卻還放行 `.` 與 `/`,因此像 `../foo`、`foo/../../bar` 這類路徑式字串仍可通過。攻擊者只要能控制 `inputs.model` 或 `CLI_PROXY_API_MODEL`,就能把惡意 model 值送進 CLIProxyAPI;若後端拿 model 名稱去拼路徑、呼叫指令或做檔名查找,這個輸入就可能被拿來做路徑穿越或指令注入。 **建議**:不要只做字元白名單,應改成明確白名單比對可用模型 slug,並額外拒絕 `..`、前導/結尾 `/`、連續 `/`、反斜線與控制字元;如果可行,直接用 `/v1/models` 回傳清單做嚴格選擇,而不是接受任意形狀的字串。
admin added 1 commit 2026-08-07 16:46:05 +00:00
chore: update ai-review findings [ai-review-bot][success]
CI / 1. BUILD (pull_request) Successful in 2s
CI / 2. TEST (pull_request) Successful in 2s
CI / 3. RESULT (pull_request) Successful in 1s
e46031cb69
admin merged commit ca868f6ea6 into develop 2026-08-07 16:49:29 +00:00
admin deleted branch feat/文件整理 2026-08-07 16:49:30 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: actions/ai-code-review#4