@@ -1,65 +1,142 @@
[
{
"level" : "critical" ,
"role" : "Rex " ,
"location" : ".gitea/workflows/review.yaml:41-44 " ,
"suggestion" : "工作流程 `AI Code Review` 被授予了 `contents: write`, `pull-requests: write`, `issues: write` 等廣泛權限。特別是 `contents: write` 權限,若工作流程所使用的 Action (`code-review`) 存在漏洞,可能導致程式碼庫被惡意修改,構成嚴重的安全風險。建議遵循最小權限原則,審查並僅授予工作流程執行所需的最少權限。例如,若僅需讀取程式碼和發布評論,則 `contents: read` 和 `pull-requests: write` 可能已足夠,而 `issues: write` 則可能完全不需要 。" ,
"is_new" : false
} ,
{
"level" : "critical" ,
"role" : "Rex" ,
"location" : "README.md" ,
"suggestion" : "`README.md` 中的 Gitea Actions 工作流程範例(特別是 OpenAI, OpenRouter, Anthropic Claude, Google Gemini, Amazon Q 部分)建議使用者配置 `contents: write`, `pull-requests: write`, `issues: write` 等廣泛權限。這會引導使用者建立具有過高權限的工作流程,若所使用的 Action 存在漏洞,可能導致程式碼庫被惡意修改。建議更新所有範例,遵循最小權限原則,僅建議授予工作流程執行所需的最少權限,例如 `contents: read` 和 `pull-requests: write`。" ,
"role" : "Leo " ,
"location" : "app/config.js:1 " ,
"suggestion" : "`getLLMConfig` 在找不到任何符合條件的 provider 時會回傳 `undefined`,而呼叫端(例如測試)假設會得到一個包含 `provider`、`apiKey`、`baseURL`、`model` 欄位的物件,導致執行時拋出 `TypeError`。請在函式結尾加入預設回傳值,例如 `return { provider: null, apiKey: null, baseURL: null, model: null };`,並在文件中說明此行為 。" ,
"is_new" : true
} ,
{
"level" : "critical" ,
"role" : "Maya " ,
"location" : "app/config.test.js " ,
"suggestion" : "在 `app/config.js` 中,`amazonq`, `kilo`, `roo`, `cline`, `continue`, `kade` 等 LLM 供應商的模型環境變數已從 `OPENAI_MODEL` 變更為各自專屬的 `PROVIDER_MODEL` (例如 `AMAZONQ_MODEL`)。然而,`app/config.test.js` 中僅針對 `amazonq` 進行了部分測試,而 `kilo`, `roo`, `cline`, `continue`, `kade` 這些供應商完全沒有任何測試案例。這導致這些供應商的配置邏輯(包括新的模型環境變數和預設值)完全未經驗證。請為這些未測試的供應商新增完整的單元測試,確保它們的 API 金鑰、基礎 URL 和模型配置都能正確解析,並驗證當對應的環境變數未設定時,能正確使用預設模型 。" ,
"is_new" : false
"role" : "Rex " ,
"location" : ".gitea/ai-review/exclusions.json:7 " ,
"suggestion" : "請移除 GITEA_TOKEN 直接嵌入 URL 的做法,改以環境變數或 Gitea Secrets 注入,避免在程式碼或設定檔中硬編碼機密資訊 。" ,
"is_new" : true
} ,
{
"level" : "warning " ,
"role" : "Leo " ,
"location" : "README.md:50 " ,
"suggestion" : "在 `2. OpenRouter` 的範例中,`with:` 區塊使用 `OPENAI_API_KEY` 參數來傳遞 `OPENROUTER_API_KEY` secret。雖然這可能是 `code-review` action 的設計,但 `OPENAI_API_KEY` 這個名稱可能會讓使用者誤解為只能用於 OpenAI。建議考慮在 `code-review` action 中提供更通用的 API key 參數(例如 `API_KEY ` 或 `PROVIDER_API_KEY`),或針對 OpenRouter 提供專屬的參數(例如 `OPENROUTER_API_KEY`),以提高清晰度並減少使用者設定時的困惑。如果 action 無法修改,目前的說明已盡力澄清,但仍是一個潛在的混淆點 。" ,
"is_new" : false
} ,
{
"level" : "warning" ,
"role" : "Leo" ,
"location" : "app/config.js:15" ,
"suggestion" : "將預設的 Gemini 模型從 `gemini-1.5-flash` 更新為 `gemini-2.5-flash`,這可能影響應用程式與 LLM 互動的效能和成本。從長期維護成本的角度來看,建議在部署前,對 `gemini-2.5-flash` 模型進行詳細的效能基準測試,評估其在回應時間、處理速度、準確性及成本效益方面的表現,確保其符合應用程式的特定需求,並避免潛在的效能退化或不必要的成本增加。" ,
"level" : "critical " ,
"role" : "Aria " ,
"location" : ".gitea/ai-review/exclusions.json " ,
"suggestion" : "新增的條目包含 `role` 欄位,但目前的 JSON schema 只接受 `location ` 與 `suggestion`,此欄位會導致驗證失敗,請移除或更新 schema 。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Maya " ,
"location" : "app/config.js:1 5" ,
"suggestion" : "預設的 `GEMINI_MODEL` 已從 `gemini-1.5-flash` 變更為 `gemini-2.5-flash`。請確保有對應的單元測試來驗證當 `process.env.GEMINI_MODEL` 未設定時,`getLLMConfig` 函數能正確回傳新的預設模型 `gemini-2.5-flash` 。" ,
"is_new" : false
"role" : "Leo " ,
"location" : "app/config.js:5" ,
"suggestion" : "目前使用硬編碼的 `checks` 陣列來管理所有 LLM provider,未來若要新增或移除 provider 必須直接修改程式碼,易產生重複與維護負擔。建議將 provider 設定抽離至外部 JSON/YAML 檔或使用可擴充的資料結構,並在程式中載入,提升模組化與可維護性 。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Leo" ,
"location" : "app/config.js:15 " ,
"suggestion" : "目前 `checks` 陣列使用多個空格進行欄位對齊,這是一種脆弱的格式化方式,當配置項的內容長度改變時,容易導致對齊混亂,增加維護成本。建議將 `checks` 陣列中的每個 LLM 配置項重構為物件形式(例如 `{ provider: 'openai', apiKeyEnv: 'OPENAI_API_KEY', baseURL: '...', modelEnv: 'OPENAI_MODEL', defaultModel: '...' }`)。這樣可以提高程式碼的可讀性、可維護性及擴展性,並使新增或修改配置項更加清晰 。" ,
"is_new" : false
"location" : "app/config.js:3 " ,
"suggestion" : "為 `getLLMConfig` 加上 JSDoc 或 TypeScript 型別註解,說明回傳物件的結構與每個欄位的意義,方便其他開發者快速了解 API,降低錯誤使用的風險 。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "May a" ,
"location" : ".gitea/workflows/review.yaml " ,
"suggestion" : "工作流程已從使用 OpenAI 轉換為 Gemini。雖然 `app/config.test.js` 增加了 ` getLLMConfig` 的單元測試,但這僅驗證了配置的解析。為了確保 AI Code Review 功能在實際使用 Gemini 模型時能正常運作,建議在 CI/CD 中增加一個整合測試步驟。此測試應能驗證使用 Gemini 模型時,AI Code Review Action 是否能成功生成 PR 評論,例如檢查 PR 評論是否存在或其內容是否符合預期,以確保端到端的整合是成功的 。" ,
"is_new" : false
"role" : "Zar a" ,
"location" : "app/config.js " ,
"suggestion" : "將 getLLMConfig 的結果快取(例如使用單例或 memoization),避免在程式執行期間多次重複遍歷 checks 陣列與讀取 process.env,減少不必要的 I/O 開銷 。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Rex" ,
"location" : ".gitea/workflows/review.yaml:33" ,
"suggestion" : "工作流程目前授予 contents、pull‑ requests、issues 三項 write 權限,過於寬鬆。建議依實際需求僅授予 read 或最小必要的 write 權限,以降低被濫用的風險。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Rex" ,
"location" : ".gitea/workflows/review.yaml:35" ,
"suggestion" : "將 OPENAI_API_KEY 參數改為使用正確的 secret 名稱(如 OPENROUTER_API_KEY)時,請確保工作流程文件中不會同時暴露兩個不同的 secret 名稱,以免因名稱錯誤導致金鑰未傳入或意外洩漏。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Aria" ,
"location" : ".gitea/ai-review/findings.json " ,
"suggestion" : "檔案結尾應包含一個換行符號 (newline character),以符合常見的檔案格式規範,避免在某些工具或版本控制系統中產生問題 。" ,
"location" : ".gitea/workflows/review.yaml:33 " ,
"suggestion" : "在 `OPENAI_API_KEY` 後的註解前應保留一個空格,以符合常見的 YAML 註解風格:`... ${{ secrets.OPENROUTER_API_KEY }} # OpenRouter 使用 OpenAI 相容介面,以 OPENAI_API_KEY 傳入` 。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Aria" ,
"location" : "README.md" ,
"suggestion" : "文件中章節編號不連續(例如 `### 2. OpenRouter` 後直接跳到 `### 3. Anthropic Claude`),建議重新編號或使用一致的標題層級,以提升可讀性與維護性。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Aria" ,
"location" : "app/config.js" ,
"suggestion" : "`checks` 陣列的每一行過長,超過 120 個字元,建議拆成多行並對齊欄位,以符合程式碼可讀性與行長限制的慣例。" ,
"is_new" : true
} ,
{
"level" : "warning" ,
"role" : "Aria" ,
"location" : "app/config.js" ,
"suggestion" : "`amazonq` 那一行的空格對齊與其他項目不一致,請統一使用單一個空格分隔欄位,或使用對齊工具保持列的垂直對齊。" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Leo" ,
"location" : "app/findings.js:150" ,
"suggestion" : "在 `filterFalsePositivesWithAI` 中,當 AI 回傳空陣列時拋出錯誤,可能導致上層流程中斷。建議改為回傳原始 `findings` 或提供更具體的錯誤類別,並在文件中說明此行為,以提升錯誤處理的可預測性。" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Zara" ,
"location" : "app/findings.js" ,
"suggestion" : "在 filterFalsePositivesWithAI 中,若 AI 回傳的陣列非常大,建議在回傳前加入分頁或限制筆數,避免一次性載入過多資料導致記憶體使用量激增。" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Zara" ,
"location" : "app/config.js" ,
"suggestion" : "對於未設定 API 金鑰的 provider(如 ollama),可提前返回快取的預設設定,避免每次呼叫都進行條件檢查。" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Rex" ,
"location" : "README.md:28" ,
"suggestion" : "文件中列出的權限說明應與實際 workflow 中的 permissions 保持一致,並提醒使用者僅在必要時授予 write 權限,避免在 CI/CD 環境中過度授權。" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Rex" ,
"location" : "app/config.js:12" ,
"suggestion" : "在取得 LLM 設定時,若 key 為空字串仍會被視為有效。建議在判斷前先檢查 key 是否為非空字串,以防止意外使用空的 API 金鑰發送請求。" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Aria" ,
"location" : "app/config.test.js" ,
"suggestion" : "匯入語句過長,建議改寫為多行匯入,例如:\n```js\nimport {\n describe,\n it,\n beforeEach,\n afterEach\n} from 'node:test';\n```" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Aria" ,
"location" : "app/config.test.js" ,
"suggestion" : "`ENV_KEYS` 陣列過長,建議分行列舉,每行放置一個環境變數,以提升可讀性。" ,
"is_new" : true
} ,
{
"level" : "info" ,
"role" : "Aria" ,
"location" : "app/findings.js" ,
"suggestion" : "錯誤訊息 `AI 回傳空陣列或非陣列` 可簡化為 `AI 回傳的結果不是有效的非空陣列`,讓訊息更清晰。" ,
"is_new" : true
}
]