universal-dev-standards 5.1.0-beta.6 → 5.1.0
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.md +6 -0
- package/bin/uds.js +14 -0
- package/bundled/ai/standards/agent-communication-protocol.ai.yaml +34 -0
- package/bundled/ai/standards/anti-sycophancy-prompting.ai.yaml +111 -0
- package/bundled/ai/standards/capability-declaration.ai.yaml +113 -0
- package/bundled/ai/standards/circuit-breaker.ai.yaml +93 -0
- package/bundled/ai/standards/developer-memory.ai.yaml +13 -0
- package/bundled/ai/standards/dual-phase-output.ai.yaml +108 -0
- package/bundled/ai/standards/failure-source-taxonomy.ai.yaml +115 -0
- package/bundled/ai/standards/frontend-design-standards.ai.yaml +305 -0
- package/bundled/ai/standards/health-check-standards.ai.yaml +140 -0
- package/bundled/ai/standards/immutability-first.ai.yaml +112 -0
- package/bundled/ai/standards/model-selection.ai.yaml +111 -3
- package/bundled/ai/standards/packaging-standards.ai.yaml +142 -0
- package/bundled/ai/standards/recovery-recipe-registry.ai.yaml +200 -0
- package/bundled/ai/standards/retry-standards.ai.yaml +134 -0
- package/bundled/ai/standards/security-decision.ai.yaml +87 -0
- package/bundled/ai/standards/skill-standard-alignment-check.ai.yaml +119 -0
- package/bundled/ai/standards/standard-admission-criteria.ai.yaml +107 -0
- package/bundled/ai/standards/standard-lifecycle-management.ai.yaml +144 -0
- package/bundled/ai/standards/timeout-standards.ai.yaml +104 -0
- package/bundled/ai/standards/token-budget.ai.yaml +108 -0
- package/bundled/ai/standards/translation-lifecycle-standards.ai.yaml +145 -0
- package/bundled/core/anti-sycophancy-prompting.md +184 -0
- package/bundled/core/capability-declaration.md +59 -0
- package/bundled/core/circuit-breaker.md +58 -0
- package/bundled/core/developer-memory.md +29 -1
- package/bundled/core/dual-phase-output.md +56 -0
- package/bundled/core/failure-source-taxonomy.md +72 -0
- package/bundled/core/frontend-design-standards.md +474 -0
- package/bundled/core/health-check-standards.md +72 -0
- package/bundled/core/immutability-first.md +105 -0
- package/bundled/core/model-selection.md +80 -0
- package/bundled/core/packaging-standards.md +216 -0
- package/bundled/core/recovery-recipe-registry.md +69 -0
- package/bundled/core/retry-standards.md +62 -0
- package/bundled/core/security-decision.md +65 -0
- package/bundled/core/skill-standard-alignment-check.md +79 -0
- package/bundled/core/standard-admission-criteria.md +84 -0
- package/bundled/core/standard-lifecycle-management.md +94 -0
- package/bundled/core/timeout-standards.md +63 -0
- package/bundled/core/token-budget.md +58 -0
- package/bundled/core/translation-lifecycle-standards.md +162 -0
- package/bundled/locales/zh-CN/CHANGELOG.md +51 -3
- package/bundled/locales/zh-CN/README.md +1 -1
- package/bundled/locales/zh-CN/core/anti-hallucination.md +22 -3
- package/bundled/locales/zh-CN/core/anti-sycophancy-prompting.md +192 -0
- package/bundled/locales/zh-CN/core/capability-declaration.md +123 -0
- package/bundled/locales/zh-CN/core/circuit-breaker.md +106 -0
- package/bundled/locales/zh-CN/core/dual-phase-output.md +103 -0
- package/bundled/locales/zh-CN/core/failure-source-taxonomy.md +99 -0
- package/bundled/locales/zh-CN/core/frontend-design-standards.md +289 -0
- package/bundled/locales/zh-CN/core/health-check-standards.md +144 -0
- package/bundled/locales/zh-CN/core/immutability-first.md +96 -0
- package/bundled/locales/zh-CN/core/packaging-standards.md +224 -0
- package/bundled/locales/zh-CN/core/recovery-recipe-registry.md +146 -0
- package/bundled/locales/zh-CN/core/retry-standards.md +131 -0
- package/bundled/locales/zh-CN/core/security-decision.md +104 -0
- package/bundled/locales/zh-CN/core/skill-standard-alignment-check.md +112 -0
- package/bundled/locales/zh-CN/core/standard-admission-criteria.md +104 -0
- package/bundled/locales/zh-CN/core/standard-lifecycle-management.md +116 -0
- package/bundled/locales/zh-CN/core/timeout-standards.md +117 -0
- package/bundled/locales/zh-CN/core/token-budget.md +108 -0
- package/bundled/locales/zh-CN/core/translation-lifecycle-standards.md +159 -0
- package/bundled/locales/zh-TW/CHANGELOG.md +51 -3
- package/bundled/locales/zh-TW/README.md +1 -1
- package/bundled/locales/zh-TW/core/anti-sycophancy-prompting.md +192 -0
- package/bundled/locales/zh-TW/core/capability-declaration.md +111 -0
- package/bundled/locales/zh-TW/core/circuit-breaker.md +111 -0
- package/bundled/locales/zh-TW/core/dual-phase-output.md +132 -0
- package/bundled/locales/zh-TW/core/failure-source-taxonomy.md +146 -0
- package/bundled/locales/zh-TW/core/frontend-design-standards.md +460 -0
- package/bundled/locales/zh-TW/core/health-check-standards.md +144 -0
- package/bundled/locales/zh-TW/core/immutability-first.md +159 -0
- package/bundled/locales/zh-TW/core/packaging-standards.md +224 -0
- package/bundled/locales/zh-TW/core/recovery-recipe-registry.md +146 -0
- package/bundled/locales/zh-TW/core/retry-standards.md +140 -0
- package/bundled/locales/zh-TW/core/security-decision.md +120 -0
- package/bundled/locales/zh-TW/core/skill-standard-alignment-check.md +112 -0
- package/bundled/locales/zh-TW/core/standard-admission-criteria.md +104 -0
- package/bundled/locales/zh-TW/core/standard-lifecycle-management.md +116 -0
- package/bundled/locales/zh-TW/core/timeout-standards.md +117 -0
- package/bundled/locales/zh-TW/core/token-budget.md +143 -0
- package/bundled/locales/zh-TW/core/translation-lifecycle-standards.md +159 -0
- package/bundled/skills/e2e-assistant/SKILL.md +19 -5
- package/bundled/skills/testing-guide/SKILL.md +5 -0
- package/bundled/skills/testing-guide/test-skeleton-templates.md +316 -0
- package/package.json +2 -1
- package/src/commands/check.js +6 -0
- package/src/commands/config.js +9 -0
- package/src/commands/init.js +97 -46
- package/src/commands/mcp.js +26 -0
- package/src/commands/run-intent.js +66 -0
- package/src/commands/update.js +41 -4
- package/src/core/command-router.js +85 -0
- package/src/core/project-config.js +91 -0
- package/src/flows/init-flow.js +6 -1
- package/src/i18n/messages.js +6 -6
- package/src/mcp/__tests__/server.test.js +251 -0
- package/src/mcp/server.js +352 -0
- package/src/prompts/init.js +157 -1
- package/src/reconciler/actual-state-scanner.js +24 -0
- package/src/uninstallers/hook-uninstaller.js +32 -1
- package/src/utils/detect-self-adoption.js +173 -0
- package/src/utils/e2e-analyzer.js +88 -5
- package/src/utils/e2e-detector.js +73 -1
- package/src/utils/integration-generator.js +22 -3
- package/standards-registry.json +203 -4
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
source: ../../../core/token-budget.md
|
|
3
|
+
source_version: 1.0.0
|
|
4
|
+
translation_version: 1.0.0
|
|
5
|
+
last_synced: 2026-04-20
|
|
6
|
+
status: current
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Token 預算區間標準
|
|
10
|
+
|
|
11
|
+
> **語言**: [English](../../../core/token-budget.md) | 繁體中文
|
|
12
|
+
|
|
13
|
+
**版本**: 1.0.0
|
|
14
|
+
**最後更新**: 2026-04-15
|
|
15
|
+
**適用範圍**: 所有有 token 預算限制的 Agent 執行環境
|
|
16
|
+
**Scope**: universal
|
|
17
|
+
**來源**: XSPEC-036(claude-code-book Ch.7 four-zone threshold model)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 目的
|
|
22
|
+
|
|
23
|
+
Token 閾值四區模型:以使用率百分比劃分四個運作區間,漸進觸發不同強度的保護策略。
|
|
24
|
+
|
|
25
|
+
比「打到上限才停」更優雅,為使用者提供早期預警和自動降級機會。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 核心規範
|
|
30
|
+
|
|
31
|
+
- 所有有 token 預算限制的執行環境必須使用四區模型監控使用率
|
|
32
|
+
- WARNING 區必須記錄日誌並發出可觀測事件,不得靜默
|
|
33
|
+
- DANGER 區必須觸發輕量保護策略(如截斷工具結果、縮減輸出預算)
|
|
34
|
+
- BLOCKING 區必須拒絕新請求,回傳 `TOKEN_BUDGET_EXCEEDED` 而非讓請求超時崩潰
|
|
35
|
+
- 壓縮操作本身需保留足夠的輸出空間(否則壓縮本身也可能失敗)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 四區模型
|
|
40
|
+
|
|
41
|
+
| 區間 | 使用率範圍 | 行動 | 日誌等級 |
|
|
42
|
+
|------|----------|------|---------|
|
|
43
|
+
| **SAFE**(安全) | 0% – 84% | 正常執行 | — |
|
|
44
|
+
| **WARNING**(警告) | 85% – 89% | 發出 `TOKEN_BUDGET_WARNING` 事件,通知 Coordinator/使用者 | `info` |
|
|
45
|
+
| **DANGER**(危險) | 90% – 94% | 觸發輕量壓縮策略 | `warn` |
|
|
46
|
+
| **BLOCKING**(阻塞) | 95% – 100% | 拒絕新請求,回傳 `TOKEN_BUDGET_EXCEEDED` | `error` |
|
|
47
|
+
|
|
48
|
+
### WARNING 區可選行動
|
|
49
|
+
|
|
50
|
+
- 降低 `model_tier`(capable → standard)
|
|
51
|
+
- 提示使用者考慮分割任務
|
|
52
|
+
|
|
53
|
+
### DANGER 區必要行動
|
|
54
|
+
|
|
55
|
+
- 截斷超大工具結果(Tool Result Snip)
|
|
56
|
+
- 縮減後續 Agent 的 `maxToolRounds`(建議降低 20%)
|
|
57
|
+
|
|
58
|
+
### DANGER 區可選行動
|
|
59
|
+
|
|
60
|
+
- 將重要輸出持久化到磁碟,上下文只保留摘要
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 閾值常數
|
|
65
|
+
|
|
66
|
+
| 常數 | 值 |
|
|
67
|
+
|------|-----|
|
|
68
|
+
| `WARNING_THRESHOLD` | `0.85` |
|
|
69
|
+
| `DANGER_THRESHOLD` | `0.90` |
|
|
70
|
+
| `BLOCKING_THRESHOLD` | `0.95` |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 類型定義
|
|
75
|
+
|
|
76
|
+
### TokenBudgetZone
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
safe | warning | danger | blocking
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### TokenBudgetStatus
|
|
83
|
+
|
|
84
|
+
| 欄位 | 類型 |
|
|
85
|
+
|------|------|
|
|
86
|
+
| `current_tokens` | `number` |
|
|
87
|
+
| `max_tokens` | `number` |
|
|
88
|
+
| `usage_ratio` | `number` |
|
|
89
|
+
| `zone` | `TokenBudgetZone` |
|
|
90
|
+
|
|
91
|
+
### TokenBudgetExceededError
|
|
92
|
+
|
|
93
|
+
| 欄位 | 類型 |
|
|
94
|
+
|------|------|
|
|
95
|
+
| `code` | `"TOKEN_BUDGET_EXCEEDED"` |
|
|
96
|
+
| `current_tokens` | `number` |
|
|
97
|
+
| `max_tokens` | `number` |
|
|
98
|
+
| `usage_ratio` | `number` |
|
|
99
|
+
| `zone` | `"blocking"` |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 壓縮後預算常數參考
|
|
104
|
+
|
|
105
|
+
| 常數 | 值 |
|
|
106
|
+
|------|-----|
|
|
107
|
+
| `MAX_FILES_TO_RESTORE` | `5` |
|
|
108
|
+
| `TOTAL_TOKEN_BUDGET` | `50000` |
|
|
109
|
+
| `MAX_TOKENS_PER_FILE` | `5000` |
|
|
110
|
+
| `MAX_TOKENS_PER_SKILL` | `5000` |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 遙測事件
|
|
115
|
+
|
|
116
|
+
**`token_budget_zone_change`**
|
|
117
|
+
|
|
118
|
+
| 欄位 | 類型 |
|
|
119
|
+
|------|------|
|
|
120
|
+
| `from_zone` | `TokenBudgetZone` |
|
|
121
|
+
| `to_zone` | `TokenBudgetZone` |
|
|
122
|
+
| `usage_ratio` | `number` |
|
|
123
|
+
| `agent_name` | `string` |
|
|
124
|
+
| `timestamp` | `string` |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 適用場景
|
|
129
|
+
|
|
130
|
+
- DevAP 任務執行(Task token 預算監控)
|
|
131
|
+
- VibeOps 9-Agent Pipeline(跨 Agent 累積上下文監控)
|
|
132
|
+
- VibeOps PipelineMemory Snip 觸發條件
|
|
133
|
+
- 任何有 `maxTotalTokens` 限制的 Agent 執行環境
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 錯誤碼
|
|
138
|
+
|
|
139
|
+
| 代碼 | 說明 |
|
|
140
|
+
|------|------|
|
|
141
|
+
| `TB-001` | `TOKEN_BUDGET_EXCEEDED` — 已進入 BLOCKING 區,拒絕新請求 |
|
|
142
|
+
| `TB-002` | `TOKEN_BUDGET_WARNING` — 已進入 WARNING 區,建議採取行動 |
|
|
143
|
+
| `TB-003` | `SNIP_FAILED` — 輕量壓縮失敗,仍在 DANGER 區 |
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
source: ../../../core/translation-lifecycle-standards.md
|
|
3
|
+
source_version: 1.0.0
|
|
4
|
+
translation_version: 1.0.0
|
|
5
|
+
last_synced: 2026-04-20
|
|
6
|
+
status: current
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# 翻譯生命週期標準
|
|
10
|
+
|
|
11
|
+
> **語言**: [English](../../../core/translation-lifecycle-standards.md) | 繁體中文
|
|
12
|
+
|
|
13
|
+
**版本**: 1.0.0
|
|
14
|
+
**最後更新**: 2026-04-20
|
|
15
|
+
**狀態**: Trial(到期 2026-10-20)
|
|
16
|
+
**適用範圍**: 所有具備多語言文件的專案
|
|
17
|
+
**來源**: UDS BUG-A06 事後分析(2026-04-20)
|
|
18
|
+
**父標準**: [documentation-lifecycle](documentation-lifecycle.md)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 目的
|
|
23
|
+
|
|
24
|
+
翻譯生命週期標準:MISSING 與 OUTDATED 的區別、Semver 嚴重度分級,以及自動化整合(pre-commit hook、release gate)。
|
|
25
|
+
|
|
26
|
+
`documentation-lifecycle` 標準提到翻譯同步是 release gate 的一環,但未定義如何分類或回應不同程度的漂移。本標準填補這個缺口:翻譯檔案不存在與略微過時有本質差異,major 版本落差與 patch 升版也有本質差異。若不作區分,團隊要麼過度阻塞(任何過時都 fail),要麼阻塞不足(忽略所有過時直到成為用戶可見的問題)。
|
|
27
|
+
|
|
28
|
+
**證據(BUG-A06 事後分析)**:
|
|
29
|
+
1. UDS 在 3 個月內新增 32 個標準時,因缺乏 MISSING gate,翻譯全部缺失,直到 Q2 audit 才發現。
|
|
30
|
+
2. `anti-hallucination.md` zh-CN 停在 1.5.0,來源已升至 1.5.1——新的 Agent 認識論校準框架段落在 zh-CN 版本中完全缺失,使用者看不到。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 核心規範
|
|
35
|
+
|
|
36
|
+
- `MISSING`(翻譯檔案不存在)永遠是 release blocker — `exit 1`
|
|
37
|
+
- `MAJOR` 版本落差(來源 X > 翻譯 x,X > x)是 release blocker — `exit 1`
|
|
38
|
+
- `MINOR` 版本落差是 advisory — 醒目警告,不阻塞
|
|
39
|
+
- `PATCH` 版本落差是 advisory — 柔和警告,不阻塞
|
|
40
|
+
- 嚴重度由翻譯 frontmatter 的 `source_version` 與目前來源版本的 semver 比較決定
|
|
41
|
+
- 每個翻譯檔案必須有 YAML frontmatter,包含 `source`、`source_version`、`translation_version`、`last_synced`、`status`
|
|
42
|
+
- 來源標準被修改後,翻譯的 `source_version` 立即過時——這種漂移可在 commit 時透過 pre-commit hook 偵測
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 嚴重度分級
|
|
47
|
+
|
|
48
|
+
| 等級 | 條件 | Exit Code | 行動 |
|
|
49
|
+
|------|------|-----------|------|
|
|
50
|
+
| `MISSING` | 翻譯檔案不存在 | 1 | 發布前建立 |
|
|
51
|
+
| `MAJOR` | 來源 MAJOR > 翻譯 MAJOR | 1 | 正式版發布前更新 |
|
|
52
|
+
| `MINOR` | 來源 MINOR > 翻譯 MINOR(同 MAJOR)| 0 | 下次發布前更新(advisory)|
|
|
53
|
+
| `PATCH` | 來源 PATCH > 翻譯 PATCH(同 MAJOR.MINOR)| 0 | 方便時更新(advisory)|
|
|
54
|
+
| `CURRENT` | source_version == 目前來源版本 | 0 | 無需行動 |
|
|
55
|
+
|
|
56
|
+
### Semver 差異公式
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
diff_level = compare(
|
|
60
|
+
strip_prerelease(current_source_version),
|
|
61
|
+
strip_prerelease(translation.source_version)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
其中:major 不同 → MAJOR,minor 不同 → MINOR,其他 → PATCH
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 觸發條件
|
|
70
|
+
|
|
71
|
+
| 事件 | 必要行動 |
|
|
72
|
+
|------|---------|
|
|
73
|
+
| 新增標準到 `core/` | 在所有支援的語言建立翻譯(MISSING check 阻塞發布)|
|
|
74
|
+
| 標準 PATCH 升版 | 方便時更新翻譯的 `source_version` + `last_synced` |
|
|
75
|
+
| 標準 MINOR 升版(含新段落)| 更新翻譯內容 + frontmatter,下次發布前完成 |
|
|
76
|
+
| 標準 MAJOR 升版(大改寫)| 更新翻譯內容 + frontmatter,當前發布前完成(阻塞)|
|
|
77
|
+
| 手動更新翻譯 | 升版 `translation_version` + `last_synced` |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 翻譯 Frontmatter 協議
|
|
82
|
+
|
|
83
|
+
每個翻譯檔案必須以以下格式開頭:
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
---
|
|
87
|
+
source: ../../../core/<filename>.md # 指向來源的相對路徑
|
|
88
|
+
source_version: <X.Y.Z> # 最後同步時的來源版本
|
|
89
|
+
translation_version: <X.Y.Z> # 翻譯自身的版本
|
|
90
|
+
last_synced: <YYYY-MM-DD> # 最後同步日期
|
|
91
|
+
status: current | outdated | draft # 人類可讀狀態
|
|
92
|
+
---
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
更新翻譯時:
|
|
96
|
+
1. 翻譯新增或修改的內容
|
|
97
|
+
2. 設定 `source_version` = 新的來源版本
|
|
98
|
+
3. 設定 `translation_version` = 與 `source_version` 相同(或獨立升版)
|
|
99
|
+
4. 設定 `last_synced` = 今天日期
|
|
100
|
+
5. 設定 `status: current`
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 自動化整合
|
|
105
|
+
|
|
106
|
+
### Pre-Commit Hook
|
|
107
|
+
|
|
108
|
+
當 `core/*.md` 檔案被暫存時,pre-commit hook 執行 `check-translation-sync.sh` 並顯示 OUTDATED 警告。Hook **永不阻塞** commit(在 commit 時阻塞過於擾人)——純提醒用途。
|
|
109
|
+
|
|
110
|
+
設定方式:`./scripts/install-hooks.sh`(clone 後執行一次)
|
|
111
|
+
|
|
112
|
+
### Release Gate(`check-translation-sync.sh`)
|
|
113
|
+
|
|
114
|
+
在 `npm publish` 前或作為 `pre-release-check.sh` 的一部分執行:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
bash scripts/check-translation-sync.sh
|
|
118
|
+
# MISSING 或 MAJOR 落差 → exit 1
|
|
119
|
+
# 僅 MINOR/PATCH 落差 → exit 0(附 advisory 輸出)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Version Bump 整合(`bump-version.sh`)
|
|
123
|
+
|
|
124
|
+
`bump-version.sh` 在更新版本檔案後自動執行 `check-translation-sync.sh`,在升版時即時顯示翻譯健康狀態快照——讓作者立即知道發布前需要更新什麼。
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 情境範例
|
|
129
|
+
|
|
130
|
+
**情境 1 — 標準 patch 升版(1.0.0 → 1.0.1)**
|
|
131
|
+
- 翻譯 `source_version: 1.0.0`,來源現在是 `1.0.1`
|
|
132
|
+
- 嚴重度:`PATCH` — advisory,exit 0
|
|
133
|
+
- 行動:下次方便時更新,不阻塞發布
|
|
134
|
+
|
|
135
|
+
**情境 2 — 標準 minor 升版含新段落(1.0.0 → 1.1.0)**
|
|
136
|
+
- 翻譯 `source_version: 1.0.0`,來源現在是 `1.1.0`
|
|
137
|
+
- 嚴重度:`MINOR` — advisory,exit 0
|
|
138
|
+
- 行動:下次發布前更新;zh-CN 使用者缺少新內容
|
|
139
|
+
|
|
140
|
+
**情境 3 — 標準 major 大改寫(1.x.x → 2.0.0)**
|
|
141
|
+
- 翻譯 `source_version: 1.5.0`,來源現在是 `2.0.0`
|
|
142
|
+
- 嚴重度:`MAJOR` — 阻塞,exit 1
|
|
143
|
+
- 行動:正式版發布前必須更新
|
|
144
|
+
|
|
145
|
+
**情境 4 — 新標準,無翻譯檔案**
|
|
146
|
+
- `locales/zh-TW/core/new-standard.md` 不存在
|
|
147
|
+
- 嚴重度:`MISSING` — 阻塞,exit 1
|
|
148
|
+
- 行動:發布前建立翻譯檔案
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 錯誤碼
|
|
153
|
+
|
|
154
|
+
| 代碼 | 說明 |
|
|
155
|
+
|------|------|
|
|
156
|
+
| `TRANS-001` | `MISSING_TRANSLATION` — 來源標準的翻譯檔案不存在 |
|
|
157
|
+
| `TRANS-002` | `MAJOR_VERSION_GAP` — 翻譯的 source_version 落後目前來源 MAJOR 版本 |
|
|
158
|
+
| `TRANS-003` | `MISSING_FRONTMATTER` — 翻譯檔案缺少必要的 YAML frontmatter |
|
|
159
|
+
| `TRANS-004` | `STALE_SOURCE_REF` — frontmatter 的 `source` 路徑指向不存在的檔案 |
|
|
@@ -53,11 +53,25 @@ Scan coverage gaps between BDD features and existing E2E tests.
|
|
|
53
53
|
|
|
54
54
|
## Supported Frameworks | 支援框架
|
|
55
55
|
|
|
56
|
-
| Framework | Auto-detected |
|
|
57
|
-
|
|
58
|
-
| Playwright | ✅ | `@playwright/test` |
|
|
59
|
-
| Cypress | ✅ | `
|
|
60
|
-
| Vitest | ✅ | `
|
|
56
|
+
| Ecosystem | Framework | Auto-detected | Detection signal |
|
|
57
|
+
|-----------|-----------|:------------:|----------|
|
|
58
|
+
| JavaScript | Playwright | ✅ | `@playwright/test` in package.json |
|
|
59
|
+
| JavaScript | Cypress | ✅ | `cypress` dep + config file |
|
|
60
|
+
| JavaScript | Vitest | ✅ | `vitest` dep + e2e directory |
|
|
61
|
+
| JavaScript | WebdriverIO | ❌ Manual | listed in SUPPORTED_FRAMEWORKS |
|
|
62
|
+
| Python | pytest-playwright | ✅ | `pytest-playwright` in requirements |
|
|
63
|
+
| Python | Selenium + pytest | ✅ | `selenium` in requirements |
|
|
64
|
+
| Python | Robot Framework | ✅ | `robotframework` in requirements |
|
|
65
|
+
| Python | Behave | ✅ | `behave` in requirements |
|
|
66
|
+
| Go | chromedp | ✅ | `chromedp` in go.mod |
|
|
67
|
+
| Go | rod | ✅ | `rod` in go.mod |
|
|
68
|
+
| Java | Selenium WebDriver | ✅ | `selenium-java` in pom.xml / build.gradle |
|
|
69
|
+
| Java | Playwright for Java | ✅ | `playwright` in pom.xml / build.gradle |
|
|
70
|
+
| Java | Gauge | ✅ | `gauge-java` in pom.xml / build.gradle |
|
|
71
|
+
| Ruby | Capybara | ✅ | `capybara` in Gemfile |
|
|
72
|
+
| Ruby | Watir | ✅ | `watir` in Gemfile |
|
|
73
|
+
| C# | Playwright for .NET | ❌ Manual | not yet auto-detected |
|
|
74
|
+
| C# | Selenium WebDriver | ❌ Manual | not yet auto-detected |
|
|
61
75
|
|
|
62
76
|
## Usage | 使用方式
|
|
63
77
|
|
|
@@ -96,6 +96,7 @@ For complete standards, see:
|
|
|
96
96
|
- [Testing Standards](../../core/testing-standards.md) - Actionable rules
|
|
97
97
|
- [Testing Theory](./testing-theory.md) - Educational knowledge base
|
|
98
98
|
- [Testing Pyramid](./testing-pyramid.md) - Detailed pyramid ratios
|
|
99
|
+
- [Test Skeleton Templates](./test-skeleton-templates.md) - Multi-language skeletons for UT/IT/ST/Perf/Contract
|
|
99
100
|
|
|
100
101
|
### AI-Optimized Format (Token-Efficient)
|
|
101
102
|
|
|
@@ -109,6 +110,10 @@ For AI assistants, use the YAML format files for reduced token usage:
|
|
|
109
110
|
- Integration Testing: `ai/options/testing/integration-testing.ai.yaml`
|
|
110
111
|
- System Testing: `ai/options/testing/system-testing.ai.yaml`
|
|
111
112
|
- E2E Testing: `ai/options/testing/e2e-testing.ai.yaml`
|
|
113
|
+
- Security Testing: `ai/options/testing/security-testing.ai.yaml`
|
|
114
|
+
- Performance Testing: `ai/options/testing/performance-testing.ai.yaml`
|
|
115
|
+
- Contract Testing: `ai/options/testing/contract-testing.ai.yaml`
|
|
116
|
+
- Skeleton templates (all levels, multi-language): [test-skeleton-templates.md](./test-skeleton-templates.md)
|
|
112
117
|
|
|
113
118
|
## Naming Conventions
|
|
114
119
|
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# Test Skeleton Templates | 測試骨架模板
|
|
2
|
+
|
|
3
|
+
> **Language**: English | [繁體中文](../../locales/zh-TW/skills/testing-guide/test-skeleton-templates.md)
|
|
4
|
+
|
|
5
|
+
**Version**: 2.0.0
|
|
6
|
+
**Last Updated**: 2026-04-14
|
|
7
|
+
|
|
8
|
+
Language-agnostic test skeleton patterns for all testing pyramid levels.
|
|
9
|
+
AI should read `uds.project.yaml` at runtime to determine the target ecosystem,
|
|
10
|
+
then generate code using the appropriate framework for that language.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## How to Use This Document | 如何使用本文件
|
|
15
|
+
|
|
16
|
+
This document contains **patterns only** — pseudocode that applies to any language.
|
|
17
|
+
|
|
18
|
+
**AI workflow for generating tests:**
|
|
19
|
+
1. Read `uds.project.yaml` to identify `ecosystem` (e.g. `python`, `go`, `java`, `rust`)
|
|
20
|
+
2. Select the test framework standard for that ecosystem (e.g. pytest, testing, JUnit, #[test])
|
|
21
|
+
3. Apply the pseudocode pattern below, translated into the target language
|
|
22
|
+
4. Fill in `[TODO]` markers with real implementation details
|
|
23
|
+
|
|
24
|
+
> If `uds.project.yaml` is not present, ask the user for their language/framework before generating.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Unit Test (UT) | 單元測試
|
|
29
|
+
|
|
30
|
+
**Purpose**: Test a single function/method in isolation — no external dependencies.
|
|
31
|
+
**Speed**: < 100ms per test.
|
|
32
|
+
**Isolation**: Complete (use stubs/mocks for all dependencies).
|
|
33
|
+
|
|
34
|
+
### Pattern: Arrange-Act-Assert
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
# [TODO: Replace with target language syntax]
|
|
38
|
+
# Arrange
|
|
39
|
+
subject = new TargetClass()
|
|
40
|
+
input = <test_value>
|
|
41
|
+
|
|
42
|
+
# Act
|
|
43
|
+
result = subject.method(input)
|
|
44
|
+
|
|
45
|
+
# Assert
|
|
46
|
+
assert result == <expected_value>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Pattern: Error / Edge Case
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
# [TODO: Replace with target language syntax]
|
|
53
|
+
# Assert that invalid input raises / returns error
|
|
54
|
+
assert throws_error( subject.method(invalid_input) )
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Naming convention
|
|
58
|
+
```
|
|
59
|
+
methodName_scenario_expectedResult
|
|
60
|
+
# Examples:
|
|
61
|
+
# calculateTotal_withEmptyCart_returnsZero
|
|
62
|
+
# validateEmail_withInvalidFormat_returnsFalse
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### AI generation instruction
|
|
66
|
+
> Read `uds.project.yaml → ecosystem`, then:
|
|
67
|
+
> - Wrap the above pseudocode in the ecosystem's test runner structure
|
|
68
|
+
> - Use the ecosystem's assertion library
|
|
69
|
+
> - Use the ecosystem's mock/stub mechanism for dependencies
|
|
70
|
+
> - Apply the ecosystem's file naming convention (e.g. `_test.go`, `*_spec.rb`, `Test*.java`)
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Integration Test (IT) | 整合測試
|
|
75
|
+
|
|
76
|
+
**Purpose**: Test the boundary between two components (DB, HTTP, queue).
|
|
77
|
+
**Speed**: < 1 second per test.
|
|
78
|
+
**Isolation**: Partial — use real implementations when possible, stubs for external services.
|
|
79
|
+
|
|
80
|
+
### Pattern: Database Integration
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
# [TODO: Replace with target language syntax]
|
|
84
|
+
# Arrange — start test database (in-memory or container)
|
|
85
|
+
db = start_test_database()
|
|
86
|
+
repo = new Repository(db)
|
|
87
|
+
|
|
88
|
+
# Act
|
|
89
|
+
repo.save(entity)
|
|
90
|
+
found = repo.findById(entity.id)
|
|
91
|
+
|
|
92
|
+
# Assert
|
|
93
|
+
assert found == entity
|
|
94
|
+
|
|
95
|
+
# Teardown — rollback or truncate
|
|
96
|
+
db.cleanup()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Pattern: HTTP API Integration
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
# [TODO: Replace with target language syntax]
|
|
103
|
+
# Act
|
|
104
|
+
response = http_client.post("/api/resource", body = { key: value })
|
|
105
|
+
|
|
106
|
+
# Assert
|
|
107
|
+
assert response.status == 201
|
|
108
|
+
assert response.body contains expected_fields
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Pattern: Message Queue Integration
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
# [TODO: Replace with target language syntax]
|
|
115
|
+
# Act
|
|
116
|
+
publisher.send("topic.created", event)
|
|
117
|
+
received = consumer.receive(timeout = 5s)
|
|
118
|
+
|
|
119
|
+
# Assert
|
|
120
|
+
assert received.payload == event
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### AI generation instruction
|
|
124
|
+
> Read `uds.project.yaml → ecosystem`, then select the appropriate:
|
|
125
|
+
> - In-memory or Testcontainers-compatible DB driver for that ecosystem
|
|
126
|
+
> - HTTP test client for that ecosystem
|
|
127
|
+
> - Embedded queue or mock transport for that ecosystem
|
|
128
|
+
> Never hardcode a specific library — choose based on detected ecosystem.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## System Test (ST) | 系統測試
|
|
133
|
+
|
|
134
|
+
**Purpose**: Test a complete business flow within one subsystem, with external services stubbed.
|
|
135
|
+
**Isolation**: Stub all external HTTP/queue calls; use real DB.
|
|
136
|
+
|
|
137
|
+
### Pattern: Full Flow with Stubbed External Service
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
# [TODO: Replace with target language syntax]
|
|
141
|
+
# Arrange — stub external dependency
|
|
142
|
+
stub_server = start_http_stub("/external-api/charge",
|
|
143
|
+
response = { status: "approved", id: "TX-001" })
|
|
144
|
+
|
|
145
|
+
# Boot subsystem under test
|
|
146
|
+
app = start_system(config = { external_url: stub_server.url })
|
|
147
|
+
|
|
148
|
+
# Act
|
|
149
|
+
result = app.run_flow(input_data)
|
|
150
|
+
|
|
151
|
+
# Assert
|
|
152
|
+
assert result.status == "confirmed"
|
|
153
|
+
assert result.id is not null
|
|
154
|
+
|
|
155
|
+
# Teardown
|
|
156
|
+
stub_server.stop()
|
|
157
|
+
app.stop()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### AI generation instruction
|
|
161
|
+
> Read `uds.project.yaml → ecosystem`, then select the appropriate:
|
|
162
|
+
> - HTTP stub/mock server for that ecosystem (e.g. WireMock, MSW, responses, httpretty, httpmock)
|
|
163
|
+
> - Application test harness / test client for that framework
|
|
164
|
+
> Never hardcode a specific stub library — choose based on detected ecosystem.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Performance Test | 效能測試
|
|
169
|
+
|
|
170
|
+
**Purpose**: Validate throughput, latency, and resource usage under load.
|
|
171
|
+
**Focus**: SLOs — p95 latency target, requests-per-second target, error rate threshold.
|
|
172
|
+
|
|
173
|
+
### Pattern: Load Test
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
# [TODO: Replace with target load testing tool syntax]
|
|
177
|
+
# Configuration
|
|
178
|
+
rate = <RPS target> # [TODO] e.g. 50 requests/sec
|
|
179
|
+
duration = <test duration> # [TODO] e.g. 60 seconds
|
|
180
|
+
target = "<API_URL>/api/resource"
|
|
181
|
+
|
|
182
|
+
# Thresholds
|
|
183
|
+
p95_latency_threshold = <ms> # [TODO] e.g. 500ms
|
|
184
|
+
error_rate_threshold = <rate> # [TODO] e.g. 1%
|
|
185
|
+
|
|
186
|
+
# Execute
|
|
187
|
+
results = run_load_test(rate, duration, target)
|
|
188
|
+
|
|
189
|
+
# Assert
|
|
190
|
+
assert results.p95_latency < p95_latency_threshold
|
|
191
|
+
assert results.error_rate < error_rate_threshold
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### AI generation instruction
|
|
195
|
+
> Read `uds.project.yaml → ecosystem`, then select the appropriate load testing tool:
|
|
196
|
+
> - Performance tests are **language-independent by default** (k6, Gatling, Locust, vegeta, wrk)
|
|
197
|
+
> - Prefer the tool already present in the project (check for existing config files)
|
|
198
|
+
> - If none present, suggest the most common tool for the detected ecosystem
|
|
199
|
+
> Set `[TODO]` thresholds based on the project's SLO definition if available.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Contract Test | 合約測試
|
|
204
|
+
|
|
205
|
+
**Purpose**: Verify API contracts between consumer and provider without deploying both.
|
|
206
|
+
**When**: Microservices, shared APIs, CI on every PR.
|
|
207
|
+
|
|
208
|
+
### Pattern: Consumer Contract (Consumer-Driven)
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
# [TODO: Replace with target language / Pact version syntax]
|
|
212
|
+
# Define the contract
|
|
213
|
+
pact = new ConsumerPactBuilder(
|
|
214
|
+
consumer = "[ConsumerName]", # [TODO]
|
|
215
|
+
provider = "[ProviderName]" # [TODO]
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
pact.given("resource 123 exists")
|
|
219
|
+
.upon_receiving("a GET request for resource 123")
|
|
220
|
+
.with_request(method = GET, path = "/resources/123")
|
|
221
|
+
.will_respond_with(
|
|
222
|
+
status = 200,
|
|
223
|
+
body = { id: like("123"), name: like("Alice") } # [TODO] add fields
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# Run consumer test against mock provider
|
|
227
|
+
pact.run_test(lambda mock_url:
|
|
228
|
+
client = new ApiClient(mock_url)
|
|
229
|
+
resource = client.get_resource("123")
|
|
230
|
+
assert resource.id == "123"
|
|
231
|
+
)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Pattern: Provider Verification
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
# [TODO: Replace with target language / Pact version syntax]
|
|
238
|
+
# Verify all consumer pacts against the real provider
|
|
239
|
+
verifier = new ProviderVerifier(
|
|
240
|
+
provider_url = "http://localhost:[PORT]", # [TODO]
|
|
241
|
+
pact_broker = env("PACT_BROKER_URL"),
|
|
242
|
+
provider_name = "[ProviderName]", # [TODO]
|
|
243
|
+
state_handlers = {
|
|
244
|
+
"resource 123 exists": lambda: seed_database(id = "123") # [TODO]
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
verifier.verify()
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Pattern: OpenAPI / Schema Contract Test
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
# [TODO: Replace with target language syntax]
|
|
254
|
+
# Load OpenAPI spec and validate responses
|
|
255
|
+
spec = load_openapi_spec("./api/openapi.yaml") # [TODO] spec path
|
|
256
|
+
server = start_test_server()
|
|
257
|
+
|
|
258
|
+
for each critical_endpoint in spec.paths:
|
|
259
|
+
response = http_client.request(critical_endpoint)
|
|
260
|
+
assert spec.validates(critical_endpoint, response)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### AI generation instruction
|
|
264
|
+
> Read `uds.project.yaml → ecosystem`, then select:
|
|
265
|
+
> - Consumer-Driven: Pact has SDKs for most languages — use the SDK for the detected ecosystem
|
|
266
|
+
> - OpenAPI: Use the OpenAPI validation library available for the detected ecosystem
|
|
267
|
+
> Never hardcode a specific Pact version or library — choose based on detected ecosystem.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Choosing the Right Test Level | 選擇正確的測試層
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
Use UT when:
|
|
275
|
+
✓ Testing a single function or method
|
|
276
|
+
✓ All dependencies can be replaced by stubs
|
|
277
|
+
✓ Should run in < 100ms
|
|
278
|
+
|
|
279
|
+
Use IT when:
|
|
280
|
+
✓ Testing interaction with a real DB, HTTP endpoint, or message queue
|
|
281
|
+
✓ Crossing a component boundary
|
|
282
|
+
✓ Needs a real or containerised dependency
|
|
283
|
+
|
|
284
|
+
Use ST when:
|
|
285
|
+
✓ Testing a complete business flow within one subsystem
|
|
286
|
+
✓ External services should be stubbed (not mocked)
|
|
287
|
+
✓ Validates non-functional requirements (latency, throughput)
|
|
288
|
+
|
|
289
|
+
Use E2E when:
|
|
290
|
+
✓ Testing a full user journey across multiple systems
|
|
291
|
+
✓ Uses a production-like environment
|
|
292
|
+
✓ Critical paths only (top 5–10 journeys)
|
|
293
|
+
|
|
294
|
+
Use Performance when:
|
|
295
|
+
✓ Validating SLOs before production
|
|
296
|
+
✓ Checking throughput or latency under load
|
|
297
|
+
|
|
298
|
+
Use Contract when:
|
|
299
|
+
✓ Two services share an API contract
|
|
300
|
+
✓ You want CI to catch consumer/provider drift early
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Related Documents | 相關文件
|
|
306
|
+
|
|
307
|
+
- [Testing Pyramid](./testing-pyramid.md)
|
|
308
|
+
- [E2E Assistant](../e2e-assistant/SKILL.md)
|
|
309
|
+
- [Contract Test Assistant](../contract-test-assistant/SKILL.md)
|
|
310
|
+
- Core: [testing-standards.md](../../core/testing-standards.md)
|
|
311
|
+
- Options:
|
|
312
|
+
- [unit-testing.ai.yaml](../../.standards/options/testing/unit-testing.ai.yaml)
|
|
313
|
+
- [integration-testing.ai.yaml](../../.standards/options/testing/integration-testing.ai.yaml)
|
|
314
|
+
- [system-testing.ai.yaml](../../.standards/options/testing/system-testing.ai.yaml)
|
|
315
|
+
- [performance-testing.ai.yaml](../../.standards/options/testing/performance-testing.ai.yaml)
|
|
316
|
+
- [contract-testing.ai.yaml](../../.standards/options/testing/contract-testing.ai.yaml)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-dev-standards",
|
|
3
|
-
"version": "5.1.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "CLI tool for adopting Universal Development Standards",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"documentation",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"generate:e2e-spec": "node scripts/generate-e2e-spec.mjs",
|
|
56
56
|
"prepare": "node ../scripts/setup-husky.mjs",
|
|
57
57
|
"test:upgrade": "node scripts/test-upgrade-path.mjs",
|
|
58
|
+
"check:bundle-parity": "node scripts/check-bundle-parity.mjs",
|
|
58
59
|
"prepack": "node scripts/prepack.mjs"
|
|
59
60
|
},
|
|
60
61
|
"dependencies": {
|