ai-review-resolve/develop-20260626-091820
develop
ANTIGRAVITY_OAUTH
.gitea/ai-review/findings.json
Dockerfile
action.yaml
app/config.js
app/preflight.js
app/usage.js
app/llm.js
app/main.js
app/git.js
app/gitea.js
.gitea/workflows/ci.yaml
app/test/*
package.json
git diff --check
getOpenCodeHttpsAgent
🔍 服務:opencode 模型:gemini-2.5-flash
🔍 服務:antigravity 模型:gemini-2.5-flash
本次審查(antigravity / gemini-2.5-flash,共 6 次呼叫)
剩餘可用
剩餘可用:無法計算百分比(Antigravity 額度由 Google 帳務/方案管理,CLI 無法直接查詢)
🔍 服務:codex 模型:gpt-5
🔍 服務:codex 模型:gpt-5.4-mini
本次審查(codex / gpt-5.4-mini,共 2 次呼叫)
剩餘可用:無法計算百分比(未支援 codex 額度查詢)
@@ -8,27 +8,30 @@ inputs:
comment_token:
嚴重等級:🟡 警告 審查員:Bard 問題:這個新加入的 model 輸入沒有任何描述,讓 action 的公開介面像是少了說明書的樂譜,讀者只能靠猜來理解它要吃什麼值。 建議:補上一句簡短但明確的描述,例如說明這個欄位是「要使用的模型名稱」或「AI 助理 CLI 的模型識別字串」;讓使用者一眼看懂用途。
model
@@ -1,4 +1,7 @@
import https from 'https';
import { execFileSync } from 'child_process';
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
嚴重等級:🟡 警告 審查員:Bard 問題:process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' 放在模組載入時就直接生效,這種全域副作用太早出聲,會讓讀者在還沒看到任何呼叫前,就先被迫接受一個隱晦的環境改寫。 建議:把這種全域設定移到明確的啟動流程或初始化函式中,至少搭配更醒目的註解,讓副作用出現的位置和目的都更清楚。
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
@@ -19,4 +22,4 @@
* @remarks 首次呼叫時建立,之後快取為模組層級單例(singleton)重複使用,
* 避免每次都新建 Agent 與連線池、浪費 TCP 三次握手。
* 停用憑證驗證有中間人攻擊風險,僅限受信任的內部環境使用。
* @returns {import('https').Agent} 已關閉憑證驗證的 HTTPS Agent 單例。
嚴重等級:🟡 警告 審查員:Bard 問題:getInsecureHttpsAgent 與 getOpenCodeHttpsAgent 同時存在,卻指向同一個物件來源,等於替同一段旋律寫了兩個名字,容易讓後續維護者搞不清楚哪個才是正規稱呼。 建議:保留一個主名稱即可;如果一定要兼容舊名稱,請加上明確的遷移註解,說明哪個是新名字、哪個只是過渡別名。
getInsecureHttpsAgent
@@ -65,0 +64,4 @@
const credEnv = {
...process.env,
GIT_ASKPASS: askpassScript,
GIT_SSL_NO_VERIFY: 'true',
嚴重等級:🟡 警告 審查員:Assassin 問題:這裡對所有 git 網路操作強制關閉 SSL 驗證。攻擊者若能攔截遠端回應,就能偽造 ls-remote、污染抓到的內容,甚至在有認證的情況下竊取 GITEA_TOKEN,讓後續審查建立在被污染的資料上。 建議:移除 GIT_SSL_NO_VERIFY=true。若是內部憑證問題,改用正確的 CA bundle 或指定受信任憑證檔,不要整體關閉 git 的憑證驗證。
ls-remote
GIT_SSL_NO_VERIFY=true
@@ -18,0 +24,4 @@
}
function cliArgs(provider, model, promptFile = null, prompt = null) {
if (provider === 'codex') {
嚴重等級:🟡 警告 審查員:Bard 問題:cliArgs(provider, model, promptFile = null, prompt = null) 這個簽名把不同 provider 的參數意義混在一起,光看位置很難分辨哪個值在某條分支才有用,讀起來像把三種節拍硬塞進同一小節。 建議:改成物件參數或拆成各 provider 專用的組裝函式,讓每個欄位的用途能被名字直接說明,而不是靠呼叫順序猜測。
cliArgs(provider, model, promptFile = null, prompt = null)
@@ -130,2 +101,3 @@
* 對應 provider 且其列出指定 model。任一不符回傳對應錯誤;錯誤被攔截不會 throw。
* 確認目前環境可偵測到支援的 CLI,且已解析出 model。實際模型可用性由 CLI
* 在正式呼叫時回報;preflight 不主動送 prompt,避免額外消耗額度。
* @returns {Promise<{ok: true, provider: string}|{ok: false, provider?: string, error: string}>}
嚴重等級:🟡 警告 審查員:Bard 問題:verifyLLM 的 JSDoc 仍然只描述 provider 與 error,但實際回傳已經多了 command 和 model。註解和程式碼不同步,會讓人以為這段函式比實際更單薄。 建議:把 @returns 的型別與欄位補完整,讓文件精準反映目前回傳結構,避免讀者依舊沿用舊版心智模型。
verifyLLM
provider
error
command
@returns
@@ -212,7 +170,7 @@ export async function runPreflight(workspace = process.env.GITHUB_WORKSPACE || '
error(`LLM 驗證失敗: ${llm.error}`);
嚴重等級:🔵 建議 審查員:Bard 問題:成功訊息仍寫成 LLM provider=... CLI 可用,語氣還停在 provider 中心,但整個流程已改成 CLI 中心,術語有些半新半舊,節奏不夠一致。 建議:把成功訊息統一成 CLI 觀點,例如直接報 command=... 或改成更中性的「LLM CLI 可用」,讓文字系統保持同一把調性。
LLM provider=... CLI 可用
command=...
@@ -176,6 +177,7 @@ async function fetchOpenRouterQuota({ apiKey, baseURL }, get) {
const resp = await get(`${stripSlash(baseURL)}/auth/key`, {
headers: { Authorization: `Bearer ${apiKey}` },
timeout: 30000,
httpsAgent: getInsecureHttpsAgent(),
嚴重等級:🟡 警告 審查員:Assassin 問題:這裡對 OpenRouter 額度查詢也明確套用不驗證憑證的 agent。攻擊者只要攔截這條 HTTPS 請求,就能讀到 Authorization: Bearer 的 API key,還能回傳假 quota 資料誤導流程判斷。 建議:改回預設的 HTTPS 憑證驗證。若必須支援自簽憑證,僅對特定內部主機單獨配置受信任 CA,且不要對外部 API 一律關閉驗證。
Authorization: Bearer
No dependencies set.
The note is not visible to the blocked user.
變更摘要
ANTIGRAVITY_OAUTHsecret。.gitea/ai-review/findings.json,移除已處理的 review findings。影響範圍
Dockerfile、action.yaml:容器環境、action 輸入與執行流程。app/config.js、app/preflight.js、app/usage.js:AI CLI 設定、前置檢查與使用方式輸出。app/llm.js、app/main.js、app/git.js、app/gitea.js:審查流程、LLM 呼叫、Gitea / git 互動。.gitea/workflows/ci.yaml:CI 安裝與驗證 AI 助理工具的流程,包含 Antigravity action 來源與 OAuth secret 傳遞。app/test/*、package.json:測試覆蓋與 Node.js 測試腳本。驗證
git diff --check,未發現空白錯誤。注意事項
ai-review-resolve/develop-20260626-091820。ANTIGRAVITY_OAUTH需在 Gitea secrets 中正確設定,否則 CI 安裝 Antigravity action 時可能缺少認證。getOpenCodeHttpsAgent的自簽憑證情境已作為已知設計取捨記錄於 exclusions。🤖 AI Code Review 團隊
🤖 AI Code Review 團隊
修復 Dockerfile TLS 風險並套用憑證忽略設定to 改用 AI 助理 CLI 並強化 AI Code Review 執行流程🤖 AI Code Review 團隊
AI Code Review 統計
🤖 AI 助理使用量
本次審查(antigravity / gemini-2.5-flash,共 6 次呼叫)
剩餘可用
剩餘可用:無法計算百分比(Antigravity 額度由 Google 帳務/方案管理,CLI 無法直接查詢)
🤖 AI Code Review 團隊
🤖 AI Code Review 團隊
AI Code Review 統計
🤖 AI 助理使用量
本次審查(antigravity / gemini-2.5-flash,共 6 次呼叫)
剩餘可用
剩餘可用:無法計算百分比(Antigravity 額度由 Google 帳務/方案管理,CLI 無法直接查詢)
🤖 AI Code Review 團隊
🤖 AI Code Review 團隊
🤖 AI Code Review 團隊
AI Code Review 統計
🤖 AI 助理使用量
本次審查(codex / gpt-5.4-mini,共 2 次呼叫)
剩餘可用
剩餘可用:無法計算百分比(未支援 codex 額度查詢)
@@ -8,27 +8,30 @@ inputs:comment_token:嚴重等級:🟡 警告
審查員:Bard
問題:這個新加入的
model輸入沒有任何描述,讓 action 的公開介面像是少了說明書的樂譜,讀者只能靠猜來理解它要吃什麼值。建議:補上一句簡短但明確的描述,例如說明這個欄位是「要使用的模型名稱」或「AI 助理 CLI 的模型識別字串」;讓使用者一眼看懂用途。
@@ -1,4 +1,7 @@import https from 'https';import { execFileSync } from 'child_process';process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';嚴重等級:🟡 警告
審查員:Bard
問題:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'放在模組載入時就直接生效,這種全域副作用太早出聲,會讓讀者在還沒看到任何呼叫前,就先被迫接受一個隱晦的環境改寫。建議:把這種全域設定移到明確的啟動流程或初始化函式中,至少搭配更醒目的註解,讓副作用出現的位置和目的都更清楚。
@@ -19,4 +22,4 @@* @remarks 首次呼叫時建立,之後快取為模組層級單例(singleton)重複使用,* 避免每次都新建 Agent 與連線池、浪費 TCP 三次握手。* 停用憑證驗證有中間人攻擊風險,僅限受信任的內部環境使用。* @returns {import('https').Agent} 已關閉憑證驗證的 HTTPS Agent 單例。嚴重等級:🟡 警告
審查員:Bard
問題:
getInsecureHttpsAgent與getOpenCodeHttpsAgent同時存在,卻指向同一個物件來源,等於替同一段旋律寫了兩個名字,容易讓後續維護者搞不清楚哪個才是正規稱呼。建議:保留一個主名稱即可;如果一定要兼容舊名稱,請加上明確的遷移註解,說明哪個是新名字、哪個只是過渡別名。
@@ -65,0 +64,4 @@const credEnv = {...process.env,GIT_ASKPASS: askpassScript,GIT_SSL_NO_VERIFY: 'true',嚴重等級:🟡 警告
審查員:Assassin
問題:這裡對所有 git 網路操作強制關閉 SSL 驗證。攻擊者若能攔截遠端回應,就能偽造
ls-remote、污染抓到的內容,甚至在有認證的情況下竊取 GITEA_TOKEN,讓後續審查建立在被污染的資料上。建議:移除
GIT_SSL_NO_VERIFY=true。若是內部憑證問題,改用正確的 CA bundle 或指定受信任憑證檔,不要整體關閉 git 的憑證驗證。@@ -18,0 +24,4 @@}function cliArgs(provider, model, promptFile = null, prompt = null) {if (provider === 'codex') {嚴重等級:🟡 警告
審查員:Bard
問題:
cliArgs(provider, model, promptFile = null, prompt = null)這個簽名把不同 provider 的參數意義混在一起,光看位置很難分辨哪個值在某條分支才有用,讀起來像把三種節拍硬塞進同一小節。建議:改成物件參數或拆成各 provider 專用的組裝函式,讓每個欄位的用途能被名字直接說明,而不是靠呼叫順序猜測。
@@ -130,2 +101,3 @@* 對應 provider 且其列出指定 model。任一不符回傳對應錯誤;錯誤被攔截不會 throw。* 確認目前環境可偵測到支援的 CLI,且已解析出 model。實際模型可用性由 CLI* 在正式呼叫時回報;preflight 不主動送 prompt,避免額外消耗額度。* @returns {Promise<{ok: true, provider: string}|{ok: false, provider?: string, error: string}>}嚴重等級:🟡 警告
審查員:Bard
問題:
verifyLLM的 JSDoc 仍然只描述provider與error,但實際回傳已經多了command和model。註解和程式碼不同步,會讓人以為這段函式比實際更單薄。建議:把
@returns的型別與欄位補完整,讓文件精準反映目前回傳結構,避免讀者依舊沿用舊版心智模型。@@ -212,7 +170,7 @@ export async function runPreflight(workspace = process.env.GITHUB_WORKSPACE || 'error(`LLM 驗證失敗: ${llm.error}`);嚴重等級:🔵 建議
審查員:Bard
問題:成功訊息仍寫成
LLM provider=... CLI 可用,語氣還停在 provider 中心,但整個流程已改成 CLI 中心,術語有些半新半舊,節奏不夠一致。建議:把成功訊息統一成 CLI 觀點,例如直接報
command=...或改成更中性的「LLM CLI 可用」,讓文字系統保持同一把調性。@@ -176,6 +177,7 @@ async function fetchOpenRouterQuota({ apiKey, baseURL }, get) {const resp = await get(`${stripSlash(baseURL)}/auth/key`, {headers: { Authorization: `Bearer ${apiKey}` },timeout: 30000,httpsAgent: getInsecureHttpsAgent(),嚴重等級:🟡 警告
審查員:Assassin
問題:這裡對 OpenRouter 額度查詢也明確套用不驗證憑證的 agent。攻擊者只要攔截這條 HTTPS 請求,就能讀到
Authorization: Bearer的 API key,還能回傳假 quota 資料誤導流程判斷。建議:改回預設的 HTTPS 憑證驗證。若必須支援自簽憑證,僅對特定內部主機單獨配置受信任 CA,且不要對外部 API 一律關閉驗證。