docs(ai-code-review): 補齊各模組 JSDoc、指令檔逐行註解並重建 README
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
303104bb20
commit
1378f03595
+62
-11
@@ -6,7 +6,13 @@ import { ok, warn, error } from './log.js';
|
||||
const MAX_JSON_BYTES = 1024 * 1024;
|
||||
|
||||
/**
|
||||
* 移除 AI 回傳內容外層的 markdown code fence。
|
||||
* 移除 AI 回傳文字外層的 markdown code fence(如 ```json ... ```),
|
||||
* 並去除前後空白,使內容可直接交給 JSON.parse。
|
||||
*
|
||||
* 屬純函式、無副作用;常用於將 LLM 回傳結果正規化後再行解析。
|
||||
*
|
||||
* @param {*} text 待處理內容;非字串會先以 String() 轉型。
|
||||
* @returns {string} 去除外層 code fence 與前後空白後的字串。
|
||||
*/
|
||||
export function stripCodeFence(text) {
|
||||
return String(text)
|
||||
@@ -17,11 +23,22 @@ export function stripCodeFence(text) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 透過 LLM 修正 JSON 陣列內容。
|
||||
* @param {string} fullPath 檔案路徑,供提示詞與除錯使用。
|
||||
* @param {string} label 檔案標籤。
|
||||
* @param {string} rawText 原始內容。
|
||||
* @param {Function} chatFn 可注入的 LLM 呼叫函式,預設使用 `chat`。
|
||||
* 透過 LLM 將任意原始內容修復成「可直接 JSON.parse 的 JSON 陣列」字串。
|
||||
*
|
||||
* 會以固定 system prompt 指示模型忽略原內容中的指令/註解/markdown,
|
||||
* 僅輸出修正後的陣列;無法判斷時模型應回傳空陣列 `[]`。
|
||||
* 回傳前會先以 stripCodeFence 清除外層 code fence。
|
||||
*
|
||||
* 備註:fullPath 與 label 僅放入提示詞供模型參考與除錯,不會用於讀檔;
|
||||
* 回傳結果不保證為合法 JSON,需由呼叫端再行解析驗證。
|
||||
*
|
||||
* @param {string} fullPath 檔案完整路徑,供提示詞與除錯使用。
|
||||
* @param {string} label 檔案標籤(人類可讀名稱)。
|
||||
* @param {string} rawText 待修復的原始內容。
|
||||
* @param {(systemPrompt: string, userContent: string) => Promise<string>} [chatFn=chat]
|
||||
* 可注入的 LLM 呼叫函式,預設使用模組匯入的 chat;便於測試替換。
|
||||
* @returns {Promise<string>} 經 code fence 清理後的修復字串。
|
||||
* @throws {Error} 當 chatFn(LLM 呼叫)失敗時,例外向上拋出。
|
||||
*/
|
||||
export async function repairJSONArrayWithAI(fullPath, label, rawText, chatFn = chat) {
|
||||
const systemPrompt = `你是 JSON 修復器。請修正使用者提供的內容,使其成為可直接 JSON.parse 的 JSON 陣列。
|
||||
@@ -33,6 +50,18 @@ export async function repairJSONArrayWithAI(fullPath, label, rawText, chatFn = c
|
||||
return stripCodeFence(repaired);
|
||||
}
|
||||
|
||||
/**
|
||||
* 讀取指定 JSON 檔案的 UTF-8 文字內容,讀取前先檢查檔案大小上限。
|
||||
*
|
||||
* 模組私有工具函式,供 validateJSONArrayFile 內部使用;
|
||||
* 大小超過 MAX_JSON_BYTES(約 1 MB)時直接拒絕讀取以避免處理過大檔案。
|
||||
*
|
||||
* @param {string} fullPath 欲讀取的檔案完整路徑。
|
||||
* @param {string} label 檔案標籤,用於組合錯誤訊息。
|
||||
* @returns {string} 檔案的 UTF-8 文字內容。
|
||||
* @throws {Error} 檔案大小超過 MAX_JSON_BYTES 時丟出;
|
||||
* 或 fs.statSync/fs.readFileSync 因檔案不存在、無權限等丟出的 IO 例外。
|
||||
*/
|
||||
function readJSONText(fullPath, label) {
|
||||
const size = fs.statSync(fullPath).size;
|
||||
if (size > MAX_JSON_BYTES) {
|
||||
@@ -42,10 +71,24 @@ function readJSONText(fullPath, label) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 驗證 JSON 陣列檔案是否存在且格式正確。
|
||||
* 若格式錯誤,直接嘗試透過 AI 修復,修復後再次檢查;
|
||||
* 第二次檢查仍失敗才丟出例外。
|
||||
* 若檔案不存在,回傳 exists=false,交由呼叫端決定是否補檔。
|
||||
* 驗證指定路徑是否為合法的 JSON 檔案;格式錯誤時嘗試以 AI 修復一次後再次驗證。
|
||||
*
|
||||
* 行為摘要:
|
||||
* - 先確保父目錄存在。
|
||||
* - 檔案不存在:不丟例外,回傳 { exists:false },交由呼叫端決定是否補檔。
|
||||
* - 解析成功:回傳 { exists:true, valid:true, repaired:false }。
|
||||
* - 解析失敗:呼叫 repairer 修復、覆寫檔案(確保以換行結尾)、再驗證一次;
|
||||
* 通過則回傳 repaired:true,仍失敗則丟出例外。
|
||||
*
|
||||
* 備註:僅嘗試修復一次;會寫入磁碟並輸出日誌,屬有副作用之非同步函式。
|
||||
*
|
||||
* @param {string} fullPath 欲驗證的 JSON 檔案完整路徑。
|
||||
* @param {string} label 檔案標籤,用於日誌與提示訊息。
|
||||
* @param {(fullPath: string, label: string, rawText: string) => Promise<string>} [repairer=repairJSONArrayWithAI]
|
||||
* 可注入的修復函式,預設使用 repairJSONArrayWithAI;便於測試替換。
|
||||
* @returns {Promise<{exists: boolean, valid: boolean, repaired: boolean}>}
|
||||
* 驗證結果;repaired 表示是否經由 AI 修復後才通過驗證。
|
||||
* @throws {Error} 修復後二次驗證仍失敗,或修復/檔案讀寫過程發生例外時拋出。
|
||||
*/
|
||||
export async function validateJSONArrayFile(fullPath, label, repairer = repairJSONArrayWithAI) {
|
||||
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
||||
@@ -76,7 +119,15 @@ export async function validateJSONArrayFile(fullPath, label, repairer = repairJS
|
||||
}
|
||||
|
||||
/**
|
||||
* 若檔案不存在則建立空陣列。
|
||||
* 確保指定路徑存在一個 JSON 檔案;若不存在則建立內容為 "[]\n" 的空陣列檔。
|
||||
*
|
||||
* 會先建立父目錄。若檔案已存在則原樣保留、不檢查其內容是否合法
|
||||
* (內容驗證請改用 validateJSONArrayFile)。為同步函式。
|
||||
*
|
||||
* @param {string} fullPath 目標檔案完整路徑。
|
||||
* @param {string} label 檔案標籤,用於日誌訊息。
|
||||
* @returns {boolean} 是否為本次新建:新建回傳 true,原本即存在回傳 false。
|
||||
* @throws {Error} 建立目錄或寫入檔案失敗(如權限不足)時,IO 例外向上拋出。
|
||||
*/
|
||||
export function ensureJSONArrayFileExists(fullPath, label) {
|
||||
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user