universal-dev-standards 6.2.1 → 6.2.3
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 +15 -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 +15 -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 +12 -6
- 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.3
|
|
4
|
+
translation_version: 6.2.3
|
|
5
5
|
last_synced: 2026-07-31
|
|
6
6
|
status: current
|
|
7
7
|
---
|
|
@@ -17,6 +17,19 @@ status: current
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [6.2.3] - 2026-07-31
|
|
21
|
+
|
|
22
|
+
### 修复
|
|
23
|
+
|
|
24
|
+
- **重新选取已安装的 agent 会追加一笔重复的 manifest 记录。** 四个 manifest 写入端以 `[...existing, ...new]` 追加安装记录,于是一个已被记录的 agent 每次被重新选取就多一笔;某个项目的 manifest 读起来是 `['claude-code', 'claude-code']`。安装器本身从未受影响——`installSkillsToMultipleAgents` 会对输入去重。损害仅限于**记录**,以及每一个会迭代它的消费端:`checkNewFeatures`、reconciler 的扫描器与期望状态计算器都把那个 agent 走了两遍。效果无害——**这正是它跨越五次升级都没被注意到的原因**。四个写入端现在改用安装器早就在用的那个 helper。
|
|
25
|
+
|
|
26
|
+
## [6.2.2] - 2026-07-31
|
|
27
|
+
|
|
28
|
+
### 修复
|
|
29
|
+
|
|
30
|
+
- **`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。
|
|
31
|
+
|
|
32
|
+
|
|
20
33
|
## [6.2.1] - 2026-07-31
|
|
21
34
|
|
|
22
35
|
### 修复
|
|
@@ -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.3 | **发布日期**: 2026-07-31 | **授权**: [双重授权](../../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.3
|
|
4
|
+
translation_version: 6.2.3
|
|
5
5
|
last_synced: 2026-07-31
|
|
6
6
|
status: current
|
|
7
7
|
---
|
|
@@ -17,6 +17,19 @@ status: current
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [6.2.3] - 2026-07-31
|
|
21
|
+
|
|
22
|
+
### 修復
|
|
23
|
+
|
|
24
|
+
- **重新選取已安裝的 agent 會追加一筆重複的 manifest 紀錄。** 四個 manifest 寫入端以 `[...existing, ...new]` 追加安裝紀錄,於是一個已被記錄的 agent 每次被重新選取就多一筆;某個專案的 manifest 讀起來是 `['claude-code', 'claude-code']`。安裝器本身從未受影響——`installSkillsToMultipleAgents` 會對輸入去重。損害僅限於**紀錄**,以及每一個會迭代它的消費端:`checkNewFeatures`、reconciler 的掃描器與期望狀態計算器都把那個 agent 走了兩次。效果無害——**這正是它跨越五次升級都沒被注意到的原因**。四個寫入端現在改用安裝器早就在用的那個 helper。
|
|
25
|
+
|
|
26
|
+
## [6.2.2] - 2026-07-31
|
|
27
|
+
|
|
28
|
+
### 修復
|
|
29
|
+
|
|
30
|
+
- **`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。
|
|
31
|
+
|
|
32
|
+
|
|
20
33
|
## [6.2.1] - 2026-07-31
|
|
21
34
|
|
|
22
35
|
### 修復
|
|
@@ -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.3 | **發布日期**: 2026-07-31 | **授權**: [雙重授權](../../LICENSE) (CC BY 4.0 + MIT)
|
|
19
19
|
|
|
20
20
|
語言無關、框架無關的軟體專案文件標準。透過 AI 原生工作流,確保不同技術堆疊之間的一致性、品質和可維護性。
|
|
21
21
|
|
package/package.json
CHANGED
package/src/commands/update.js
CHANGED
|
@@ -27,6 +27,7 @@ import { config } from '../utils/config-manager.js';
|
|
|
27
27
|
import {
|
|
28
28
|
installSkillsToMultipleAgents,
|
|
29
29
|
installCommandsToMultipleAgents,
|
|
30
|
+
deduplicateInstallations,
|
|
30
31
|
getInstalledSkillsInfoForAgent,
|
|
31
32
|
getInstalledCommandsForAgent,
|
|
32
33
|
cleanupDuplicateSkills,
|
|
@@ -958,10 +959,15 @@ export async function updateCommand(options) {
|
|
|
958
959
|
manifest.skills.installed = true;
|
|
959
960
|
manifest.skills.version = repoInfo.skills.version;
|
|
960
961
|
manifest.skills.locale = skillsLocale;
|
|
961
|
-
|
|
962
|
+
// Deduplicate: the append form accumulated a duplicate entry every time
|
|
963
|
+
// an already-installed agent was re-selected. dev-platform's manifest read
|
|
964
|
+
// `['claude-code', 'claude-code']`. Harmless to the installer, which
|
|
965
|
+
// dedupes at install time, but every consumer that iterates installations
|
|
966
|
+
// saw the agent twice. (XSPEC-343 R2)
|
|
967
|
+
manifest.skills.installations = deduplicateInstallations([
|
|
962
968
|
...(manifest.skills.installations || []),
|
|
963
969
|
...installSkills
|
|
964
|
-
];
|
|
970
|
+
]);
|
|
965
971
|
manifest.skills.names = mergeInstalledNames(manifest.skills.names, skillResult);
|
|
966
972
|
|
|
967
973
|
// Derive location from installations if not set
|
|
@@ -1038,10 +1044,10 @@ export async function updateCommand(options) {
|
|
|
1038
1044
|
if (!manifest.commands) manifest.commands = {};
|
|
1039
1045
|
manifest.commands.installed = true;
|
|
1040
1046
|
manifest.commands.version = repoInfo.skills.version; // Track version
|
|
1041
|
-
manifest.commands.installations = [
|
|
1047
|
+
manifest.commands.installations = deduplicateInstallations([
|
|
1042
1048
|
...(manifest.commands.installations || []),
|
|
1043
1049
|
...installCommands
|
|
1044
|
-
];
|
|
1050
|
+
]);
|
|
1045
1051
|
manifest.commands.names = mergeInstalledNames(manifest.commands.names, cmdResult);
|
|
1046
1052
|
|
|
1047
1053
|
// Update command hashes for integrity tracking
|
|
@@ -1143,7 +1149,7 @@ export async function updateCommand(options) {
|
|
|
1143
1149
|
manifest.skills.installed = true;
|
|
1144
1150
|
manifest.skills.version = repoInfo.skills.version;
|
|
1145
1151
|
manifest.skills.locale = skillsLocale;
|
|
1146
|
-
manifest.skills.installations = [...(manifest.skills.installations || []), ...missingSkills];
|
|
1152
|
+
manifest.skills.installations = deduplicateInstallations([...(manifest.skills.installations || []), ...missingSkills]);
|
|
1147
1153
|
manifest.skills.names = mergeInstalledNames(manifest.skills.names, result);
|
|
1148
1154
|
if (result.allFileHashes) {
|
|
1149
1155
|
if (!manifest.skillHashes) manifest.skillHashes = {};
|
|
@@ -1187,7 +1193,7 @@ export async function updateCommand(options) {
|
|
|
1187
1193
|
if (!manifest.commands) manifest.commands = {};
|
|
1188
1194
|
manifest.commands.installed = true;
|
|
1189
1195
|
manifest.commands.version = repoInfo.skills.version;
|
|
1190
|
-
manifest.commands.installations = [...(manifest.commands.installations || []), ...missingCommands];
|
|
1196
|
+
manifest.commands.installations = deduplicateInstallations([...(manifest.commands.installations || []), ...missingCommands]);
|
|
1191
1197
|
manifest.commands.names = mergeInstalledNames(manifest.commands.names, result);
|
|
1192
1198
|
if (result.allFileHashes) {
|
|
1193
1199
|
if (!manifest.commandHashes) manifest.commandHashes = {};
|
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.3",
|
|
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.3"
|
|
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.3",
|
|
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.3",
|
|
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.3",
|
|
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.3",
|
|
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.3",
|
|
2276
2276
|
"source": {
|
|
2277
2277
|
"human": "core/resource-cost-boundary.md",
|
|
2278
2278
|
"ai": "ai/standards/resource-cost-boundary.ai.yaml"
|