universal-dev-standards 6.13.1 → 6.14.0-beta.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/bin/uds.js +37 -0
- package/bundled/ai/standards/open-work-tracking.ai.yaml +71 -4
- package/bundled/ai/standards/turn-completion-integrity.ai.yaml +14 -7
- package/bundled/core/open-work-tracking.md +111 -8
- package/bundled/core/turn-completion-integrity.md +58 -11
- package/bundled/hooks/check-turn-completion-agy.mjs +147 -0
- package/bundled/hooks/turn-completion/locales/en.mjs +54 -5
- package/bundled/hooks/turn-completion/locales/zh-TW.mjs +37 -6
- package/bundled/locales/zh-CN/CHANGELOG.md +33 -3
- package/bundled/locales/zh-CN/README.md +2 -2
- package/bundled/locales/zh-CN/SECURITY.md +1 -0
- package/bundled/locales/zh-CN/core/turn-completion-integrity.md +46 -13
- package/bundled/locales/zh-CN/docs/CHEATSHEET.md +6 -1
- package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +33 -8
- package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +17 -7
- package/bundled/locales/zh-TW/CHANGELOG.md +33 -3
- package/bundled/locales/zh-TW/README.md +2 -2
- package/bundled/locales/zh-TW/SECURITY.md +1 -0
- package/bundled/locales/zh-TW/core/open-work-tracking.md +88 -9
- package/bundled/locales/zh-TW/core/turn-completion-integrity.md +46 -13
- package/bundled/locales/zh-TW/docs/CHEATSHEET.md +6 -1
- package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +33 -8
- package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +17 -7
- package/package.json +1 -1
- package/src/commands/init.js +17 -2
- package/src/commands/open-work.js +60 -0
- package/src/commands/uninstall.js +1 -1
- package/src/commands/update.js +91 -0
- package/src/i18n/messages.js +3 -0
- package/src/installers/hooks-installer.js +276 -11
- package/src/uninstallers/hook-uninstaller.js +107 -4
- package/src/utils/detector.js +46 -1
- package/src/utils/open-work-tracking.mjs +693 -0
- package/standards-registry.json +8 -8
|
@@ -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-29
|
|
5
5
|
|
|
6
6
|
**Language**: [English](../../../docs/reference/FEATURE-REFERENCE.md) | 繁體中文 | [简体中文](../../zh-CN/docs/FEATURE-REFERENCE.md)
|
|
7
7
|
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
|
|
10
10
|
## 目錄
|
|
11
11
|
|
|
12
|
-
1. [CLI 指令](#cli-commands) (
|
|
12
|
+
1. [CLI 指令](#cli-commands) (24)
|
|
13
13
|
2. [斜線命令](#slash-commands) (51)
|
|
14
14
|
3. [技能](#skills) (55)
|
|
15
15
|
4. [代理](#agents) (5)
|
|
16
16
|
5. [工作流程](#workflows) (5)
|
|
17
17
|
6. [核心規範](#core-standards) (153)
|
|
18
|
-
7. [腳本](#scripts) (
|
|
18
|
+
7. [腳本](#scripts) (63)
|
|
19
19
|
|
|
20
|
-
**Total Features:
|
|
20
|
+
**Total Features: 356**
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
@@ -158,6 +158,8 @@
|
|
|
158
158
|
| `--rollback` | Rollback to the most recent backup |
|
|
159
159
|
| `--claude-target` | Switch an existing install to a different Claude Code integration target: project (CLAUDE.md) or local (CLAUDE.local.md) — moves the UDS block, keeps your content, no reinstall |
|
|
160
160
|
| `--locale` | Override locale for skills install (zh-tw, zh-cn, en); also reads .uds/install.yaml + UDS_LOCALE env |
|
|
161
|
+
| `--with-hooks` | Install the enforcement hooks that are missing from this already-initialized project (re-detects tools; hooks already there and your own hooks are not touched; with --plan, writes nothing; --force also overwrites edited hook scripts) |
|
|
162
|
+
| `--ai-tool` | With --with-hooks: comma-separated tools to install hooks for (claude-code, codex, gemini-cli, antigravity) instead of detecting them |
|
|
161
163
|
|
|
162
164
|
### `uds skills`
|
|
163
165
|
|
|
@@ -276,6 +278,10 @@
|
|
|
276
278
|
|
|
277
279
|
**說明**: MCP server commands for AI tool integration
|
|
278
280
|
|
|
281
|
+
### `uds open-work`
|
|
282
|
+
|
|
283
|
+
**說明**: Reference checks for open-work-tracking (OWT-017/018/019). Exit 0 no violation, 1 violation, 2 cannot decide (not a pass)
|
|
284
|
+
|
|
279
285
|
### `uds run`
|
|
280
286
|
|
|
281
287
|
**說明**: Run a project command by intent (test/lint/build/security) via uds.project.yaml
|
|
@@ -478,7 +484,7 @@
|
|
|
478
484
|
| `deployment-standards` | 1.1.0 | This standard defines guidelines for safely deploying software to production, co |
|
|
479
485
|
| `deprecation-standards` | 1.1.0 | |
|
|
480
486
|
| `design-document-standards` | 1.0.0 | |
|
|
481
|
-
| `developer-memory` | 1.
|
|
487
|
+
| `developer-memory` | 1.2.0 | This standard defines a structured system for capturing, retrieving, and surfaci |
|
|
482
488
|
| `disaster-recovery-drill` | - | |
|
|
483
489
|
| `documentation-lifecycle` | 1.0.0 | This standard defines **when** to update documentation, **when** to check it, an |
|
|
484
490
|
| `documentation-structure` | 1.5.0 | This standard defines a consistent documentation structure for software projects |
|
|
@@ -516,7 +522,7 @@
|
|
|
516
522
|
| `mutation-testing` | 1.1.0 | Mutation testing evaluates test suite effectiveness by injecting artificial bugs |
|
|
517
523
|
| `no-cicd-deployment` | - | |
|
|
518
524
|
| `observability-standards` | 1.0.0 | |
|
|
519
|
-
| `open-work-tracking` | 1.
|
|
525
|
+
| `open-work-tracking` | 1.1.0 | The deferred-item-exit standard requires that a deferred item leave its document |
|
|
520
526
|
| `packaging-standards` | 1.1.0 | This standard defines a Recipe-based packaging framework that enables user proje |
|
|
521
527
|
| `performance-standards` | 1.2.0 | This standard defines comprehensive guidelines for software performance engineer |
|
|
522
528
|
| `pii-classification` | 1.1.0 | **Status**: Active | **Updated**: 2026-06-19 | |
|
|
@@ -574,7 +580,7 @@
|
|
|
574
580
|
| `timeout-standards` | - | |
|
|
575
581
|
| `token-budget` | - | |
|
|
576
582
|
| `translation-lifecycle-standards` | 1.0.1 | Translation lifecycle standards: MISSING vs OUTDATED distinction, semver-aware s |
|
|
577
|
-
| `turn-completion-integrity` | 1.
|
|
583
|
+
| `turn-completion-integrity` | 1.5.0 | An agent writes *"I'll do X next"* and then ends the turn without doing X. |
|
|
578
584
|
| `user-journey-testing` | - | |
|
|
579
585
|
| `user-story-mapping` | 1.0.0 | **Status**: Active | **Updated**: 2026-06-17 | |
|
|
580
586
|
| `verification-evidence` | 1.3.0 | Establish an "Iron Law" that no task can be claimed as complete without verifica |
|
|
@@ -610,8 +616,11 @@
|
|
|
610
616
|
| `check-docs-sync.sh` | Documentation Sync Checker |
|
|
611
617
|
| `check-error-exit.mjs` | 🔴 沒填就是沒設定,而沒設定會 exit 2, |
|
|
612
618
|
| `check-external-references.mjs` | External Reference Checker (SPEC-SELFDIAG-001 REQ-5, AC-7) |
|
|
619
|
+
| `check-home-untouched.mjs` | check-home-untouched — did this run write anywhere UDS writes under HOME? |
|
|
620
|
+
| `check-open-work-tracking.mjs` | Open-work-tracking reference checks for OWT-017 / OWT-018 / OWT-019 — repo entry point. |
|
|
613
621
|
| `check-orphan-specs.ps1` | Check Orphan Specs |
|
|
614
622
|
| `check-orphan-specs.sh` | Orphan Spec Detection Script |
|
|
623
|
+
| `check-prompt-footprint.mjs` | Prompt Footprint Ratchet — DEC-117 D2/L2 |
|
|
615
624
|
| `check-scope-sync.ps1` | Check Scope Sync |
|
|
616
625
|
| `check-scope-sync.sh` | Scope Consistency Check Script |
|
|
617
626
|
| `check-skill-next-steps-sync.ps1` | Check Skill Next Steps Sync |
|
|
@@ -625,6 +634,7 @@
|
|
|
625
634
|
| `check-translation-hash-ratchet.sh` | XSPEC-392 R6 棘輪:新的翻譯必須帶 source_hash,既有的欠債冷凍為基線。 |
|
|
626
635
|
| `check-translation-sync.ps1` | Check Translation Sync |
|
|
627
636
|
| `check-translation-sync.sh` | Translation Sync Checker |
|
|
637
|
+
| `check-upgrade-fidelity.sh` | Upgrade Fidelity Checker |
|
|
628
638
|
| `check-usage-docs-sync.ps1` | Check if usage documentation needs to be regenerated |
|
|
629
639
|
| `check-usage-docs-sync.sh` | check-usage-docs-sync.sh |
|
|
630
640
|
| `check-version-sync.ps1` | Check Version Sync |
|
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -52,6 +52,8 @@ export async function initCommand(options) {
|
|
|
52
52
|
if (isInitialized(projectPath)) {
|
|
53
53
|
console.log(chalk.yellow(msg.alreadyInitialized));
|
|
54
54
|
console.log(chalk.gray(` ${msg.useUpdateOrDelete}`));
|
|
55
|
+
// `init` cannot run twice, so `--with-hooks` has no effect here; say where the door is.
|
|
56
|
+
if (options.withHooks) console.log(chalk.yellow(` ${msg.useUpdateWithHooks}`));
|
|
55
57
|
return;
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -281,8 +283,8 @@ export async function initCommand(options) {
|
|
|
281
283
|
}
|
|
282
284
|
}
|
|
283
285
|
|
|
284
|
-
// turn-completion-integrity is also extended to Codex
|
|
285
|
-
// (2026-09-25), each with its own config file and output contract — see
|
|
286
|
+
// turn-completion-integrity is also extended to Codex, Gemini CLI and
|
|
287
|
+
// Antigravity CLI (2026-09-25; agy 2026-09-29), each with its own config file and output contract — see
|
|
286
288
|
// installCodexHooks/installGeminiHooks in hooks-installer.js. Gated on the
|
|
287
289
|
// tools the adopter actually selected: writing a hooks.json into every
|
|
288
290
|
// project's .codex/ regardless of whether Codex is used would be noise,
|
|
@@ -311,6 +313,19 @@ export async function initCommand(options) {
|
|
|
311
313
|
console.log(chalk.yellow(` ⚠ Gemini CLI hook not installed — ${geminiResult.reason}`));
|
|
312
314
|
}
|
|
313
315
|
}
|
|
316
|
+
if (selectedTools.includes('antigravity')) {
|
|
317
|
+
const { installAgyHooks } = await import('../installers/hooks-installer.js');
|
|
318
|
+
const agyResult = installAgyHooks(projectPath);
|
|
319
|
+
if (agyResult.installed) {
|
|
320
|
+
console.log(chalk.green(' ✓ Antigravity CLI Stop hook installed (turn-completion-integrity; .agents/hooks.json)'));
|
|
321
|
+
// Verified 2026-09-29 (agy 1.2.12): single turn, no tool calls, `agy -p`.
|
|
322
|
+
// Multi-turn, tool-call turns and interactive mode are not verified —
|
|
323
|
+
// say so here, where the adopter believes it now works everywhere.
|
|
324
|
+
console.log(chalk.yellow(' ⚠ Verified against a real agy session for a single turn without tool calls in `agy -p` mode only; multi-turn, tool-call turns and interactive mode are not yet verified.'));
|
|
325
|
+
} else {
|
|
326
|
+
console.log(chalk.yellow(` ⚠ Antigravity CLI hook not installed — ${agyResult.reason}`));
|
|
327
|
+
}
|
|
328
|
+
}
|
|
314
329
|
}
|
|
315
330
|
|
|
316
331
|
// 5. Setup Pre-commit Hook
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `uds open-work` — the open-work-tracking reference checks (OWT-017 / 018 / 019)
|
|
3
|
+
* as a command, so an adopter can run them from the npm package.
|
|
4
|
+
*
|
|
5
|
+
* This file holds no rules. The one body of them is
|
|
6
|
+
* `../utils/open-work-tracking.mjs`; this only turns commander's parsed
|
|
7
|
+
* arguments back into the argv that module's `main()` reads, so the command and
|
|
8
|
+
* `node scripts/check-open-work-tracking.mjs` cannot disagree.
|
|
9
|
+
*
|
|
10
|
+
* Exit codes are the module's and are not translated: 0 no violation, 1
|
|
11
|
+
* violation, 2 cannot decide (no structure found, git failed, or the checker's
|
|
12
|
+
* own self-test arms failed). 2 is NOT a pass. `process.exitCode` is set rather
|
|
13
|
+
* than calling `process.exit()`, so commander's post-action hook still runs.
|
|
14
|
+
*
|
|
15
|
+
* It is a reference decision procedure offered as evidence (OWT-015), not a
|
|
16
|
+
* gate, and its coverage is unknown and uncalibrated (OWT-011, OWT-016); the
|
|
17
|
+
* module prints both statements on every run.
|
|
18
|
+
*
|
|
19
|
+
* @module commands/open-work
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { main } from '../utils/open-work-tracking.mjs';
|
|
23
|
+
|
|
24
|
+
/** Append `--name value` when the option was given. */
|
|
25
|
+
function withOption(argv, name, value) {
|
|
26
|
+
if (value !== undefined && value !== null) argv.push(name, String(value));
|
|
27
|
+
return argv;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function run(argv) {
|
|
31
|
+
process.exitCode = main(argv);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** uds open-work next-action [files...] [--root DIR] [--id-pattern RE] — OWT-019 */
|
|
35
|
+
export function openWorkNextActionCommand(files = [], options = {}) {
|
|
36
|
+
const argv = ['next-action'];
|
|
37
|
+
withOption(argv, '--root', options.root);
|
|
38
|
+
withOption(argv, '--id-pattern', options.idPattern);
|
|
39
|
+
run([...argv, ...files]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** uds open-work revision (--file PATH --base REV | --before FILE --after FILE) — OWT-018 */
|
|
43
|
+
export function openWorkRevisionCommand(options = {}) {
|
|
44
|
+
const argv = ['revision'];
|
|
45
|
+
withOption(argv, '--file', options.file);
|
|
46
|
+
withOption(argv, '--base', options.base);
|
|
47
|
+
withOption(argv, '--before', options.before);
|
|
48
|
+
withOption(argv, '--after', options.after);
|
|
49
|
+
run(argv);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** uds open-work separation [files...] — OWT-017 */
|
|
53
|
+
export function openWorkSeparationCommand(files = []) {
|
|
54
|
+
run(['separation', ...files]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** uds open-work self-test — run the checker's own arms and nothing else */
|
|
58
|
+
export function openWorkSelfTestCommand() {
|
|
59
|
+
run(['--self-test']);
|
|
60
|
+
}
|
|
@@ -56,7 +56,7 @@ export async function uninstallCommand(options) {
|
|
|
56
56
|
const categories = await checkbox({
|
|
57
57
|
message: msg.selectCategories,
|
|
58
58
|
choices: [
|
|
59
|
-
{ name: `${msg.categoryHooks} (.husky/pre-commit, .claude/settings.json, .codex/hooks.json, .gemini/settings.json)`, value: 'hooks', checked: true },
|
|
59
|
+
{ name: `${msg.categoryHooks} (.husky/pre-commit, .claude/settings.json, .codex/hooks.json, .gemini/settings.json, .agents/hooks.json)`, value: 'hooks', checked: true },
|
|
60
60
|
{ name: `${msg.categorySkills} (skills, commands)`, value: 'skills', checked: true },
|
|
61
61
|
{ name: `${msg.categoryIntegrations} (CLAUDE.md, .cursorrules, ...)`, value: 'integrations', checked: true },
|
|
62
62
|
{ name: `${msg.categoryStandards} (.standards/)`, value: 'standards', checked: true }
|
package/src/commands/update.js
CHANGED
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
} from '../config/ai-agent-paths.js';
|
|
47
47
|
import { getMarketplaceSkillsInfo } from '../utils/github.js';
|
|
48
48
|
import { detectAITools } from '../utils/detector.js';
|
|
49
|
+
import { HOOK_CAPABLE_TOOLS, resolveHookTools, installMissingHooks } from '../installers/hooks-installer.js';
|
|
49
50
|
import {
|
|
50
51
|
promptSkillsInstallLocation,
|
|
51
52
|
promptCommandsInstallation
|
|
@@ -451,6 +452,15 @@ export async function updateCommand(options) {
|
|
|
451
452
|
return;
|
|
452
453
|
}
|
|
453
454
|
|
|
455
|
+
// Handle --with-hooks (added 2026-09-29): install the enforcement hooks that are
|
|
456
|
+
// MISSING from an already-initialized project — the door `uds init --with-hooks`
|
|
457
|
+
// cannot be, because `uds init` refuses to run twice. Standalone like
|
|
458
|
+
// --claude-target and --sync-refs; and like them it honours --plan by writing nothing.
|
|
459
|
+
if (options.withHooks) {
|
|
460
|
+
await updateHooksOnly(projectPath, manifest, options);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
|
|
454
464
|
// Handle --sync-refs option.
|
|
455
465
|
// `--plan` is honoured here too. This branch is above the mode dispatch
|
|
456
466
|
// because sync-refs is its own operation rather than a scope of the
|
|
@@ -1827,6 +1837,87 @@ async function switchClaudeTarget(projectPath, manifest, target, options) { // e
|
|
|
1827
1837
|
* @param {Object} manifest - Manifest object (will be mutated with updated hashes)
|
|
1828
1838
|
* @returns {{success: boolean, updated: string[], errors: string[]}}
|
|
1829
1839
|
*/
|
|
1840
|
+
/**
|
|
1841
|
+
* `uds update --with-hooks [--ai-tool <list>] [--plan] [--force]`
|
|
1842
|
+
*
|
|
1843
|
+
* Adds the enforcement hooks that are missing; a hook that is already there is not
|
|
1844
|
+
* touched, and the adopter's own hooks are never touched (see installMissingHooks).
|
|
1845
|
+
* Exit code 1 only when there is no hook-capable tool to act on, or an install failed:
|
|
1846
|
+
* "nothing to do" is 0, "could not tell which tool" is not.
|
|
1847
|
+
*
|
|
1848
|
+
* @param {string} projectPath
|
|
1849
|
+
* @param {object} manifest
|
|
1850
|
+
* @param {{ plan?: boolean, force?: boolean, aiTool?: string, yes?: boolean }} options
|
|
1851
|
+
* @returns {Promise<void>}
|
|
1852
|
+
*/
|
|
1853
|
+
export async function updateHooksOnly(projectPath, manifest, options = {}) {
|
|
1854
|
+
const ignored = ['skills', 'commands', 'syncRefs', 'integrationsOnly', 'standardsOnly', 'apply', 'rollback', 'prune']
|
|
1855
|
+
.filter((k) => options[k]).map((k) => `--${k.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase())}`);
|
|
1856
|
+
if (ignored.length) {
|
|
1857
|
+
console.log(chalk.yellow(` ! --with-hooks does one thing and does not compose; ${ignored.join(', ')} ignored.`));
|
|
1858
|
+
console.log();
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
const capable = HOOK_CAPABLE_TOOLS.join(', ');
|
|
1862
|
+
const resolved = resolveHookTools(projectPath, manifest, { aiTool: options.aiTool });
|
|
1863
|
+
|
|
1864
|
+
if (resolved.unknown.length) {
|
|
1865
|
+
console.log(chalk.red(` ✗ No hook installer for: ${resolved.unknown.join(', ')}`));
|
|
1866
|
+
console.log(chalk.gray(` Tools with hooks: ${capable}`));
|
|
1867
|
+
console.log();
|
|
1868
|
+
process.exitCode = 1;
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
if (resolved.tools.length === 0) {
|
|
1872
|
+
// Both non-interactive and interactive get the same message: there is no prompt to
|
|
1873
|
+
// fall back to here, so the way to say which tool is spelled out instead.
|
|
1874
|
+
console.log(chalk.yellow(' ⚠ Could not tell which AI tool to install hooks for.'));
|
|
1875
|
+
console.log(chalk.gray(' Neither this project\'s manifest nor its files name one of: ' + capable + '.'));
|
|
1876
|
+
console.log(chalk.gray(' Say which one: uds update --with-hooks --ai-tool <tool>[,<tool>...]'));
|
|
1877
|
+
console.log(chalk.gray(' e.g. uds update --with-hooks --ai-tool antigravity'));
|
|
1878
|
+
console.log(chalk.gray(' What is detected: claude-code (.claude/ or CLAUDE.md) · codex (root AGENTS.md) · gemini-cli (GEMINI.md)'));
|
|
1879
|
+
console.log(chalk.gray(' antigravity (.agents/AGENTS.md, .agents/rules/, .agents/workflows/, .agents/plugins/ or .agents/hooks.json; .agents/skills/ is shared with Codex and does not count)'));
|
|
1880
|
+
console.log();
|
|
1881
|
+
process.exitCode = 1;
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
console.log(chalk.bold(options.plan ? 'Hooks — plan (nothing is written)' : 'Hooks'));
|
|
1886
|
+
for (const tool of resolved.tools) {
|
|
1887
|
+
console.log(chalk.gray(` ${tool}: ${resolved.sources[tool].join(', ')}`));
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
const { results, scripts } = installMissingHooks(projectPath, resolved.tools, {
|
|
1891
|
+
plan: !!options.plan,
|
|
1892
|
+
overwriteScripts: !!options.force,
|
|
1893
|
+
});
|
|
1894
|
+
|
|
1895
|
+
let failed = false;
|
|
1896
|
+
for (const r of results) {
|
|
1897
|
+
const rel = r.path ? relative(projectPath, r.path) || r.path : '';
|
|
1898
|
+
if (r.outcome === 'installed') console.log(chalk.green(` ✓ ${r.tool}: installed${r.repaired ? ' (replaced an out-of-date UDS entry)' : ''} — ${rel}`));
|
|
1899
|
+
else if (r.outcome === 'would-install') console.log(chalk.cyan(` + ${r.tool}: would install${r.repaired ? ' (replacing an out-of-date UDS entry)' : ''} — ${rel}`));
|
|
1900
|
+
else if (r.outcome === 'unchanged') console.log(chalk.gray(` · ${r.tool}: already installed, not touched — ${rel}`));
|
|
1901
|
+
else { failed = true; console.log(chalk.yellow(` ⚠ ${r.tool}: not installed — ${r.why}`)); }
|
|
1902
|
+
}
|
|
1903
|
+
const installedAny = results.some((r) => r.outcome === 'installed' || r.outcome === 'would-install');
|
|
1904
|
+
if (installedAny && scripts.kept.length) {
|
|
1905
|
+
console.log(chalk.yellow(` ! ${scripts.kept.length} hook script(s) in scripts/hooks/ differ from this UDS version and were kept: ${scripts.kept.slice(0, 5).join(', ')}${scripts.kept.length > 5 ? ', ...' : ''}`));
|
|
1906
|
+
console.log(chalk.gray(' Add --force to overwrite them with the shipped versions.'));
|
|
1907
|
+
}
|
|
1908
|
+
if (results.some((r) => r.tool === 'antigravity' && r.outcome === 'installed')) {
|
|
1909
|
+
console.log(chalk.yellow(' ⚠ Verified against a real agy session for a single turn without tool calls in `agy -p` mode only; multi-turn, tool-call turns and interactive mode are not yet verified.'));
|
|
1910
|
+
}
|
|
1911
|
+
if (results.some((r) => r.tool === 'codex' && r.outcome === 'installed')) {
|
|
1912
|
+
console.log(chalk.yellow(' ⚠ Codex will not run it until you trust it: open Codex in this project, trust the project, then run /hooks and trust this hook.'));
|
|
1913
|
+
}
|
|
1914
|
+
if (!results.some((r) => r.outcome === 'installed' || r.outcome === 'would-install')) {
|
|
1915
|
+
console.log(chalk.gray(' Nothing to add.'));
|
|
1916
|
+
}
|
|
1917
|
+
console.log();
|
|
1918
|
+
if (failed) process.exitCode = 1;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1830
1921
|
export function regenerateIntegrations(projectPath, manifest) {
|
|
1831
1922
|
const aiTools = manifest.aiTools || [];
|
|
1832
1923
|
|
package/src/i18n/messages.js
CHANGED
|
@@ -930,6 +930,7 @@ export const messages = {
|
|
|
930
930
|
title: 'Universal Development Standards - Initialize',
|
|
931
931
|
alreadyInitialized: '⚠ Standards already initialized in this project.',
|
|
932
932
|
useUpdateOrDelete: 'Use `uds update` to update, or delete .standards/ to reinitialize.',
|
|
933
|
+
useUpdateWithHooks: 'To add enforcement hooks to this project (including for tools UDS began supporting after you initialized), run `uds update --with-hooks`.',
|
|
933
934
|
// Detection
|
|
934
935
|
detectingProject: 'Detecting project characteristics...',
|
|
935
936
|
analysisComplete: 'Project analysis complete',
|
|
@@ -2188,6 +2189,7 @@ export const messages = {
|
|
|
2188
2189
|
title: '通用開發標準 - 初始化',
|
|
2189
2190
|
alreadyInitialized: '⚠ 此專案已初始化標準。',
|
|
2190
2191
|
useUpdateOrDelete: '使用 `uds update` 更新,或刪除 .standards/ 重新初始化。',
|
|
2192
|
+
useUpdateWithHooks: '要為這個專案補裝執行關卡(含 UDS 在你初始化之後才支援的工具),請執行 `uds update --with-hooks`。',
|
|
2191
2193
|
// Detection
|
|
2192
2194
|
detectingProject: '正在偵測專案特性...',
|
|
2193
2195
|
analysisComplete: '專案分析完成',
|
|
@@ -3158,6 +3160,7 @@ export const messages = {
|
|
|
3158
3160
|
title: '通用开发标准 - 初始化',
|
|
3159
3161
|
alreadyInitialized: '⚠ 此项目已初始化标准。',
|
|
3160
3162
|
useUpdateOrDelete: '使用 `uds update` 更新,或删除 .standards/ 重新初始化。',
|
|
3163
|
+
useUpdateWithHooks: '要为这个项目补装执行关卡(含 UDS 在你初始化之后才支持的工具),请执行 `uds update --with-hooks`。',
|
|
3161
3164
|
// Detection
|
|
3162
3165
|
detectingProject: '正在检测项目特性...',
|
|
3163
3166
|
analysisComplete: '项目分析完成',
|