universal-dev-standards 6.9.0 → 6.11.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/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/execution-history.md +8 -0
- package/bundled/core/pipeline-integration-standards.md +8 -0
- package/bundled/core/workflow-enforcement.md +8 -0
- package/bundled/core/workflow-state-protocol.md +8 -0
- package/bundled/locales/zh-CN/CHANGELOG.md +49 -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/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/pipeline-integration-standards.md +7 -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 +1 -1
- package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +52 -5
- package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +3 -1
- package/bundled/locales/zh-CN/docs/MIGRATION-v6.md +8 -4
- package/bundled/locales/zh-TW/CHANGELOG.md +50 -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/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/execution-history.md +7 -0
- package/bundled/locales/zh-TW/core/pipeline-integration-standards.md +7 -0
- 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 +1 -1
- package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +52 -5
- package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +3 -1
- package/bundled/locales/zh-TW/docs/MIGRATION-v6.md +8 -4
- package/bundled/locales/zh-TW/integrations/claude-code/README.md +14 -5
- package/package.json +7 -6
- package/src/commands/check.js +413 -44
- package/src/commands/config.js +34 -28
- package/src/commands/init.js +37 -7
- package/src/commands/spec.js +2 -2
- package/src/commands/update.js +560 -74
- package/src/core/manifest.js +39 -1
- package/src/flows/init-flow.js +9 -1
- package/src/generators/layered-claudemd.js +13 -4
- package/src/i18n/messages.js +39 -3
- package/src/installers/integration-installer.js +17 -10
- package/src/installers/manifest-installer.js +4 -0
- package/src/installers/skills-installer.js +4 -4
- package/src/installers/standards-installer.js +3 -3
- package/src/prompts/init.js +33 -4
- package/src/reconciler/actual-state-scanner.js +29 -2
- package/src/reconciler/desired-state-calculator.js +51 -2
- package/src/reconciler/diff-engine.js +76 -5
- package/src/reconciler/plan-executor.js +48 -27
- package/src/utils/hasher.js +61 -5
- package/src/utils/integration-generator.js +431 -92
- package/src/utils/marker-locator.js +140 -0
- package/src/utils/reference-sync.js +156 -8
- package/src/utils/registry.js +57 -0
- package/src/utils/spinner.js +31 -0
- package/standards-registry.json +8 -8
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';
|
|
@@ -45,11 +45,11 @@ import {
|
|
|
45
45
|
import { displayLanguageToLocale } from '../utils/locale.js';
|
|
46
46
|
import {
|
|
47
47
|
writeIntegrationFile,
|
|
48
|
-
|
|
48
|
+
resolveIntegrationTargetFile
|
|
49
49
|
} from '../utils/integration-generator.js';
|
|
50
50
|
import { getMarketplaceSkillsInfo } from '../utils/github.js';
|
|
51
51
|
import { regenerateIntegrations } from './update.js';
|
|
52
|
-
import { mergeInstalledNames } from '../core/manifest.js';
|
|
52
|
+
import { mergeInstalledNames, bumpManifestVersion } from '../core/manifest.js';
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* Get localized message with fallback (for config-specific keys)
|
|
@@ -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,15 +665,18 @@ 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
|
+
// XSPEC-418 R3: remove the file this tool actually targets (e.g.
|
|
671
|
+
// CLAUDE.local.md), not always its hardcoded default.
|
|
672
|
+
const removedToolFile = resolveIntegrationTargetFile(tool, manifest);
|
|
673
|
+
const filePath = join(projectPath, removedToolFile);
|
|
671
674
|
if (existsSync(filePath)) {
|
|
672
675
|
try {
|
|
673
676
|
unlinkSync(filePath);
|
|
674
|
-
console.log(chalk.gray(` ${msgObj.removed}: ${
|
|
677
|
+
console.log(chalk.gray(` ${msgObj.removed}: ${removedToolFile}`));
|
|
675
678
|
} catch {
|
|
676
|
-
console.log(chalk.yellow(` ${msgObj.couldNotRemove}: ${
|
|
679
|
+
console.log(chalk.yellow(` ${msgObj.couldNotRemove}: ${removedToolFile}`));
|
|
677
680
|
}
|
|
678
681
|
}
|
|
679
682
|
|
|
@@ -711,7 +714,7 @@ export async function runProjectConfiguration(options) {
|
|
|
711
714
|
}
|
|
712
715
|
|
|
713
716
|
// Remove from integrationBlockHashes (keyed by tool file path)
|
|
714
|
-
const toolFileName =
|
|
717
|
+
const toolFileName = removedToolFile;
|
|
715
718
|
if (manifest.integrationBlockHashes?.[toolFileName]) {
|
|
716
719
|
delete manifest.integrationBlockHashes[toolFileName];
|
|
717
720
|
}
|
|
@@ -854,7 +857,7 @@ export async function runProjectConfiguration(options) {
|
|
|
854
857
|
}
|
|
855
858
|
|
|
856
859
|
// Apply changes
|
|
857
|
-
const spinner =
|
|
860
|
+
const spinner = createSpinner(msgObj.updatingConfig).start();
|
|
858
861
|
|
|
859
862
|
const results = {
|
|
860
863
|
copied: [],
|
|
@@ -914,7 +917,7 @@ export async function runProjectConfiguration(options) {
|
|
|
914
917
|
|
|
915
918
|
// Regenerate integration files if needed
|
|
916
919
|
if (needsIntegrationRegeneration && newAITools.length > 0) {
|
|
917
|
-
const intSpinner =
|
|
920
|
+
const intSpinner = createSpinner(msgObj.regeneratingIntegrations).start();
|
|
918
921
|
|
|
919
922
|
// Build installed standards list
|
|
920
923
|
// Raw, not basename()d. Resolution needs the registry (an ID is not a
|
|
@@ -934,7 +937,8 @@ export async function runProjectConfiguration(options) {
|
|
|
934
937
|
const generatedFiles = new Set();
|
|
935
938
|
|
|
936
939
|
for (const tool of newAITools) {
|
|
937
|
-
|
|
940
|
+
// XSPEC-418 R3
|
|
941
|
+
const targetFile = resolveIntegrationTargetFile(tool, manifest);
|
|
938
942
|
if (generatedFiles.has(targetFile)) {
|
|
939
943
|
continue; // Skip if already generated (AGENTS.md sharing)
|
|
940
944
|
}
|
|
@@ -947,7 +951,9 @@ export async function runProjectConfiguration(options) {
|
|
|
947
951
|
standardsFormat: manifest.format || 'ai',
|
|
948
952
|
contentMode: newContentMode,
|
|
949
953
|
// Pass output_language for dynamic commit standards generation
|
|
950
|
-
outputLanguage: newOptions.output_language || 'english'
|
|
954
|
+
outputLanguage: newOptions.output_language || 'english',
|
|
955
|
+
// XSPEC-418 R2/R3
|
|
956
|
+
integrationTargets: manifest.integrationTargets
|
|
951
957
|
};
|
|
952
958
|
|
|
953
959
|
const result = writeIntegrationFile(tool, toolConfig, projectPath);
|
|
@@ -989,7 +995,7 @@ export async function runProjectConfiguration(options) {
|
|
|
989
995
|
|
|
990
996
|
if (confirmSkills) {
|
|
991
997
|
const newInstallations = skillCapableTools.map(agent => ({ agent, level }));
|
|
992
|
-
const spinner =
|
|
998
|
+
const spinner = createSpinner(t('config.installingSkillsForNewTools', 'Installing Skills for new tools...')).start();
|
|
993
999
|
const skillResult = await installSkillsToMultipleAgents(newInstallations, null, projectPath, cmdLocale);
|
|
994
1000
|
spinner.succeed(t('config.skillsInstalledForNewTools', 'Skills installed for new tools'));
|
|
995
1001
|
|
|
@@ -1026,7 +1032,7 @@ export async function runProjectConfiguration(options) {
|
|
|
1026
1032
|
|
|
1027
1033
|
if (confirmCmds) {
|
|
1028
1034
|
const newCmdInstallations = commandCapableTools.map(agent => ({ agent, level }));
|
|
1029
|
-
const spinner =
|
|
1035
|
+
const spinner = createSpinner(t('config.installingCommandsForNewTools', 'Installing Commands for new tools...')).start();
|
|
1030
1036
|
const cmdResult = await installCommandsToMultipleAgents(newCmdInstallations, null, projectPath, cmdLocale);
|
|
1031
1037
|
spinner.succeed(t('config.commandsInstalledForNewTools', 'Commands installed for new tools'));
|
|
1032
1038
|
|
|
@@ -1052,7 +1058,7 @@ export async function runProjectConfiguration(options) {
|
|
|
1052
1058
|
manifest.options = newOptions;
|
|
1053
1059
|
manifest.contentMode = newContentMode;
|
|
1054
1060
|
manifest.aiTools = newAITools;
|
|
1055
|
-
manifest
|
|
1061
|
+
bumpManifestVersion(manifest);
|
|
1056
1062
|
|
|
1057
1063
|
// Update methodology
|
|
1058
1064
|
if (newMethodology) {
|
|
@@ -1124,7 +1130,7 @@ export async function runProjectConfiguration(options) {
|
|
|
1124
1130
|
|
|
1125
1131
|
if (options.yes) {
|
|
1126
1132
|
// --yes flag: auto-apply without prompting
|
|
1127
|
-
const applySpinner =
|
|
1133
|
+
const applySpinner = createSpinner(msgObj.applyingChanges).start();
|
|
1128
1134
|
const applyResults = regenerateIntegrations(projectPath, manifest);
|
|
1129
1135
|
applySpinner.succeed(msgObj.changesApplied || msgObj.regeneratedIntegrations.replace('{count}', applyResults.updated.length));
|
|
1130
1136
|
|
|
@@ -1146,7 +1152,7 @@ export async function runProjectConfiguration(options) {
|
|
|
1146
1152
|
});
|
|
1147
1153
|
|
|
1148
1154
|
if (apply) {
|
|
1149
|
-
const applySpinner =
|
|
1155
|
+
const applySpinner = createSpinner(msgObj.applyingChanges).start();
|
|
1150
1156
|
const applyResults = regenerateIntegrations(projectPath, manifest);
|
|
1151
1157
|
applySpinner.succeed(msgObj.changesApplied || msgObj.regeneratedIntegrations.replace('{count}', applyResults.updated.length));
|
|
1152
1158
|
|
|
@@ -1172,12 +1178,12 @@ export async function runProjectConfiguration(options) {
|
|
|
1172
1178
|
if (hasSkillInstalls || hasCommandInstalls) {
|
|
1173
1179
|
const cmdLocale = displayLanguageToLocale(newOptions.display_language);
|
|
1174
1180
|
if (hasSkillInstalls) {
|
|
1175
|
-
const skillSpinner =
|
|
1181
|
+
const skillSpinner = createSpinner(t('config.reinstallingSkills', 'Reinstalling Skills...')).start();
|
|
1176
1182
|
await installSkillsToMultipleAgents(manifest.skills.installations, null, projectPath, cmdLocale);
|
|
1177
1183
|
skillSpinner.succeed(t('config.skillsReinstalled', 'Skills reinstalled'));
|
|
1178
1184
|
}
|
|
1179
1185
|
if (hasCommandInstalls) {
|
|
1180
|
-
const cmdSpinner =
|
|
1186
|
+
const cmdSpinner = createSpinner(t('config.reinstallingCommands', 'Reinstalling Commands...')).start();
|
|
1181
1187
|
await installCommandsToMultipleAgents(manifest.commands.installations, null, projectPath, cmdLocale);
|
|
1182
1188
|
cmdSpinner.succeed(t('config.commandsReinstalled', 'Commands reinstalled'));
|
|
1183
1189
|
}
|
|
@@ -1222,7 +1228,7 @@ async function handleSkillsConfiguration(manifest, projectPath, msgObj, common,
|
|
|
1222
1228
|
|
|
1223
1229
|
// Install to specified level (defaults to project)
|
|
1224
1230
|
const installations = [{ agent: specificTool, level }];
|
|
1225
|
-
const spinner =
|
|
1231
|
+
const spinner = createSpinner(`Installing Skills for ${getAgentDisplayName(specificTool)} (${level} level)...`).start();
|
|
1226
1232
|
const result = await installSkillsToMultipleAgents(installations, null, projectPath);
|
|
1227
1233
|
spinner.stop();
|
|
1228
1234
|
|
|
@@ -1359,7 +1365,7 @@ async function handleSkillsConfiguration(manifest, projectPath, msgObj, common,
|
|
|
1359
1365
|
}));
|
|
1360
1366
|
|
|
1361
1367
|
// Install Skills
|
|
1362
|
-
const spinner =
|
|
1368
|
+
const spinner = createSpinner(msgObj.installingSkills || 'Installing Skills...').start();
|
|
1363
1369
|
const result = await installSkillsToMultipleAgents(installations, null, projectPath);
|
|
1364
1370
|
spinner.stop();
|
|
1365
1371
|
|
|
@@ -1394,7 +1400,7 @@ async function handleSkillsConfiguration(manifest, projectPath, msgObj, common,
|
|
|
1394
1400
|
}
|
|
1395
1401
|
|
|
1396
1402
|
// Install Skills
|
|
1397
|
-
const spinner =
|
|
1403
|
+
const spinner = createSpinner(msgObj.installingSkills || 'Installing Skills...').start();
|
|
1398
1404
|
const result = await installSkillsToMultipleAgents(installations, null, projectPath);
|
|
1399
1405
|
spinner.stop();
|
|
1400
1406
|
|
|
@@ -1453,7 +1459,7 @@ async function handleCommandsConfiguration(manifest, projectPath, msgObj, common
|
|
|
1453
1459
|
|
|
1454
1460
|
// Install to selected level
|
|
1455
1461
|
const installations = [{ agent: specificTool, level: commandsLevel }];
|
|
1456
|
-
const spinner =
|
|
1462
|
+
const spinner = createSpinner(`Installing Commands for ${getAgentDisplayName(specificTool)} (${commandsLevel} level)...`).start();
|
|
1457
1463
|
const cmdLocale = displayLanguageToLocale(manifest.options?.display_language);
|
|
1458
1464
|
const result = await installCommandsToMultipleAgents(installations, null, projectPath, cmdLocale);
|
|
1459
1465
|
spinner.stop();
|
|
@@ -1559,7 +1565,7 @@ async function handleCommandsConfiguration(manifest, projectPath, msgObj, common
|
|
|
1559
1565
|
}
|
|
1560
1566
|
|
|
1561
1567
|
// Install Commands
|
|
1562
|
-
const spinner =
|
|
1568
|
+
const spinner = createSpinner(msgObj.installingCommands || 'Installing Commands...').start();
|
|
1563
1569
|
const cmdLocale = displayLanguageToLocale(manifest.options?.display_language);
|
|
1564
1570
|
const result = await installCommandsToMultipleAgents(declinedCommandsWithSupport, null, projectPath, cmdLocale);
|
|
1565
1571
|
spinner.stop();
|
|
@@ -1595,7 +1601,7 @@ async function handleCommandsConfiguration(manifest, projectPath, msgObj, common
|
|
|
1595
1601
|
}
|
|
1596
1602
|
|
|
1597
1603
|
// Install Commands
|
|
1598
|
-
const spinner =
|
|
1604
|
+
const spinner = createSpinner(msgObj.installingCommands || 'Installing Commands...').start();
|
|
1599
1605
|
const cmdLocale = displayLanguageToLocale(manifest.options?.display_language);
|
|
1600
1606
|
const result = await installCommandsToMultipleAgents(selectedAgents, null, projectPath, cmdLocale);
|
|
1601
1607
|
spinner.stop();
|
package/src/commands/init.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import
|
|
2
|
+
import { createSpinner } from '../utils/spinner.js';
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
5
|
-
import {
|
|
5
|
+
import { join } from 'path';
|
|
6
6
|
import {
|
|
7
7
|
manifestExists as isInitialized,
|
|
8
8
|
normalizeContentMode,
|
|
@@ -26,7 +26,7 @@ import { displayLanguageToLocale } from '../utils/locale.js';
|
|
|
26
26
|
import { generateReleaseConfig, RELEASE_MODE_LABELS } from '../utils/release-config.js';
|
|
27
27
|
import { guardAgainstSelfAdoption } from '../utils/detect-self-adoption.js';
|
|
28
28
|
import { readInstallYaml } from '../utils/config-manager.js';
|
|
29
|
-
import {
|
|
29
|
+
import { resolveIntegrationTargetFile } from '../utils/integration-generator.js';
|
|
30
30
|
import { withFileTransaction } from '../utils/transaction.js';
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -55,7 +55,7 @@ export async function initCommand(options) {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
// STEP 2: Detect project characteristics
|
|
58
|
-
const spinner =
|
|
58
|
+
const spinner = createSpinner(msg.detectingProject).start();
|
|
59
59
|
const detected = detectAll(projectPath);
|
|
60
60
|
spinner.succeed(msg.analysisComplete);
|
|
61
61
|
|
|
@@ -107,7 +107,10 @@ export async function initCommand(options) {
|
|
|
107
107
|
// `uds init` re-installs them idempotently.
|
|
108
108
|
const ownedPaths = [join(projectPath, '.standards')];
|
|
109
109
|
for (const tool of (config.integrations || config.aiTools || [])) {
|
|
110
|
-
|
|
110
|
+
// XSPEC-418 R2: honors --claude-target so a local-target install's owned
|
|
111
|
+
// path is CLAUDE.local.md, not CLAUDE.md — rollback must tear down the
|
|
112
|
+
// file actually written, not the tool's default.
|
|
113
|
+
const file = resolveIntegrationTargetFile(tool, { integrationTargets: config.integrationTargets });
|
|
111
114
|
if (file) ownedPaths.push(join(projectPath, file));
|
|
112
115
|
}
|
|
113
116
|
if (config.generateAgentsMd) ownedPaths.push(join(projectPath, 'AGENTS.md'));
|
|
@@ -123,7 +126,16 @@ export async function initCommand(options) {
|
|
|
123
126
|
apply: async () => {
|
|
124
127
|
// 1. Install Standards
|
|
125
128
|
const standardsResults = await installStandards(config, projectPath);
|
|
126
|
-
|
|
129
|
+
// Paths, not basenames. Everything downstream classifies an option
|
|
130
|
+
// by an `/options/` segment, so reducing to basenames here is not a
|
|
131
|
+
// simplification — it deletes the only signal that distinguishes the
|
|
132
|
+
// two, and `contentLayout: flat` installs option files with no
|
|
133
|
+
// directory to recover it from. The index block consequently said
|
|
134
|
+
// "options 0" on every project for two releases, while the manifest
|
|
135
|
+
// right beside it listed seven. `buildToolIntegrationConfig` (the
|
|
136
|
+
// update path's equivalent) has carried a comment warning against
|
|
137
|
+
// exactly this reduction the whole time; only this call site did it.
|
|
138
|
+
config.installedStandards = standardsResults.standards;
|
|
127
139
|
|
|
128
140
|
// 1.5. Generate release-config.yaml if non-default mode selected
|
|
129
141
|
if (config.releaseMode && config.releaseMode !== 'ci-cd') {
|
|
@@ -649,6 +661,23 @@ function buildNonInteractiveConfig(options, detected, projectPath) {
|
|
|
649
661
|
? false // codex/opencode handles AGENTS.md, skip universal output
|
|
650
662
|
: (options.agentsMd !== undefined ? !!options.agentsMd : true);
|
|
651
663
|
|
|
664
|
+
// XSPEC-418 R2: --claude-target <project|local>, default 'project'. An
|
|
665
|
+
// unrecognized value is never substituted quietly (same policy as
|
|
666
|
+
// --content-mode above) — it falls back to 'project' with a warning rather
|
|
667
|
+
// than silently writing into CLAUDE.local.md or vice versa.
|
|
668
|
+
let claudeTargetFlag = options.claudeTarget || 'project';
|
|
669
|
+
if (claudeTargetFlag !== 'project' && claudeTargetFlag !== 'local') {
|
|
670
|
+
console.log(chalk.yellow(
|
|
671
|
+
`⚠ Unknown --claude-target '${claudeTargetFlag}'; using 'project'. Supported: project, local.`
|
|
672
|
+
));
|
|
673
|
+
claudeTargetFlag = 'project';
|
|
674
|
+
}
|
|
675
|
+
// Only ever set when 'local' — 'project' or unspecified leaves the manifest
|
|
676
|
+
// shape completely unchanged (XSPEC-418 AC-5).
|
|
677
|
+
const integrationTargets = claudeTargetFlag === 'local'
|
|
678
|
+
? { 'claude-code': 'CLAUDE.local.md' }
|
|
679
|
+
: undefined;
|
|
680
|
+
|
|
652
681
|
return {
|
|
653
682
|
languages: options.lang ? [options.lang] : Object.keys(detected.languages).filter(k => detected.languages[k]),
|
|
654
683
|
frameworks: options.framework ? [options.framework] : Object.keys(detected.frameworks).filter(k => detected.frameworks[k]),
|
|
@@ -669,7 +698,8 @@ function buildNonInteractiveConfig(options, detected, projectPath) {
|
|
|
669
698
|
generateAgentsMd,
|
|
670
699
|
releaseMode: options.releaseMode || 'ci-cd',
|
|
671
700
|
withHooks: !!options.withHooks,
|
|
672
|
-
contentLayout: options.contentLayout || 'flat'
|
|
701
|
+
contentLayout: options.contentLayout || 'flat',
|
|
702
|
+
integrationTargets
|
|
673
703
|
};
|
|
674
704
|
}
|
|
675
705
|
|
package/src/commands/spec.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import chalk from 'chalk';
|
|
12
|
-
import
|
|
12
|
+
import { createSpinner } from '../utils/spinner.js';
|
|
13
13
|
import { select, confirm as inquirerConfirm } from '@inquirer/prompts';
|
|
14
14
|
import { existsSync, readFileSync } from 'node:fs';
|
|
15
15
|
import { join } from 'node:path';
|
|
@@ -48,7 +48,7 @@ export async function specCreateCommand(intent, options = {}) {
|
|
|
48
48
|
output: options.output
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
const spinner =
|
|
51
|
+
const spinner = createSpinner({
|
|
52
52
|
text: t('spec.generating', 'Generating micro-spec...'),
|
|
53
53
|
color: 'cyan'
|
|
54
54
|
}).start();
|