universal-dev-standards 5.14.0 → 5.16.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/bin/uds.js +2 -0
- package/bundled/ai/standards/acceptance-criteria-traceability.ai.yaml +31 -0
- package/bundled/ai/standards/ai-instruction-standards.ai.yaml +190 -3
- package/bundled/ai/standards/forward-derivation-standards.ai.yaml +23 -0
- package/bundled/ai/standards/knowledge-graph-memory.ai.yaml +83 -0
- package/bundled/core/acceptance-criteria-traceability.md +46 -0
- package/bundled/core/ai-instruction-standards.md +136 -11
- package/bundled/core/forward-derivation-standards.md +19 -0
- package/bundled/core/knowledge-graph-memory.md +119 -0
- package/bundled/locales/COVERAGE.md +226 -0
- package/bundled/locales/zh-CN/CHANGELOG.md +42 -3
- package/bundled/locales/zh-CN/README.md +1 -1
- package/bundled/locales/zh-CN/SECURITY.md +1 -1
- package/bundled/locales/zh-CN/core/acceptance-criteria-traceability.md +46 -0
- package/bundled/locales/zh-CN/core/ai-instruction-standards.md +111 -5
- package/bundled/locales/zh-CN/core/forward-derivation-standards.md +19 -0
- package/bundled/locales/zh-CN/skills/ac-coverage/SKILL.md +194 -0
- package/bundled/locales/zh-CN/skills/adr-assistant/SKILL.md +135 -40
- package/bundled/locales/zh-CN/skills/brainstorm-assistant/SKILL.md +217 -63
- package/bundled/locales/zh-CN/skills/brainstorm-assistant/guide.md +599 -0
- package/bundled/locales/zh-CN/skills/commands/brainstorm.md +92 -25
- package/bundled/locales/zh-CN/skills/commit-standards/SKILL.md +78 -16
- package/bundled/locales/zh-CN/skills/contract-test-assistant/SKILL.md +85 -26
- package/bundled/locales/zh-CN/skills/deploy-assistant/SKILL.md +189 -0
- package/bundled/locales/zh-CN/skills/dev-methodology/SKILL.md +110 -0
- package/bundled/locales/zh-CN/skills/dev-methodology/guide.md +255 -0
- package/bundled/locales/zh-CN/skills/dev-workflow-guide/SKILL.md +70 -11
- package/bundled/locales/zh-CN/skills/journey-test-assistant/SKILL.md +209 -0
- package/bundled/locales/zh-CN/skills/knowledge-graph/SKILL.md +58 -0
- package/bundled/locales/zh-CN/skills/knowledge-graph/guide.md +74 -0
- package/bundled/locales/zh-CN/skills/migration-assistant/SKILL.md +125 -8
- package/bundled/locales/zh-CN/skills/observability-assistant/guide.md +188 -0
- package/bundled/locales/zh-CN/skills/orchestrate/SKILL.md +173 -0
- package/bundled/locales/zh-CN/skills/plan/SKILL.md +240 -0
- package/bundled/locales/zh-CN/skills/push/SKILL.md +242 -0
- package/bundled/locales/zh-CN/skills/retrospective-assistant/SKILL.md +104 -36
- package/bundled/locales/zh-CN/skills/reverse-engineer/SKILL.md +88 -32
- package/bundled/locales/zh-CN/skills/runbook-assistant/guide.md +216 -0
- package/bundled/locales/zh-CN/skills/skill-builder/SKILL.md +149 -0
- package/bundled/locales/zh-CN/skills/slo-assistant/guide.md +188 -0
- package/bundled/locales/zh-CN/skills/spec-derivation/SKILL.md +86 -0
- package/bundled/locales/zh-CN/skills/spec-derivation/guide.md +476 -0
- package/bundled/locales/zh-CN/skills/spec-driven-dev/SKILL.md +155 -81
- package/bundled/locales/zh-CN/skills/sweep/SKILL.md +151 -0
- package/bundled/locales/zh-CN/skills/testing-guide/SKILL.md +207 -110
- package/bundled/locales/zh-TW/CHANGELOG.md +46 -3
- package/bundled/locales/zh-TW/README.md +1 -1
- package/bundled/locales/zh-TW/SECURITY.md +1 -1
- package/bundled/locales/zh-TW/core/acceptance-criteria-traceability.md +46 -0
- package/bundled/locales/zh-TW/core/ai-instruction-standards.md +130 -5
- package/bundled/locales/zh-TW/core/browser-compatibility-standards.md +222 -5
- package/bundled/locales/zh-TW/core/contract-testing-standards.md +184 -5
- package/bundled/locales/zh-TW/core/cross-flow-regression.md +192 -5
- package/bundled/locales/zh-TW/core/forward-derivation-standards.md +19 -0
- package/bundled/locales/zh-TW/core/knowledge-graph-memory.md +127 -0
- package/bundled/locales/zh-TW/core/release-readiness-gate.md +186 -5
- package/bundled/locales/zh-TW/core/self-review-protocol.md +9 -1
- package/bundled/locales/zh-TW/skills/ac-coverage/SKILL.md +192 -0
- package/bundled/locales/zh-TW/skills/adr-assistant/SKILL.md +21 -42
- package/bundled/locales/zh-TW/skills/ai-collaboration-standards/SKILL.md +5 -1
- package/bundled/locales/zh-TW/skills/brainstorm-assistant/SKILL.md +212 -59
- package/bundled/locales/zh-TW/skills/brainstorm-assistant/guide.md +266 -579
- package/bundled/locales/zh-TW/skills/commands/brainstorm.md +91 -26
- package/bundled/locales/zh-TW/skills/commit-standards/SKILL.md +77 -15
- package/bundled/locales/zh-TW/skills/contract-test-assistant/SKILL.md +75 -16
- package/bundled/locales/zh-TW/skills/deploy-assistant/SKILL.md +187 -0
- package/bundled/locales/zh-TW/skills/dev-methodology/SKILL.md +108 -0
- package/bundled/locales/zh-TW/skills/dev-methodology/guide.md +255 -0
- package/bundled/locales/zh-TW/skills/dev-workflow-guide/SKILL.md +125 -64
- package/bundled/locales/zh-TW/skills/journey-test-assistant/SKILL.md +222 -0
- package/bundled/locales/zh-TW/skills/knowledge-graph/SKILL.md +56 -0
- package/bundled/locales/zh-TW/skills/knowledge-graph/guide.md +74 -0
- package/bundled/locales/zh-TW/skills/migration-assistant/SKILL.md +128 -11
- package/bundled/locales/zh-TW/skills/observability-assistant/guide.md +188 -0
- package/bundled/locales/zh-TW/skills/orchestrate/SKILL.md +173 -0
- package/bundled/locales/zh-TW/skills/plan/SKILL.md +240 -0
- package/bundled/locales/zh-TW/skills/project-structure-guide/SKILL.md +5 -1
- package/bundled/locales/zh-TW/skills/push/SKILL.md +242 -0
- package/bundled/locales/zh-TW/skills/retrospective-assistant/SKILL.md +94 -28
- package/bundled/locales/zh-TW/skills/reverse-engineer/SKILL.md +84 -28
- package/bundled/locales/zh-TW/skills/runbook-assistant/guide.md +216 -0
- package/bundled/locales/zh-TW/skills/skill-builder/SKILL.md +165 -0
- package/bundled/locales/zh-TW/skills/slo-assistant/guide.md +188 -0
- package/bundled/locales/zh-TW/skills/spec-derivation/SKILL.md +83 -0
- package/bundled/locales/zh-TW/skills/spec-derivation/guide.md +476 -0
- package/bundled/locales/zh-TW/skills/spec-driven-dev/SKILL.md +148 -77
- package/bundled/locales/zh-TW/skills/sweep/SKILL.md +149 -0
- package/bundled/locales/zh-TW/skills/testing-guide/SKILL.md +141 -44
- package/bundled/skills/adr-assistant/SKILL.md +1 -1
- package/bundled/skills/ai-collaboration-standards/SKILL.md +1 -1
- package/bundled/skills/ai-friendly-architecture/SKILL.md +1 -1
- package/bundled/skills/ai-instruction-standards/SKILL.md +1 -1
- package/bundled/skills/api-design-assistant/SKILL.md +1 -1
- package/bundled/skills/audit-assistant/SKILL.md +1 -1
- package/bundled/skills/brainstorm-assistant/SKILL.md +142 -106
- package/bundled/skills/brainstorm-assistant/guide.md +256 -661
- package/bundled/skills/ci-cd-assistant/SKILL.md +1 -1
- package/bundled/skills/commands/brainstorm.md +51 -30
- package/bundled/skills/contract-test-assistant/SKILL.md +1 -1
- package/bundled/skills/database-assistant/SKILL.md +1 -1
- package/bundled/skills/deploy-assistant/SKILL.md +1 -1
- package/bundled/skills/documentation-guide/SKILL.md +1 -1
- package/bundled/skills/error-code-guide/SKILL.md +1 -1
- package/bundled/skills/git-workflow-guide/SKILL.md +1 -1
- package/bundled/skills/incident-response-assistant/SKILL.md +1 -1
- package/bundled/skills/journey-test-assistant/SKILL.md +1 -1
- package/bundled/skills/knowledge-graph/SKILL.md +58 -0
- package/bundled/skills/knowledge-graph/guide.md +69 -0
- package/bundled/skills/logging-guide/SKILL.md +1 -1
- package/bundled/skills/observability-assistant/SKILL.md +1 -1
- package/bundled/skills/orchestrate/SKILL.md +1 -1
- package/bundled/skills/plan/SKILL.md +1 -1
- package/bundled/skills/pr-automation-assistant/SKILL.md +1 -1
- package/bundled/skills/project-structure-guide/SKILL.md +1 -1
- package/bundled/skills/push/SKILL.md +1 -1
- package/bundled/skills/retrospective-assistant/SKILL.md +1 -1
- package/bundled/skills/reverse-engineer/SKILL.md +1 -1
- package/bundled/skills/runbook-assistant/SKILL.md +1 -1
- package/bundled/skills/security-assistant/SKILL.md +1 -1
- package/bundled/skills/security-scan-assistant/SKILL.md +1 -1
- package/bundled/skills/slo-assistant/SKILL.md +1 -1
- package/bundled/skills/sweep/SKILL.md +1 -1
- package/bundled/skills/testing-guide/SKILL.md +1 -1
- package/package.json +2 -2
- package/src/commands/check.js +80 -0
- package/src/commands/init.js +8 -1
- package/src/commands/update.js +49 -14
- package/src/i18n/messages.js +32 -5
- package/src/installers/skills-installer.js +49 -0
- package/src/lint/i18n.js +424 -0
- package/src/utils/config-manager.js +39 -0
- package/src/utils/skills-installer.js +39 -7
- package/standards-registry.json +16 -4
- package/bundled/locales/zh-TW/docs/SKILL-FALLBACK-GUIDE.md +0 -407
package/src/commands/init.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
import { displayLanguageToLocale } from '../utils/locale.js';
|
|
24
24
|
import { generateReleaseConfig, RELEASE_MODE_LABELS } from '../utils/release-config.js';
|
|
25
25
|
import { guardAgainstSelfAdoption } from '../utils/detect-self-adoption.js';
|
|
26
|
+
import { readInstallYaml } from '../utils/config-manager.js';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Init command - initialize standards in current project
|
|
@@ -308,7 +309,13 @@ echo "Pre-commit checks passed"
|
|
|
308
309
|
* Build configuration for non-interactive mode
|
|
309
310
|
*/
|
|
310
311
|
function buildNonInteractiveConfig(options, detected, projectPath) {
|
|
311
|
-
|
|
312
|
+
// Locale resolution order (XSPEC-239 §Req-3):
|
|
313
|
+
// CLI --locale > .uds/install.yaml locale: > UDS_LOCALE env > LANG > 'en'
|
|
314
|
+
// detectLanguage() handles UDS_LOCALE + LANG fallback internally (P1-CLI-3).
|
|
315
|
+
const installYaml = readInstallYaml(projectPath);
|
|
316
|
+
const displayLanguage = options.locale
|
|
317
|
+
|| installYaml.locale
|
|
318
|
+
|| detectLanguage(null);
|
|
312
319
|
|
|
313
320
|
// Determine AI tools
|
|
314
321
|
const detectedAiTools = Object.keys(detected.aiTools).filter(k => detected.aiTools[k]);
|
package/src/commands/update.js
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
cleanupLegacyCommands
|
|
31
31
|
} from '../utils/skills-installer.js';
|
|
32
32
|
import { displayLanguageToLocale, isLocalizedLocale, detectLocaleFromStandards } from '../utils/locale.js';
|
|
33
|
+
import { readInstallYaml } from '../utils/config-manager.js';
|
|
33
34
|
import {
|
|
34
35
|
getAgentDisplayName,
|
|
35
36
|
getAgentConfig,
|
|
@@ -237,17 +238,49 @@ function checkNewStandards(manifest) {
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
/**
|
|
240
|
-
* Resolve locale
|
|
241
|
-
*
|
|
241
|
+
* Resolve locale for skill / command installation.
|
|
242
|
+
*
|
|
243
|
+
* Resolution order (XSPEC-239 §Req-3 / P1-CLI-2 + P1-CLI-3):
|
|
244
|
+
* 1. CLI `--locale` (passed via `options.locale`)
|
|
245
|
+
* 2. `.uds/install.yaml` `locale:`
|
|
246
|
+
* 3. `UDS_LOCALE` env var
|
|
247
|
+
* 4. manifest `options.display_language` (existing behaviour)
|
|
248
|
+
* 5. `.standards/` file-based detection (existing behaviour)
|
|
249
|
+
* 6. `'en'`
|
|
250
|
+
*
|
|
242
251
|
* @param {Object} manifest - Project manifest
|
|
243
252
|
* @param {string} projectPath - Project root path
|
|
253
|
+
* @param {Object} [options] - CLI options object (optional, for `--locale`)
|
|
244
254
|
* @returns {string} Locale directory name (e.g., 'zh-TW', 'en')
|
|
245
255
|
*/
|
|
246
|
-
function resolveLocale(manifest, projectPath) {
|
|
256
|
+
function resolveLocale(manifest, projectPath, options) {
|
|
257
|
+
// 1. CLI flag wins
|
|
258
|
+
const cliLocale = options?.locale && displayLanguageToLocale(options.locale);
|
|
259
|
+
if (cliLocale && isLocalizedLocale(cliLocale)) return cliLocale;
|
|
260
|
+
if (cliLocale === 'en') return 'en';
|
|
261
|
+
|
|
262
|
+
// 2. .uds/install.yaml
|
|
263
|
+
const installYaml = readInstallYaml(projectPath);
|
|
264
|
+
if (installYaml.locale) {
|
|
265
|
+
const fromYaml = displayLanguageToLocale(installYaml.locale);
|
|
266
|
+
if (isLocalizedLocale(fromYaml)) return fromYaml;
|
|
267
|
+
if (fromYaml === 'en') return 'en';
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// 3. UDS_LOCALE env
|
|
271
|
+
if (process.env.UDS_LOCALE) {
|
|
272
|
+
const fromEnv = displayLanguageToLocale(process.env.UDS_LOCALE);
|
|
273
|
+
if (isLocalizedLocale(fromEnv)) return fromEnv;
|
|
274
|
+
if (fromEnv === 'en') return 'en';
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 4. Manifest
|
|
247
278
|
const fromManifest = displayLanguageToLocale(manifest.options?.display_language);
|
|
248
279
|
if (isLocalizedLocale(fromManifest)) {
|
|
249
280
|
return fromManifest;
|
|
250
281
|
}
|
|
282
|
+
|
|
283
|
+
// 5. .standards/ detection → 6. 'en'
|
|
251
284
|
return detectLocaleFromStandards(projectPath) || 'en';
|
|
252
285
|
}
|
|
253
286
|
|
|
@@ -309,13 +342,13 @@ export async function updateCommand(options) {
|
|
|
309
342
|
|
|
310
343
|
// Handle --skills option
|
|
311
344
|
if (options.skills) {
|
|
312
|
-
await updateSkillsOnly(projectPath, manifest);
|
|
345
|
+
await updateSkillsOnly(projectPath, manifest, options);
|
|
313
346
|
return;
|
|
314
347
|
}
|
|
315
348
|
|
|
316
349
|
// Handle --commands option
|
|
317
350
|
if (options.commands) {
|
|
318
|
-
await updateCommandsOnly(projectPath, manifest);
|
|
351
|
+
await updateCommandsOnly(projectPath, manifest, options);
|
|
319
352
|
return;
|
|
320
353
|
}
|
|
321
354
|
|
|
@@ -892,7 +925,7 @@ export async function updateCommand(options) {
|
|
|
892
925
|
// Install Skills if user agreed
|
|
893
926
|
if (installSkills.length > 0) {
|
|
894
927
|
const skillSpinner = ora(msg.installingNewSkills || 'Installing Skills...').start();
|
|
895
|
-
const skillsLocale = resolveLocale(manifest, projectPath);
|
|
928
|
+
const skillsLocale = resolveLocale(manifest, projectPath, options);
|
|
896
929
|
const skillResult = await installSkillsToMultipleAgents(installSkills, null, projectPath, skillsLocale);
|
|
897
930
|
|
|
898
931
|
// Update manifest
|
|
@@ -933,7 +966,7 @@ export async function updateCommand(options) {
|
|
|
933
966
|
// Update outdated Skills if user agreed
|
|
934
967
|
if (updateSkills.length > 0) {
|
|
935
968
|
const updateSpinner = ora(msg.updatingSkills || 'Updating Skills...').start();
|
|
936
|
-
const updateLocale = resolveLocale(manifest, projectPath);
|
|
969
|
+
const updateLocale = resolveLocale(manifest, projectPath, options);
|
|
937
970
|
const updateResult = await installSkillsToMultipleAgents(updateSkills, null, projectPath, updateLocale);
|
|
938
971
|
|
|
939
972
|
// Update manifest version
|
|
@@ -969,7 +1002,7 @@ export async function updateCommand(options) {
|
|
|
969
1002
|
// Install Commands if user agreed
|
|
970
1003
|
if (installCommands.length > 0) {
|
|
971
1004
|
const cmdSpinner = ora(msg.installingNewCommands || 'Installing commands...').start();
|
|
972
|
-
const cmdLocale = resolveLocale(manifest, projectPath);
|
|
1005
|
+
const cmdLocale = resolveLocale(manifest, projectPath, options);
|
|
973
1006
|
const cmdResult = await installCommandsToMultipleAgents(installCommands, null, projectPath, cmdLocale);
|
|
974
1007
|
|
|
975
1008
|
// Update manifest
|
|
@@ -999,7 +1032,7 @@ export async function updateCommand(options) {
|
|
|
999
1032
|
// Update outdated Commands if user agreed
|
|
1000
1033
|
if (updateCommands.length > 0) {
|
|
1001
1034
|
const updateCmdSpinner = ora(msg.updatingCommands || 'Updating Commands...').start();
|
|
1002
|
-
const updateCmdLocale = resolveLocale(manifest, projectPath);
|
|
1035
|
+
const updateCmdLocale = resolveLocale(manifest, projectPath, options);
|
|
1003
1036
|
const updateCmdResult = await installCommandsToMultipleAgents(updateCommands, null, projectPath, updateCmdLocale);
|
|
1004
1037
|
|
|
1005
1038
|
// Update manifest version
|
|
@@ -1069,7 +1102,7 @@ export async function updateCommand(options) {
|
|
|
1069
1102
|
}
|
|
1070
1103
|
} else {
|
|
1071
1104
|
// --yes mode: auto-install/update Skills and Commands (treat -y as confirming all prompts)
|
|
1072
|
-
const skillsLocale = resolveLocale(manifest, projectPath);
|
|
1105
|
+
const skillsLocale = resolveLocale(manifest, projectPath, options);
|
|
1073
1106
|
let hasChanges = false;
|
|
1074
1107
|
|
|
1075
1108
|
if (missingSkills.length > 0) {
|
|
@@ -1551,8 +1584,9 @@ async function syncIntegrationReferences(projectPath, manifest) {
|
|
|
1551
1584
|
* Update Skills for all AI agents (--skills option)
|
|
1552
1585
|
* @param {string} projectPath - Project path
|
|
1553
1586
|
* @param {Object} manifest - Manifest object
|
|
1587
|
+
* @param {Object} [options] - CLI options (forwarded for locale resolution)
|
|
1554
1588
|
*/
|
|
1555
|
-
async function updateSkillsOnly(projectPath, manifest) {
|
|
1589
|
+
async function updateSkillsOnly(projectPath, manifest, options) {
|
|
1556
1590
|
const msg = t().commands.update;
|
|
1557
1591
|
const repoInfo = getRepositoryInfo();
|
|
1558
1592
|
const latestVersion = repoInfo.skills.version;
|
|
@@ -1621,7 +1655,7 @@ async function updateSkillsOnly(projectPath, manifest) {
|
|
|
1621
1655
|
|
|
1622
1656
|
const spinner = ora(msg.installingSkills || 'Installing Skills...').start();
|
|
1623
1657
|
|
|
1624
|
-
const skillsLocaleForUpdate = resolveLocale(manifest, projectPath);
|
|
1658
|
+
const skillsLocaleForUpdate = resolveLocale(manifest, projectPath, options);
|
|
1625
1659
|
const result = await installSkillsToMultipleAgents(
|
|
1626
1660
|
fileBasedInstallations,
|
|
1627
1661
|
null, // Install all skills
|
|
@@ -1665,8 +1699,9 @@ async function updateSkillsOnly(projectPath, manifest) {
|
|
|
1665
1699
|
* Update slash commands for all AI agents (--commands option)
|
|
1666
1700
|
* @param {string} projectPath - Project path
|
|
1667
1701
|
* @param {Object} manifest - Manifest object
|
|
1702
|
+
* @param {Object} [options] - CLI options (forwarded for locale resolution)
|
|
1668
1703
|
*/
|
|
1669
|
-
async function updateCommandsOnly(projectPath, manifest) {
|
|
1704
|
+
async function updateCommandsOnly(projectPath, manifest, options) {
|
|
1670
1705
|
const msg = t().commands.update;
|
|
1671
1706
|
|
|
1672
1707
|
console.log(chalk.cyan(msg.updatingCommandsOnly || 'Updating slash commands for all AI Agents...'));
|
|
@@ -1715,7 +1750,7 @@ async function updateCommandsOnly(projectPath, manifest) {
|
|
|
1715
1750
|
|
|
1716
1751
|
const spinner = ora(msg.installingCommands || 'Installing commands...').start();
|
|
1717
1752
|
|
|
1718
|
-
const commandsLocale = resolveLocale(manifest, projectPath);
|
|
1753
|
+
const commandsLocale = resolveLocale(manifest, projectPath, options);
|
|
1719
1754
|
const result = await installCommandsToMultipleAgents(
|
|
1720
1755
|
commandsInstallations,
|
|
1721
1756
|
null, // Install all commands
|
package/src/i18n/messages.js
CHANGED
|
@@ -1003,6 +1003,10 @@ export const messages = {
|
|
|
1003
1003
|
installingSkills: 'Installing Claude Code Skills...',
|
|
1004
1004
|
installedSkills: 'Installed {count} Skills to {locations}',
|
|
1005
1005
|
installedSkillsWithErrors: 'Installed {count} Skills with {errors} errors',
|
|
1006
|
+
// P1-CLI-1: locale fallback summary (printed after install when some
|
|
1007
|
+
// skills lack a localized variant and fell back to English source)
|
|
1008
|
+
localeFallbackTitle: 'Locale fallback: {count} skill(s) fell back to English because no {locale} variant exists:',
|
|
1009
|
+
localeFallbackHint: 'See locales/COVERAGE.md for full coverage status.',
|
|
1006
1010
|
// Success
|
|
1007
1011
|
initializedSuccess: '✓ Standards initialized successfully!',
|
|
1008
1012
|
filesCopied: '{count} files copied to project',
|
|
@@ -2264,6 +2268,9 @@ export const messages = {
|
|
|
2264
2268
|
installingSkills: '安裝 Claude Code Skills 中...',
|
|
2265
2269
|
installedSkills: '已安裝 {count} 個 Skills 到 {locations}',
|
|
2266
2270
|
installedSkillsWithErrors: '已安裝 {count} 個 Skills,有 {errors} 個錯誤',
|
|
2271
|
+
// P1-CLI-1:locale fallback 摘要(安裝結束後顯示,列出沒有對應語系變體而退回英文來源的 skill)
|
|
2272
|
+
localeFallbackTitle: 'Locale fallback:{count} 個 skill 因為沒有 {locale} 變體而退回英文版本:',
|
|
2273
|
+
localeFallbackHint: '完整覆蓋率請參閱 locales/COVERAGE.md。',
|
|
2267
2274
|
// Success
|
|
2268
2275
|
initializedSuccess: '✓ 標準初始化成功!',
|
|
2269
2276
|
filesCopied: '已複製 {count} 個檔案到專案',
|
|
@@ -3270,6 +3277,9 @@ export const messages = {
|
|
|
3270
3277
|
installingSkills: '正在安装 Claude Code Skills...',
|
|
3271
3278
|
installedSkills: '已安装 {count} 个 Skills 到 {locations}',
|
|
3272
3279
|
installedSkillsWithErrors: '已安装 {count} 个 Skills,有 {errors} 个错误',
|
|
3280
|
+
// P1-CLI-1:locale fallback 摘要(安装结束后显示,列出没有对应语种变体而退回英文来源的 skill)
|
|
3281
|
+
localeFallbackTitle: 'Locale fallback:{count} 个 skill 因为没有 {locale} 变体而退回英文版本:',
|
|
3282
|
+
localeFallbackHint: '完整覆盖率请参阅 locales/COVERAGE.md。',
|
|
3273
3283
|
// Success
|
|
3274
3284
|
initializedSuccess: '✓ 标准初始化成功!',
|
|
3275
3285
|
filesCopied: '已复制 {count} 个文件到项目',
|
|
@@ -3792,12 +3802,19 @@ export function msg(path) {
|
|
|
3792
3802
|
}
|
|
3793
3803
|
|
|
3794
3804
|
/**
|
|
3795
|
-
* Detect language from environment or locale setting
|
|
3805
|
+
* Detect language from environment or locale setting.
|
|
3806
|
+
*
|
|
3807
|
+
* Resolution order (XSPEC-239 §Req-3 / P1-CLI-3):
|
|
3808
|
+
* 1. explicit `locale` arg (from CLI `--locale`)
|
|
3809
|
+
* 2. `UDS_LOCALE` env var (UDS-specific override; takes precedence over LANG)
|
|
3810
|
+
* 3. POSIX locale env vars (`LANG` / `LC_ALL` / `LC_MESSAGES`)
|
|
3811
|
+
* 4. `'en'`
|
|
3812
|
+
*
|
|
3796
3813
|
* @param {string|null} locale - Locale setting from CLI options
|
|
3797
|
-
* @returns {string} Detected language code
|
|
3814
|
+
* @returns {string} Detected language code ('zh-tw' | 'zh-cn' | 'en')
|
|
3798
3815
|
*/
|
|
3799
3816
|
export function detectLanguage(locale) {
|
|
3800
|
-
// If locale is explicitly set, use it
|
|
3817
|
+
// 1. If locale is explicitly set, use it
|
|
3801
3818
|
if (locale === 'zh-tw') {
|
|
3802
3819
|
return 'zh-tw';
|
|
3803
3820
|
}
|
|
@@ -3805,7 +3822,17 @@ export function detectLanguage(locale) {
|
|
|
3805
3822
|
return 'zh-cn';
|
|
3806
3823
|
}
|
|
3807
3824
|
|
|
3808
|
-
//
|
|
3825
|
+
// 2. UDS-specific env var (P1-CLI-3): preferred over generic POSIX LANG so
|
|
3826
|
+
// adopters can opt into a specific UDS locale in CI without touching LANG.
|
|
3827
|
+
if (process.env.UDS_LOCALE) {
|
|
3828
|
+
const v = process.env.UDS_LOCALE.toLowerCase();
|
|
3829
|
+
if (v === 'zh-tw' || v === 'zh_tw') return 'zh-tw';
|
|
3830
|
+
if (v === 'zh-cn' || v === 'zh_cn') return 'zh-cn';
|
|
3831
|
+
if (v === 'en') return 'en';
|
|
3832
|
+
// Unknown UDS_LOCALE values fall through to LANG detection below
|
|
3833
|
+
}
|
|
3834
|
+
|
|
3835
|
+
// 3. Check POSIX environment variables
|
|
3809
3836
|
const envLang = process.env.LANG || process.env.LC_ALL || process.env.LC_MESSAGES || '';
|
|
3810
3837
|
if (envLang.toLowerCase().includes('zh_tw') || envLang.toLowerCase().includes('zh-tw')) {
|
|
3811
3838
|
return 'zh-tw';
|
|
@@ -3814,6 +3841,6 @@ export function detectLanguage(locale) {
|
|
|
3814
3841
|
return 'zh-cn';
|
|
3815
3842
|
}
|
|
3816
3843
|
|
|
3817
|
-
// Default to English
|
|
3844
|
+
// 4. Default to English
|
|
3818
3845
|
return 'en';
|
|
3819
3846
|
}
|
|
@@ -34,6 +34,46 @@ import {
|
|
|
34
34
|
} from '../config/ai-agent-paths.js';
|
|
35
35
|
import { getRepositoryInfo } from '../utils/registry.js';
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Print a single WARN block summarizing skills that fell back to the English
|
|
39
|
+
* source because no localized variant exists for the requested locale.
|
|
40
|
+
*
|
|
41
|
+
* Adopter-facing behaviour (XSPEC-239 §Req-3 / P1-CLI-1):
|
|
42
|
+
* - One yellow block at the end of install, listing all fallen-back skills.
|
|
43
|
+
* - Hint pointer to `locales/COVERAGE.md` for the full coverage matrix.
|
|
44
|
+
*
|
|
45
|
+
* The `messages` bundle is the same flat command-scope bundle that `installSkills`
|
|
46
|
+
* receives (e.g. `t().commands.init`). Falls back to English literals if keys
|
|
47
|
+
* are absent so older translation bundles keep working.
|
|
48
|
+
*
|
|
49
|
+
* @param {string[]} fallenBack - Skill names that fell back to English
|
|
50
|
+
* @param {string} [locale] - Requested locale (e.g. 'zh-TW'); used in the message
|
|
51
|
+
* @param {Object} [messages] - Command-scope i18n bundle (optional)
|
|
52
|
+
* @returns {void}
|
|
53
|
+
*/
|
|
54
|
+
export function printLocaleFallbackWarning(fallenBack, locale, messages) {
|
|
55
|
+
if (!fallenBack || fallenBack.length === 0) return;
|
|
56
|
+
|
|
57
|
+
const count = fallenBack.length;
|
|
58
|
+
const localeLabel = locale || 'requested locale';
|
|
59
|
+
|
|
60
|
+
const titleTemplate = messages?.localeFallbackTitle
|
|
61
|
+
|| 'Locale fallback: {count} skill(s) fell back to English because no {locale} variant exists:';
|
|
62
|
+
const hint = messages?.localeFallbackHint
|
|
63
|
+
|| 'See locales/COVERAGE.md for full coverage status.';
|
|
64
|
+
|
|
65
|
+
const title = titleTemplate
|
|
66
|
+
.replace('{count}', String(count))
|
|
67
|
+
.replace('{locale}', localeLabel);
|
|
68
|
+
|
|
69
|
+
console.log();
|
|
70
|
+
console.log(chalk.yellow(`⚠ ${title}`));
|
|
71
|
+
for (const name of fallenBack) {
|
|
72
|
+
console.log(chalk.yellow(` - ${name}`));
|
|
73
|
+
}
|
|
74
|
+
console.log(chalk.gray(` ${hint}`));
|
|
75
|
+
}
|
|
76
|
+
|
|
37
77
|
/**
|
|
38
78
|
* Get all skill files mapping (skill name -> file paths)
|
|
39
79
|
* Used for remote download fallback
|
|
@@ -120,6 +160,15 @@ export async function installSkills(skillsConfig, projectPath, messages, results
|
|
|
120
160
|
.replace('{count}', installResult.totalInstalled)
|
|
121
161
|
.replace('{errors}', installResult.totalErrors));
|
|
122
162
|
}
|
|
163
|
+
|
|
164
|
+
// P1-CLI-1: Emit a single locale-fallback WARN after the install loop when
|
|
165
|
+
// adopters requested a localized variant but some skills only ship in English.
|
|
166
|
+
// The aggregated list is built in installSkillsToMultipleAgents (deduped).
|
|
167
|
+
if (Array.isArray(installResult.localeFallbacks) && installResult.localeFallbacks.length > 0) {
|
|
168
|
+
// `messages` is a flat command-scope bundle (e.g. t().commands.init);
|
|
169
|
+
// the WARN helper looks for localeFallbackTitle/Hint keys directly on it.
|
|
170
|
+
printLocaleFallbackWarning(installResult.localeFallbacks, skillsConfig.locale, messages);
|
|
171
|
+
}
|
|
123
172
|
} else if (skillsConfig.needsInstall && skillsConfig.updateTargets?.length > 0) {
|
|
124
173
|
// Legacy fallback for backward compatibility (remote download)
|
|
125
174
|
await installSkillsLegacy(skillsConfig, projectPath, messages, results);
|