universal-dev-standards 6.8.0 → 6.10.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 +12 -2
- package/bundled/ai/standards/acceptance-criteria-traceability.ai.yaml +14 -2
- package/bundled/ai/standards/adr-standards.ai.yaml +14 -2
- package/bundled/ai/standards/code-review.ai.yaml +13 -3
- package/bundled/ai/standards/commit-message.ai.yaml +8 -4
- package/bundled/ai/standards/deferred-item-exit.ai.yaml +225 -0
- package/bundled/ai/standards/feature-discovery-standards.ai.yaml +14 -2
- package/bundled/ai/standards/governance-layer.ai.yaml +128 -2
- package/bundled/ai/standards/logging.ai.yaml +2 -2
- package/bundled/ai/standards/retrospective-standards.ai.yaml +14 -2
- package/bundled/ai/standards/reverse-engineering-standards.ai.yaml +73 -2
- package/bundled/ai/standards/security-standards.ai.yaml +2 -2
- package/bundled/ai/standards/spec-driven-development.ai.yaml +14 -2
- package/bundled/ai/standards/tech-debt-standards.ai.yaml +87 -3
- package/bundled/ai/standards/turn-completion-integrity.ai.yaml +131 -0
- package/bundled/core/acceptance-criteria-traceability.md +5 -2
- package/bundled/core/adr-standards.md +26 -2
- package/bundled/core/agent-communication-protocol.md +8 -0
- package/bundled/core/branch-completion.md +8 -0
- package/bundled/core/change-batching-standards.md +8 -0
- package/bundled/core/code-review-checklist.md +5 -2
- package/bundled/core/context-aware-loading.md +1 -1
- package/bundled/core/deferred-item-exit.md +254 -0
- package/bundled/core/execution-history.md +8 -0
- package/bundled/core/feature-discovery-standards.md +5 -1
- package/bundled/core/governance-layer.md +114 -2
- package/bundled/core/pipeline-integration-standards.md +8 -0
- package/bundled/core/retrospective-standards.md +4 -2
- package/bundled/core/reverse-engineering-standards.md +81 -2
- package/bundled/core/spec-driven-development.md +8 -2
- package/bundled/core/tech-debt-standards.md +67 -8
- package/bundled/core/turn-completion-integrity.md +196 -0
- package/bundled/core/workflow-enforcement.md +8 -0
- package/bundled/core/workflow-state-protocol.md +8 -0
- package/bundled/hooks/check-dangerous-cmd.mjs +60 -0
- package/bundled/hooks/check-logging-standard.mjs +59 -0
- package/bundled/hooks/check-turn-completion.mjs +233 -0
- package/bundled/hooks/inject-standards.mjs +183 -0
- package/bundled/hooks/telemetry-wrapper.mjs +77 -0
- package/bundled/hooks/turn-completion/detect.mjs +99 -0
- package/bundled/hooks/turn-completion/locales/en.mjs +159 -0
- package/bundled/hooks/turn-completion/locales/zh-TW.mjs +166 -0
- package/bundled/hooks/validate-commit-msg.mjs +104 -0
- package/bundled/locales/zh-CN/CHANGELOG.md +73 -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 +1 -1
- package/bundled/locales/zh-CN/core/adr-standards.md +1 -1
- package/bundled/locales/zh-CN/core/agent-communication-protocol.md +7 -0
- package/bundled/locales/zh-CN/core/branch-completion.md +7 -0
- package/bundled/locales/zh-CN/core/change-batching-standards.md +7 -0
- package/bundled/locales/zh-CN/core/execution-history.md +7 -0
- package/bundled/locales/zh-CN/core/governance-layer.md +118 -6
- package/bundled/locales/zh-CN/core/pipeline-integration-standards.md +7 -0
- package/bundled/locales/zh-CN/core/retrospective-standards.md +1 -1
- package/bundled/locales/zh-CN/core/tech-debt-standards.md +71 -4
- package/bundled/locales/zh-CN/core/turn-completion-integrity.md +190 -0
- package/bundled/locales/zh-CN/core/workflow-enforcement.md +7 -0
- package/bundled/locales/zh-CN/core/workflow-state-protocol.md +7 -0
- package/bundled/locales/zh-CN/docs/CHEATSHEET.md +8 -1
- package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +29 -68
- package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +25 -15
- package/bundled/locales/zh-CN/docs/MIGRATION-v6.md +8 -4
- package/bundled/locales/zh-CN/docs/USAGE-MODES-COMPARISON.md +1 -2
- package/bundled/locales/zh-CN/integrations/google-antigravity/{INSTRUCTIONS.md → AGENTS.md} +1 -1
- package/bundled/locales/zh-CN/integrations/google-antigravity/README.md +3 -3
- package/bundled/locales/zh-CN/skills/atdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/bdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/brainstorm-assistant/SKILL.md +22 -12
- package/bundled/locales/zh-CN/skills/brainstorm-assistant/guide.md +12 -9
- package/bundled/locales/zh-CN/skills/code-review-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/commands/brainstorm.md +17 -13
- package/bundled/locales/zh-CN/skills/commands/config.md +0 -1
- package/bundled/locales/zh-CN/skills/commands/init.md +1 -2
- package/bundled/locales/zh-CN/skills/commit-standards/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/contract-test-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/dev-methodology/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/observability-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/project-structure-guide/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/release-standards/SKILL.md +3 -0
- package/bundled/locales/zh-CN/skills/requirement-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/reverse-engineer/SKILL.md +3 -0
- package/bundled/locales/zh-CN/skills/runbook-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/slo-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/tdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/CHANGELOG.md +74 -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 +1 -1
- package/bundled/locales/zh-TW/core/acceptance-criteria-traceability.md +2 -0
- package/bundled/locales/zh-TW/core/adr-standards.md +26 -5
- package/bundled/locales/zh-TW/core/agent-communication-protocol.md +7 -0
- package/bundled/locales/zh-TW/core/branch-completion.md +7 -0
- package/bundled/locales/zh-TW/core/change-batching-standards.md +7 -0
- package/bundled/locales/zh-TW/core/code-review-checklist.md +2 -0
- package/bundled/locales/zh-TW/core/container-image-standards.md +2 -2
- package/bundled/locales/zh-TW/core/contract-testing-standards.md +2 -2
- package/bundled/locales/zh-TW/core/cross-flow-regression.md +8 -7
- package/bundled/locales/zh-TW/core/data-contract.md +2 -2
- package/bundled/locales/zh-TW/core/data-migration-testing.md +2 -2
- package/bundled/locales/zh-TW/core/data-pipeline.md +2 -2
- package/bundled/locales/zh-TW/core/deferred-item-exit.md +251 -0
- package/bundled/locales/zh-TW/core/documentation-writing-standards.md +228 -3
- package/bundled/locales/zh-TW/core/execution-history.md +7 -0
- package/bundled/locales/zh-TW/core/full-coverage-testing.md +15 -2
- package/bundled/locales/zh-TW/core/governance-layer.md +118 -5
- package/bundled/locales/zh-TW/core/iac-design-principles.md +2 -2
- package/bundled/locales/zh-TW/core/incident-response.md +2 -2
- package/bundled/locales/zh-TW/core/model-provenance.md +4 -2
- package/bundled/locales/zh-TW/core/pii-classification.md +42 -6
- package/bundled/locales/zh-TW/core/pipeline-integration-standards.md +7 -0
- package/bundled/locales/zh-TW/core/prd-standards.md +4 -2
- package/bundled/locales/zh-TW/core/product-metrics-standards.md +4 -2
- package/bundled/locales/zh-TW/core/release-readiness-gate.md +2 -2
- package/bundled/locales/zh-TW/core/resource-cost-boundary.md +2 -2
- package/bundled/locales/zh-TW/core/retrospective-standards.md +5 -3
- package/bundled/locales/zh-TW/core/reverse-engineering-standards.md +83 -5
- package/bundled/locales/zh-TW/core/runbook.md +2 -2
- package/bundled/locales/zh-TW/core/schema-evolution.md +2 -2
- package/bundled/locales/zh-TW/core/secret-management-standards.md +2 -2
- package/bundled/locales/zh-TW/core/slo-sli.md +2 -2
- package/bundled/locales/zh-TW/core/spec-driven-development.md +2 -0
- package/bundled/locales/zh-TW/core/tech-debt-standards.md +71 -4
- package/bundled/locales/zh-TW/core/turn-completion-integrity.md +190 -0
- package/bundled/locales/zh-TW/core/user-journey-testing.md +2 -2
- package/bundled/locales/zh-TW/core/user-story-mapping.md +2 -2
- package/bundled/locales/zh-TW/core/verification-oracle.md +2 -2
- package/bundled/locales/zh-TW/core/workflow-enforcement.md +7 -0
- package/bundled/locales/zh-TW/core/workflow-state-protocol.md +7 -0
- package/bundled/locales/zh-TW/docs/CHEATSHEET.md +8 -1
- package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +29 -68
- package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +25 -15
- package/bundled/locales/zh-TW/docs/MIGRATION-v6.md +8 -4
- package/bundled/locales/zh-TW/docs/USAGE-MODES-COMPARISON.md +1 -2
- package/bundled/locales/zh-TW/integrations/google-antigravity/{INSTRUCTIONS.md → AGENTS.md} +1 -1
- package/bundled/locales/zh-TW/integrations/google-antigravity/README.md +3 -3
- package/bundled/locales/zh-TW/skills/adr-assistant/SKILL.md +1 -1
- package/bundled/locales/zh-TW/skills/atdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/bdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/brainstorm-assistant/SKILL.md +22 -12
- package/bundled/locales/zh-TW/skills/brainstorm-assistant/guide.md +12 -9
- package/bundled/locales/zh-TW/skills/code-review-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/commands/brainstorm.md +17 -13
- package/bundled/locales/zh-TW/skills/commands/config.md +0 -1
- package/bundled/locales/zh-TW/skills/commands/init.md +1 -2
- package/bundled/locales/zh-TW/skills/commit-standards/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/contract-test-assistant/SKILL.md +2 -1
- package/bundled/locales/zh-TW/skills/dev-methodology/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/dev-workflow-guide/SKILL.md +1 -1
- package/bundled/locales/zh-TW/skills/knowledge-graph/guide.md +2 -2
- package/bundled/locales/zh-TW/skills/migration-assistant/SKILL.md +1 -1
- package/bundled/locales/zh-TW/skills/observability-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/project-discovery/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/project-structure-guide/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/release-standards/SKILL.md +3 -0
- package/bundled/locales/zh-TW/skills/requirement-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/reverse-engineer/SKILL.md +3 -0
- package/bundled/locales/zh-TW/skills/runbook-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/slo-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/tdd-assistant/SKILL.md +2 -0
- package/bundled/skills/atdd-assistant/SKILL.md +2 -0
- package/bundled/skills/bdd-assistant/SKILL.md +2 -0
- package/bundled/skills/brainstorm-assistant/SKILL.md +31 -13
- package/bundled/skills/brainstorm-assistant/guide.md +9 -6
- package/bundled/skills/code-review-assistant/SKILL.md +1 -0
- package/bundled/skills/commands/brainstorm.md +12 -9
- package/bundled/skills/commands/config.md +0 -1
- package/bundled/skills/commands/init.md +2 -3
- package/bundled/skills/commit-standards/SKILL.md +2 -0
- package/bundled/skills/contract-test-assistant/SKILL.md +1 -0
- package/bundled/skills/dev-methodology/SKILL.md +4 -0
- package/bundled/skills/observability-assistant/SKILL.md +1 -0
- package/bundled/skills/project-discovery/SKILL.md +1 -0
- package/bundled/skills/project-structure-guide/SKILL.md +1 -0
- package/bundled/skills/release-standards/SKILL.md +3 -0
- package/bundled/skills/requirement-assistant/SKILL.md +2 -0
- package/bundled/skills/reverse-engineer/SKILL.md +3 -0
- package/bundled/skills/runbook-assistant/SKILL.md +1 -0
- package/bundled/skills/slo-assistant/SKILL.md +1 -0
- package/bundled/skills/tdd-assistant/SKILL.md +2 -0
- package/bundled/templates/.ai-context.yaml.template +194 -0
- package/bundled/templates/CLAUDE.md.template +145 -0
- package/bundled/templates/DESIGN.md +237 -0
- package/bundled/templates/SKILL-BRIEF-TEMPLATE.md +57 -0
- package/bundled/templates/SKILL-CANDIDATES.md +39 -0
- package/bundled/templates/gates/check-error-exit.mjs +309 -0
- package/bundled/templates/mcp-config.json +10 -0
- package/bundled/templates/methodology-template.yaml +209 -0
- package/bundled/templates/migration-template.md +408 -0
- package/bundled/templates/requirement-checklist.md +410 -0
- package/bundled/templates/requirement-document-template.md +591 -0
- package/bundled/templates/requirement-template.md +881 -0
- package/bundled/templates/reverse-spec-template.md +409 -0
- package/bundled/templates/test-case-template.md +74 -0
- package/bundled/templates/test-plan-template.md +74 -0
- package/package.json +12 -9
- package/src/commands/audit.js +82 -0
- package/src/commands/check.js +227 -34
- package/src/commands/config.js +19 -19
- package/src/commands/init.js +174 -20
- package/src/commands/spec.js +2 -2
- package/src/commands/update.js +537 -43
- package/src/compilers/claude-code-compiler.js +4 -1
- package/src/config/ai-agent-paths.js +62 -17
- package/src/core/constants.js +42 -11
- package/src/core/manifest.js +201 -3
- package/src/core/paths.js +2 -2
- package/src/i18n/messages.js +42 -29
- package/src/installers/hooks-installer.js +167 -75
- package/src/installers/integration-installer.js +13 -9
- package/src/installers/skills-installer.js +4 -4
- package/src/installers/standards-installer.js +3 -3
- package/src/prompts/init.js +47 -18
- package/src/reconciler/diff-engine.js +57 -2
- package/src/reconciler/plan-executor.js +31 -11
- package/src/utils/detector.js +21 -1
- package/src/utils/effect-boundary.js +1093 -0
- package/src/utils/hasher.js +166 -1
- package/src/utils/hook-stats.js +1 -1
- package/src/utils/integration-generator.js +288 -82
- package/src/utils/reference-sync.js +107 -8
- package/src/utils/registry.js +57 -0
- package/src/utils/spinner.js +31 -0
- package/src/utils/yaml-generator.js +51 -9
- package/standards-registry.json +32 -9
package/src/commands/check.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { select } from '@inquirer/prompts';
|
|
3
|
-
import
|
|
3
|
+
import { createSpinner } from '../utils/spinner.js';
|
|
4
4
|
import { existsSync, readFileSync } from 'fs';
|
|
5
5
|
import { join, basename } from 'path';
|
|
6
6
|
import { execSync } from 'child_process';
|
|
7
7
|
import { readManifest, writeManifest, isInitialized, copyStandard, copyIntegration } from '../utils/copier.js';
|
|
8
8
|
import {
|
|
9
9
|
getAllStandards,
|
|
10
|
-
getRepositoryInfo, resolveStandardFilename, resolveStandardSourcePath } from '../utils/registry.js';
|
|
10
|
+
getRepositoryInfo, isShippedFilename, resolveStandardFilename, resolveStandardSourcePath } from '../utils/registry.js';
|
|
11
11
|
import {
|
|
12
12
|
computeFileHash,
|
|
13
13
|
compareFileHash,
|
|
@@ -27,9 +27,11 @@ import {
|
|
|
27
27
|
} from '../config/ai-agent-paths.js';
|
|
28
28
|
import {
|
|
29
29
|
parseReferences,
|
|
30
|
+
findBrokenPathMentions,
|
|
30
31
|
compareStandardsWithReferences
|
|
31
32
|
} from '../utils/reference-sync.js';
|
|
32
|
-
import { extractMarkedContent, getToolFilePath, parseStandardsIndexCount } from '../utils/integration-generator.js';
|
|
33
|
+
import { extractMarkedContent, getToolFilePath, parseStandardsIndexCount, writeIntegrationFile } from '../utils/integration-generator.js';
|
|
34
|
+
import { INTEGRATION_MAPPINGS } from '../installers/integration-installer.js';
|
|
33
35
|
import { getToolFormat } from '../core/constants.js';
|
|
34
36
|
import { checkForUpdates } from '../utils/npm-registry.js';
|
|
35
37
|
import { writeUpdateCache } from '../utils/update-checker.js';
|
|
@@ -59,6 +61,19 @@ function displayFileIntegritySummary(fileStatus, msg) {
|
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
// Reported apart from `missing`, and in grey rather than red, because the
|
|
65
|
+
// adopter who sees this did what the migration guide asked. The remedy named
|
|
66
|
+
// here is the one that works: `--restore` cannot resolve a source for any of
|
|
67
|
+
// them, and used to be the only thing offered.
|
|
68
|
+
if (fileStatus.retired?.length > 0) {
|
|
69
|
+
console.log();
|
|
70
|
+
console.log(chalk.gray(` ${(msg.retiredHeader || '{count} tracked file(s) are no longer shipped by UDS:').replace('{count}', fileStatus.retired.length)}`));
|
|
71
|
+
for (const file of fileStatus.retired) {
|
|
72
|
+
console.log(chalk.gray(` - ${file} (${msg.retired || 'no longer shipped by UDS'})`));
|
|
73
|
+
}
|
|
74
|
+
console.log(chalk.gray(` ${msg.retiredHint || 'Run `uds update --prune` to drop their manifest entries.'}`));
|
|
75
|
+
}
|
|
76
|
+
|
|
62
77
|
if (fileStatus.noHash.length > 0) {
|
|
63
78
|
for (const file of fileStatus.noHash) {
|
|
64
79
|
console.log(chalk.gray(` ? ${file} (${msg.existsNoHash})`));
|
|
@@ -70,10 +85,39 @@ function displayFileIntegritySummary(fileStatus, msg) {
|
|
|
70
85
|
.replace('{unchanged}', fileStatus.unchanged.length)
|
|
71
86
|
.replace('{modified}', fileStatus.modified.length)
|
|
72
87
|
.replace('{missing}', fileStatus.missing.length)}` +
|
|
88
|
+
(fileStatus.retired?.length > 0 ? `, ${fileStatus.retired.length} ${msg.retired || 'no longer shipped'}` : '') +
|
|
73
89
|
(fileStatus.noHash.length > 0 ? `, ${fileStatus.noHash.length} no hash` : '')));
|
|
74
90
|
console.log();
|
|
75
91
|
}
|
|
76
92
|
|
|
93
|
+
/**
|
|
94
|
+
* A file `fileHashes` tracks has gone. Is that a problem, or is it the migration
|
|
95
|
+
* guide's instruction carried out?
|
|
96
|
+
*
|
|
97
|
+
* MIGRATION-v6 §2 told adopters to delete the seven descoped `.ai.yaml` copies
|
|
98
|
+
* by hand. Doing so left the hash entries behind, and this check called each one
|
|
99
|
+
* `missing` and offered `uds check --restore` — a restore that then failed on
|
|
100
|
+
* every one with "could not determine source", because there has been no source
|
|
101
|
+
* upstream since 6.0.0. The tool asked the user to undo its own documentation,
|
|
102
|
+
* using a command it already knew could not work.
|
|
103
|
+
*
|
|
104
|
+
* The distinguishing question is whether UDS still ships a file by that name,
|
|
105
|
+
* which is the registry's to answer, not the manifest's. Anything outside
|
|
106
|
+
* `.standards/` is never retired: integration files are generated, not shipped
|
|
107
|
+
* under a standard's name, so a missing CLAUDE.md is exactly what it looks like.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} relativePath - Path as recorded in fileHashes
|
|
110
|
+
* @param {Object} manifest - Project manifest (unused today; kept so callers
|
|
111
|
+
* need not know whether the answer depends on project state)
|
|
112
|
+
* @returns {'missing'|'retired'}
|
|
113
|
+
*/
|
|
114
|
+
export function classifyMissingFile(relativePath, manifest) { // eslint-disable-line no-unused-vars
|
|
115
|
+
const normalized = String(relativePath).replace(/\\/g, '/');
|
|
116
|
+
if (!normalized.startsWith('.standards/')) return 'missing';
|
|
117
|
+
const fileName = normalized.split('/').pop();
|
|
118
|
+
return isShippedFilename(fileName) ? 'missing' : 'retired';
|
|
119
|
+
}
|
|
120
|
+
|
|
77
121
|
/**
|
|
78
122
|
* Perform integrity check for standards and integration files
|
|
79
123
|
* @returns {Object} File status object
|
|
@@ -83,6 +127,10 @@ function performFileIntegrityCheck(projectPath, manifest, msg) {
|
|
|
83
127
|
unchanged: [],
|
|
84
128
|
modified: [],
|
|
85
129
|
missing: [],
|
|
130
|
+
// Tracked, gone, and gone on purpose: UDS stopped shipping it. Counted
|
|
131
|
+
// apart from `missing` so the summary line stops calling a completed
|
|
132
|
+
// migration a fault.
|
|
133
|
+
retired: [],
|
|
86
134
|
noHash: []
|
|
87
135
|
};
|
|
88
136
|
|
|
@@ -100,7 +148,7 @@ function performFileIntegrityCheck(projectPath, manifest, msg) {
|
|
|
100
148
|
fileStatus.modified.push(relativePath);
|
|
101
149
|
break;
|
|
102
150
|
case 'missing':
|
|
103
|
-
fileStatus.
|
|
151
|
+
fileStatus[classifyMissingFile(relativePath, manifest)].push(relativePath);
|
|
104
152
|
break;
|
|
105
153
|
}
|
|
106
154
|
}
|
|
@@ -415,6 +463,9 @@ export async function checkCommand(options = {}) {
|
|
|
415
463
|
// XSPEC-178: Full coverage compliance check
|
|
416
464
|
checkFullCoverageCompliance(manifest, projectPath);
|
|
417
465
|
|
|
466
|
+
// 錯誤訊息單一出口閘門是否已安裝(只報告,不寫入)
|
|
467
|
+
checkErrorExitGate(projectPath);
|
|
468
|
+
|
|
418
469
|
// Workflow status
|
|
419
470
|
displayWorkflowStatus(projectPath);
|
|
420
471
|
|
|
@@ -664,6 +715,27 @@ export async function restoreSingleFile(projectPath, manifest, relativePath, msg
|
|
|
664
715
|
msg = t().commands.check;
|
|
665
716
|
}
|
|
666
717
|
|
|
718
|
+
// 🔴 Integration files are GENERATED, not copied. Restoring one by downloading a
|
|
719
|
+
// repo template overwrites the adopter's file with a document they never had —
|
|
720
|
+
// `integrations/claude-code/CLAUDE.md` is 140 lines last touched 2026-03-25, and no
|
|
721
|
+
// code path writes it at install time. The installer already records how each file
|
|
722
|
+
// was generated (`manifest.integrationConfigs`), so a correct restore regenerates
|
|
723
|
+
// from that, exactly as `uds update --sync-refs` does.
|
|
724
|
+
const genConfig = manifest.integrationConfigs?.[relativePath];
|
|
725
|
+
if (genConfig?.tool) {
|
|
726
|
+
const result = writeIntegrationFile(genConfig.tool, {
|
|
727
|
+
...genConfig,
|
|
728
|
+
installedStandards: genConfig.installedStandards || manifest.standards || []
|
|
729
|
+
}, projectPath);
|
|
730
|
+
if (result.success) {
|
|
731
|
+
updateFileHash(projectPath, manifest, relativePath);
|
|
732
|
+
console.log(chalk.green(` ✓ ${relativePath}: ${msg.restored}`));
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
console.log(chalk.red(` ✗ ${relativePath}: ${result.error}`));
|
|
736
|
+
return false;
|
|
737
|
+
}
|
|
738
|
+
|
|
667
739
|
const sourcePath = getSourcePathFromRelative(manifest, relativePath);
|
|
668
740
|
if (!sourcePath) {
|
|
669
741
|
console.log(chalk.red(` ✗ ${relativePath}: ${msg.couldNotDetermineSource}`));
|
|
@@ -775,15 +847,18 @@ export function getSourcePathFromRelative(manifest, relativePath) {
|
|
|
775
847
|
|
|
776
848
|
// Check integrations - these might need special handling
|
|
777
849
|
if (manifest.integrations.some(i => (resolveIntegrationFile(i) || i) === relativePath)) {
|
|
778
|
-
//
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
850
|
+
// 🔴 This was a hand-copied list of five targets. The installer's own
|
|
851
|
+
// INTEGRATION_MAPPINGS covers eight and is the map actually used when a
|
|
852
|
+
// generation falls back to a static copy, so a second copy here could only
|
|
853
|
+
// drift — and had: it named `CLAUDE.md`, which INTEGRATION_MAPPINGS does not
|
|
854
|
+
// contain because no code path ever writes that template.
|
|
855
|
+
//
|
|
856
|
+
// Reached only for legacy manifests with no `integrationConfigs`; a current
|
|
857
|
+
// install regenerates instead (see restoreSingleFile).
|
|
858
|
+
for (const { source, target } of Object.values(INTEGRATION_MAPPINGS)) {
|
|
859
|
+
if (target === relativePath) return source;
|
|
860
|
+
}
|
|
861
|
+
return null;
|
|
787
862
|
}
|
|
788
863
|
|
|
789
864
|
return null;
|
|
@@ -1003,6 +1078,34 @@ function displaySkillsStatus(manifest, projectPath, msg) {
|
|
|
1003
1078
|
return { missingSkills, missingCommands };
|
|
1004
1079
|
}
|
|
1005
1080
|
|
|
1081
|
+
/**
|
|
1082
|
+
* 錯誤訊息單一出口閘門:**偵測並報告,絕不寫入。**
|
|
1083
|
+
*
|
|
1084
|
+
* 🔴 為什麼只報告:`uds update` 之外沒有任何時刻是採用者同意我們動他的 repo 的。
|
|
1085
|
+
* 未經同意往別人的專案寫可執行腳本,比它要修的那個問題更糟。
|
|
1086
|
+
* 所以這裡只說「你沒有這道閘門」與「怎麼拿」,寫入留給 `uds update`,
|
|
1087
|
+
* 而那裡會顯示內容並要人點頭。
|
|
1088
|
+
*
|
|
1089
|
+
* 起因(VibeOps 2026-09-03):使用者照著建議打上名字,畫面回他一句 `Bad Request`。
|
|
1090
|
+
* 真正的原因寫在回應的 `details` 裡,而呼叫端只讀了 `error`。當天的修法改了一個
|
|
1091
|
+
* 呼叫端;走訪之後發現同型的有二十四個——其中三個在同一個檔案裡。
|
|
1092
|
+
*/
|
|
1093
|
+
function checkErrorExitGate(projectPath) {
|
|
1094
|
+
const gatePath = join(projectPath, 'scripts', 'check-error-exit.mjs');
|
|
1095
|
+
if (existsSync(gatePath)) {
|
|
1096
|
+
return; // 裝了就不出聲。這裡的沉默代表「有」,不代表「跑過了」——那是它自己的事。
|
|
1097
|
+
}
|
|
1098
|
+
// 沒有 src/ 的專案(純文件、純設定)本來就沒有這個問題,不要對他們嘮叨。
|
|
1099
|
+
if (!existsSync(join(projectPath, 'src'))) {
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
console.log(chalk.yellow(' ⚠ [error-exit] 沒有錯誤訊息單一出口檢查(scripts/check-error-exit.mjs)。'));
|
|
1103
|
+
console.log(chalk.gray(' 這道閘門防的是「每個呼叫端各自把錯誤回應拼成給人看的字串」——'));
|
|
1104
|
+
console.log(chalk.gray(' 第一處是實作,第二處開始就會各寫各的,而畫面上只剩一句 Bad Request。'));
|
|
1105
|
+
console.log(chalk.gray(' 要裝的話:`uds update` 會顯示內容並徵求同意後寫入。'));
|
|
1106
|
+
console.log();
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1006
1109
|
/**
|
|
1007
1110
|
* XSPEC-178: Check full-coverage-testing standard presence and STUB markers
|
|
1008
1111
|
*/
|
|
@@ -1095,19 +1198,37 @@ function checkIntegrationFiles(manifest, projectPath, msg) {
|
|
|
1095
1198
|
// After migrateStandardsPathsToIds(), manifest.standards contains IDs, so a plain
|
|
1096
1199
|
// content.includes(id) check would fail for these mismatched entries.
|
|
1097
1200
|
const allRegistryStds = getAllStandards();
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1201
|
+
// 🔴 `source` is a string for some entries and an object for others. Reading
|
|
1202
|
+
// `s.source.ai` on a string yields undefined, so `zh-tw-locale`
|
|
1203
|
+
// (source: 'extensions/locales/zh-tw.md') fell out of this map and the file it
|
|
1204
|
+
// installs — `.standards/zh-tw.md` — was never recognised: "67/68 項標準已參考,
|
|
1205
|
+
// 缺少: zh-tw-locale" on a project whose index lists it (reported 2026-09-16).
|
|
1206
|
+
const idToFilenames = new Map(
|
|
1207
|
+
allRegistryStds.map(s => {
|
|
1208
|
+
const sources = typeof s.source === 'string'
|
|
1209
|
+
? [s.source]
|
|
1210
|
+
: [s.source?.ai, s.source?.human].filter(Boolean);
|
|
1211
|
+
return [s.id, sources.map(src => basename(src))];
|
|
1212
|
+
})
|
|
1102
1213
|
);
|
|
1103
1214
|
|
|
1104
1215
|
let hasIssues = false;
|
|
1105
1216
|
let checkedCount = 0;
|
|
1106
1217
|
|
|
1218
|
+
// codex and opencode both write AGENTS.md, so iterating tools printed the same
|
|
1219
|
+
// file twice with identical verdicts (reported 2026-09-16). One file, one
|
|
1220
|
+
// verdict — the tools that share it are named on the line instead.
|
|
1221
|
+
const toolsByFile = new Map();
|
|
1107
1222
|
for (const tool of manifest.aiTools) {
|
|
1108
|
-
const
|
|
1109
|
-
if (!
|
|
1223
|
+
const file = getToolFilePath(tool);
|
|
1224
|
+
if (!file) continue;
|
|
1225
|
+
if (!toolsByFile.has(file)) toolsByFile.set(file, []);
|
|
1226
|
+
toolsByFile.get(file).push(tool);
|
|
1227
|
+
}
|
|
1110
1228
|
|
|
1229
|
+
for (const [toolFile, sharingTools] of toolsByFile) {
|
|
1230
|
+
const tool = sharingTools[0];
|
|
1231
|
+
const sharedSuffix = sharingTools.length > 1 ? ` (${sharingTools.join(', ')})` : '';
|
|
1111
1232
|
const fullPath = join(projectPath, toolFile);
|
|
1112
1233
|
|
|
1113
1234
|
// Check if file exists
|
|
@@ -1145,9 +1266,9 @@ function checkIntegrationFiles(manifest, projectPath, msg) {
|
|
|
1145
1266
|
// migration. For standards where the ID doesn't match the .ai.yaml basename
|
|
1146
1267
|
// (e.g. ID "error-code-standards" → file "error-codes.ai.yaml"), we must
|
|
1147
1268
|
// also check the actual filename so those aren't falsely reported as missing.
|
|
1148
|
-
const
|
|
1269
|
+
const filenames = idToFilenames.get(stdFile) || [];
|
|
1149
1270
|
const isReferenced = content.includes(stdFile) ||
|
|
1150
|
-
(
|
|
1271
|
+
filenames.some(name => name !== stdFile && content.includes(name)) ||
|
|
1151
1272
|
content.includes(`.standards/${stdFile}`) ||
|
|
1152
1273
|
content.includes(`standards/${stdFile}`);
|
|
1153
1274
|
|
|
@@ -1168,7 +1289,7 @@ function checkIntegrationFiles(manifest, projectPath, msg) {
|
|
|
1168
1289
|
const declaredCount = parseStandardsIndexCount(content);
|
|
1169
1290
|
if (declaredCount !== null) {
|
|
1170
1291
|
if (declaredCount === totalTrackable) {
|
|
1171
|
-
console.log(chalk.green(` ✓ ${toolFile}:`));
|
|
1292
|
+
console.log(chalk.green(` ✓ ${toolFile}${sharedSuffix}:`));
|
|
1172
1293
|
console.log(chalk.gray(` ${msg.standardsIndexPresent}`));
|
|
1173
1294
|
console.log(chalk.gray(` ${msg.standardsIndexCount
|
|
1174
1295
|
? msg.standardsIndexCount.replace('{count}', declaredCount)
|
|
@@ -1348,9 +1469,12 @@ function checkReferenceSync(manifest, projectPath, msg) {
|
|
|
1348
1469
|
}
|
|
1349
1470
|
|
|
1350
1471
|
const references = parseReferences(content);
|
|
1351
|
-
|
|
1472
|
+
// Whole-file scan, separate from reference sync: the paths that matter here
|
|
1473
|
+
// are the ones outside the UDS block, which no generation ever revisits.
|
|
1474
|
+
const brokenMentions = findBrokenPathMentions(content, projectPath);
|
|
1475
|
+
if (references.length === 0 && brokenMentions.length === 0) continue;
|
|
1352
1476
|
|
|
1353
|
-
results.push({ integrationPath, references });
|
|
1477
|
+
results.push({ integrationPath, references, brokenMentions });
|
|
1354
1478
|
}
|
|
1355
1479
|
|
|
1356
1480
|
// Skip entire section if no files have references
|
|
@@ -1360,14 +1484,42 @@ function checkReferenceSync(manifest, projectPath, msg) {
|
|
|
1360
1484
|
|
|
1361
1485
|
let hasIssues = false;
|
|
1362
1486
|
|
|
1363
|
-
for (const { integrationPath, references } of results) {
|
|
1487
|
+
for (const { integrationPath, references, brokenMentions } of results) {
|
|
1488
|
+
// Paths mentioned anywhere in the file that resolve to nothing. Reported
|
|
1489
|
+
// first and separately from reference sync, because these are usually
|
|
1490
|
+
// outside the UDS markers — left by an older `uds init`, never revisited by
|
|
1491
|
+
// any regeneration, and followed by an AI tool that then finds nothing.
|
|
1492
|
+
if (brokenMentions?.length > 0) {
|
|
1493
|
+
hasIssues = true;
|
|
1494
|
+
console.log(chalk.red(` ✗ ${integrationPath}:`));
|
|
1495
|
+
console.log(chalk.red(` ${msg.brokenMentions || 'mentions paths that do not exist in this project:'}`));
|
|
1496
|
+
for (const path of brokenMentions) {
|
|
1497
|
+
console.log(chalk.red(` - ${path}`));
|
|
1498
|
+
}
|
|
1499
|
+
console.log(chalk.gray(` ${msg.brokenMentionsFix || 'These are usually outside the UDS block and must be corrected by hand; UDS does not rewrite text it did not write.'}`));
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1364
1502
|
// Compare with manifest standards
|
|
1365
|
-
const { orphanedRefs, missingRefs, syncedRefs } = compareStandardsWithReferences(
|
|
1503
|
+
const { orphanedRefs, missingRefs, syncedRefs, danglingRefs } = compareStandardsWithReferences(
|
|
1366
1504
|
manifest.standards,
|
|
1367
|
-
references
|
|
1505
|
+
references,
|
|
1506
|
+
{ projectPath, options: manifest.options }
|
|
1368
1507
|
);
|
|
1369
1508
|
|
|
1370
1509
|
// Report results
|
|
1510
|
+
// 🔴 A reference to a file that is not on disk is the one failure an AI tool
|
|
1511
|
+
// cannot work around: it follows the link and finds nothing. Reported before
|
|
1512
|
+
// the manifest-level findings because it needs no interpretation.
|
|
1513
|
+
if (danglingRefs.length > 0) {
|
|
1514
|
+
hasIssues = true;
|
|
1515
|
+
console.log(chalk.red(` ✗ ${integrationPath}:`));
|
|
1516
|
+
console.log(chalk.red(` ${msg.danglingRefs || 'references files that do not exist:'}`));
|
|
1517
|
+
for (const ref of danglingRefs) {
|
|
1518
|
+
console.log(chalk.red(` - .standards/${ref}`));
|
|
1519
|
+
}
|
|
1520
|
+
console.log(chalk.gray(` ${msg.danglingRefsFix || 'Run `uds update --integrations-only` to regenerate them.'}`));
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1371
1523
|
if (orphanedRefs.length > 0) {
|
|
1372
1524
|
hasIssues = true;
|
|
1373
1525
|
console.log(chalk.yellow(` ⚠ ${integrationPath}:`));
|
|
@@ -1386,14 +1538,21 @@ function checkReferenceSync(manifest, projectPath, msg) {
|
|
|
1386
1538
|
}
|
|
1387
1539
|
}
|
|
1388
1540
|
|
|
1389
|
-
if (orphanedRefs.length === 0 && missingRefs.length === 0) {
|
|
1541
|
+
if (orphanedRefs.length === 0 && missingRefs.length === 0 && danglingRefs.length === 0) {
|
|
1390
1542
|
console.log(chalk.green(` ✓ ${msg.refsInSync.replace('{path}', integrationPath).replace('{count}', syncedRefs.length)}`));
|
|
1391
1543
|
}
|
|
1392
1544
|
}
|
|
1393
1545
|
|
|
1394
1546
|
if (hasIssues) {
|
|
1395
1547
|
console.log();
|
|
1396
|
-
|
|
1548
|
+
// `uds update --sync-refs` refuses to run without `integrationConfigs`, and a
|
|
1549
|
+
// project initialised non-interactively never had that key — so this hint
|
|
1550
|
+
// named a command that could not work (reproduced on a clean 6.9.0 project,
|
|
1551
|
+
// 2026-09-16). Name the one that regenerates from the manifest instead.
|
|
1552
|
+
const canSyncRefs = manifest.integrationConfigs && Object.keys(manifest.integrationConfigs).length > 0;
|
|
1553
|
+
console.log(chalk.yellow(` ${canSyncRefs
|
|
1554
|
+
? msg.runSyncRefs
|
|
1555
|
+
: (msg.runIntegrationsOnly || 'Run `uds update --integrations-only` to regenerate integration files.')}`));
|
|
1397
1556
|
}
|
|
1398
1557
|
|
|
1399
1558
|
console.log();
|
|
@@ -1405,7 +1564,7 @@ function checkReferenceSync(manifest, projectPath, msg) {
|
|
|
1405
1564
|
*/
|
|
1406
1565
|
async function checkCliVersion(bundledVersion) {
|
|
1407
1566
|
const msg = t().commands.check;
|
|
1408
|
-
const spinner =
|
|
1567
|
+
const spinner = createSpinner({ text: msg.checkingCliUpdates, spinner: 'dots' }).start();
|
|
1409
1568
|
|
|
1410
1569
|
try {
|
|
1411
1570
|
const result = await checkForUpdates(bundledVersion, {
|
|
@@ -1526,17 +1685,17 @@ function checkSkillsIntegrity(manifest, projectPath, msg) {
|
|
|
1526
1685
|
* @param {Object} msg - Localized messages
|
|
1527
1686
|
* @returns {Object} Status { unchanged: [], modified: [], missing: [] }
|
|
1528
1687
|
*/
|
|
1529
|
-
function checkCommandsIntegrity(manifest, projectPath, msg) {
|
|
1688
|
+
export function checkCommandsIntegrity(manifest, projectPath, msg) {
|
|
1530
1689
|
const commandHashes = manifest.commandHashes;
|
|
1531
1690
|
|
|
1532
1691
|
// Skip if no command hashes tracked
|
|
1533
1692
|
if (!commandHashes || Object.keys(commandHashes).length === 0) {
|
|
1534
|
-
return { unchanged: [], modified: [], missing: [], tracked: false };
|
|
1693
|
+
return { unchanged: [], modified: [], missing: [], untracked: [], tracked: false };
|
|
1535
1694
|
}
|
|
1536
1695
|
|
|
1537
1696
|
console.log(chalk.cyan(msg.commandsIntegrityCheck || 'Commands File Integrity'));
|
|
1538
1697
|
|
|
1539
|
-
const status = { unchanged: [], modified: [], missing: [], tracked: true };
|
|
1698
|
+
const status = { unchanged: [], modified: [], missing: [], untracked: [], tracked: true };
|
|
1540
1699
|
|
|
1541
1700
|
for (const [hashKey, hashInfo] of Object.entries(commandHashes)) {
|
|
1542
1701
|
// Parse key format: agent/filename.md
|
|
@@ -1576,8 +1735,42 @@ function checkCommandsIntegrity(manifest, projectPath, msg) {
|
|
|
1576
1735
|
}
|
|
1577
1736
|
}
|
|
1578
1737
|
|
|
1738
|
+
// 🔴 The loop above measures only what the manifest happens to track. When a
|
|
1739
|
+
// partial apply dropped 48 of 51 entries (6.9.0, fixed in plan-executor.js),
|
|
1740
|
+
// this section printed "All command files intact (3 files)" while the adoption
|
|
1741
|
+
// summary printed "Commands: 51 installed" from a directory listing — two
|
|
1742
|
+
// numbers, two sources, never compared, so the gap read as a pass.
|
|
1743
|
+
const trackedKeys = new Set(Object.keys(commandHashes));
|
|
1744
|
+
const agentsToScan = new Set(Object.keys(commandHashes).map(k => k.split('/')[0]));
|
|
1745
|
+
for (const entry of manifest.commands?.installations || []) {
|
|
1746
|
+
const agentName = typeof entry === 'string' ? entry : entry?.agent;
|
|
1747
|
+
if (agentName) agentsToScan.add(agentName);
|
|
1748
|
+
}
|
|
1749
|
+
for (const agentName of agentsToScan) {
|
|
1750
|
+
// Reuse the installer's own listing so this file filter cannot drift from it.
|
|
1751
|
+
const info = getInstalledCommandsForAgent(agentName, 'project', projectPath);
|
|
1752
|
+
if (!info?.installed) continue;
|
|
1753
|
+
const ext = agentName === 'gemini-cli' ? '.toml' : '.md';
|
|
1754
|
+
for (const name of info.commands || []) {
|
|
1755
|
+
const key = `${agentName}/${name}${ext}`;
|
|
1756
|
+
if (!trackedKeys.has(key)) status.untracked.push(key);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
if (status.untracked.length > 0) {
|
|
1760
|
+
console.log(chalk.yellow(` ⚠ ${(msg.commandsUntracked || '{count} installed command file(s) are covered by no hash — integrity is not checked for them')
|
|
1761
|
+
.replace('{count}', status.untracked.length)}`));
|
|
1762
|
+
for (const key of status.untracked.slice(0, 5)) {
|
|
1763
|
+
console.log(chalk.yellow(` - ${key}`));
|
|
1764
|
+
}
|
|
1765
|
+
if (status.untracked.length > 5) {
|
|
1766
|
+
console.log(chalk.yellow(` … +${status.untracked.length - 5}`));
|
|
1767
|
+
}
|
|
1768
|
+
console.log(chalk.gray(` ${msg.commandsUntrackedFix || 'Run `uds update --commands` to record them again.'}`));
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
|
|
1579
1772
|
// Summary
|
|
1580
|
-
if (status.modified.length === 0 && status.missing.length === 0) {
|
|
1773
|
+
if (status.modified.length === 0 && status.missing.length === 0 && status.untracked.length === 0) {
|
|
1581
1774
|
console.log(chalk.green(` ✓ ${msg.allCommandsIntact || 'All command files intact'} (${status.unchanged.length} files)`));
|
|
1582
1775
|
} else {
|
|
1583
1776
|
console.log(chalk.gray(` ${(msg.commandsIntegritySummary || '{unchanged} unchanged, {modified} modified, {missing} missing')
|
package/src/commands/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { select, confirm as inquirerConfirm } from '@inquirer/prompts';
|
|
3
|
-
import
|
|
3
|
+
import { createSpinner } from '../utils/spinner.js';
|
|
4
4
|
import { unlinkSync, existsSync, writeFileSync, mkdirSync } from 'fs';
|
|
5
5
|
import { join, basename } from 'path';
|
|
6
6
|
import { config } from '../utils/config-manager.js';
|
|
@@ -381,12 +381,12 @@ async function handleDisplayLanguageChange() {
|
|
|
381
381
|
if (confirmReinstall) {
|
|
382
382
|
const cmdLocale = displayLanguageToLocale(newLang);
|
|
383
383
|
if (hasSkillInstalls) {
|
|
384
|
-
const spinner =
|
|
384
|
+
const spinner = createSpinner(t('config.reinstallingSkills', 'Reinstalling Skills...')).start();
|
|
385
385
|
await installSkillsToMultipleAgents(manifest.skills.installations, null, projectPath, cmdLocale);
|
|
386
386
|
spinner.succeed(t('config.skillsReinstalled', 'Skills reinstalled'));
|
|
387
387
|
}
|
|
388
388
|
if (hasCommandInstalls) {
|
|
389
|
-
const spinner =
|
|
389
|
+
const spinner = createSpinner(t('config.reinstallingCommands', 'Reinstalling Commands...')).start();
|
|
390
390
|
await installCommandsToMultipleAgents(manifest.commands.installations, null, projectPath, cmdLocale);
|
|
391
391
|
spinner.succeed(t('config.commandsReinstalled', 'Commands reinstalled'));
|
|
392
392
|
}
|
|
@@ -401,7 +401,7 @@ async function handleDisplayLanguageChange() {
|
|
|
401
401
|
});
|
|
402
402
|
|
|
403
403
|
if (confirmRegen) {
|
|
404
|
-
const spinner =
|
|
404
|
+
const spinner = createSpinner(t('config.applyingPreset', 'Applying...')).start();
|
|
405
405
|
regenerateIntegrations(projectPath, manifest);
|
|
406
406
|
spinner.succeed(t('config.integrationsRegenerated', 'Integrations regenerated'));
|
|
407
407
|
}
|
|
@@ -665,7 +665,7 @@ export async function runProjectConfiguration(options) {
|
|
|
665
665
|
newAITools = newAITools.filter(tool => !result.tools.includes(tool));
|
|
666
666
|
|
|
667
667
|
// Remove integration files for removed tools
|
|
668
|
-
const spinner =
|
|
668
|
+
const spinner = createSpinner(msgObj.removingIntegrations).start();
|
|
669
669
|
for (const tool of result.tools) {
|
|
670
670
|
const filePath = join(projectPath, getToolFilePath(tool));
|
|
671
671
|
if (existsSync(filePath)) {
|
|
@@ -854,7 +854,7 @@ export async function runProjectConfiguration(options) {
|
|
|
854
854
|
}
|
|
855
855
|
|
|
856
856
|
// Apply changes
|
|
857
|
-
const spinner =
|
|
857
|
+
const spinner = createSpinner(msgObj.updatingConfig).start();
|
|
858
858
|
|
|
859
859
|
const results = {
|
|
860
860
|
copied: [],
|
|
@@ -914,7 +914,7 @@ export async function runProjectConfiguration(options) {
|
|
|
914
914
|
|
|
915
915
|
// Regenerate integration files if needed
|
|
916
916
|
if (needsIntegrationRegeneration && newAITools.length > 0) {
|
|
917
|
-
const intSpinner =
|
|
917
|
+
const intSpinner = createSpinner(msgObj.regeneratingIntegrations).start();
|
|
918
918
|
|
|
919
919
|
// Build installed standards list
|
|
920
920
|
// Raw, not basename()d. Resolution needs the registry (an ID is not a
|
|
@@ -989,7 +989,7 @@ export async function runProjectConfiguration(options) {
|
|
|
989
989
|
|
|
990
990
|
if (confirmSkills) {
|
|
991
991
|
const newInstallations = skillCapableTools.map(agent => ({ agent, level }));
|
|
992
|
-
const spinner =
|
|
992
|
+
const spinner = createSpinner(t('config.installingSkillsForNewTools', 'Installing Skills for new tools...')).start();
|
|
993
993
|
const skillResult = await installSkillsToMultipleAgents(newInstallations, null, projectPath, cmdLocale);
|
|
994
994
|
spinner.succeed(t('config.skillsInstalledForNewTools', 'Skills installed for new tools'));
|
|
995
995
|
|
|
@@ -1026,7 +1026,7 @@ export async function runProjectConfiguration(options) {
|
|
|
1026
1026
|
|
|
1027
1027
|
if (confirmCmds) {
|
|
1028
1028
|
const newCmdInstallations = commandCapableTools.map(agent => ({ agent, level }));
|
|
1029
|
-
const spinner =
|
|
1029
|
+
const spinner = createSpinner(t('config.installingCommandsForNewTools', 'Installing Commands for new tools...')).start();
|
|
1030
1030
|
const cmdResult = await installCommandsToMultipleAgents(newCmdInstallations, null, projectPath, cmdLocale);
|
|
1031
1031
|
spinner.succeed(t('config.commandsInstalledForNewTools', 'Commands installed for new tools'));
|
|
1032
1032
|
|
|
@@ -1124,7 +1124,7 @@ export async function runProjectConfiguration(options) {
|
|
|
1124
1124
|
|
|
1125
1125
|
if (options.yes) {
|
|
1126
1126
|
// --yes flag: auto-apply without prompting
|
|
1127
|
-
const applySpinner =
|
|
1127
|
+
const applySpinner = createSpinner(msgObj.applyingChanges).start();
|
|
1128
1128
|
const applyResults = regenerateIntegrations(projectPath, manifest);
|
|
1129
1129
|
applySpinner.succeed(msgObj.changesApplied || msgObj.regeneratedIntegrations.replace('{count}', applyResults.updated.length));
|
|
1130
1130
|
|
|
@@ -1146,7 +1146,7 @@ export async function runProjectConfiguration(options) {
|
|
|
1146
1146
|
});
|
|
1147
1147
|
|
|
1148
1148
|
if (apply) {
|
|
1149
|
-
const applySpinner =
|
|
1149
|
+
const applySpinner = createSpinner(msgObj.applyingChanges).start();
|
|
1150
1150
|
const applyResults = regenerateIntegrations(projectPath, manifest);
|
|
1151
1151
|
applySpinner.succeed(msgObj.changesApplied || msgObj.regeneratedIntegrations.replace('{count}', applyResults.updated.length));
|
|
1152
1152
|
|
|
@@ -1172,12 +1172,12 @@ export async function runProjectConfiguration(options) {
|
|
|
1172
1172
|
if (hasSkillInstalls || hasCommandInstalls) {
|
|
1173
1173
|
const cmdLocale = displayLanguageToLocale(newOptions.display_language);
|
|
1174
1174
|
if (hasSkillInstalls) {
|
|
1175
|
-
const skillSpinner =
|
|
1175
|
+
const skillSpinner = createSpinner(t('config.reinstallingSkills', 'Reinstalling Skills...')).start();
|
|
1176
1176
|
await installSkillsToMultipleAgents(manifest.skills.installations, null, projectPath, cmdLocale);
|
|
1177
1177
|
skillSpinner.succeed(t('config.skillsReinstalled', 'Skills reinstalled'));
|
|
1178
1178
|
}
|
|
1179
1179
|
if (hasCommandInstalls) {
|
|
1180
|
-
const cmdSpinner =
|
|
1180
|
+
const cmdSpinner = createSpinner(t('config.reinstallingCommands', 'Reinstalling Commands...')).start();
|
|
1181
1181
|
await installCommandsToMultipleAgents(manifest.commands.installations, null, projectPath, cmdLocale);
|
|
1182
1182
|
cmdSpinner.succeed(t('config.commandsReinstalled', 'Commands reinstalled'));
|
|
1183
1183
|
}
|
|
@@ -1222,7 +1222,7 @@ async function handleSkillsConfiguration(manifest, projectPath, msgObj, common,
|
|
|
1222
1222
|
|
|
1223
1223
|
// Install to specified level (defaults to project)
|
|
1224
1224
|
const installations = [{ agent: specificTool, level }];
|
|
1225
|
-
const spinner =
|
|
1225
|
+
const spinner = createSpinner(`Installing Skills for ${getAgentDisplayName(specificTool)} (${level} level)...`).start();
|
|
1226
1226
|
const result = await installSkillsToMultipleAgents(installations, null, projectPath);
|
|
1227
1227
|
spinner.stop();
|
|
1228
1228
|
|
|
@@ -1359,7 +1359,7 @@ async function handleSkillsConfiguration(manifest, projectPath, msgObj, common,
|
|
|
1359
1359
|
}));
|
|
1360
1360
|
|
|
1361
1361
|
// Install Skills
|
|
1362
|
-
const spinner =
|
|
1362
|
+
const spinner = createSpinner(msgObj.installingSkills || 'Installing Skills...').start();
|
|
1363
1363
|
const result = await installSkillsToMultipleAgents(installations, null, projectPath);
|
|
1364
1364
|
spinner.stop();
|
|
1365
1365
|
|
|
@@ -1394,7 +1394,7 @@ async function handleSkillsConfiguration(manifest, projectPath, msgObj, common,
|
|
|
1394
1394
|
}
|
|
1395
1395
|
|
|
1396
1396
|
// Install Skills
|
|
1397
|
-
const spinner =
|
|
1397
|
+
const spinner = createSpinner(msgObj.installingSkills || 'Installing Skills...').start();
|
|
1398
1398
|
const result = await installSkillsToMultipleAgents(installations, null, projectPath);
|
|
1399
1399
|
spinner.stop();
|
|
1400
1400
|
|
|
@@ -1453,7 +1453,7 @@ async function handleCommandsConfiguration(manifest, projectPath, msgObj, common
|
|
|
1453
1453
|
|
|
1454
1454
|
// Install to selected level
|
|
1455
1455
|
const installations = [{ agent: specificTool, level: commandsLevel }];
|
|
1456
|
-
const spinner =
|
|
1456
|
+
const spinner = createSpinner(`Installing Commands for ${getAgentDisplayName(specificTool)} (${commandsLevel} level)...`).start();
|
|
1457
1457
|
const cmdLocale = displayLanguageToLocale(manifest.options?.display_language);
|
|
1458
1458
|
const result = await installCommandsToMultipleAgents(installations, null, projectPath, cmdLocale);
|
|
1459
1459
|
spinner.stop();
|
|
@@ -1559,7 +1559,7 @@ async function handleCommandsConfiguration(manifest, projectPath, msgObj, common
|
|
|
1559
1559
|
}
|
|
1560
1560
|
|
|
1561
1561
|
// Install Commands
|
|
1562
|
-
const spinner =
|
|
1562
|
+
const spinner = createSpinner(msgObj.installingCommands || 'Installing Commands...').start();
|
|
1563
1563
|
const cmdLocale = displayLanguageToLocale(manifest.options?.display_language);
|
|
1564
1564
|
const result = await installCommandsToMultipleAgents(declinedCommandsWithSupport, null, projectPath, cmdLocale);
|
|
1565
1565
|
spinner.stop();
|
|
@@ -1595,7 +1595,7 @@ async function handleCommandsConfiguration(manifest, projectPath, msgObj, common
|
|
|
1595
1595
|
}
|
|
1596
1596
|
|
|
1597
1597
|
// Install Commands
|
|
1598
|
-
const spinner =
|
|
1598
|
+
const spinner = createSpinner(msgObj.installingCommands || 'Installing Commands...').start();
|
|
1599
1599
|
const cmdLocale = displayLanguageToLocale(manifest.options?.display_language);
|
|
1600
1600
|
const result = await installCommandsToMultipleAgents(selectedAgents, null, projectPath, cmdLocale);
|
|
1601
1601
|
spinner.stop();
|