@loviusc/sa-spec 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.zh-TW.md CHANGED
@@ -724,6 +724,12 @@ git push origin master
724
724
 
725
725
  ## 更新紀錄
726
726
 
727
+ ### v0.2.5
728
+ - **支援前端 UI 線框圖(PlantUML Salt Code-as-Wireframe)**:
729
+ - **純文字代碼化線框圖**:在 `uml/` 目錄新增標準 `uml/wireframe.puml`,使用 PlantUML Salt 語法(`@startsalt ... @endsalt`)以純文字定義頁面排版、輸入欄位、選項與按鈕,可直接在 VS Code 渲染預覽,並可納入 Git 版本追蹤。
730
+ - **AI 開發交接前後閉環**:`srs.md` 與 `handoff.md` 新增「UI / 畫面規格」區塊,前端需求直接引用 `uml/wireframe.puml`,供 OpenSpec / Claude Code 精準產出前端元件;純後端需求則標示「無 UI 介面需求」。
731
+ - **版本升級(`sa-spec upgrade`)既有需求防護**:升級時主動掃描既有需求,若偵測到前端介面描述且缺少 wireframe 則發出補齊提示;已標記無 UI 之純後端需求則略過,不盲目覆蓋既有規格。
732
+
727
733
  ### v0.2.4
728
734
  - **序號重複主動告警與重新定號自癒支援**:
729
735
  - **唯一性主動檢驗**:`sa-spec check` 與 `sa-spec reindex` 加入重複序號檢測,遇到衝突時即時發出 WARNING 告警並列出衝突目錄與修復建議。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loviusc/sa-spec",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Personal system analysis documentation workspace CLI",
