universal-dev-standards 6.11.0 → 6.13.0-beta.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/bundled/ai/standards/developer-memory.ai.yaml +24 -2
- package/bundled/ai/standards/open-work-tracking.ai.yaml +216 -0
- package/bundled/ai/standards/turn-completion-integrity.ai.yaml +34 -2
- package/bundled/core/developer-memory.md +58 -2
- package/bundled/core/open-work-tracking.md +333 -0
- package/bundled/core/turn-completion-integrity.md +36 -2
- package/bundled/hooks/check-turn-completion-codex.mjs +116 -0
- package/bundled/hooks/check-turn-completion-gemini.mjs +81 -0
- package/bundled/hooks/check-turn-completion.mjs +24 -149
- package/bundled/hooks/turn-completion/engine.mjs +206 -0
- package/bundled/hooks/turn-completion/locales/en.mjs +29 -1
- package/bundled/hooks/turn-completion/locales/zh-TW.mjs +29 -1
- package/bundled/locales/zh-CN/CHANGELOG.md +23 -3
- package/bundled/locales/zh-CN/CLAUDE.md +1 -1
- package/bundled/locales/zh-CN/README.md +2 -2
- package/bundled/locales/zh-CN/SECURITY.md +2 -1
- package/bundled/locales/zh-CN/core/turn-completion-integrity.md +36 -6
- package/bundled/locales/zh-CN/docs/CHEATSHEET.md +2 -1
- package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +24 -5
- package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +4 -3
- package/bundled/locales/zh-TW/CHANGELOG.md +23 -3
- package/bundled/locales/zh-TW/CLAUDE.md +1 -1
- package/bundled/locales/zh-TW/README.md +2 -2
- package/bundled/locales/zh-TW/SECURITY.md +2 -1
- package/bundled/locales/zh-TW/core/open-work-tracking.md +255 -0
- package/bundled/locales/zh-TW/core/turn-completion-integrity.md +36 -6
- package/bundled/locales/zh-TW/docs/CHEATSHEET.md +2 -1
- package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +24 -5
- package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +4 -3
- package/package.json +1 -1
- package/src/commands/init.js +26 -0
- package/src/installers/hooks-installer.js +104 -0
- package/standards-registry.json +19 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# UDS 功能參考手冊
|
|
2
2
|
|
|
3
3
|
> Universal Development Standards - 完整功能文件
|
|
4
|
-
> Auto-generated | Last updated: 2026-09-
|
|
4
|
+
> Auto-generated | Last updated: 2026-09-23
|
|
5
5
|
|
|
6
6
|
**Language**: [English](../../../docs/reference/FEATURE-REFERENCE.md) | 繁體中文 | [简体中文](../../zh-CN/docs/FEATURE-REFERENCE.md)
|
|
7
7
|
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
3. [技能](#skills) (55)
|
|
15
15
|
4. [代理](#agents) (5)
|
|
16
16
|
5. [工作流程](#workflows) (5)
|
|
17
|
-
6. [核心規範](#core-standards) (
|
|
17
|
+
6. [核心規範](#core-standards) (153)
|
|
18
18
|
7. [腳本](#scripts) (59)
|
|
19
19
|
|
|
20
|
-
**Total Features:
|
|
20
|
+
**Total Features: 351**
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
@@ -516,6 +516,7 @@
|
|
|
516
516
|
| `mutation-testing` | 1.1.0 | Mutation testing evaluates test suite effectiveness by injecting artificial bugs |
|
|
517
517
|
| `no-cicd-deployment` | - | |
|
|
518
518
|
| `observability-standards` | 1.0.0 | |
|
|
519
|
+
| `open-work-tracking` | 1.0.0 | The deferred-item-exit standard requires that a deferred item leave its document |
|
|
519
520
|
| `packaging-standards` | 1.1.0 | This standard defines a Recipe-based packaging framework that enables user proje |
|
|
520
521
|
| `performance-standards` | 1.2.0 | This standard defines comprehensive guidelines for software performance engineer |
|
|
521
522
|
| `pii-classification` | 1.1.0 | **Status**: Active | **Updated**: 2026-06-19 | |
|
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -279,6 +279,32 @@ export async function initCommand(options) {
|
|
|
279
279
|
console.log(chalk.gray(` ${line}`));
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
+
|
|
283
|
+
// turn-completion-integrity is also extended to Codex and Gemini CLI
|
|
284
|
+
// (2026-09-25), each with its own config file and output contract — see
|
|
285
|
+
// installCodexHooks/installGeminiHooks in hooks-installer.js. Gated on the
|
|
286
|
+
// tools the adopter actually selected: writing a hooks.json into every
|
|
287
|
+
// project's .codex/ regardless of whether Codex is used would be noise,
|
|
288
|
+
// not help.
|
|
289
|
+
const selectedTools = config.integrations || config.aiTools || [];
|
|
290
|
+
if (selectedTools.includes('codex')) {
|
|
291
|
+
const { installCodexHooks } = await import('../installers/hooks-installer.js');
|
|
292
|
+
const codexResult = installCodexHooks(projectPath);
|
|
293
|
+
if (codexResult.installed) {
|
|
294
|
+
console.log(chalk.green(' ✓ Codex Stop hook installed (turn-completion-integrity)'));
|
|
295
|
+
} else {
|
|
296
|
+
console.log(chalk.yellow(` ⚠ Codex hook not installed — ${codexResult.reason}`));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (selectedTools.includes('gemini-cli')) {
|
|
300
|
+
const { installGeminiHooks } = await import('../installers/hooks-installer.js');
|
|
301
|
+
const geminiResult = installGeminiHooks(projectPath);
|
|
302
|
+
if (geminiResult.installed) {
|
|
303
|
+
console.log(chalk.green(' ✓ Gemini CLI AfterAgent hook installed (turn-completion-integrity)'));
|
|
304
|
+
} else {
|
|
305
|
+
console.log(chalk.yellow(` ⚠ Gemini CLI hook not installed — ${geminiResult.reason}`));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
282
308
|
}
|
|
283
309
|
|
|
284
310
|
// 5. Setup Pre-commit Hook
|
|
@@ -218,3 +218,107 @@ export function installHooks(projectPath) {
|
|
|
218
218
|
languageLimits: probeLanguageLimits(hooksDir, scripts),
|
|
219
219
|
};
|
|
220
220
|
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* turn-completion-integrity is the only standard extended to Codex and Gemini
|
|
224
|
+
* CLI so far (2026-09-25). Unlike installHooks() above, these two functions do
|
|
225
|
+
* NOT walk every standard's `enforcement:` block — the other three shipped
|
|
226
|
+
* standards declare Claude-Code-specific events (PreToolUse/PostToolUse with
|
|
227
|
+
* a Bash/Write matcher) that Codex and Gemini CLI's hook models don't obviously
|
|
228
|
+
* map onto, and generalizing that mapping is a separate piece of work. These
|
|
229
|
+
* are narrowly scoped to the one hook that has been verified against each
|
|
230
|
+
* tool's own docs.
|
|
231
|
+
*
|
|
232
|
+
* @see core/turn-completion-integrity.md
|
|
233
|
+
*/
|
|
234
|
+
const CODEX_HOOK_SCRIPT = 'check-turn-completion-codex.mjs';
|
|
235
|
+
const GEMINI_HOOK_SCRIPT = 'check-turn-completion-gemini.mjs';
|
|
236
|
+
|
|
237
|
+
/** Copy the shared hook scripts into the project, same as installHooks() does. */
|
|
238
|
+
function copyHookScripts(hookDir, hooksDir) {
|
|
239
|
+
if (!existsSync(hooksDir)) mkdirSync(hooksDir, { recursive: true });
|
|
240
|
+
cpSync(hookDir, hooksDir, { recursive: true });
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Install the turn-completion-integrity Stop hook for Codex.
|
|
245
|
+
*
|
|
246
|
+
* Config lives at <project>/.codex/hooks.json — a dedicated file, NOT
|
|
247
|
+
* config.toml's [hooks] table. Codex runs matching hooks from every file that
|
|
248
|
+
* defines them (https://learn.chatgpt.com/docs/hooks, fetched 2026-09-25), so
|
|
249
|
+
* writing only hooks.json here is a deliberate choice, not an oversight: it
|
|
250
|
+
* does not need to also read or merge config.toml to avoid double-registering
|
|
251
|
+
* the same hook, and an adopter who already has a Stop hook in config.toml
|
|
252
|
+
* keeps it untouched.
|
|
253
|
+
*
|
|
254
|
+
* @param {string} projectPath
|
|
255
|
+
* @returns {{ installed: boolean, settingsPath: string, event?: string, reason?: string }}
|
|
256
|
+
*/
|
|
257
|
+
export function installCodexHooks(projectPath) {
|
|
258
|
+
const hooksJsonPath = join(projectPath, '.codex', 'hooks.json');
|
|
259
|
+
const hookDir = hooksSourceDir();
|
|
260
|
+
|
|
261
|
+
if (!hookDir || !existsSync(join(hookDir, CODEX_HOOK_SCRIPT))) {
|
|
262
|
+
return { installed: false, settingsPath: hooksJsonPath, reason: `hook script not found: ${CODEX_HOOK_SCRIPT}` };
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const codexDir = join(projectPath, '.codex');
|
|
266
|
+
if (!existsSync(codexDir)) mkdirSync(codexDir, { recursive: true });
|
|
267
|
+
copyHookScripts(hookDir, join(projectPath, 'scripts', 'hooks'));
|
|
268
|
+
|
|
269
|
+
let config = {};
|
|
270
|
+
if (existsSync(hooksJsonPath)) {
|
|
271
|
+
try { config = JSON.parse(readFileSync(hooksJsonPath, 'utf-8')); } catch { config = {}; }
|
|
272
|
+
}
|
|
273
|
+
if (!config.hooks) config.hooks = {};
|
|
274
|
+
if (!config.hooks.Stop) config.hooks.Stop = [];
|
|
275
|
+
|
|
276
|
+
// Matcher is omitted, not empty-stringed: Codex ignores any matcher on Stop
|
|
277
|
+
// ("any configured matcher is ignored"), and mergeHookArray's dedupe treats
|
|
278
|
+
// undefined === undefined, so this still merges idempotently.
|
|
279
|
+
config.hooks.Stop = mergeHookArray(config.hooks.Stop, [
|
|
280
|
+
{ hooks: [{ type: 'command', command: `node scripts/hooks/${CODEX_HOOK_SCRIPT}`, timeout: 30 }] },
|
|
281
|
+
]);
|
|
282
|
+
|
|
283
|
+
writeFileSync(hooksJsonPath, JSON.stringify(config, null, 2) + '\n');
|
|
284
|
+
return { installed: true, settingsPath: hooksJsonPath, event: 'Stop' };
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Install the turn-completion-integrity AfterAgent hook for Gemini CLI.
|
|
289
|
+
*
|
|
290
|
+
* Config lives at <project>/.gemini/settings.json — shared with the rest of
|
|
291
|
+
* Gemini CLI's project settings, so only the `hooks.AfterAgent` key is ever
|
|
292
|
+
* touched here (https://geminicli.com/docs/hooks/, fetched 2026-09-25).
|
|
293
|
+
*
|
|
294
|
+
* @param {string} projectPath
|
|
295
|
+
* @returns {{ installed: boolean, settingsPath: string, event?: string, reason?: string }}
|
|
296
|
+
*/
|
|
297
|
+
export function installGeminiHooks(projectPath) {
|
|
298
|
+
const settingsPath = join(projectPath, '.gemini', 'settings.json');
|
|
299
|
+
const hookDir = hooksSourceDir();
|
|
300
|
+
|
|
301
|
+
if (!hookDir || !existsSync(join(hookDir, GEMINI_HOOK_SCRIPT))) {
|
|
302
|
+
return { installed: false, settingsPath, reason: `hook script not found: ${GEMINI_HOOK_SCRIPT}` };
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const geminiDir = join(projectPath, '.gemini');
|
|
306
|
+
if (!existsSync(geminiDir)) mkdirSync(geminiDir, { recursive: true });
|
|
307
|
+
copyHookScripts(hookDir, join(projectPath, 'scripts', 'hooks'));
|
|
308
|
+
|
|
309
|
+
let settings = {};
|
|
310
|
+
if (existsSync(settingsPath)) {
|
|
311
|
+
try { settings = JSON.parse(readFileSync(settingsPath, 'utf-8')); } catch { settings = {}; }
|
|
312
|
+
}
|
|
313
|
+
if (!settings.hooks) settings.hooks = {};
|
|
314
|
+
if (!settings.hooks.AfterAgent) settings.hooks.AfterAgent = [];
|
|
315
|
+
|
|
316
|
+
// AfterAgent does not use matchers either (matchers apply only to Tool
|
|
317
|
+
// hooks); see the Codex function above for why matcher is omitted, not "".
|
|
318
|
+
settings.hooks.AfterAgent = mergeHookArray(settings.hooks.AfterAgent, [
|
|
319
|
+
{ hooks: [{ type: 'command', command: `node scripts/hooks/${GEMINI_HOOK_SCRIPT}`, timeout: 5000 }] },
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
323
|
+
return { installed: true, settingsPath, event: 'AfterAgent' };
|
|
324
|
+
}
|
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.
|
|
3
|
+
"version": "6.13.0-beta.1",
|
|
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.
|
|
61
|
+
"version": "6.13.0-beta.1"
|
|
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.
|
|
68
|
+
"version": "6.13.0-beta.1",
|
|
69
69
|
"note": "Skills are now included in the main repository under skills/"
|
|
70
70
|
}
|
|
71
71
|
},
|
|
@@ -1789,6 +1789,18 @@
|
|
|
1789
1789
|
"skillName": null,
|
|
1790
1790
|
"description": "A deferred item must leave the document: a traceable exit outside it, identified beside the item. The carrier is deliberately unspecified. A present link is not a working link — verified and unverified links are two states, never one green. Anchor on document structure, not wording"
|
|
1791
1791
|
},
|
|
1792
|
+
{
|
|
1793
|
+
"id": "open-work-tracking",
|
|
1794
|
+
"name": "Open Work Tracking Standard",
|
|
1795
|
+
"nameZh": "開放工作追蹤標準",
|
|
1796
|
+
"source": {
|
|
1797
|
+
"human": "core/open-work-tracking.md",
|
|
1798
|
+
"ai": "ai/standards/open-work-tracking.ai.yaml"
|
|
1799
|
+
},
|
|
1800
|
+
"category": "reference",
|
|
1801
|
+
"skillName": null,
|
|
1802
|
+
"description": "Downstream of deferred-item-exit: once an item has an exit, its carrier must stay trustworthy. Capture costs no more than two fields; a waiting item records its release condition; derivable fields are generated, not hand-written; a coverage figure states what it could not see; a checkpoint at turn end reports open work but never blocks"
|
|
1803
|
+
},
|
|
1792
1804
|
{
|
|
1793
1805
|
"id": "verification-evidence",
|
|
1794
1806
|
"name": "Verification Evidence Standard",
|
|
@@ -2283,7 +2295,7 @@
|
|
|
2283
2295
|
"id": "license-compliance",
|
|
2284
2296
|
"name": "License Compliance Standards",
|
|
2285
2297
|
"nameZh": "授權合規標準",
|
|
2286
|
-
"version": "6.
|
|
2298
|
+
"version": "6.13.0-beta.1",
|
|
2287
2299
|
"source": {
|
|
2288
2300
|
"human": "core/license-compliance.md",
|
|
2289
2301
|
"ai": "ai/standards/license-compliance.ai.yaml"
|
|
@@ -2295,7 +2307,7 @@
|
|
|
2295
2307
|
"id": "verification-oracle",
|
|
2296
2308
|
"name": "Verification Oracle Standards",
|
|
2297
2309
|
"nameZh": "驗證 Oracle 標準",
|
|
2298
|
-
"version": "6.
|
|
2310
|
+
"version": "6.13.0-beta.1",
|
|
2299
2311
|
"source": {
|
|
2300
2312
|
"human": "core/verification-oracle.md",
|
|
2301
2313
|
"ai": "ai/standards/verification-oracle.ai.yaml"
|
|
@@ -2307,7 +2319,7 @@
|
|
|
2307
2319
|
"id": "model-provenance",
|
|
2308
2320
|
"name": "Model Provenance Policy Standards",
|
|
2309
2321
|
"nameZh": "模型來源政策標準",
|
|
2310
|
-
"version": "6.
|
|
2322
|
+
"version": "6.13.0-beta.1",
|
|
2311
2323
|
"source": {
|
|
2312
2324
|
"human": "core/model-provenance.md",
|
|
2313
2325
|
"ai": "ai/standards/model-provenance.ai.yaml"
|
|
@@ -2319,7 +2331,7 @@
|
|
|
2319
2331
|
"id": "resource-cost-boundary",
|
|
2320
2332
|
"name": "Resource / Cost Boundary Declaration Standards",
|
|
2321
2333
|
"nameZh": "資源/成本邊界宣告標準",
|
|
2322
|
-
"version": "6.
|
|
2334
|
+
"version": "6.13.0-beta.1",
|
|
2323
2335
|
"source": {
|
|
2324
2336
|
"human": "core/resource-cost-boundary.md",
|
|
2325
2337
|
"ai": "ai/standards/resource-cost-boundary.ai.yaml"
|