universal-dev-standards 6.2.0 → 6.2.2
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/bundled/locales/zh-CN/CHANGELOG.md +16 -2
- package/bundled/locales/zh-CN/README.md +1 -1
- package/bundled/locales/zh-CN/SECURITY.md +1 -1
- package/bundled/locales/zh-TW/CHANGELOG.md +16 -2
- package/bundled/locales/zh-TW/README.md +1 -1
- package/bundled/locales/zh-TW/SECURITY.md +1 -1
- package/package.json +1 -1
- package/src/commands/update.js +5 -0
- package/src/utils/hasher.js +12 -4
- package/standards-registry.json +7 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
source: ../../CHANGELOG.md
|
|
3
|
-
source_version: 6.2.
|
|
4
|
-
translation_version: 6.2.
|
|
3
|
+
source_version: 6.2.2
|
|
4
|
+
translation_version: 6.2.2
|
|
5
5
|
last_synced: 2026-07-31
|
|
6
6
|
status: current
|
|
7
7
|
---
|
|
@@ -17,6 +17,20 @@ status: current
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [6.2.2] - 2026-07-31
|
|
21
|
+
|
|
22
|
+
### 修复
|
|
23
|
+
|
|
24
|
+
- **`uds check` 的技能完整性只检查了你文件中的一小部分。** 某个项目上它打印出 `✓ All skill files intact (6 files)`,而实际安装了 **345** 个。`scanDirectory` 以 `fullPath.slice(basePath.length + 1)` 推导相对路径,这假设了 base path 不带尾部分隔符——而三个 agent 的技能路径带(`.claude/skills/`、`.opencode/skill/`、`.cursor/skills/`)。于是每个条目都被砍掉第一个字符(`ac-coverage` → `c-coverage`、`.manifest.json` → `manifest.json`);`computeDirectoryHashes` 用这个坏掉的名字重组绝对路径、找不到文件、跳过该条目。**扫了 115 个文件,只算出 2 个哈希。** 过程中没有任何一步失败——目录存在、循环跑完、函数返回对象,而检查在 2% 的表面上打了绿勾。`manifest.skillHashes` 现在会被正确填入;同一个项目报告 345。
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## [6.2.1] - 2026-07-31
|
|
28
|
+
|
|
29
|
+
### 修复
|
|
30
|
+
|
|
31
|
+
- **`uds update --locale <x> --skills` 现在会记录它安装的是哪个语言。** `manifest.skills.locale` 只有 `init` 会写,其他路径一律不写——与 6.2.0 刚决定不再信任的 `skills.names` 是同一种「设计上就会过期」的形状。把项目的技能切换到本地化变体时,磁盘上每个文件都被换掉,而这个字段动也没动。**这个字段在 6.2.0 之后变成承重的**:该版的 locale 修复会优先读 `skills.locale`、读不到才回退到 `display_language`。当两者不一致时——例如显示语言是英文、技能却是以 `--locale zh-tw` 安装的项目——下一次 reconcile 会无声地把它们全部换回英文。**正是 6.2.0 修掉的那个缺陷,从另一扇门走回来。** 五个技能安装路径现在都会记录实际安装的语言。
|
|
32
|
+
|
|
33
|
+
|
|
20
34
|
## [6.2.0] - 2026-07-31
|
|
21
35
|
|
|
22
36
|
> **Reconciler 一直在删除不是它安装的东西,事后还回报成功。** `uds update --plan` 在某个采用 repo 提议移除 86 个文件,其中 72 个是 UDS 有发布、项目也正在用的技能、命令与选项文件。十二个缺陷,形状完全相同:一个格式完好、却永远对不上的名字——所以什么都不会报错,而计划看起来很权威。**如果你曾看着 `--plan` 的输出、纳闷它为什么要删掉你的东西——那不是你的问题。**
|
|
@@ -15,7 +15,7 @@ status: current
|
|
|
15
15
|
|
|
16
16
|
> **语言**: [English](../../README.md) | [繁體中文](../zh-TW/README.md) | 简体中文
|
|
17
17
|
|
|
18
|
-
**版本**: 6.2.
|
|
18
|
+
**版本**: 6.2.2 | **发布日期**: 2026-07-30 | **授权**: [双重授权](../../LICENSE) (CC BY 4.0 + MIT)
|
|
19
19
|
|
|
20
20
|
语言无关、框架无关的软件项目文档标准。通过 AI 原生工作流,确保不同技术栈之间的一致性、质量和可维护性。
|
|
21
21
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
source: ../../CHANGELOG.md
|
|
3
|
-
source_version: 6.2.
|
|
4
|
-
translation_version: 6.2.
|
|
3
|
+
source_version: 6.2.2
|
|
4
|
+
translation_version: 6.2.2
|
|
5
5
|
last_synced: 2026-07-31
|
|
6
6
|
status: current
|
|
7
7
|
---
|
|
@@ -17,6 +17,20 @@ status: current
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [6.2.2] - 2026-07-31
|
|
21
|
+
|
|
22
|
+
### 修復
|
|
23
|
+
|
|
24
|
+
- **`uds check` 的技能完整性只檢查了你檔案中的一小部分。** 某個專案上它印出 `✓ All skill files intact (6 files)`,而實際安裝了 **345** 個。`scanDirectory` 以 `fullPath.slice(basePath.length + 1)` 推導相對路徑,這假設了 base path 不帶尾端分隔符——而三個 agent 的技能路徑帶(`.claude/skills/`、`.opencode/skill/`、`.cursor/skills/`)。於是每個項目都被砍掉第一個字元(`ac-coverage` → `c-coverage`、`.manifest.json` → `manifest.json`);`computeDirectoryHashes` 用這個壞掉的名字重組絕對路徑、找不到檔案、跳過該項。**掃了 115 個檔,只算出 2 個雜湊。** 過程中沒有任何一步失敗——目錄存在、迴圈跑完、函式回傳物件,而檢查在 2% 的表面上印了綠勾。`manifest.skillHashes` 現在會被正確填入;同一個專案回報 345。
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## [6.2.1] - 2026-07-31
|
|
28
|
+
|
|
29
|
+
### 修復
|
|
30
|
+
|
|
31
|
+
- **`uds update --locale <x> --skills` 現在會記錄它安裝的是哪個語系。** `manifest.skills.locale` 只有 `init` 會寫,其他路徑一律不寫——與 6.2.0 剛決定不再信任的 `skills.names` 是同一種「設計上就會過期」的形狀。把專案的技能切換到在地化變體時,磁碟上每個檔案都被換掉,而這個欄位動也沒動。**這個欄位在 6.2.0 之後變成承重的**:該版的 locale 修復會優先讀 `skills.locale`、讀不到才退回 `display_language`。當兩者不一致時——例如顯示語言是英文、技能卻是以 `--locale zh-tw` 安裝的專案——下一次 reconcile 會無聲地把它們全部換回英文。**正是 6.2.0 修掉的那個缺陷,從另一扇門走回來。** 五個技能安裝路徑現在都會記錄實際安裝的語系。
|
|
32
|
+
|
|
33
|
+
|
|
20
34
|
## [6.2.0] - 2026-07-31
|
|
21
35
|
|
|
22
36
|
> **Reconciler 一直在刪除不是它安裝的東西,事後還回報成功。** `uds update --plan` 在某個採用 repo 提議移除 86 個檔案,其中 72 個是 UDS 有出貨、專案也正在用的技能、指令與選項檔。十二個缺陷,形狀完全相同:一個格式完好、卻永遠對不上的名字——所以什麼都不會報錯,而計畫看起來很權威。**如果你曾看著 `--plan` 的輸出、納悶它為什麼要刪掉你的東西——那不是你的問題。**
|
|
@@ -15,7 +15,7 @@ status: current
|
|
|
15
15
|
|
|
16
16
|
> **語言**: [English](../../README.md) | 繁體中文 | [简体中文](../zh-CN/README.md)
|
|
17
17
|
|
|
18
|
-
**版本**: 6.2.
|
|
18
|
+
**版本**: 6.2.2 | **發布日期**: 2026-07-30 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
|
|
19
19
|
|
|
20
20
|
語言無關、框架無關的軟體專案文件標準。透過 AI 原生工作流,確保不同技術堆疊之間的一致性、品質和可維護性。
|
|
21
21
|
|
package/package.json
CHANGED
package/src/commands/update.js
CHANGED
|
@@ -957,6 +957,7 @@ export async function updateCommand(options) {
|
|
|
957
957
|
if (!manifest.skills) manifest.skills = {};
|
|
958
958
|
manifest.skills.installed = true;
|
|
959
959
|
manifest.skills.version = repoInfo.skills.version;
|
|
960
|
+
manifest.skills.locale = skillsLocale;
|
|
960
961
|
manifest.skills.installations = [
|
|
961
962
|
...(manifest.skills.installations || []),
|
|
962
963
|
...installSkills
|
|
@@ -998,6 +999,7 @@ export async function updateCommand(options) {
|
|
|
998
999
|
// Update manifest version
|
|
999
1000
|
if (!manifest.skills) manifest.skills = {};
|
|
1000
1001
|
manifest.skills.version = repoInfo.skills.version;
|
|
1002
|
+
manifest.skills.locale = updateLocale;
|
|
1001
1003
|
manifest.skills.names = mergeInstalledNames(manifest.skills.names, updateResult);
|
|
1002
1004
|
|
|
1003
1005
|
// Derive location from installations if not set
|
|
@@ -1140,6 +1142,7 @@ export async function updateCommand(options) {
|
|
|
1140
1142
|
if (!manifest.skills) manifest.skills = {};
|
|
1141
1143
|
manifest.skills.installed = true;
|
|
1142
1144
|
manifest.skills.version = repoInfo.skills.version;
|
|
1145
|
+
manifest.skills.locale = skillsLocale;
|
|
1143
1146
|
manifest.skills.installations = [...(manifest.skills.installations || []), ...missingSkills];
|
|
1144
1147
|
manifest.skills.names = mergeInstalledNames(manifest.skills.names, result);
|
|
1145
1148
|
if (result.allFileHashes) {
|
|
@@ -1159,6 +1162,7 @@ export async function updateCommand(options) {
|
|
|
1159
1162
|
const result = await installSkillsToMultipleAgents(outdatedSkills, null, projectPath, skillsLocale);
|
|
1160
1163
|
if (!manifest.skills) manifest.skills = {};
|
|
1161
1164
|
manifest.skills.version = repoInfo.skills.version;
|
|
1165
|
+
manifest.skills.locale = skillsLocale;
|
|
1162
1166
|
manifest.skills.names = mergeInstalledNames(manifest.skills.names, result);
|
|
1163
1167
|
if (!manifest.skills.location && manifest.skills.installations?.length > 0) {
|
|
1164
1168
|
const levels = manifest.skills.installations.map(s => s.level).filter(Boolean);
|
|
@@ -1746,6 +1750,7 @@ async function updateSkillsOnly(projectPath, manifest, options) {
|
|
|
1746
1750
|
|
|
1747
1751
|
// Update manifest
|
|
1748
1752
|
manifest.skills.version = latestVersion;
|
|
1753
|
+
manifest.skills.locale = skillsLocaleForUpdate;
|
|
1749
1754
|
manifest.skills.installations = skillsInstallations;
|
|
1750
1755
|
manifest.skills.names = mergeInstalledNames(manifest.skills.names, result);
|
|
1751
1756
|
|
package/src/utils/hasher.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
2
|
import { readFileSync, statSync, existsSync, readdirSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
3
|
+
import { join, relative } from 'path';
|
|
4
4
|
import { UDS_MARKERS } from '../core/constants.js';
|
|
5
5
|
import { resolveIntegrationFile } from '../core/constants.js';
|
|
6
6
|
|
|
@@ -163,9 +163,17 @@ function scanDirectory(dirPath, basePath) {
|
|
|
163
163
|
|
|
164
164
|
for (const item of items) {
|
|
165
165
|
const fullPath = join(dirPath, item.name);
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
|
|
166
|
+
// `relative()` rather than slice arithmetic. The old form was
|
|
167
|
+
// `fullPath.slice(basePath.length + 1)`, which assumed basePath carries no
|
|
168
|
+
// trailing separator. Three agent skill paths do (`.claude/skills/`,
|
|
169
|
+
// `.opencode/skill/`, `.cursor/skills/`), so every name lost its first
|
|
170
|
+
// character — `ac-coverage` became `c-coverage`, `.manifest.json` became
|
|
171
|
+
// `manifest.json`. computeDirectoryHashes then rebuilt an absolute path from
|
|
172
|
+
// the mangled name, found no file, and dropped the entry: 115 files in, 2
|
|
173
|
+
// out. `manifest.skillHashes` was therefore never populated, the reconciler
|
|
174
|
+
// read that as "no hash available for comparison", and every `uds update`
|
|
175
|
+
// rewrote all 55 skill directories forever. (XSPEC-343 R2)
|
|
176
|
+
const relativePath = relative(basePath, fullPath).replace(/\\/g, '/');
|
|
169
177
|
|
|
170
178
|
if (item.isDirectory()) {
|
|
171
179
|
files.push(...scanDirectory(fullPath, basePath));
|
package/standards-registry.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"version": "6.2.
|
|
3
|
+
"version": "6.2.2",
|
|
4
4
|
"lastUpdated": "2026-05-13",
|
|
5
5
|
"description": "Standards registry for universal-dev-standards with integrated skills and AI-optimized formats",
|
|
6
6
|
"formats": {
|
|
@@ -58,14 +58,14 @@
|
|
|
58
58
|
"standards": {
|
|
59
59
|
"name": "universal-dev-standards",
|
|
60
60
|
"url": "https://github.com/AsiaOstrich/universal-dev-standards",
|
|
61
|
-
"version": "6.2.
|
|
61
|
+
"version": "6.2.2"
|
|
62
62
|
},
|
|
63
63
|
"skills": {
|
|
64
64
|
"name": "universal-dev-standards",
|
|
65
65
|
"url": "https://github.com/AsiaOstrich/universal-dev-standards",
|
|
66
66
|
"localPath": "skills",
|
|
67
67
|
"rawUrl": "https://raw.githubusercontent.com/AsiaOstrich/universal-dev-standards/main/skills",
|
|
68
|
-
"version": "6.2.
|
|
68
|
+
"version": "6.2.2",
|
|
69
69
|
"note": "Skills are now included in the main repository under skills/"
|
|
70
70
|
}
|
|
71
71
|
},
|
|
@@ -2236,7 +2236,7 @@
|
|
|
2236
2236
|
"id": "license-compliance",
|
|
2237
2237
|
"name": "License Compliance Standards",
|
|
2238
2238
|
"nameZh": "授權合規標準",
|
|
2239
|
-
"version": "6.2.
|
|
2239
|
+
"version": "6.2.2",
|
|
2240
2240
|
"source": {
|
|
2241
2241
|
"human": "core/license-compliance.md",
|
|
2242
2242
|
"ai": "ai/standards/license-compliance.ai.yaml"
|
|
@@ -2248,7 +2248,7 @@
|
|
|
2248
2248
|
"id": "verification-oracle",
|
|
2249
2249
|
"name": "Verification Oracle Standards",
|
|
2250
2250
|
"nameZh": "驗證 Oracle 標準",
|
|
2251
|
-
"version": "6.2.
|
|
2251
|
+
"version": "6.2.2",
|
|
2252
2252
|
"source": {
|
|
2253
2253
|
"human": "core/verification-oracle.md",
|
|
2254
2254
|
"ai": "ai/standards/verification-oracle.ai.yaml"
|
|
@@ -2260,7 +2260,7 @@
|
|
|
2260
2260
|
"id": "model-provenance",
|
|
2261
2261
|
"name": "Model Provenance Policy Standards",
|
|
2262
2262
|
"nameZh": "模型來源政策標準",
|
|
2263
|
-
"version": "6.2.
|
|
2263
|
+
"version": "6.2.2",
|
|
2264
2264
|
"source": {
|
|
2265
2265
|
"human": "core/model-provenance.md",
|
|
2266
2266
|
"ai": "ai/standards/model-provenance.ai.yaml"
|
|
@@ -2272,7 +2272,7 @@
|
|
|
2272
2272
|
"id": "resource-cost-boundary",
|
|
2273
2273
|
"name": "Resource / Cost Boundary Declaration Standards",
|
|
2274
2274
|
"nameZh": "資源/成本邊界宣告標準",
|
|
2275
|
-
"version": "6.2.
|
|
2275
|
+
"version": "6.2.2",
|
|
2276
2276
|
"source": {
|
|
2277
2277
|
"human": "core/resource-cost-boundary.md",
|
|
2278
2278
|
"ai": "ai/standards/resource-cost-boundary.ai.yaml"
|