指令
Blueprint 支援 Node ^18.18.0 || ^20.9.0 || >=21.1.0。不必安裝全域指令,直接透過套件 執行:
npx @kekkai/blueprint <command>根指令與每個子指令都支援 --help;--version 會顯示套件版本。支援 --json 的指令會 保留與文字報告相同的事實,讓自動化程式與程式撰寫 Agent 不必解析說明文字。
init
init 用來導入 Blueprint、修復既有整合,或啟動受保護的拓樸轉換。它會根據專案證據與 明確指定的目標,選擇三種流程之一:
- 建置或修復:替經量測確認沒有原始碼的應用程式建立框架預設設定(layer-first,
或沒有任何模組的 module-first 起點)、替規模小的 layer-first 專案建立預設設定,
或依既有有效設定檔更新產生的整合內容。 - 架構編寫指南:適用於尚無有效設定檔的既有原始碼,包含以 module-first 導入既有原始碼。
- 拓樸轉換指南:既有有效設定檔已確立另一種專案拓樸時使用。
第一次導入一定要明確選擇拓樸:
npx @kekkai/blueprint init --topology layer-first
npx @kekkai/blueprint init --topology module-first先預覽完整動作,不寫檔、不安裝、不啟動 Agent:
npx @kekkai/blueprint init --topology layer-first --dry-run旗標
--topology layer-first|module-first— 第一次導入專案時必填。
在沒有原始碼的 React 或 Vue 應用程式上,module-first會以預設設定建立空的模組起點;已有原始碼時則產生架構編寫指南。
已導入的專案若指定相同目標,會修復現有拓樸;指定相反目標,則啟動全專案轉換。--preset— 跳過架構編寫,使用偵測到的 Vue、React 或 Next 預設設定。
這只是 layer-first 的導入方式;指定 module-first、已是 module-first 的專案,以及已有自訂設定檔的應用程式都會拒絕執行。
沒有原始碼的 module-first 應用程式不需要這個旗標,只下--topology module-first就會建立起點。--authoring— 即使少於 10 個原始碼檔案,或是沒有原始碼的 module-first 應用程式,也強制產生架構編寫指南;後者的指南結論會帶你回到模組起點。不能與--preset並用。--agent claude|codex— 編寫或轉換流程會在指南安全寫入後啟動指定的本機 Agent CLI;預設設定流程不啟動 Agent,只縮小要產生的 Agent 守則目標。--framework vue|react— 框架證據不明確時指定。一般 Vue、React 會自動偵測;Next.js 會使用能辨識路由器的預設設定。--no-install— 不執行偵測到的套件管理工具,並在計畫裡列出待安裝內容。--dry-run— 只顯示計畫,不修改檔案,也不啟動 Agent。--recover-transformation— 從 Git 保留的權威記錄還原遺失的 LF→MF 待完成證據與復原指南,保留既有決策與指南;不執行導入、產生架構檔案或完成轉換。請單獨使用,或搭配--dry-run。復原要求目前HEAD與原始記錄一致,且應用程式與來源範圍安全。若決策檔曾遭刪除,必須重新審查並記錄遺失的決策,才能驗證完成。詳見產出檔案。
可能修改的內容
完成建置時,可能建立 blueprint.config.mjs、Blueprint 管理的 ESLint 設定或參考設定、 指定路徑的架構手冊、所選 Agent 守則,以及全新 layer-first 預設設定缺少的分層資料夾;
module-first 起點不會建立任何模組資料夾。 它也可能更新別名接線、一般 lint 指令、.gitignore,並透過偵測到的套件管理工具更新 相依套件。完整清單與管理權責見產出檔案。
既有 ESLint 設定絕不會被覆寫。除非 Blueprint 能辨識出自己產生並管理的設定檔,否則 只會建立 eslint.config.blueprint.mjs 供你整合。重複執行 init 應得到相同結果。
重要邊界
- 原始碼形狀只是證據,不是拓樸權威。同一個專案內的有效設定檔必須解析成同一種拓樸。
- 多應用程式範圍未確定時,任何寫入前就會停止;編寫階段必須明確選擇應用程式的原始碼根目錄。
- Blueprint 絕不自行發明領域模組。沒有原始碼的 React 或 Vue 應用程式,
可以從預設設定的空模組起點開始 module-first;已有原始碼時,模組圖一定要先由人或 Agent 編寫。 - 拓樸轉換要求 Git 專案、乾淨工作目錄與可復原的已提交
HEAD。Blueprint 會記錄量測到的 搬移證據,但領域命名、擺放位置、衝突處理與匯入改寫仍由 Agent 判斷,並以git mv執行。 - Next.js App Router 會保留。遇到不支援的 Pages Router 或不明確路由器轉換時,流程會停止, 不會暗中改變路由架構。
- Nuxt 的自動匯入讓 Blueprint 無法提出可信的靜態分析結果,因此目前不支援。
遭拒或執行失敗時會以非零狀態結束。若明確要求的 Agent 啟動失敗,先前產生的指南與檔案 仍已保存在磁碟上,可改走手動流程。
init 何時算完成導入
Blueprint 會把「已經寫入專案、可以證明由 Blueprint 擁有的內容」和「這次導入是否真的完成」分開記錄。
如果 init 執行到一半失敗,已經落地的 Blueprint 內容仍會保留所有權紀錄,但不會因此建立已完成的生命週期檢查點。
以下情況也還不算完成導入:
- 使用
--no-install跳過了目前仍需要安裝的 Blueprint 或相關工具相依套件; - brownfield authoring 目前只建立了
blueprint-authoring.md與 Agent 交接內容,還沒產生並採用最後的blueprint.config.mjs。
等缺少的工作補完後,再次執行 init。Blueprint 會保留前一次已記錄的所有權事實,並在這次導入真正完成時建立生命週期檢查點。
brownfield authoring 中,當 Agent 已經完成設定檔,而後續的 init 成功採用這份設定時,就代表 Blueprint 的導入已完成,可以建立檢查點。blueprint-authoring.md 可能仍會暫時保留到 Agent 執行最後的清理步驟;只要這類尚未完成的 workflow 檔案仍存在,upgrade 仍會拒絕開始新的升級。
全新專案與既有專案的導入姿態
第一次導入時,空的應用程式跟已有原始碼的應用程式走不同路線。
決定路線的是量測到的原始碼,不是旗標。
- 全新專案(經量測確認為空) — survey 在 React 或 Vue 應用程式裡數到 0 個原始碼檔案。
init會直接建立框架預設設定的完整標準治理:分層職責、框架所有權、命名、核心信念、
元件形狀軸線、工作指南,以及各規則的等級。--topology layer-first寫出reactPreset()或vuePreset()。--topology module-first寫出同一份預設設定,再加上modules: []。
這個起點已經宣告了拓樸、套用同一套治理,
但不建立任何模組資料夾,也不發明任何領域模組 —— 沒有shared、core、app,什麼都沒有。
模組根目錄佔 container 的位置,重複的內部分層保留各自的框架職責,
路由組合等實際出現路由後,再交給保留的app模組。- Next.js 應用程式不走 module-first 起點:
即使專案是空的,--topology module-first也會進入架構編寫指南。
- 既有專案(已有原始碼) —
init產生架構編寫指南。
Agent 會轉譯專案原有的意圖與門檻、先量測影響,
再把已理解的既有債務記進各自的帳本:架構問題記進 Blueprint 基準線,lint 命中記進 ESLint suppressions。
它不會替專案打開原本沒有的選用檢查。
Layer-first 在原始碼少於 10 個檔案時,也會直接建立預設設定。
既有專案產出的設定檔是真實、安全的導入結果 —— 是下限,不是 Blueprint 建議的上限。
讓 module-first 起點長出模組
Module-first 設定產出的架構手冊與 Agent 守則,都帶有一份模組成長流程。
當 owner 要求的產品功能需要一個現有模組都不擁有的邊界時,Agent 會先用暫時的 layer-first 投影來推理:
先看路由/頁面怎麼組合,再找出它組合的 container/use case 職責,最後找出每項職責需要的單元。
這些職責就是模組的種子:相關的種子合併、只有真正獨立的才拆開,
有明確領域擁有者的程式碼就留在擁有者身上。
決定好擁有權之後,才建立 Module → Layer → Unit,並依實際匯入推出 dependsOn。
它絕不會一個畫面、hook/composable、service、entity 或需求名詞就開一個模組,也絕不會開一個什麼都塞的 shared。
這個投影只是分析。
它不會把專案說成 layer-first、不會寫出 layer-first 設定檔,也不會啟動拓樸轉換。
收緊既有專案的設定檔
要不要把既有專案的設定往標準預設設定收緊,是 owner 在導入之後的決定。
動手之前先量測,一次只恢復一項更嚴格的守則,
每一步只記錄「在那一步之前就存在」的債務。
絕不為了變綠而降低目標。
決定收緊時,把下面這段 prompt 交給你的程式撰寫 Agent:
請把這個專案的 Blueprint 治理,往標準 <React|Vue> 預設設定收緊。
1. 比對 blueprint.config.mjs 與標準預設設定。用下面這行印出標準預設設定:
`node --input-type=module -e "import { reactPreset } from '@kekkai/blueprint'; console.log(JSON.stringify(reactPreset(), null, 2))"`
(Vue 專案改用 `vuePreset`;設定檔是 module-first 時傳入 `{ modules: [] }`)。
執行 `npx blueprint rules --json` 看設定檔宣告了哪些檢查,
再列出分層、所有權、命名、核心信念與規則等級的每一項差異。
2. 動手之前先量測:執行 `npx blueprint inspect --json` 與 `npx blueprint impact --json`,
把兩份輸出留作起始證據。
3. 一次只恢復一項更嚴格的守則:一項分層職責、一條所有權規則,或一個規則等級。
每一步之後執行 `npx blueprint init`、`npx blueprint impact --json` 與
`npx blueprint inspect --json`,並把每個新結果分類為「這一步揭露的既有債務」或「退步」。
4. 先修好退步,再把已理解的既有債務記進各自的帳本:
架構問題用 `npx blueprint inspect --update-baseline`,lint 命中用 `npx eslint . --suppress-all`
(ESLint 的 suppressions 檔;只有專案自己的 lint 指令已經通過時才跳過這一步,
因為 `impact` 只計算架構 glob 涵蓋到的檔案,範圍外的測試檔和其他檢查的檔案都不會算進去)。
5. 絕不為了變綠而降低目標規則、門檻或邊界。某一步的代價若大於價值,
停下來把量測到的影響回報給 owner,而不是把它放寬。
6. 最後執行 `npx blueprint inspect --baseline`、`npx blueprint doctor`,以及專案自己的
lint、typecheck、test、build 指令。回報每一項恢復的守則、每一步記錄的債務,
以及所有留給 owner 決定的事項。survey
survey 在設定檔建立前蒐集可重現的客觀證據,包括原始碼資料夾與形狀、重複子資料夾 模式、資料夾匯入矩陣、同資料夾別名匯入、測試命名慣例、原始碼根目錄接線檔案,以及套件 使用集中度。
npx @kekkai/blueprint survey
npx @kekkai/blueprint survey --source-root apps/web/src --json--alias <name>— TypeScript/JavaScript 設定找不到別名時,由使用者提供。--source-root <path>— 在多應用程式工作區中選擇一個原始碼根目錄。--json— 輸出機器可讀的證據。
這是唯讀指令,只回報事實,不替你決定分層、模組、所有權或依賴方向。
inspect
inspect 會拿設定過的原始碼樹與架構比對,找出未宣告資料夾、模組或分層流向違規、非 標準別名、深入匯入、相對路徑逃逸、套件所有權違規、selfOnly 再匯出、缺少公開入口, 以及尚未落地的模組/分層提示。只有在 rules.cycles 已宣告且層級不是 off 時,它才會 回報單元循環。關卡未宣告或為 off 時,沒有循環 finding 只代表 Blueprint 未啟用循環 偵測,不能證明相依圖中沒有循環。
npx @kekkai/blueprint inspect
npx @kekkai/blueprint inspect --update-baseline
npx @kekkai/blueprint inspect --baseline --json--framework vue|react— 框架證據不明確時指定。--json— 輸出結構化報告。--update-baseline— 將目前 error/warn 記錄進.blueprint-baseline.json;info 不會列入,沒有債務時不建立檔案。匯入分析若為降級或失敗,會拒絕更新並以1結束,避免把不完整的相依圖寫成基準線。--baseline— 只讓基準線以外的新問題造成失敗,形成既有專案的棘輪。
任何未列入基準線的 error 都會讓指令以 1 結束;warn 與 info 不會。解析失敗也會以 1 結束:只要有一個檔案解析失敗,匯入分析就是降級;若所有掃描檔案都解析失敗,則是失敗。 報告會把解析狀態與架構規則涵蓋的原始碼檔案數、已啟用的選用關卡數分開呈現,避免把結構 涵蓋率誤當成相依圖完整性的證明。
architecture.testFiles 是唯一的結構性測試檔豁免來源。靜態匯入與再匯出會進入相依圖; 動態匯入只有在目標可化約成確定字串時才會納入。無法判定的動態目標會揭露;若 module-first 專案需要檢查來源目錄外的範圍,這些目標可能跨越邊界,因此範圍證據會標示為不完整,Inspect 不會判定驗證完成,也不允許更新基準線。只分析受管來源與 layer-first 的行為維持不變。 解析失敗可能隱藏相依邊,因此會讓驗證失敗。
Module-first 報告一律包含 moduleDependencies,即使沒有設定 moduleDependencySync 或設為 off 也一樣。它比對宣告的直接相依(D)與原始碼確認的直接相依(O),並分開 呈現間接匯入權限(P)。結果包含吻合、缺少、未使用及待確認的宣告,各模組的涵蓋情況與 不確定性,以及整體 synchronized、drift、indeterminate 或 runway 狀態。 已確認的差異不會因分析不完整而消失。
啟用 rules.moduleDependencySync 後,Inspect 會依模組配對彙整 module-dependency-missing、module-dependency-unused,並為每個分析不完整的匯入模組 產生一筆 module-dependency-unverified,採用此規則自己的 warn/error 層級。 已有間接權限的參照仍可能缺少直接宣告;禁止的參照則保留原有流向違規。 調整原始碼或 dependsOn 前,應先確認預期架構。
inspect --baseline 用來防止已知債務增加,不是精確相等的證明。基準線可以讓已記錄的 同步問題不影響結束狀態,但不會改變文字、JSON 或 runInspect() 中完整的 moduleDependencies 狀態、差異清單、涵蓋情況與不確定性。 相依圖納入型別參照與可靜態確認的動態匯入,排除設定指定的測試檔,仍納入 layerFilesIgnore 與看似自動產生的受管原始碼。執行時才能決定的目標、解析失敗,以及 無法解析的專案內參照只影響所屬匯入模組。完整規則見 來源範圍與啟用方式。
inspect 不接受位置參數路徑。請在應用程式根目錄執行,掃描範圍由 architecture.sourceRoot 決定;額外傳入路徑會被拒絕,不會默默忽略。
Module-first 專案中,sourceRoot 外的原始碼與受管原始碼相依時, uncovered-application-source 仍屬於錯誤。如果外部匯入者確實是工具或其他外部使用端, 負責人可以在 architecture.consumerFiles 宣告 相對於應用程式根目錄的精確模式;若它其實是應用程式原始碼,就應擴大或重新整理受管範圍, 或移除相依。資料夾名稱不會自動取得豁免,模式應盡量限縮,避免掩蓋真正的應用程式原始碼。
外部使用端宣告只會移除「外部匯入內部」的範圍證據。若受管原始碼反向匯入使用端,仍須移除 該相依,或把目標搬入受管架構並正確宣告。雙向相依時,反向那條仍會阻擋。這個角色不賦予 拓樸身分,也不證明目標 API 或公開入口的使用正確。testFiles 維持獨立且優先的雙向豁免; layerFilesIgnore 不會隱藏範圍證據。省略或清空使用端宣告、layer-first 專案,以及 sourceRoot: '.' 都維持既有行為。允許的使用端相依不新增訊息,也不改變結束碼。基準線用來 記錄債務,不能取代外部使用端的角色宣告。
Module-first 的完整分析只收集一次來源目錄外的證據,Doctor 與轉換驗證共用這份結果。 在 Git 工作目錄中,候選範圍包含此應用程式內已追蹤的檔案、尚未追蹤且未被忽略的檔案, 再加上 consumerFiles 明確指定的搜尋根目錄,以及受管原始碼匯入的外部目錄。 無關且被忽略的輸出不會被解析;已追蹤的原始碼即使符合忽略規則,仍會被納入。 明確搜尋範圍也會納入同目錄內其他角色的檔案,因此過寬的使用端模式會增加掃描成本。 測試檔會在讀取與解析外部檔案前排除,既有的掃描器排除規則仍然適用。
外部證據會區分 not-requested(未要求)、not-applicable(不適用)、complete(完整)、 partial(部分完成)與 unavailable(無法取得)。Layer-first 與 sourceRoot: '.' 不分析外部範圍;deps、survey、rules 等只需要受管來源的指令,不會盤點、讀取或解析 外部檔案。無法取得 Git 檔案清單時,會改用完整的檔案系統掃描,並揭露可能增加的成本。 即使 finding 已列入基準線,部分完成或無法取得的證據仍會阻擋完整驗證。JSON 會提供共用的 範圍證據與檔案操作次數。「完整」指依設定的收集政策完成,並不代表已證明那些被忽略、 且未被宣告或受管相依觸及的檔案沒有問題。
impact
impact 會在正式接線前,只預覽 Blueprint 產生的規則將新增哪些 lint 問題。它使用專案 自己的 ESLint,依規則統計命中次數並列出問題最多的檔案。
npx @kekkai/blueprint impact
npx @kekkai/blueprint impact --json唯一旗標是 --json。執行時需要已編寫的 blueprint.config.mjs、ESLint 9 或 10,以及專案 技術組合需要的解析器與外掛;init 會安裝支援的相依套件。若專案仍使用 ESLint 8, impact 會明確回報不可用並指向 ESLint 9/10 遷移,不會曝露 flat config API 原始錯誤, 也不會把未量測結果寫成零命中。
這是資訊指令:即使有 lint 命中也維持成功狀態。解析錯誤、未使用的停用註解與非 Blueprint 規則會另外列出,不會灌進 Blueprint 總數;這些仍須回到專案平常的 lint 驗證。 支援 Vue JSX/TSX script 區塊。若有檔案無法解析,JSON 會回報 status: "partial", 文字報告也會說明命中數只是已觀察到的下限,並非完整總數。請先修正來源或解析器設定, 重新執行 Impact,再決定規則層級或記錄 suppressions。
deps
deps 讀取與 inspect 相同的受管理匯入圖。指定單元時會列出它匯入什麼、哪些單元匯入 它;省略單元則輸出被引用數排行榜。
npx @kekkai/blueprint deps hooks/useCart
npx @kekkai/blueprint deps src/orders/components/OrderRow.tsx --json
npx @kekkai/blueprint deps--framework vue|react— 框架證據不明確時指定。--json— 輸出結構化相依圖結果。
只有架構涵蓋的單元會進圖;被略過的資料夾與匯入分析限制都會明列。Folder layout 以單元 為粒度,file layout 則收斂成分層粒度。設定為測試檔的匯入不會增加影響範圍,且只有別名 與相對匯入會形成邊。
Module-first 未指定目標時,會在單元排行榜之前列出直接宣告、間接權限、觀察到的相依及其 參照次數與固定排序的範例,再呈現比對結果、涵蓋情況與不確定性。 指定目標時,文字報告仍保留整個專案的狀態,另顯示目標所屬模組。 JSON 與 runDeps() 永遠保留完整、未篩選的 moduleDependencies,並另外標示目標模組; 指定目標不會縮小整體判定範圍。JSON 包含每一組不重複的證據路徑與匯入字串,順序固定。 Layer-first 的 moduleDependencies 為 null,文字報告省略此區段。
模組資料與 Inspect 共用受管來源分析,不需要盤點來源目錄外的檔案。 型別參照會計算,設定指定的測試檔不計算;layerFilesIgnore 與自動產生風格的檔名不構成 豁免。無法判定的動態目標與專案內參照保留為不確定性,不猜測相依,也不當成宣告未使用的 證據。詳見範圍與狀態定義。
rules
rules 說明可用的 lint 與 Inspect 檢查。它會區分一定產生的結構性規則、由 blueprint.rules 啟用的選用關卡,以及只寫入文件的規則識別碼。有設定檔時,還會顯示每個 關卡的 tier/數值、在目前技術組合是否生效,以及實際結構限制。
npx @kekkai/blueprint rules
npx @kekkai/blueprint rules --json唯一旗標是 --json。此指令唯讀,也不要求設定檔。需要理解真實結果時,應使用它,而不是 反向推測產生後的 flat config;規則設定總表見設定。
moduleDependencySync 會列出宣告層級、可用性、啟用狀態,以及執行來源 inspect (module dependency reconciliation)。它僅適用於 module-first,不是 lint 規則; 與 cycles 一樣,必須執行 Inspect 才會檢查,也不受 emit.lint.severity 控制。
doctor
若 ESLint 無法為規則存續檢查的探測路徑提供設定,Doctor 會列出路徑並標為未驗證。 應檢查全域忽略規則與檔案匹配,不能據此斷言規則遭到覆蓋;其他位置若確實遺失規則, 仍會判定失敗。Suppressions ledger 會同時檢查應用程式與實際 ESLint 設定所在目錄。
doctor 評估目前設定下的導入證據,包括設定檔、殘留的暫存/Agent 檔案、ESLint 接線、 package.json 一般 lint 入口能否安全到達並實際跑完 ESLint、別名接線、結構性規則在合併後 的 flat config 是否仍存在、架構狀態,以及停用規則帳本。
Doctor 不會替 moduleDependencySync 檢查 ESLint 接線,也不證明 CI 有執行 Inspect。 啟用同步關卡後,專案的檢查流程仍須實際呼叫 Inspect。
別名證據會依可辨識的 TypeScript、bundler/runtime、套件 imports 子路徑與 test runner 分開回報。單一 consumer 的證據不會產生涵蓋整個工具鏈的綠燈:缺少對應會讓該項失敗; 應適用但無法讀取時會標示為尚未驗證;不存在或不適用的 consumer 也會明確標示。
npx @kekkai/blueprint doctor
npx @kekkai/blueprint doctor --json唯一旗標是 --json。公開的 runDoctor() 回傳值與 JSON 都以 assessment 作為評估依據, 分成四個獨立面向:
gates:適用的可執行檢查已通過、失敗,或仍未驗證。conformance:新增違規、基準線保留的既有債務,以及不阻擋執行的觀察。 這些計數可能重疊,不能相加;基準線略過違規不會抹去證據。reach:已涵蓋、部分涵蓋與僅宣告的位置。無法取得的來源目錄外證據會計入partial, 但項目證據仍保留原始狀態。有意保留的modules: []起步狀態屬於宣告,不代表導入失敗。review:仍需審查或沒有已知審查項目,並分別列出待審查與已記錄的數量。 沒有已知項目只代表 Blueprint 未產生待審查項目,不代表產品模型已證實正確。
共用的 assessment.headline 依序優先呈現:檢查失敗、可執行與來源證據同時未驗證、 只有可執行證據未驗證、只有必要來源證據未驗證、仍需語意審查、尚未實際驗證的宣告, 最後才是沒有已知審查項目。檢查通過不能掩蓋必要來源證據不完整。每個項目保留穩定的 來源識別、型別化證據、限制、審查訊號與既有退出碼政策;引用該模組的模組數量不能決定它是否應歸為共用模組。
gateVerdict 保留原本只反映檢查結果的 complete | unverified | incomplete。 verdict 在 4.2 保留為已棄用的相容別名;兩者都不是導入結論。 ok 與退出碼維持相容:Doctor 沒有失敗項目時退出碼為 0,即使有跳過檢查也一樣; 有失敗項目才是 1。要求完整證據的自動化流程應讀取 assessment,不能只看退出碼。 不安全或語意不明的 lint 指令會跳過,不會交給 shell 執行。
inspect 與公開的 runInspect() 使用相同評估模型,提供架構範圍的子集。 Doctor 彙整目前設定的證據;兩者都不證明模組歸屬、分層與根目錄責任、呈現責任, 也不能證明過去的拓樸轉換已完成。生命週期升級與拓樸轉換維持各自範圍及決策紀錄。 靜態產出的守則只說明這些界線,不會快取即時評估結果。
Doctor 會辨識 lint 指令;未宣告 lint 時,則辨識 eslint 指令。兩者都無法辨識時, 這項檢查會標成未驗證,而不是斷言接線錯誤。對可執行的 JavaScript 別名設定,無法判讀的 運算式或匯入的別名表也會標成未驗證。只有靜態證據足以確認缺少或目標不符時,才會回報 對應的別名有問題;建置成功本身也不能證明每個別名都正確。
upgrade
upgrade 負責把已導入 Blueprint 的專案升級到較新的版本。
要升級到哪一版,就用那一版的 Blueprint 執行:
npx @kekkai/blueprint@latest upgrade --dry-run
npx @kekkai/blueprint@latest upgrade
npx @kekkai/blueprint@4.1.0 upgrade正在執行的 @kekkai/blueprint 套件就是唯一的目標版本來源,因此沒有另外的 --to 旗標。
upgrade 不會用來降版。它也會同時確認專案目前實際安裝的 Blueprint 版本與生命週期檢查點;只有兩者都已經位於正確的目標狀態時,才會回報目前不需要升級。
如果只是要重新產生 Blueprint 管理的內容,請使用 blueprint init;如果只是要確認目前狀態,請使用 blueprint doctor。
為什麼只執行 npm update 不夠
Blueprint 的版本升級不只包含 npm 套件本身。
新版本可能同時需要:
- 更新專案中的
@kekkai/blueprint相依套件; - 執行 Blueprint 可以安全確定的設定或整合遷移;
- 重新產生 Blueprint 管理的輸出;
- 執行需要人或程式撰寫 Agent 判斷的語意工作;
- 驗證所有已導入的應用程式是否真的完成升級。
因此,單獨執行 npm update、pnpm update 或 yarn upgrade 並不等於完成 Blueprint 的升級生命週期。
upgrade 會依序處理完整流程:
確認起始狀態並產生計畫。 讀取
.blueprint-lifecycle.json中已完成的生命週期版本與升級紀錄。 如果專案是在生命週期狀態功能加入之前就已經導入 Blueprint,只能使用當時實際安裝、可精確證明的套件版本建立起始檢查點。舊版設定格式橫跨受支援與不受支援的 3.x 版本,不能單獨證明來源版本;若較新的套件已覆蓋這項證據,必須先建立已知的 3.2 檢查點再升級。 接著一次收集(source, target]區間內所有版本的結構化升級操作,先處理requires、cancels、supersedes與適用條件,算出最終有效計畫,之後才開始修改專案。記錄尚未完成的升級。 在執行其他修改之前,先把本次升級的來源版本、目標版本與有效計畫寫進生命週期狀態。 如果流程中斷,之後可以從同一份 pending state 接續,不會重複已完成的操作。
把專案相依套件更新到目標版本。 Blueprint 會使用偵測到的 npm、pnpm 或 Yarn,更新真正宣告
@kekkai/blueprint的package.json與 lockfile。 更新完成後,後續流程會改由專案剛安裝好的 Blueprint 執行,確保設定檔載入、遷移與產出全部使用目標版本。執行可由程式確定完成的遷移。 Blueprint 會透過既有的
init與其他既有 owner,執行可以安全自動完成的設定與整合遷移,不把可確定的工作丟給 Agent 判斷。處理仍需要語意判斷的工作。 如果最終有效計畫還有語意操作,Blueprint 會產生一份
blueprint-upgrade.md。 Agent 只執行這份已解析完成的計畫,不直接執行歷史 CHANGELOG 或 release note。 每完成一項操作後,使用:bashnpx blueprint upgrade --complete <operation-id>Blueprint 會先執行該操作可以量測的驗證,再記錄完成狀態。
完成最後驗證。 所有語意操作完成後,再執行:
bashnpx blueprint upgradeBlueprint 會重新對齊每個已導入的應用程式,並執行
blueprint inspect --baseline與blueprint doctor。 只有所有必要驗證都成功,生命週期檢查點才會移到目標版本。最後仍應執行專案自己的 lint、typecheck、test 與 build 指令。
套件更新途中中斷
升級開始前,Blueprint 會先記錄這次 pending upgrade,再更新各個已導入應用程式實際使用的 Blueprint 套件。
如果 repository 有多個套件宣告位置,而更新途中只有部分應用程式成功到達目標版本,下一次執行 upgrade 會從已記錄的 pending upgrade 接續:
- 已經位於目標版本的應用程式不會重複安裝;
- 還停在這次升級起始版本的應用程式會繼續更新到目標版本;
- 如果出現不屬於這次升級起始版本或目標版本的其他版本,Blueprint 會停止,不會猜測如何修正這個狀態。
因此,由 Blueprint 自己造成的「部分套件已更新」狀態是可接續的升級中間態,而不是要求使用者自行修復的混合版本錯誤。
跨版本的累積升級計畫
一個 Blueprint 版本可以新增零到多項結構化升級操作。
每項操作都有固定 id、加入它的版本、適用條件與驗證方式,也可以宣告與較早操作的關係:
requires:這項操作必須排在另一項操作之後。cancels:如果較舊的操作在這個 repository 還沒執行過,就從本次直接升級的有效計畫中移除。取消不等於還原;已經執行過的歷史不會被假裝成沒發生過。supersedes:由新的操作接手最終狀態。無論舊操作以前已經執行過,還是直接跨版本而從未執行,新操作都必須把專案收斂到同一個受支援的目標狀態。
因此:
3.2 → 4.1直接升級,和:
3.2 → 4.0 → 4.1分段升級,可以有不同的歷史執行紀錄,但最後必須收斂到同一個 Blueprint 目標狀態。
Agent 不會自行重播每一版的 CHANGELOG 或 release note,只會收到 Blueprint 已經解析完成的最終有效計畫。
選項
--dry-run— 顯示起始版本、起始版本的證據、目標版本、所有已導入的應用程式與實際安裝版本、套件更新指令、確定性遷移、最終有效的語意計畫,以及開始升級前必須滿足的安全條件。完全不修改專案。--complete <operation-id>— 在某項待完成的語意操作通過自己的驗證後,記錄這項操作已完成。不能與--dry-run同時使用。
升級邊界
支援的升級起點目前從 3.2.0 開始。更早的 Blueprint 導入,必須先依該版本原本支援的方式到達 3.2.0,再進入目前的 upgrade lifecycle。
目前執行的目的版本只負責自己宣告的升級支援範圍,也就是 supportedFrom 到目前版本。
已經完成、而且隨著支援範圍前移而退出可執行範圍的舊升級操作,可以只保留辨識歷史所需的最小紀錄;它們不會重新進入新的 pending upgrade,也不需要永久保留舊版的執行指示、適用條件或驗證方式。
換句話說,最新版 Blueprint 不需要理解所有歷史版本彼此之間的升級路徑。已完成的生命週期檢查點會結束它之前的可執行升級義務,之後的 resolver 只處理目前檢查點到目的版本之間仍受支援的區間。
開始新的升級之前,必須位於 Git repository,而且工作目錄不能有未提交的變更,讓整次升級可以完整檢視與還原。已經有 pending upgrade 時,則依既有紀錄接續,不要求把升級本身造成的修改先清掉。
Blueprint 的 lifecycle 是 repository-wide。所有已導入的應用程式都必須維持一致且可證明的 Blueprint 套件狀態;只有每個必要應用程式都完成驗證,repository 的生命週期才能推進。
如果還有未完成的架構編寫或拓樸轉換流程,必須先完成或明確處理,不能同時開始新的 upgrade lifecycle。
如果 .blueprint-lifecycle.json 損壞、內容無法驗證,或 Git 歷史能證明它曾經存在但目前檔案已遺失,upgrade 會停止,不會依目前的設定或已安裝套件自行重建 lifecycle history。若不在 Git repository 內,或 shallow clone 無法提供完整歷史,也同樣停止。請先從版本控制或其他可信來源還原 lifecycle state;無法還原時,交由 owner 決定後續處理。
如果 .blueprint-lifecycle.json 目前不存在,而且完整 Git 歷史中所有目前可追溯的 ref 都找不到曾包含這個檔案的 commit,Blueprint 不會把它視為「遺失的 lifecycle state」,因為現有版本控制證據無法證明 lifecycle 曾經成立。這種 repository 只能由實際安裝、可精確定年的舊版套件建立起始檢查點;若 Renovate、Dependabot 或 npm update 已把套件升到較新版本,舊版設定格式本身無法區分 3.1 與 3.2,Blueprint 會拒絕猜測,並要求先建立已知的 3.2 檢查點。請把 .blueprint-lifecycle.json 提交進版本控制,讓後續遺失時有可恢復的歷史依據。
remove
remove 用來安全地把 Blueprint 從專案中移除。
請在解除安裝 @kekkai/blueprint 之前執行:
npx blueprint remove --dry-run
npx blueprint removeBlueprint 會先算出完整的 repository-wide 移除計畫,確認每一項內容的所有權證據與可逆性。只要有任何共用內容無法安全判定,整次移除都會在實際修改之前停止。
Blueprint 可以移除哪些內容
Blueprint 自己的檔案 例如
blueprint.config.mjs、.blueprint-lifecycle.json、.blueprint-baseline.json、受支援的設定備份,以及未完成的 Blueprint workflow 檔案。Blueprint 產生的輸出 例如架構手冊、Blueprint 完整管理的 Agent 規則檔與 Blueprint 產生的 ESLint 設定。 要刪除整個檔案,必須有足夠證據證明整份檔案都由 Blueprint 擁有;如果檔案後來已改由專案自行管理,就會保留並回報。
共用 Agent 文件中的 Blueprint 區塊
CLAUDE.md、AGENTS.md等共用文件只會移除<!-- BLUEPRINT:START -->到<!-- BLUEPRINT:END -->之間的 Blueprint-managed section。 只有能證明整個檔案原本就是 Blueprint 建立時,才可以在移除區塊後刪除整個檔案;原本就存在的 user-owned file 必須保留。Blueprint 對共用檔案做過的修改
.gitignore、package.jsonscripts、TypeScript / JavaScriptpaths、Vite alias 等內容,只有在 lifecycle provenance 與目前檔案內容能共同證明「這一段就是 Blueprint 當初做的修改」時才會自動還原。 如果 Blueprint 插入的內容已經不在檔案裡,或 script 已經變回原本的值,就視為已經還原,不會擋下移除。 如果應用程式原始碼仍需要某段一般性接線,例如 import alias,該接線會保留。Blueprint 建立的資料夾 Blueprint 能證明由自己建立,而且目前沒有專案內容的資料夾可以移除。若資料夾已經放入實際專案檔案,就會保留並回報。
相依套件
@kekkai/blueprint一定最後才解除安裝。Blueprint 有完整 provenance 證明由自己加入的相關工具套件,也只會在其餘專案內容不再使用時一起移除。
有衝突時,整次移除會先停止
以下情況不能直接進行破壞性清理:
package.jsonscript 目前的值既不是 Blueprint 寫入的,也不是原本的值;- 同一段曾由 Blueprint 插入的內容現在出現多次,無法判斷哪一段才是原本的修改;
- lifecycle 雖然記得 Blueprint 做過修改,但目前證據不足以精確還原;
- Blueprint-managed section 的 marker 已損壞或不完整;
- 會留下來的設定、script 或其他檔案仍引用
@kekkai/blueprint、Blueprint CLI,或即將刪除的blueprint.config.mjs。
這些情況都會在任何刪除或改寫之前停止,並指出衝突的位置。處理完之後,再重新執行:
npx blueprint remove --dry-run確認新的完整計畫。
多應用程式 repository
從 repository root 執行 remove,會移除範圍內所有已導入的應用程式。
如果只在其中一個應用程式範圍執行,Blueprint 可以只移除該應用程式,但必須保持 repository-wide lifecycle 一致。其他仍採用 Blueprint 的 sibling application,其 lifecycle/provenance 與共用 Blueprint 套件都必須保留。
如果 repository 目前還有尚未完成的 upgrade lifecycle,而只移除其中部分應用程式會讓 pending plan 失效,Blueprint 必須先停止,而不是留下仍引用已移除應用程式的 stale upgrade plan。
在生命週期紀錄出現之前就已導入的專案
較舊的 Blueprint 導入沒有完整 provenance 可以證明所有共用檔案修改。
這種情況下,remove 只會自動刪除能從檔名、Blueprint marker 或其他可靠內容證據證明屬於 Blueprint 的項目。
無法證明的內容會保留並明確列出,例如可能由 Blueprint 加入的 alias wiring、lint script、只剩 .gitkeep 的舊分層資料夾,或無法證明由 Blueprint 安裝的工具套件。
對於生命週期紀錄出現之前就已經導入 Blueprint 的共用 Agent 文件,Blueprint 可能可以從 BLUEPRINT:START / BLUEPRINT:END marker 證明其中一個區塊屬於 Blueprint,但沒有足夠證據證明整份檔案都是由 Blueprint 建立。
這種情況下,remove 只會移除可證明由 Blueprint 管理的區塊。即使移除後整份檔案變成空檔,也會保留該檔案,並列在需要使用者確認的保留項目中;是否刪除整份檔案由使用者自行決定。
Blueprint 不會因為某個值「看起來很像預設值」就把它當成自己的修改。
移除完成後,範圍內不應再留下任何能證明仍由 Blueprint 擁有或管理的設定、生命週期狀態、產出、managed section 或相依套件。
remove 的目標是乾淨地移除 Blueprint 的 ownership 與 tooling footprint,不是為了追求位元組層級的回復,而去改寫仍由應用程式本身需要的程式碼或設定。
可執行的分層限制
Rules 的人類可讀與 JSON 輸出依宣告順序列出共用的 mustNot 計畫:review-only/executable 模式、active/partial/unavailable 可用性、精確檢查與限制、lint 嚴重程度、檔案範圍、 豁免與實測涵蓋狀態。靜態宣告不會宣稱原始碼已違規。Inspect 提供相同事實與目前的 covered/vacuous/runway 範圍,不執行第二套偵測器,也不新增退出碼政策。見 設定契約。
Doctor 驗證最後合併的 ESLint 設定是否完整保留必要載體,空位置也會使用合成檔案探測。 載體缺失、停用、替換或過期是 failed;無法檢查設定,或必要 parser/框架支援不可用, 則是 unverified。兩者都阻擋導入完成,但 unverified 不自動改變既有退出碼相容性。 原始碼 error 是失敗關卡;warn 仍是可見的符合性觀察,affectsExit: false,不把彙總 關卡升為 failed。混合情況會分別保留 failed 與 unverified 證據。
