bmad-plus 0.12.2 → 0.13.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/CHANGELOG.md +25 -0
- package/README.md +36 -8
- package/package.json +6 -4
- package/readme-international/README.de.md +37 -8
- package/readme-international/README.es.md +38 -9
- package/readme-international/README.fr.md +37 -8
- package/src/bmad-plus/agents/agent-orchestrator/SKILL.md +2 -0
- package/src/bmad-plus/module.yaml +270 -220
- package/src/bmad-plus/packs/pack-seo/scripts/seo_apis.py +8 -8
- package/src/bmad-plus/packs/pack-seo/scripts/seo_fetch.py +1 -2
- package/src/bmad-plus/packs/pack-seo/scripts/seo_report.py +0 -1
- package/src/bmad-plus/skills/bmad-plus-autopilot/SKILL.md +1 -1
- package/tools/bmad-plus-npx.js +4 -2
- package/tools/build/adapters.config.js +60 -51
- package/tools/build/check-counts.js +52 -54
- package/tools/build/check-install-contract.js +298 -0
- package/tools/build/generate-adapters.js +252 -56
- package/tools/build/generate.js +187 -10
- package/tools/build/generated-adapters/.codex/AGENTS.md +20 -7
- package/tools/build/generated-adapters/.cursor/rules/bmad-plus.mdc +20 -7
- package/tools/build/generated-adapters/.opencode/AGENTS.md +20 -7
- package/tools/build/generated-adapters/AGENTS.md +20 -7
- package/tools/build/generated-adapters/CLAUDE.md +20 -7
- package/tools/build/generated-adapters/CONVENTIONS.md +20 -7
- package/tools/build/generated-adapters/GEMINI.md +20 -7
- package/tools/build/module.template.yaml +82 -0
- package/tools/cli/bmad-plus-cli.js +16 -1
- package/tools/cli/commands/doctor.js +12 -40
- package/tools/cli/commands/install.js +108 -163
- package/tools/cli/commands/uninstall.js +173 -65
- package/tools/cli/commands/update-check.js +31 -0
- package/tools/cli/commands/update-policy.js +39 -0
- package/tools/cli/commands/update.js +102 -113
- package/tools/cli/i18n.js +60 -0
- package/tools/cli/lib/ide-config.js +4 -261
- package/tools/cli/lib/install-manifest.js +17 -0
- package/tools/cli/lib/installed-adapters.js +89 -0
- package/tools/cli/lib/npm-runner.js +177 -0
- package/tools/cli/lib/pack-copy.js +62 -66
- package/tools/cli/lib/packs.js +437 -3
- package/tools/cli/lib/update-check.js +153 -0
- package/tools/cli/lib/update-dispatch.js +182 -0
- package/tools/cli/lib/update-policy.js +90 -0
- package/tools/cli/lib/update-transaction.js +334 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Report release status without applying updates. */
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const { checkForUpdate } = require('../lib/update-check');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
command: 'update-check',
|
|
7
|
+
description: 'Check the published BMAD+ release without applying it',
|
|
8
|
+
options: [
|
|
9
|
+
['-d, --directory <path>', 'Project directory (default: current directory)'],
|
|
10
|
+
['--refresh', 'Bypass the release cache and retry backoff'],
|
|
11
|
+
['--offline', 'Report local state without network access'],
|
|
12
|
+
['--json', 'Print machine-readable JSON'],
|
|
13
|
+
],
|
|
14
|
+
action: async (options = {}) => {
|
|
15
|
+
const result = await checkForUpdate({
|
|
16
|
+
projectDir: path.resolve(options.directory || process.cwd()),
|
|
17
|
+
runningVersion: require('../../../package.json').version,
|
|
18
|
+
refresh: Boolean(options.refresh), offline: Boolean(options.offline),
|
|
19
|
+
checkReadiness: ({ projectDir }) => {
|
|
20
|
+
const { evaluateUpdateReadiness } = require('../lib/update-transaction');
|
|
21
|
+
return evaluateUpdateReadiness({ projectDir });
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
if (result.status.startsWith('invalid-')) process.exitCode = 1;
|
|
25
|
+
if (options.json) console.log(JSON.stringify(result));
|
|
26
|
+
else {
|
|
27
|
+
console.log(`Installed: ${result.installedVersion || 'unknown'}; running: ${result.runningVersion}; channel ${result.channel || 'unknown'}: ${result.targetVersion || 'unknown'}`);
|
|
28
|
+
console.log(`${result.status}: ${result.reason}${result.stale ? ' (cached result is stale)' : ''}`);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Show or explicitly configure the local update policy; never updates packages. */
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const { readUpdatePolicy, writeUpdatePolicy } = require('../lib/update-policy');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
command: 'update-policy',
|
|
7
|
+
description: 'Show or configure the project update policy',
|
|
8
|
+
options: [
|
|
9
|
+
['-d, --directory <path>', 'Project directory (default: current directory)'],
|
|
10
|
+
['--mode <mode>', 'off, notify, or auto (auto requires --range)'],
|
|
11
|
+
['--range <range>', 'Explicit semantic-version range for automatic updates'],
|
|
12
|
+
['--channel <tag>', 'npm release tag (default: latest)'],
|
|
13
|
+
['--allow-prerelease', 'Explicitly allow prerelease targets'],
|
|
14
|
+
['--stable-only', 'Disable prerelease targets'],
|
|
15
|
+
['--json', 'Print machine-readable JSON'],
|
|
16
|
+
],
|
|
17
|
+
action: async (options = {}) => {
|
|
18
|
+
try {
|
|
19
|
+
if (options.allowPrerelease && options.stableOnly) throw new Error('Choose --allow-prerelease or --stable-only.');
|
|
20
|
+
if (options.mode === 'auto' && !options.range) throw new Error('--mode auto requires an explicit --range.');
|
|
21
|
+
const projectDir = path.resolve(options.directory || process.cwd());
|
|
22
|
+
const policy = readUpdatePolicy(projectDir);
|
|
23
|
+
const changing = options.mode !== undefined || options.range !== undefined ||
|
|
24
|
+
options.channel !== undefined || options.allowPrerelease || options.stableOnly;
|
|
25
|
+
if (options.mode !== undefined) policy.mode = options.mode;
|
|
26
|
+
if (options.range !== undefined) policy.allowedRange = options.range;
|
|
27
|
+
if (options.channel !== undefined) policy.channel = options.channel;
|
|
28
|
+
if (options.allowPrerelease) policy.allowPrerelease = true;
|
|
29
|
+
if (options.stableOnly) policy.allowPrerelease = false;
|
|
30
|
+
const saved = changing ? writeUpdatePolicy(projectDir, policy) : policy;
|
|
31
|
+
if (options.json) console.log(JSON.stringify({ policy: saved, changed: Boolean(changing) }));
|
|
32
|
+
else console.log(`Update policy${changing ? ' saved' : ''}: ${saved.mode}; channel=${saved.channel}; range=${saved.allowedRange || 'none'}; prereleases=${saved.allowPrerelease}`);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
if (options.json) console.log(JSON.stringify({ error: error.message }));
|
|
36
|
+
else console.error(error.message);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -1,134 +1,123 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* BMAD+ Update Command
|
|
3
|
-
* Updates agents and skills while preserving user config
|
|
4
|
-
*
|
|
2
|
+
* BMAD+ Update Command — planned updates with recoverable backups.
|
|
5
3
|
* Author: Laurent Rochetta
|
|
6
4
|
*/
|
|
7
|
-
|
|
8
5
|
const path = require('node:path');
|
|
9
6
|
const fs = require('node:fs');
|
|
10
|
-
const
|
|
7
|
+
const semver = require('semver');
|
|
11
8
|
const clack = require('@clack/prompts');
|
|
12
9
|
const pc = require('picocolors');
|
|
13
10
|
const { t } = require('../i18n');
|
|
14
|
-
const {
|
|
15
|
-
const {
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
const { safeTarget } = require('../../build/generate-adapters');
|
|
12
|
+
const { readInstallManifest } = require('../lib/install-manifest');
|
|
13
|
+
const { isExactVersion } = require('../lib/update-policy');
|
|
14
|
+
const { planUpdate, applyPlan, restoreUpdate, MANIFEST } = require('../lib/update-transaction');
|
|
15
|
+
|
|
16
|
+
function authorizeAuto(projectDir, version) {
|
|
17
|
+
const { readUpdatePolicy, authorizeTarget } = require('../lib/update-policy');
|
|
18
|
+
const decision = authorizeTarget(readUpdatePolicy(projectDir), version);
|
|
19
|
+
if (!decision.allowed) throw new Error('Automatic update refused: ' + decision.reason);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function confirmAction(options, message, lang = 'en') {
|
|
23
|
+
if (options.yes || options.auto) return true;
|
|
24
|
+
const i = t(lang);
|
|
25
|
+
if (!process.stdin.isTTY) throw new Error(i.noninteractive_requires_yes('update'));
|
|
26
|
+
const confirmed = await clack.confirm({ message });
|
|
27
|
+
if (!confirmed || clack.isCancel(confirmed)) {
|
|
28
|
+
clack.cancel(i.cancelled);
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
18
33
|
|
|
19
34
|
module.exports = {
|
|
20
35
|
command: 'update',
|
|
21
|
-
description: 'Update BMAD+ agents and skills (preserves
|
|
36
|
+
description: 'Update BMAD+ agents and skills (preserves local changes)',
|
|
22
37
|
options: [
|
|
23
38
|
['-d, --directory <path>', 'Project directory (default: current directory)'],
|
|
39
|
+
['-y, --yes', 'Confirm update without prompting'],
|
|
24
40
|
['-l, --lang <code>', 'Language code: en, fr, es, de, pt-br, ru, zh, he, ja, it'],
|
|
41
|
+
['--latest', 'Resolve and run the exact latest compatible published package'],
|
|
42
|
+
['--expected-version <version>', 'Require this exact executing package version'],
|
|
43
|
+
['--auto', 'Apply only when automatic update policy and ownership allow it'],
|
|
44
|
+
['--restore <receipt-id>', 'Restore files from an update receipt'],
|
|
25
45
|
],
|
|
26
46
|
action: async (options) => {
|
|
27
47
|
const projectDir = path.resolve(options.directory || process.cwd());
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
clack.intro(pc.bgMagenta(pc.white(` BMAD+ Updater v${packageJson.version} `)));
|
|
32
|
-
|
|
33
|
-
// Check if installed
|
|
34
|
-
const manifestPath = path.join(projectDir, '_bmad', '.bmad-plus-install.json');
|
|
35
|
-
if (!fs.existsSync(manifestPath)) {
|
|
36
|
-
clack.log.error('BMAD+ is not installed in this directory.');
|
|
37
|
-
clack.log.info('Run `npx bmad-plus install` first.');
|
|
38
|
-
clack.outro(pc.red('Update aborted.'));
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let manifest;
|
|
48
|
+
const version = require('../../../package.json').version;
|
|
49
|
+
let spinner;
|
|
43
50
|
try {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
if (options.restore && (options.latest || options.expectedVersion)) {
|
|
52
|
+
throw new Error('--restore cannot be combined with --latest or --expected-version.');
|
|
53
|
+
}
|
|
54
|
+
// The dispatcher resolves the target package; this local package may be older.
|
|
55
|
+
if (options.latest) {
|
|
56
|
+
const result = await require('../lib/update-dispatch').runLatestUpdate({
|
|
57
|
+
projectDir, auto: Boolean(options.auto), yes: Boolean(options.yes),
|
|
58
|
+
});
|
|
59
|
+
clack.log.info(result.reason || result.status);
|
|
60
|
+
if (result.output) clack.log.info(result.output);
|
|
61
|
+
if (result.targetVersion) clack.log.info('Target: v' + result.targetVersion);
|
|
62
|
+
if (result.reloadInstructions) clack.log.info('Reload your agent instructions or start a new session.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
clack.intro(pc.bgMagenta(pc.white(' BMAD+ Updater v' + version + ' ')));
|
|
67
|
+
if (options.restore) {
|
|
68
|
+
if (options.auto) throw new Error('Recovery requires manual approval.');
|
|
69
|
+
if (!await confirmAction(options, 'Restore the files saved in receipt ' + options.restore + '?', options.lang)) return;
|
|
70
|
+
const restored = restoreUpdate({ projectDir, receiptId: options.restore });
|
|
71
|
+
clack.log.success('Restored BMAD+ v' + restored.restoredVersion);
|
|
72
|
+
clack.log.info('Receipt: ' + restored.receiptPath);
|
|
73
|
+
clack.outro('Reload your agent instructions or start a new session.');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options.auto && !options.expectedVersion) throw new Error('Automatic update requires --expected-version.');
|
|
78
|
+
if (options.expectedVersion && options.expectedVersion !== version) {
|
|
79
|
+
throw new Error('Executing package version ' + version + ' does not match expected version ' + options.expectedVersion + '.');
|
|
80
|
+
}
|
|
81
|
+
const manifestPath = safeTarget(projectDir, MANIFEST);
|
|
82
|
+
if (!fs.existsSync(manifestPath)) throw new Error('BMAD+ is not installed in this directory. Run bmad-plus install first.');
|
|
83
|
+
let manifest;
|
|
84
|
+
try { manifest = readInstallManifest(manifestPath); } catch (error) {
|
|
85
|
+
throw new Error('Install manifest is unreadable or corrupt: ' + error.message, { cause: error });
|
|
86
|
+
}
|
|
87
|
+
if (!isExactVersion(version) || !isExactVersion(manifest.version)) throw new Error('Update versions must be strict semantic versions.');
|
|
88
|
+
if (semver.lt(version, manifest.version)) throw new Error('Downgrade refused: ' + manifest.version + ' -> ' + version);
|
|
89
|
+
const lang = options.lang || manifest.uiLanguage || 'en';
|
|
90
|
+
clack.log.info('Installed: v' + manifest.version + ' -> Executing package: v' + version);
|
|
91
|
+
if (manifest.version === version) {
|
|
92
|
+
clack.log.success('The installed version matches this executing package. Use --latest to check the registry.');
|
|
93
|
+
clack.outro(pc.green('Nothing to update.'));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const plan = planUpdate({ projectDir, manifest, version, auto: Boolean(options.auto) });
|
|
97
|
+
if (options.auto) {
|
|
98
|
+
authorizeAuto(projectDir, version);
|
|
99
|
+
const fresh = await require('../lib/update-check').checkForUpdate({ projectDir, runningVersion: version, refresh: true });
|
|
100
|
+
if (fresh.source !== 'registry' || fresh.stale || !fresh.versionEligible || fresh.targetVersion !== options.expectedVersion) {
|
|
101
|
+
throw new Error('Automatic update requires a fresh, eligible registry target matching --expected-version.');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
clack.log.info('Planned changes: ' + (plan.files.length - 1) + ' files; preserved conflicts: ' + plan.conflicts.length + '.');
|
|
106
|
+
if (plan.legacy) clack.log.warn('Legacy installation: original pack files will be backed up before replacement because ownership hashes are unavailable. Review the receipt to recover local edits.');
|
|
107
|
+
for (const conflict of plan.conflicts) clack.log.warn(conflict.file + ': preserved (' + conflict.reason + ').');
|
|
108
|
+
if (!await confirmAction(options, 'Apply this update from v' + manifest.version + ' to v' + version + '?', lang)) return;
|
|
109
|
+
|
|
110
|
+
spinner = clack.spinner();
|
|
111
|
+
spinner.start('Updating managed files...');
|
|
112
|
+
const result = applyPlan(plan, { reauthorize: () => authorizeAuto(projectDir, version) });
|
|
113
|
+
spinner.stop(result.changedFiles.length + ' files updated; ' + result.conflicts.length + ' local conflicts preserved.');
|
|
114
|
+
spinner = null;
|
|
115
|
+
clack.log.info('Receipt and backups: ' + result.receiptPath);
|
|
116
|
+
clack.outro(pc.green('BMAD+ v' + version + (result.conflicts.length ? ' applied partially.' : ' installed.') + ' Reload your agent instructions or start a new session.'));
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (spinner) spinner.stop('Update failed.');
|
|
119
|
+
clack.log.error(error.message);
|
|
120
|
+
process.exitCode = 1;
|
|
50
121
|
}
|
|
51
|
-
if (!manifest || typeof manifest !== 'object') {
|
|
52
|
-
clack.log.error('Install manifest is malformed (not an object).');
|
|
53
|
-
clack.log.info('Re-run `npx bmad-plus install` to repair the installation.');
|
|
54
|
-
clack.outro(pc.red('Update aborted.'));
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const lang = options.lang || manifest.uiLanguage || 'en';
|
|
58
|
-
const i = t(lang);
|
|
59
|
-
|
|
60
|
-
clack.log.info(`📦 Installed: v${manifest.version} → Available: v${packageJson.version}`);
|
|
61
|
-
|
|
62
|
-
if (manifest.version === packageJson.version) {
|
|
63
|
-
clack.log.success(i.update_current || '✅ Already up to date!');
|
|
64
|
-
clack.outro(pc.green('Nothing to update.'));
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Guard against a missing/malformed `packs` field (NODE-04): coerce to an array.
|
|
69
|
-
const selectedPacks = Array.isArray(manifest.packs) && manifest.packs.length > 0
|
|
70
|
-
? manifest.packs
|
|
71
|
-
: ['core'];
|
|
72
|
-
clack.log.info(`${i.selected_packs}: ${selectedPacks.join(', ')}`);
|
|
73
|
-
|
|
74
|
-
const confirm = await clack.confirm({
|
|
75
|
-
message: i.update_confirm || `Update from v${manifest.version} to v${packageJson.version}?`,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
if (!confirm || clack.isCancel(confirm)) {
|
|
79
|
-
clack.cancel(i.cancelled);
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const spinner = clack.spinner();
|
|
84
|
-
spinner.start(i.update_updating || 'Updating agents and skills...');
|
|
85
|
-
|
|
86
|
-
const targetAgentsDir = path.join(projectDir, '.agents', 'skills');
|
|
87
|
-
const targetDataDir = path.join(projectDir, '.agents', 'data');
|
|
88
|
-
|
|
89
|
-
fsExtra.ensureDirSync(targetAgentsDir);
|
|
90
|
-
fsExtra.ensureDirSync(targetDataDir);
|
|
91
|
-
|
|
92
|
-
let updated = 0;
|
|
93
|
-
|
|
94
|
-
const projectRoot = path.join(bmadSrc, '..', '..');
|
|
95
|
-
|
|
96
|
-
for (const packId of selectedPacks) {
|
|
97
|
-
const pack = PACKS[packId];
|
|
98
|
-
if (!pack) continue;
|
|
99
|
-
|
|
100
|
-
const result = copyPackFiles({
|
|
101
|
-
bmadSrc,
|
|
102
|
-
targetAgentsDir,
|
|
103
|
-
targetDataDir,
|
|
104
|
-
projectRoot,
|
|
105
|
-
pack,
|
|
106
|
-
});
|
|
107
|
-
updated += result.copiedAgents + result.copiedSkills + result.copiedFiles;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Update module config (always)
|
|
111
|
-
const moduleYaml = path.join(bmadSrc, 'module.yaml');
|
|
112
|
-
const targetBmadDir = path.join(projectDir, '_bmad');
|
|
113
|
-
if (fs.existsSync(moduleYaml)) {
|
|
114
|
-
fsExtra.copySync(moduleYaml, path.join(targetBmadDir, 'module.yaml'));
|
|
115
|
-
updated++;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const helpCsv = path.join(bmadSrc, 'module-help.csv');
|
|
119
|
-
if (fs.existsSync(helpCsv)) {
|
|
120
|
-
fsExtra.copySync(helpCsv, path.join(targetBmadDir, 'module-help.csv'));
|
|
121
|
-
updated++;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Update manifest version (preserve everything else)
|
|
125
|
-
manifest.version = packageJson.version;
|
|
126
|
-
manifest.lastUpdated = new Date().toISOString();
|
|
127
|
-
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf8');
|
|
128
|
-
|
|
129
|
-
spinner.stop(i.update_done ? i.update_done(updated) : `✅ ${updated} files updated to v${packageJson.version}`);
|
|
130
|
-
|
|
131
|
-
clack.log.info('📋 Config preserved: config.yaml, IDE configs, output directories');
|
|
132
|
-
clack.outro(pc.green(i.update_ready || `BMAD+ v${packageJson.version} is ready! 🚀`));
|
|
133
122
|
},
|
|
134
123
|
};
|
package/tools/cli/i18n.js
CHANGED
|
@@ -58,6 +58,12 @@ const LANGUAGES = {
|
|
|
58
58
|
guide_credits: '✨ BMAD+ is created by Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
59
59
|
// Uninstall
|
|
60
60
|
uninstall_confirm: 'Remove BMAD+ from this project?',
|
|
61
|
+
noninteractive_requires_yes: (command) => "This command requires a terminal. Run `npx bmad-plus " + command + " --yes` to proceed without prompts.",
|
|
62
|
+
manifest_invalid: (error) => "Install manifest is unreadable or corrupt: " + error + "",
|
|
63
|
+
manifest_repair: 'Check _bmad/.bmad-plus-install.json and repair it before retrying.',
|
|
64
|
+
uninstall_not_installed: 'BMAD+ is not installed in this directory.',
|
|
65
|
+
uninstall_aborted: (error) => "Uninstall aborted: " + error + "",
|
|
66
|
+
uninstall_preserved: 'Project memory, settings, and unknown or modified files have been preserved.',
|
|
61
67
|
uninstall_removing: 'Removing...',
|
|
62
68
|
uninstall_done: (n) => `✅ BMAD+ removed (${n} items)`,
|
|
63
69
|
uninstall_output_kept: '📁 _bmad-output/ kept (contains files)',
|
|
@@ -139,6 +145,12 @@ const LANGUAGES = {
|
|
|
139
145
|
guide_ready: 'BMAD+ est prêt ! Parle à Atlas pour commencer 🚀',
|
|
140
146
|
guide_credits: '✨ BMAD+ est créé par Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
141
147
|
uninstall_confirm: 'Supprimer BMAD+ de ce projet ?',
|
|
148
|
+
noninteractive_requires_yes: (command) => "Cette commande nécessite un terminal. Lancez `npx bmad-plus " + command + " --yes` pour continuer sans invite.",
|
|
149
|
+
manifest_invalid: (error) => "Le manifeste d’installation est illisible ou corrompu : " + error + "",
|
|
150
|
+
manifest_repair: 'Vérifiez _bmad/.bmad-plus-install.json et réparez-le avant de réessayer.',
|
|
151
|
+
uninstall_not_installed: 'BMAD+ n’est pas installé dans ce répertoire.',
|
|
152
|
+
uninstall_aborted: (error) => "Désinstallation interrompue : " + error + "",
|
|
153
|
+
uninstall_preserved: 'La mémoire, les réglages et les fichiers inconnus ou modifiés ont été conservés.',
|
|
142
154
|
uninstall_removing: 'Suppression...',
|
|
143
155
|
uninstall_done: (n) => `✅ BMAD+ supprimé (${n} éléments)`,
|
|
144
156
|
uninstall_output_kept: '📁 _bmad-output/ conservé (contient des fichiers)',
|
|
@@ -219,6 +231,12 @@ const LANGUAGES = {
|
|
|
219
231
|
guide_ready: '¡BMAD+ está listo! Habla con Atlas para comenzar 🚀',
|
|
220
232
|
guide_credits: '✨ BMAD+ es creado por Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
221
233
|
uninstall_confirm: '¿Eliminar BMAD+ de este proyecto?',
|
|
234
|
+
noninteractive_requires_yes: (command) => "Este comando requiere una terminal. Ejecute `npx bmad-plus " + command + " --yes` para continuar sin preguntas.",
|
|
235
|
+
manifest_invalid: (error) => "El manifiesto de instalación no se puede leer o está dañado: " + error + "",
|
|
236
|
+
manifest_repair: 'Revise _bmad/.bmad-plus-install.json y repárelo antes de reintentar.',
|
|
237
|
+
uninstall_not_installed: 'BMAD+ no está instalado en este directorio.',
|
|
238
|
+
uninstall_aborted: (error) => "Desinstalación interrumpida: " + error + "",
|
|
239
|
+
uninstall_preserved: 'Se han conservado la memoria, los ajustes y los archivos desconocidos o modificados.',
|
|
222
240
|
uninstall_removing: 'Eliminando...',
|
|
223
241
|
uninstall_done: (n) => `✅ BMAD+ eliminado (${n} elementos)`,
|
|
224
242
|
uninstall_output_kept: '📁 _bmad-output/ conservado (contiene archivos)',
|
|
@@ -299,6 +317,12 @@ const LANGUAGES = {
|
|
|
299
317
|
guide_ready: 'BMAD+ ist bereit! Sprich mit Atlas um loszulegen 🚀',
|
|
300
318
|
guide_credits: '✨ BMAD+ wurde erstellt von Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
301
319
|
uninstall_confirm: 'BMAD+ aus diesem Projekt entfernen?',
|
|
320
|
+
noninteractive_requires_yes: (command) => "Dieser Befehl benötigt ein Terminal. Führen Sie `npx bmad-plus " + command + " --yes` aus, um ohne Rückfragen fortzufahren.",
|
|
321
|
+
manifest_invalid: (error) => "Das Installationsmanifest ist unlesbar oder beschädigt: " + error + "",
|
|
322
|
+
manifest_repair: 'Prüfen und reparieren Sie _bmad/.bmad-plus-install.json vor einem erneuten Versuch.',
|
|
323
|
+
uninstall_not_installed: 'BMAD+ ist in diesem Verzeichnis nicht installiert.',
|
|
324
|
+
uninstall_aborted: (error) => "Deinstallation abgebrochen: " + error + "",
|
|
325
|
+
uninstall_preserved: 'Projektspeicher, Einstellungen sowie unbekannte oder geänderte Dateien wurden erhalten.',
|
|
302
326
|
uninstall_removing: 'Entfernen...',
|
|
303
327
|
uninstall_done: (n) => `✅ BMAD+ entfernt (${n} Elemente)`,
|
|
304
328
|
uninstall_output_kept: '📁 _bmad-output/ beibehalten (enthält Dateien)',
|
|
@@ -379,6 +403,12 @@ const LANGUAGES = {
|
|
|
379
403
|
guide_ready: 'BMAD+ está pronto! Fale com Atlas para começar 🚀',
|
|
380
404
|
guide_credits: '✨ BMAD+ foi criado por Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
381
405
|
uninstall_confirm: 'Remover BMAD+ deste projeto?',
|
|
406
|
+
noninteractive_requires_yes: (command) => "Este comando exige um terminal. Execute `npx bmad-plus " + command + " --yes` para continuar sem perguntas.",
|
|
407
|
+
manifest_invalid: (error) => "O manifesto de instalação está ilegível ou corrompido: " + error + "",
|
|
408
|
+
manifest_repair: 'Verifique e repare _bmad/.bmad-plus-install.json antes de tentar novamente.',
|
|
409
|
+
uninstall_not_installed: 'BMAD+ não está instalado neste diretório.',
|
|
410
|
+
uninstall_aborted: (error) => "Desinstalação interrompida: " + error + "",
|
|
411
|
+
uninstall_preserved: 'A memória, as configurações e os arquivos desconhecidos ou modificados foram preservados.',
|
|
382
412
|
uninstall_removing: 'Removendo...',
|
|
383
413
|
uninstall_done: (n) => `✅ BMAD+ removido (${n} itens)`,
|
|
384
414
|
uninstall_output_kept: '📁 _bmad-output/ mantido (contém arquivos)',
|
|
@@ -459,6 +489,12 @@ const LANGUAGES = {
|
|
|
459
489
|
guide_ready: 'BMAD+ готов! Поговорите с Atlas чтобы начать 🚀',
|
|
460
490
|
guide_credits: '✨ BMAD+ создан Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
461
491
|
uninstall_confirm: 'Удалить BMAD+ из этого проекта?',
|
|
492
|
+
noninteractive_requires_yes: (command) => "Для этой команды нужен терминал. Запустите `npx bmad-plus " + command + " --yes`, чтобы продолжить без запросов.",
|
|
493
|
+
manifest_invalid: (error) => "Манифест установки недоступен или повреждён: " + error + "",
|
|
494
|
+
manifest_repair: 'Проверьте и исправьте _bmad/.bmad-plus-install.json перед повторной попыткой.',
|
|
495
|
+
uninstall_not_installed: 'BMAD+ не установлен в этом каталоге.',
|
|
496
|
+
uninstall_aborted: (error) => "Удаление прервано: " + error + "",
|
|
497
|
+
uninstall_preserved: 'Память проекта, настройки и неизвестные или изменённые файлы сохранены.',
|
|
462
498
|
uninstall_removing: 'Удаление...',
|
|
463
499
|
uninstall_done: (n) => `✅ BMAD+ удалён (${n} элементов)`,
|
|
464
500
|
uninstall_output_kept: '📁 _bmad-output/ сохранён (содержит файлы)',
|
|
@@ -539,6 +575,12 @@ const LANGUAGES = {
|
|
|
539
575
|
guide_ready: 'BMAD+ 已就绪!与 Atlas 交谈开始 🚀',
|
|
540
576
|
guide_credits: '✨ BMAD+ 由 Laurent Rochetta 创建 — github.com/lrochetta/BMAD-PLUS ✨',
|
|
541
577
|
uninstall_confirm: '从此项目中删除 BMAD+?',
|
|
578
|
+
noninteractive_requires_yes: (command) => "此命令需要终端。运行 `npx bmad-plus " + command + " --yes` 可跳过提示并继续。",
|
|
579
|
+
manifest_invalid: (error) => "安装清单无法读取或已损坏:" + error + "",
|
|
580
|
+
manifest_repair: '请检查并修复 _bmad/.bmad-plus-install.json 后重试。',
|
|
581
|
+
uninstall_not_installed: '此目录未安装 BMAD+。',
|
|
582
|
+
uninstall_aborted: (error) => "卸载已中止:" + error + "",
|
|
583
|
+
uninstall_preserved: '项目记忆、设置以及未知或修改过的文件已保留。',
|
|
542
584
|
uninstall_removing: '删除中...',
|
|
543
585
|
uninstall_done: (n) => `✅ BMAD+ 已删除(${n} 项)`,
|
|
544
586
|
uninstall_output_kept: '📁 _bmad-output/ 已保留(包含文件)',
|
|
@@ -619,6 +661,12 @@ const LANGUAGES = {
|
|
|
619
661
|
guide_ready: '!BMAD+ מוכן! דבר עם Atlas כדי להתחיל 🚀',
|
|
620
662
|
guide_credits: '✨ BMAD+ נוצר על ידי Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
621
663
|
uninstall_confirm: 'להסיר את BMAD+ מהפרויקט הזה?',
|
|
664
|
+
noninteractive_requires_yes: (command) => "פקודה זו דורשת מסוף. להרצה ללא שאלות, הפעילו `npx bmad-plus " + command + " --yes`.",
|
|
665
|
+
manifest_invalid: (error) => "קובץ פרטי ההתקנה אינו קריא או פגום: " + error + "",
|
|
666
|
+
manifest_repair: 'בדקו ותקנו את _bmad/.bmad-plus-install.json לפני ניסיון נוסף.',
|
|
667
|
+
uninstall_not_installed: 'BMAD+ אינו מותקן בתיקייה זו.',
|
|
668
|
+
uninstall_aborted: (error) => "ההסרה הופסקה: " + error + "",
|
|
669
|
+
uninstall_preserved: 'זיכרון הפרויקט, ההגדרות וקבצים לא מוכרים או ששונו נשמרו.',
|
|
622
670
|
uninstall_removing: 'מסיר...',
|
|
623
671
|
uninstall_done: (n) => `✅ BMAD+ הוסר (${n} פריטים)`,
|
|
624
672
|
uninstall_output_kept: '📁 _bmad-output/ נשמר (מכיל קבצים)',
|
|
@@ -699,6 +747,12 @@ const LANGUAGES = {
|
|
|
699
747
|
guide_ready: 'BMAD+ 準備完了!Atlasに話しかけて始めましょう 🚀',
|
|
700
748
|
guide_credits: '✨ BMAD+ は Laurent Rochetta によって作成されました — github.com/lrochetta/BMAD-PLUS ✨',
|
|
701
749
|
uninstall_confirm: 'このプロジェクトからBMAD+を削除しますか?',
|
|
750
|
+
noninteractive_requires_yes: (command) => "このコマンドには端末が必要です。確認なしで続行するには `npx bmad-plus " + command + " --yes` を実行してください。",
|
|
751
|
+
manifest_invalid: (error) => "インストール情報を読み込めないか破損しています:" + error + "",
|
|
752
|
+
manifest_repair: '_bmad/.bmad-plus-install.json を確認・修復してから再試行してください。',
|
|
753
|
+
uninstall_not_installed: 'このディレクトリには BMAD+ がインストールされていません。',
|
|
754
|
+
uninstall_aborted: (error) => "アンインストールを中止しました:" + error + "",
|
|
755
|
+
uninstall_preserved: 'プロジェクトの記憶、設定、不明なファイルや変更されたファイルは保持されました。',
|
|
702
756
|
uninstall_removing: '削除中...',
|
|
703
757
|
uninstall_done: (n) => `✅ BMAD+を削除しました(${n}項目)`,
|
|
704
758
|
uninstall_output_kept: '📁 _bmad-output/ は保持されました(ファイルが含まれています)',
|
|
@@ -779,6 +833,12 @@ const LANGUAGES = {
|
|
|
779
833
|
guide_ready: 'BMAD+ è pronto! Parla con Atlas per iniziare 🚀',
|
|
780
834
|
guide_credits: '✨ BMAD+ è creato da Laurent Rochetta — github.com/lrochetta/BMAD-PLUS ✨',
|
|
781
835
|
uninstall_confirm: 'Rimuovere BMAD+ da questo progetto?',
|
|
836
|
+
noninteractive_requires_yes: (command) => "Questo comando richiede un terminale. Eseguire `npx bmad-plus " + command + " --yes` per continuare senza domande.",
|
|
837
|
+
manifest_invalid: (error) => "Il manifesto di installazione è illeggibile o danneggiato: " + error + "",
|
|
838
|
+
manifest_repair: 'Controllare e riparare _bmad/.bmad-plus-install.json prima di riprovare.',
|
|
839
|
+
uninstall_not_installed: 'BMAD+ non è installato in questa directory.',
|
|
840
|
+
uninstall_aborted: (error) => "Disinstallazione interrotta: " + error + "",
|
|
841
|
+
uninstall_preserved: 'La memoria, le impostazioni e i file sconosciuti o modificati sono stati conservati.',
|
|
782
842
|
uninstall_removing: 'Rimozione...',
|
|
783
843
|
uninstall_done: (n) => `✅ BMAD+ rimosso (${n} elementi)`,
|
|
784
844
|
uninstall_output_kept: '📁 _bmad-output/ conservato (contiene file)',
|