@loviusc/sa-spec 0.2.0 → 0.2.1
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/package.json +1 -1
- package/readme.md +34 -2
- package/src/cli.js +57 -7
- package/templates/AGENTS.md +6 -1
- package/templates/project/system-spec.md +1 -0
- package/templates/readme.md +34 -2
- package/templates/skills/system-analysis/SKILL.md +6 -1
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -235,8 +235,7 @@ sa-spec init --full
|
|
|
235
235
|
|
|
236
236
|
| 指令 | 用途 |
|
|
237
237
|
|---|---|
|
|
238
|
-
| `sa-spec init` |
|
|
239
|
-
| `sa-spec init --full` | 建立文件骨架與完整規則文件。 |
|
|
238
|
+
| `sa-spec init [--full] [--lang zh-TW|en|zh-CN|ja|ko]` | 建立文件骨架與規則文件(支援 5 種語言,預設 `zh-TW`)。 |
|
|
240
239
|
| `sa-spec new [--id REQ-001] --name login [--branch]` | 建立需求資料夾與空白文件模板(未帶 `--id` 時啟用多人草稿模式,可選 `--branch` 自動建立並切換至 `feat/<name>` 分支)。 |
|
|
241
240
|
| `sa-spec finalize --name login` | 將草稿需求定號歸檔為最新序號(自動計算最新號碼、重命名目錄、批次置換 `{{REQ_ID}}` 並重建索引)。 |
|
|
242
241
|
| `sa-spec reindex` | 掃描 `project/REQ-*` 目錄,依序號重新生成乾淨無衝突的 `project/index.md`。 |
|
|
@@ -409,6 +408,31 @@ sa-spec reindex
|
|
|
409
408
|
```
|
|
410
409
|
* 任何時候若有 PR 合併產生 index 衝突,只要執行 `sa-spec reindex`,即可依序號重新排序生成乾淨的總表,無需人工手動解 conflict。
|
|
411
410
|
|
|
411
|
+
## 語言與國際化支援(i18n)
|
|
412
|
+
|
|
413
|
+
`sa-spec` 支援 5 種主要語言的系統分析規格產出與規範手冊:
|
|
414
|
+
|
|
415
|
+
| 語系代碼 | 語言名稱 | 內文與風格規範 | 專有名詞處理準則 |
|
|
416
|
+
|---|---|---|---|
|
|
417
|
+
| `zh-TW` | **繁體中文**(預設) | 台灣技術常用語(如:伺服器、支援、專案) | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
418
|
+
| `en` | **English** | 100% 標準技術英文,不可出現中/日/韓文字符 | 原生技術英文 |
|
|
419
|
+
| `zh-CN` | **简体中文** | 大陸技術常用語(如:服务器、支持、项目) | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
420
|
+
| `ja` | **日本語** | 日語技術文體(です/ます 或 である),外來詞尊重 Katakana 慣例 | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
421
|
+
| `ko` | **한국어** | 韓語專業技術文體與規範敬語 | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
422
|
+
|
|
423
|
+
### 語言管理核心原則
|
|
424
|
+
|
|
425
|
+
1. **初始化強制鎖定(Init-Time Lock)**:
|
|
426
|
+
* 語言由初始化階段決定,不可模稜兩可。
|
|
427
|
+
* **CLI 指令**:可直接指定語系參數,例如 `sa-spec init --lang en`。
|
|
428
|
+
* **AI 工作流**:在對話中輸入 `spec:init`(或 `sci`)時,若未指定語言,**AI 必須主動列出 5 種語言選單詢問使用者**,選定後寫入 `project/system-spec.md` 作為全專案唯一的真理之源(Single Source of Truth)。
|
|
429
|
+
2. **全專案語言單一純粹(Single-Language Purity)**:
|
|
430
|
+
* 選定語言後,全專案的所有產出(`srs.md`、`openapi.yaml`、`db-schema.md`、`handoff.md`、`history.md` 與 `rules/`)必須 100% 統一使用該語言,禁止在同一專案內出現語言混雜。
|
|
431
|
+
3. **專有名詞保留原生英文(Technical Terms Exception)**:
|
|
432
|
+
* 在非英語系模式(繁中、簡中、日文、韓文)下,業界公認標準之技術術語、協定、資料格式與元件名稱(例如:`REST API`、`Webhook`、`JWT`、`OAuth 2.0`、`Payload`、`Idempotency Key`、`Redis`、`UUID` 等),**一律強制維持原生英文**,嚴禁生硬直譯。
|
|
433
|
+
4. **升級保護(Upgrade Inheritance)**:
|
|
434
|
+
* 執行 `sa-spec upgrade` 時,系統會**自動偵測並繼承現有專案語言**(讀取 `project/system-spec.md`),不會詢問或變更既有專案語言,確保升級零干擾。
|
|
435
|
+
|
|
412
436
|
## 完整範例:番茄時鐘
|
|
413
437
|
|
|
414
438
|
以下示範從空資料夾開始,建立一個「番茄時鐘」需求。
|
|
@@ -657,6 +681,14 @@ git push origin master
|
|
|
657
681
|
|
|
658
682
|
## 更新紀錄
|
|
659
683
|
|
|
684
|
+
### v0.2.1
|
|
685
|
+
- **5 國語言與國際化支援(i18n)**:
|
|
686
|
+
- **支援語系**:繁體中文 (`zh-TW`,台灣常用語)、英文 (`en`)、簡體中文 (`zh-CN`)、日文 (`ja`)、韓文 (`ko`)。
|
|
687
|
+
- **初始化強制鎖定**:`sa-spec init [--lang <lang>]` 或在 AI 對話中輸入 `spec:init`,未指定時主動彈出選單詢問使用者選擇,選定後寫入 `system-spec.md`。
|
|
688
|
+
- **專案語言單一純粹**:全專案規格產出 100% 統一該語言。
|
|
689
|
+
- **技術專有名詞保留原生英文**:非英語系模式下強制保留標準英文術語(如 REST API, Webhook, JWT),嚴禁生硬直譯。
|
|
690
|
+
- **升級保護**:`sa-spec upgrade` 自動偵測並繼承現有專案語言,不變更設定。
|
|
691
|
+
|
|
660
692
|
### v0.2.0
|
|
661
693
|
- **多人協作 Git-Flow 解決方案(延遲綁定序號與零衝突索引)**:
|
|
662
694
|
- **解決痛點**:多人平行開發時,傳統流水號(`REQ-001`)容易在各自分支撞車,且中心化的 `project/index.md` 容易造成 Git merge conflict。
|
package/src/cli.js
CHANGED
|
@@ -54,29 +54,54 @@ function main() {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
const SUPPORTED_LANGS = {
|
|
58
|
+
"zh-tw": { code: "zh-TW", name: "繁體中文", label: "繁體中文 (zh-TW)" },
|
|
59
|
+
"en": { code: "en", name: "English", label: "English (en)" },
|
|
60
|
+
"zh-cn": { code: "zh-CN", name: "简体中文", label: "简体中文 (zh-CN)" },
|
|
61
|
+
"ja": { code: "ja", name: "日本語", label: "日本語 (ja)" },
|
|
62
|
+
"ko": { code: "ko", name: "한국어", label: "한국어 (ko)" }
|
|
63
|
+
};
|
|
64
|
+
|
|
57
65
|
function initProject(args = []) {
|
|
58
66
|
const includeRules = args.includes("--full");
|
|
67
|
+
const langArg = getOption(args, "--lang");
|
|
68
|
+
let langConfig = SUPPORTED_LANGS["zh-tw"];
|
|
69
|
+
if (langArg) {
|
|
70
|
+
const key = langArg.toLowerCase();
|
|
71
|
+
if (SUPPORTED_LANGS[key]) {
|
|
72
|
+
langConfig = SUPPORTED_LANGS[key];
|
|
73
|
+
} else {
|
|
74
|
+
console.log(`警告: 不支援的語言代碼 "${langArg}",支援語系: zh-TW, en, zh-CN, ja, ko。已預設使用繁體中文。`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const replacements = {
|
|
79
|
+
LANG_LABEL: langConfig.label,
|
|
80
|
+
LANG_CODE: langConfig.code
|
|
81
|
+
};
|
|
82
|
+
|
|
59
83
|
const results = [
|
|
60
84
|
ensureGitRepository(),
|
|
61
85
|
ensureDir("skills"),
|
|
62
86
|
ensureDir(path.join("skills", "system-analysis")),
|
|
63
87
|
ensureDir("project"),
|
|
64
|
-
ensureFileFromTemplate("AGENTS.md", "AGENTS.md"),
|
|
65
|
-
ensureFileFromTemplate("readme.md", "readme.md"),
|
|
66
|
-
ensureFileFromTemplate(path.join("skills", "system-analysis", "SKILL.md"), path.join("skills", "system-analysis", "SKILL.md")),
|
|
67
|
-
ensureFileFromTemplate(path.join("project", "index.md"), path.join("project", "index.md")),
|
|
68
|
-
ensureFileFromTemplate(path.join("project", "system-spec.md"), path.join("project", "system-spec.md"))
|
|
88
|
+
ensureFileFromTemplate("AGENTS.md", "AGENTS.md", replacements),
|
|
89
|
+
ensureFileFromTemplate("readme.md", "readme.md", replacements),
|
|
90
|
+
ensureFileFromTemplate(path.join("skills", "system-analysis", "SKILL.md"), path.join("skills", "system-analysis", "SKILL.md"), replacements),
|
|
91
|
+
ensureFileFromTemplate(path.join("project", "index.md"), path.join("project", "index.md"), replacements),
|
|
92
|
+
ensureFileFromTemplate(path.join("project", "system-spec.md"), path.join("project", "system-spec.md"), replacements)
|
|
69
93
|
];
|
|
70
94
|
|
|
71
95
|
if (includeRules) {
|
|
72
96
|
results.push(ensureDir("rules"));
|
|
73
97
|
for (const file of listFilesRecursive(path.join(templatesDir, "rules"))) {
|
|
74
98
|
const relativePath = path.relative(templatesDir, file);
|
|
75
|
-
results.push(ensureFileFromTemplate(relativePath, relativePath));
|
|
99
|
+
results.push(ensureFileFromTemplate(relativePath, relativePath, replacements));
|
|
76
100
|
}
|
|
77
101
|
}
|
|
78
102
|
|
|
79
103
|
printResultList("init", results);
|
|
104
|
+
console.log(`專案規格主要語言已設定為: ${langConfig.label}`);
|
|
80
105
|
}
|
|
81
106
|
|
|
82
107
|
function ensureGitRepository() {
|
|
@@ -549,8 +574,33 @@ function slugify(value) {
|
|
|
549
574
|
.replace(/^-+|-+$/g, "");
|
|
550
575
|
}
|
|
551
576
|
|
|
577
|
+
function detectProjectLanguage() {
|
|
578
|
+
const systemSpecPath = path.join(cwd, "project", "system-spec.md");
|
|
579
|
+
if (fs.existsSync(systemSpecPath)) {
|
|
580
|
+
const content = fs.readFileSync(systemSpecPath, "utf8");
|
|
581
|
+
const match = content.match(/^-\s*(?:主要語言|語言|Language)[::]\s*(.+)$/im);
|
|
582
|
+
if (match) {
|
|
583
|
+
const val = match[1].trim();
|
|
584
|
+
for (const key of Object.keys(SUPPORTED_LANGS)) {
|
|
585
|
+
if (
|
|
586
|
+
val.toLowerCase().includes(key) ||
|
|
587
|
+
val.includes(SUPPORTED_LANGS[key].label) ||
|
|
588
|
+
val.includes(SUPPORTED_LANGS[key].name) ||
|
|
589
|
+
val.includes(SUPPORTED_LANGS[key].code)
|
|
590
|
+
) {
|
|
591
|
+
return SUPPORTED_LANGS[key];
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return { code: "custom", label: val };
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return SUPPORTED_LANGS["zh-tw"];
|
|
598
|
+
}
|
|
599
|
+
|
|
552
600
|
function upgradeProject(args = []) {
|
|
553
601
|
const dryRun = args.includes("--dry-run");
|
|
602
|
+
const langConfig = detectProjectLanguage();
|
|
603
|
+
console.log(`專案目前語言: ${langConfig.label}(依現有語言升級,不變更設定)`);
|
|
554
604
|
const results = [];
|
|
555
605
|
|
|
556
606
|
results.push(ensureDir("skills"));
|
|
@@ -684,7 +734,7 @@ function showHelp() {
|
|
|
684
734
|
console.log(`sa-spec
|
|
685
735
|
|
|
686
736
|
Usage:
|
|
687
|
-
sa-spec init [--full]
|
|
737
|
+
sa-spec init [--full] [--lang zh-TW|en|zh-CN|ja|ko]
|
|
688
738
|
sa-spec new [--id REQ-001] --name login [--branch]
|
|
689
739
|
sa-spec finalize --name login
|
|
690
740
|
sa-spec reindex
|
package/templates/AGENTS.md
CHANGED
|
@@ -26,7 +26,12 @@
|
|
|
26
26
|
|
|
27
27
|
# 重要限制
|
|
28
28
|
|
|
29
|
-
-
|
|
29
|
+
- 語言與國際化規範(i18n):
|
|
30
|
+
- 支援語系:繁體中文 (`zh-TW`,台灣常用語)、英文 (`en`)、簡體中文 (`zh-CN`)、日文 (`ja`)、韓文 (`ko`) 共 5 種語言。
|
|
31
|
+
- 初始化語言鎖定:執行 `spec:init` (或 `sci`) 時,若使用者未明確指定語言,AI 必須主動詢問使用者選擇上述 5 種語言之一,不得自行預設;選定後將主要語言寫入 `project/system-spec.md`。
|
|
32
|
+
- 全專案語言單一純粹:後續所有需求文件(`srs.md`、`uml/`、`openapi.yaml`、`db-schema.md`、`handoff.md`、`history.md`)必須 100% 統一使用該語言,不得在同一專案內混雜多種語言。
|
|
33
|
+
- 專有名詞保留原生英文:在中文、日文、韓文等非英語系模式下,業界公認標準之技術術語(如 REST API, Webhook, JWT, OAuth 2.0, Payload, Idempotency, Redis 等)強制保留原生英文,嚴禁生硬直譯。
|
|
34
|
+
- 升級保護:執行 `sa-spec upgrade` 時,自動偵測並繼承現有專案語言,不變更語言設定。
|
|
30
35
|
- `spec:init` 必須檢查 Git 狀態:若 Git 未安裝,提醒使用者後續歸檔會使用版本管理但不可中斷初始化;若 Git 已安裝且目前目錄尚未初始化為 Git repository,則自動執行 `git init`;若已是 Git repository,僅回報狀態,不重複初始化。
|
|
31
36
|
- `project/system-spec.md` 由 `sa-spec init` 建立;`spec:analyze` 只能讀取它做衝突檢查,並提出待確認的系統規格更新建議,不得寫入;`spec:commit` 才能依使用者確認後的內容更新 `project/system-spec.md`。
|
|
32
37
|
- 不可自行幻想未確認的業務規則、角色、流程、資料或系統行為。
|
package/templates/readme.md
CHANGED
|
@@ -235,8 +235,7 @@ sa-spec init --full
|
|
|
235
235
|
|
|
236
236
|
| 指令 | 用途 |
|
|
237
237
|
|---|---|
|
|
238
|
-
| `sa-spec init` |
|
|
239
|
-
| `sa-spec init --full` | 建立文件骨架與完整規則文件。 |
|
|
238
|
+
| `sa-spec init [--full] [--lang zh-TW|en|zh-CN|ja|ko]` | 建立文件骨架與規則文件(支援 5 種語言,預設 `zh-TW`)。 |
|
|
240
239
|
| `sa-spec new [--id REQ-001] --name login [--branch]` | 建立需求資料夾與空白文件模板(未帶 `--id` 時啟用多人草稿模式,可選 `--branch` 自動建立並切換至 `feat/<name>` 分支)。 |
|
|
241
240
|
| `sa-spec finalize --name login` | 將草稿需求定號歸檔為最新序號(自動計算最新號碼、重命名目錄、批次置換 `{{REQ_ID}}` 並重建索引)。 |
|
|
242
241
|
| `sa-spec reindex` | 掃描 `project/REQ-*` 目錄,依序號重新生成乾淨無衝突的 `project/index.md`。 |
|
|
@@ -409,6 +408,31 @@ sa-spec reindex
|
|
|
409
408
|
```
|
|
410
409
|
* 任何時候若有 PR 合併產生 index 衝突,只要執行 `sa-spec reindex`,即可依序號重新排序生成乾淨的總表,無需人工手動解 conflict。
|
|
411
410
|
|
|
411
|
+
## 語言與國際化支援(i18n)
|
|
412
|
+
|
|
413
|
+
`sa-spec` 支援 5 種主要語言的系統分析規格產出與規範手冊:
|
|
414
|
+
|
|
415
|
+
| 語系代碼 | 語言名稱 | 內文與風格規範 | 專有名詞處理準則 |
|
|
416
|
+
|---|---|---|---|
|
|
417
|
+
| `zh-TW` | **繁體中文**(預設) | 台灣技術常用語(如:伺服器、支援、專案) | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
418
|
+
| `en` | **English** | 100% 標準技術英文,不可出現中/日/韓文字符 | 原生技術英文 |
|
|
419
|
+
| `zh-CN` | **简体中文** | 大陸技術常用語(如:服务器、支持、项目) | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
420
|
+
| `ja` | **日本語** | 日語技術文體(です/ます 或 である),外來詞尊重 Katakana 慣例 | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
421
|
+
| `ko` | **한국어** | 韓語專業技術文體與規範敬語 | 強制保留原生英文(如 `REST API`, `Webhook`, `JWT`) |
|
|
422
|
+
|
|
423
|
+
### 語言管理核心原則
|
|
424
|
+
|
|
425
|
+
1. **初始化強制鎖定(Init-Time Lock)**:
|
|
426
|
+
* 語言由初始化階段決定,不可模稜兩可。
|
|
427
|
+
* **CLI 指令**:可直接指定語系參數,例如 `sa-spec init --lang en`。
|
|
428
|
+
* **AI 工作流**:在對話中輸入 `spec:init`(或 `sci`)時,若未指定語言,**AI 必須主動列出 5 種語言選單詢問使用者**,選定後寫入 `project/system-spec.md` 作為全專案唯一的真理之源(Single Source of Truth)。
|
|
429
|
+
2. **全專案語言單一純粹(Single-Language Purity)**:
|
|
430
|
+
* 選定語言後,全專案的所有產出(`srs.md`、`openapi.yaml`、`db-schema.md`、`handoff.md`、`history.md` 與 `rules/`)必須 100% 統一使用該語言,禁止在同一專案內出現語言混雜。
|
|
431
|
+
3. **專有名詞保留原生英文(Technical Terms Exception)**:
|
|
432
|
+
* 在非英語系模式(繁中、簡中、日文、韓文)下,業界公認標準之技術術語、協定、資料格式與元件名稱(例如:`REST API`、`Webhook`、`JWT`、`OAuth 2.0`、`Payload`、`Idempotency Key`、`Redis`、`UUID` 等),**一律強制維持原生英文**,嚴禁生硬直譯。
|
|
433
|
+
4. **升級保護(Upgrade Inheritance)**:
|
|
434
|
+
* 執行 `sa-spec upgrade` 時,系統會**自動偵測並繼承現有專案語言**(讀取 `project/system-spec.md`),不會詢問或變更既有專案語言,確保升級零干擾。
|
|
435
|
+
|
|
412
436
|
## 完整範例:番茄時鐘
|
|
413
437
|
|
|
414
438
|
以下示範從空資料夾開始,建立一個「番茄時鐘」需求。
|
|
@@ -657,6 +681,14 @@ git push origin master
|
|
|
657
681
|
|
|
658
682
|
## 更新紀錄
|
|
659
683
|
|
|
684
|
+
### v0.2.1
|
|
685
|
+
- **5 國語言與國際化支援(i18n)**:
|
|
686
|
+
- **支援語系**:繁體中文 (`zh-TW`,台灣常用語)、英文 (`en`)、簡體中文 (`zh-CN`)、日文 (`ja`)、韓文 (`ko`)。
|
|
687
|
+
- **初始化強制鎖定**:`sa-spec init [--lang <lang>]` 或在 AI 對話中輸入 `spec:init`,未指定時主動彈出選單詢問使用者選擇,選定後寫入 `system-spec.md`。
|
|
688
|
+
- **專案語言單一純粹**:全專案規格產出 100% 統一該語言。
|
|
689
|
+
- **技術專有名詞保留原生英文**:非英語系模式下強制保留標準英文術語(如 REST API, Webhook, JWT),嚴禁生硬直譯。
|
|
690
|
+
- **升級保護**:`sa-spec upgrade` 自動偵測並繼承現有專案語言,不變更設定。
|
|
691
|
+
|
|
660
692
|
### v0.2.0
|
|
661
693
|
- **多人協作 Git-Flow 解決方案(延遲綁定序號與零衝突索引)**:
|
|
662
694
|
- **解決痛點**:多人平行開發時,傳統流水號(`REQ-001`)容易在各自分支撞車,且中心化的 `project/index.md` 容易造成 Git merge conflict。
|
|
@@ -27,7 +27,12 @@ description: 用 init、propose、analyze、commit 四段流程整理需求,
|
|
|
27
27
|
|
|
28
28
|
## 硬性限制
|
|
29
29
|
|
|
30
|
-
-
|
|
30
|
+
- 語言與國際化規範(i18n):
|
|
31
|
+
- 支援語系:繁體中文 (`zh-TW`,台灣常用語)、英文 (`en`)、簡體中文 (`zh-CN`)、日文 (`ja`)、韓文 (`ko`) 共 5 種語言。
|
|
32
|
+
- 初始化語言鎖定:執行 `spec:init` (或 `sci`) 時,若使用者未明確指定語言,AI 必須主動詢問使用者選擇上述 5 種語言之一,不得自行預設;選定後將主要語言寫入 `project/system-spec.md`。
|
|
33
|
+
- 全專案語言單一純粹:後續所有需求文件(`srs.md`、`uml/`、`openapi.yaml`、`db-schema.md`、`handoff.md`、`history.md`)必須 100% 統一使用該語言,不得在同一專案內混雜多種語言。
|
|
34
|
+
- 專有名詞保留原生英文:在中文、日文、韓文等非英語系模式下,業界公認標準之技術術語(如 REST API, Webhook, JWT, OAuth 2.0, Payload, Idempotency, Redis 等)強制保留原生英文,嚴禁生硬直譯。
|
|
35
|
+
- 升級保護:執行 `sa-spec upgrade` 時,自動偵測並繼承現有專案語言,不變更語言設定。
|
|
31
36
|
- `spec:init` 必須檢查 Git 狀態:
|
|
32
37
|
- 若 Git 未安裝,提醒使用者後續歸檔會使用版本管理,但不可中斷初始化。
|
|
33
38
|
- 若 Git 已安裝且目前目錄尚未初始化為 Git repository,則自動執行 `git init`。
|