5
5
  "publishConfig": {
6
6
  "access": "public",
package/readme.md CHANGED
@@ -724,6 +724,12 @@ git push origin master
724
724
 
725
725
  ## 更新紀錄
726
726
 
727
+ ### v0.2.5
728
+ - **支援前端 UI 線框圖(PlantUML Salt Code-as-Wireframe)**:
729
+ - **純文字代碼化線框圖**:在 `uml/` 目錄新增標準 `uml/wireframe.puml`,使用 PlantUML Salt 語法(`@startsalt ... @endsalt`)以純文字定義頁面排版、輸入欄位、選項與按鈕,可直接在 VS Code 渲染預覽,並可納入 Git 版本追蹤。
730
+ - **AI 開發交接前後閉環**:`srs.md` 與 `handoff.md` 新增「UI / 畫面規格」區塊,前端需求直接引用 `uml/wireframe.puml`,供 OpenSpec / Claude Code 精準產出前端元件;純後端需求則標示「無 UI 介面需求」。
731
+ - **版本升級(`sa-spec upgrade`)既有需求防護**:升級時主動掃描既有需求,若偵測到前端介面描述且缺少 wireframe 則發出補齊提示;已標記無 UI 之純後端需求則略過,不盲目覆蓋既有規格。
732
+
727
733
  ### v0.2.4
728
734
  - **序號重複主動告警與重新定號自癒支援**:
729
735
  - **唯一性主動檢驗**:`sa-spec check` 與 `sa-spec reindex` 加入重複序號檢測,遇到衝突時即時發出 WARNING 告警並列出衝突目錄與修復建議。
package/src/cli.js CHANGED
@@ -316,6 +316,7 @@ function createReqTemplate(args, label = "new") {
316
316
  ensureDir(umlDir),
317
317
  ensureFileFromTemplate(path.join("project", "req", "srs.md"), path.join(reqDir, "srs.md"), replacements),
318
318
  ensureFileFromTemplate(path.join("project", "req", "uml", "main.puml"), path.join(umlDir, "main.puml"), replacements),
319
+ ensureFileFromTemplate(path.join("project", "req", "uml", "wireframe.puml"), path.join(umlDir, "wireframe.puml"), replacements),
319
320
  ensureFileFromTemplate(path.join("project", "req", "openapi.yaml"), path.join(reqDir, "openapi.yaml"), replacements),
320
321
  ensureFileFromTemplate(path.join("project", "req", "db-schema.md"), path.join(reqDir, "db-schema.md"), replacements),
321
322
  ensureFileFromTemplate(path.join("project", "req", "handoff.md"), path.join(reqDir, "handoff.md"), replacements),
@@ -337,6 +338,7 @@ function createReqTemplate(args, label = "new") {
337
338
  ensureDir(umlDir),
338
339
  ensureFileFromTemplate(path.join("project", "req", "srs.md"), path.join(reqDir, "srs.md"), replacements),
339
340
  ensureFileFromTemplate(path.join("project", "req", "uml", "main.puml"), path.join(umlDir, "main.puml"), replacements),
341
+ ensureFileFromTemplate(path.join("project", "req", "uml", "wireframe.puml"), path.join(umlDir, "wireframe.puml"), replacements),
340
342
  ensureFileFromTemplate(path.join("project", "req", "openapi.yaml"), path.join(reqDir, "openapi.yaml"), replacements),
341
343
  ensureFileFromTemplate(path.join("project", "req", "db-schema.md"), path.join(reqDir, "db-schema.md"), replacements),
342
344
  ensureFileFromTemplate(path.join("project", "req", "handoff.md"), path.join(reqDir, "handoff.md"), replacements),
@@ -846,15 +848,70 @@ function upgradeProject(args = []) {
846
848
  const handoffRelPath = path.join(reqRelDir, "handoff.md");
847
849
  const handoffAbsPath = path.join(cwd, handoffRelPath);
848
850
  if (fs.existsSync(handoffAbsPath)) {
849
- const content = fs.readFileSync(handoffAbsPath, "utf8");
851
+ let content = fs.readFileSync(handoffAbsPath, "utf8");
852
+ let updatedHandoff = false;
850
853
  if (content.includes("uml.puml")) {
854
+ content = content.replace(/uml\.puml/g, "uml/");
855
+ updatedHandoff = true;
856
+ }
857
+ if (!content.includes("## UI") && !content.includes("畫面規格")) {
858
+ const uiSection = `\n## UI / 畫面規格\n待補充;若有前端介面需求,參照 \`uml/wireframe.puml\`;若無 UI 需求,明確標示「無 UI 介面需求」。\n`;
859
+ if (content.includes("## 驗收條件")) {
860
+ content = content.replace("## 驗收條件", `${uiSection}\n## 驗收條件`);
861
+ } else {
862
+ content = `${content.trimEnd()}\n${uiSection}`;
863
+ }
864
+ updatedHandoff = true;
865
+ }
866
+ if (updatedHandoff) {
851
867
  if (!dryRun) {
852
- fs.writeFileSync(handoffAbsPath, content.replace(/uml\.puml/g, "uml/"), "utf8");
868
+ fs.writeFileSync(handoffAbsPath, content, "utf8");
853
869
  }
854
870
  results.push({
855
871
  action: "update",
856
872
  target: handoffRelPath,
857
- message: "更新來源參照 uml.puml -> uml/"
873
+ message: "更新來源參照與補全 UI/畫面規格章節"
874
+ });
875
+ }
876
+ }
877
+
878
+ // 檢查既有需求是否需要 wireframe
879
+ const wireframeRelPath = path.join(newUmlRelDir, "wireframe.puml");
880
+ const wireframeAbsPath = path.join(cwd, wireframeRelPath);
881
+ const srsRelPath = path.join(reqRelDir, "srs.md");
882
+ const srsAbsPath = path.join(cwd, srsRelPath);
883
+
884
+ let explicitNoUi = false;
885
+ let likelyHasUi = false;
886
+
887
+ const inspectUiText = (text) => {
888
+ if (/無\s*UI/i.test(text) || /純後端/i.test(text) || /無介面/i.test(text)) {
889
+ explicitNoUi = true;
890
+ }
891
+ if (/畫面|介面|UI|前端|按鈕|表單|點擊|頁面|Page|Screen|View|Modal/i.test(text)) {
892
+ likelyHasUi = true;
893
+ }
894
+ };
895
+
896
+ if (fs.existsSync(handoffAbsPath)) {
897
+ inspectUiText(fs.readFileSync(handoffAbsPath, "utf8"));
898
+ }
899
+ if (fs.existsSync(srsAbsPath)) {
900
+ inspectUiText(fs.readFileSync(srsAbsPath, "utf8"));
901
+ }
902
+
903
+ if (!fs.existsSync(wireframeAbsPath)) {
904
+ if (explicitNoUi) {
905
+ results.push({
906
+ action: "skip",
907
+ target: wireframeRelPath,
908
+ message: "已標記為無 UI 需求,略過 wireframe"
909
+ });
910
+ } else if (likelyHasUi) {
911
+ results.push({
912
+ action: "warn",
913
+ target: wireframeRelPath,
914
+ message: "偵測到包含前端介面描述,建議透過 AI (sca) 補齊 PlantUML Salt 線框圖"
858
915
  });
859
916
  }
860
917
  }
@@ -47,7 +47,7 @@
47
47
  - `spec:commit` 只有在使用者明確要求推送 remote,或專案設定啟用 auto-push 時,才可執行 `git push`;push 失敗時只回報認證或網路問題,不得回滾已完成的文件歸檔與本機 commit。
48
48
  - 多人協作與 Git-Flow 模式(延遲綁定序號與自動合併):支援多人平行開發。執行 `spec:propose`(或 `scp`)時,若目前處於 master/main 分支,AI 必須自動依需求名稱建立並切換至專屬 feature branch(如 `feat/<name>`),並在 `project/<name>/` 建立草稿目錄,內部使用 `{{REQ_ID}}` 佔位,無需使用者手動敲 CLI;執行 `spec:analyze` 前應先確保取得 master 最新規格以防漏檢衝突;執行 `spec:commit` 歸檔時自動向 master 確認最新可用序號定號,自動將目錄定名為正式 `REQ-xxx`、替換內部佔位符、完成提交並自動合併回 master,避免多人合併時的序號競爭與索引衝突。
49
49
  - 文件未經使用者確認,不得標示為 `已審核`。
50
- - `uml/` 內的 UML 圖不限單一 UML 圖型;`spec:analyze` 必須依需求選擇最能說明流程、互動、狀態或資料關係的 UML 圖,例如活動圖、循序圖、使用案例圖、狀態圖或類別圖,不可為了固定格式硬產生活動圖。**嚴禁將多張圖混在同一個檔案中**,必須在需求資料夾下的 `uml/` 目錄拆分成獨立的 `.puml` 檔案(例如 `uml/main.puml`、`uml/sequence.puml`、`uml/state.puml`),且每個檔案只能包含一組 `@startuml` 與 `@enduml`,以避免 PlantUML 渲染或預覽失敗。
50
+ - `uml/` 內的 UML 圖不限單一 UML 圖型;`spec:analyze` 必須依需求選擇最能說明流程、互動、狀態、資料關係或介面佈局的圖表,例如活動圖、循序圖、使用案例圖、狀態圖、類別圖;**若需求涉及前端 UI 或使用者操作畫面,必須在 `uml/wireframe.puml` 產出線框圖(使用 PlantUML Salt 語法:`@startsalt ... @endsalt`)**;純後端需求則在 `handoff.md` 明確標記「無 UI 介面需求」。**嚴禁將多張圖混在同一個檔案中**,必須在需求資料夾下的 `uml/` 目錄拆分成獨立的 `.puml` 檔案(例如 `uml/main.puml`、`uml/sequence.puml`、`uml/wireframe.puml`),且每個檔案只能包含一組 `@start...` 與 `@end...`,以避免 PlantUML 渲染或預覽失敗。
51
51
  - 一次最多問 3 個待確認問題,優先詢問會影響範圍、資料、權限、API、DB 或驗收的問題。
52
52
 
53
53
  # 衝突檢查重點
@@ -22,6 +22,9 @@
22
22
  ## DB 變更
23
23
  待補充;若無 DB 需求,明確標示「無 DB 需求」。
24
24
 
25
+ ## UI / 畫面規格
26
+ 待補充;若有前端介面需求,參照 `uml/wireframe.puml`(PlantUML Salt 線框圖);若無 UI 需求,明確標示「無 UI 介面需求」。
27
+
25
28
  ## 驗收條件
26
29
  - 待補充。
27
30
 
@@ -16,6 +16,9 @@
16
16
  ## 功能需求
17
17
  - 待補充。
18
18
 
19
+ ## 介面與操作需求
20
+ - 待補充(若涉及前端介面操作,可參照 `uml/wireframe.puml` 線框圖;純後端需求標示「無 UI 介面需求」)。
21
+
19
22
  ## 驗收條件
20
23
  - 待補充。
21
24
 
@@ -0,0 +1,13 @@
1
+ @startsalt
2
+ {+
3
+ {* {{REQ_ID}} {{REQ_NAME}} 介面草稿 }
4
+ --
5
+ {
6
+ 輸入欄位: | "預設內容"
7
+ 選項: | (X) 單選項目 A | ( ) 單選項目 B
8
+ 核取方塊: | [] 核取項目 1 | [] 核取項目 2
9
+ }
10
+ --
11
+ [ 確認送出 ] | [ 取消 ]
12
+ }
13
+ @endsalt
@@ -724,6 +724,12 @@ git push origin master
724
724
 
725
725
  ## 更新紀錄
726
726
 
727
+ ### v0.2.5
728
+ - **支援前端 UI 線框圖(PlantUML Salt Code-as-Wireframe)**:
729
+ - **純文字代碼化線框圖**:在 `uml/` 目錄新增標準 `uml/wireframe.puml`,使用 PlantUML Salt 語法(`@startsalt ... @endsalt`)以純文字定義頁面排版、輸入欄位、選項與按鈕,可直接在 VS Code 渲染預覽,並可納入 Git 版本追蹤。
730
+ - **AI 開發交接前後閉環**:`srs.md` 與 `handoff.md` 新增「UI / 畫面規格」區塊,前端需求直接引用 `uml/wireframe.puml`,供 OpenSpec / Claude Code 精準產出前端元件;純後端需求則標示「無 UI 介面需求」。
731
+ - **版本升級(`sa-spec upgrade`)既有需求防護**:升級時主動掃描既有需求,若偵測到前端介面描述且缺少 wireframe 則發出補齊提示;已標記無 UI 之純後端需求則略過,不盲目覆蓋既有規格。
732
+
727
733
  ### v0.2.4
728
734
  - **序號重複主動告警與重新定號自癒支援**:
729
735
  - **唯一性主動檢驗**:`sa-spec check` 與 `sa-spec reindex` 加入重複序號檢測,遇到衝突時即時發出 WARNING 告警並列出衝突目錄與修復建議。
@@ -20,6 +20,7 @@
20
20
  - Sequence Diagram:用於描述角色、系統、服務或 API 之間的互動順序。
21
21
  - Class Diagram:用於描述主要資料物件、屬性與關聯。
22
22
  - State Diagram:用於描述有明確生命週期的物件狀態。
23
+ - Wireframe / Mockup (PlantUML Salt):用於描述前端介面佈局、表單欄位、按鈕與操作畫面,獨立存放於 `uml/wireframe.puml`(使用 `@startsalt` 與 `@endsalt`)。若需求涉及前端 UI 或使用者操作畫面時按需產出;純後端需求則在 `handoff.md` 標示「無 UI 介面需求」。
23
24
 
24
25
  ## 圖表說明
25
26
  每張 UML 圖旁邊或同一文件內需補充:
@@ -51,7 +51,7 @@ description: 用 init、propose、analyze、commit 四段流程整理需求,
51
51
  - `spec:commit` 只有在使用者明確要求推送 remote,或專案設定啟用 auto-push 時,才可執行 `git push`;push 失敗時只回報認證或網路問題,不得回滾已完成的文件歸檔與本機 commit。
52
52
  - 多人協作與 Git-Flow 模式(延遲綁定序號與自動合併):支援多人平行開發。執行 `spec:propose`(或 `scp`)時,若目前處於 master/main 分支,AI 必須自動依需求名稱建立並切換至專屬 feature branch(如 `feat/<name>`),並在 `project/<name>/` 建立草稿目錄,內部使用 `{{REQ_ID}}` 佔位,無需使用者手動敲 CLI;執行 `spec:analyze` 前應先確保取得 master 最新規格以防漏檢衝突;執行 `spec:commit` 歸檔時自動向 master 確認最新可用序號定號,自動將目錄定名為正式 `REQ-xxx`、替換內部佔位符、完成提交並自動合併回 master,避免多人合併時的序號競爭與索引衝突。
53
53
  - 文件未經使用者確認,不得標示為 `已審核`。
54
- - `uml/` 內的 UML 圖不限單一 UML 圖型;`spec:analyze` 必須依需求選擇最能說明流程、互動、狀態或資料關係的 UML 圖,例如活動圖、循序圖、使用案例圖、狀態圖或類別圖,不可為了固定格式硬產生活動圖。**嚴禁將多張圖混在同一個檔案中**,必須在需求資料夾下的 `uml/` 目錄拆分成獨立的 `.puml` 檔案(例如 `uml/main.puml`、`uml/sequence.puml`、`uml/state.puml`),且每個檔案只能包含一組 `@startuml` 與 `@enduml`,以避免 PlantUML 渲染或預覽失敗。
54
+ - `uml/` 內的 UML 圖不限單一 UML 圖型;`spec:analyze` 必須依需求選擇最能說明流程、互動、狀態、資料關係或介面佈局的圖表,例如活動圖、循序圖、使用案例圖、狀態圖、類別圖;**若需求涉及前端 UI 或使用者操作畫面,必須在 `uml/wireframe.puml` 產出線框圖(使用 PlantUML Salt 語法:`@startsalt ... @endsalt`)**;純後端需求則在 `handoff.md` 明確標記「無 UI 介面需求」。**嚴禁將多張圖混在同一個檔案中**,必須在需求資料夾下的 `uml/` 目錄拆分成獨立的 `.puml` 檔案(例如 `uml/main.puml`、`uml/sequence.puml`、`uml/wireframe.puml`),且每個檔案只能包含一組 `@start...` 與 `@end...`,以避免 PlantUML 渲染或預覽失敗。
55
55
  - 一次最多問 3 個待確認問題,優先詢問會影響範圍、資料、權限、API、DB 或驗收的問題。
56
56
 
57
57
  ## analyze 衝突檢查