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
|
@@ -28,16 +28,21 @@ To activate an agent, say its name or persona:
|
|
|
28
28
|
- **Forge** (Architect-Dev) — Architecture + Development + Documentation
|
|
29
29
|
- **Sentinel** (Quality) — QA + UX review
|
|
30
30
|
- **Nexus** (Orchestrator) — Sprint management + Autopilot + Parallel execution
|
|
31
|
-
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (
|
|
32
|
-
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents
|
|
33
|
-
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (
|
|
31
|
+
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (OSINT)
|
|
32
|
+
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents (Maker)
|
|
33
|
+
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (Shield)
|
|
34
|
+
- **SEO Scout** (Technical Scanner) — Crawling + technical inspection + performance (SEO)
|
|
35
|
+
- **SEO Chief** (Strategist & Reporter) — Scoring + strategy + reporting (SEO)
|
|
36
|
+
- **SEO Judge** (Content & AI Analyst) — Content quality + structured data + GEO analysis (SEO)
|
|
37
|
+
- **Zecher** (זכר, Memory Guardian) — Memory Archivist — Persistent cross-session memory, consolidation, project scanning, context recall, session handoffs (Memory)
|
|
34
38
|
- **Miriam** (מרים) — Business Analyst — Strategic analysis, research, product briefs (Dev Studio)
|
|
35
39
|
- **Huldah** (חולדה) — Technical Writer — Documentation, diagrams, editorial review (Dev Studio)
|
|
36
40
|
- **Yosef** (יוסף) — Product Manager — PRD, requirements, feature prioritization (Dev Studio)
|
|
37
41
|
- **Rachel** (רחל) — UX Designer — User experience, wireframes, empathy mapping (Dev Studio)
|
|
38
42
|
- **Bezalel** (בצלאל) — System Architect — Architecture, ADRs, epics & stories (Dev Studio)
|
|
39
43
|
- **Oholiab** (אהליאב) — Senior Engineer — TDD, sprint, code review, implementation (Dev Studio)
|
|
40
|
-
- **
|
|
44
|
+
- **Backup Manager** (Backup & Restore) — Timestamped backups, restoration, and rotation (Backup)
|
|
45
|
+
- **Animated Website Creator** (Website Builder) — Video-driven scrolling websites (Animated)
|
|
41
46
|
|
|
42
47
|
## Skills
|
|
43
48
|
|
|
@@ -98,19 +103,27 @@ Agents MUST follow these behavioral principles:
|
|
|
98
103
|
- `.agents/memory/patterns.md` — Write when a reusable pattern is validated
|
|
99
104
|
- `.agents/memory/context.md` — Update at session end with project state
|
|
100
105
|
|
|
106
|
+
## Framework updates
|
|
107
|
+
|
|
108
|
+
Once per session, check the installed framework before starting project work. If this is the BMAD+ source checkout, use `node tools/cli/bmad-plus-cli.js update-check --json`; otherwise use `npx --no-install bmad-plus update-check --json` from the project root.
|
|
109
|
+
If the command is unavailable or the result is off, unknown, offline or stale, continue the user task. Do not install a CLI just to perform this check or claim that an offline version is current.
|
|
110
|
+
When `updateAvailable` is true and `canAutoApply` is true, run the same CLI with `update --latest --auto`. This follows the project update policy; it does not grant permission to expand that policy.
|
|
111
|
+
When an update is available but automatic application is not eligible, explain the version and reason. An explicit request to update can be fulfilled with `update --latest --yes`; do not change the policy, overwrite customized files, or resolve conflicts without the user request covering that action.
|
|
112
|
+
After a successful update, reread the project spine and relevant installed skills, or start a fresh session if the client cannot reload them. Respect preserved local instructions. Check only once even when several adapters include this section.
|
|
113
|
+
|
|
101
114
|
## Registry facts (computed from registry.yaml — never hand-typed)
|
|
102
115
|
|
|
103
|
-
- Product: BMAD+ v0.
|
|
116
|
+
- Product: BMAD+ v0.13.0 (derived from BMAD-METHOD v6.6.0)
|
|
104
117
|
- Models supported: claude, gpt, gemini, local (model-agnostic by contract)
|
|
105
118
|
- Packs (9): Core, OSINT, Maker, Shield, SEO, Memory, Dev Studio, Backup, Animated
|
|
106
119
|
- Installer agents (14 across all packs):
|
|
107
120
|
- Core (required): 4 installer agents — Core agents & skills
|
|
108
121
|
- OSINT: 1 installer agent — OSINT & investigation — 2 compliance frameworks
|
|
109
122
|
- Maker: 1 installer agent — Agent creation toolkit
|
|
110
|
-
- Shield: 1 installer agent — GRC compliance (
|
|
123
|
+
- Shield: 1 installer agent — GRC compliance (26 frameworks) — 27 specialized agents, 11 workflows, 26 compliance frameworks
|
|
111
124
|
- SEO: 3 installer agents — SEO audit & optimization — 1 compliance frameworks
|
|
112
125
|
- Memory: 1 installer agent — Persistent cross-session memory
|
|
113
|
-
- Dev Studio: 1 installer agent — SDLC automation (6 agents,
|
|
126
|
+
- Dev Studio: 1 installer agent — SDLC automation (6 agents, specialized workflows) — 6 sub-agents, 38 workflows
|
|
114
127
|
- Backup: 1 installer agent — Backup & restore
|
|
115
128
|
- Animated: 1 installer agent — Animated website agents
|
|
116
129
|
|
|
@@ -33,16 +33,21 @@ To activate an agent, say its name or persona:
|
|
|
33
33
|
- **Forge** (Architect-Dev) — Architecture + Development + Documentation
|
|
34
34
|
- **Sentinel** (Quality) — QA + UX review
|
|
35
35
|
- **Nexus** (Orchestrator) — Sprint management + Autopilot + Parallel execution
|
|
36
|
-
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (
|
|
37
|
-
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents
|
|
38
|
-
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (
|
|
36
|
+
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (OSINT)
|
|
37
|
+
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents (Maker)
|
|
38
|
+
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (Shield)
|
|
39
|
+
- **SEO Scout** (Technical Scanner) — Crawling + technical inspection + performance (SEO)
|
|
40
|
+
- **SEO Chief** (Strategist & Reporter) — Scoring + strategy + reporting (SEO)
|
|
41
|
+
- **SEO Judge** (Content & AI Analyst) — Content quality + structured data + GEO analysis (SEO)
|
|
42
|
+
- **Zecher** (זכר, Memory Guardian) — Memory Archivist — Persistent cross-session memory, consolidation, project scanning, context recall, session handoffs (Memory)
|
|
39
43
|
- **Miriam** (מרים) — Business Analyst — Strategic analysis, research, product briefs (Dev Studio)
|
|
40
44
|
- **Huldah** (חולדה) — Technical Writer — Documentation, diagrams, editorial review (Dev Studio)
|
|
41
45
|
- **Yosef** (יוסף) — Product Manager — PRD, requirements, feature prioritization (Dev Studio)
|
|
42
46
|
- **Rachel** (רחל) — UX Designer — User experience, wireframes, empathy mapping (Dev Studio)
|
|
43
47
|
- **Bezalel** (בצלאל) — System Architect — Architecture, ADRs, epics & stories (Dev Studio)
|
|
44
48
|
- **Oholiab** (אהליאב) — Senior Engineer — TDD, sprint, code review, implementation (Dev Studio)
|
|
45
|
-
- **
|
|
49
|
+
- **Backup Manager** (Backup & Restore) — Timestamped backups, restoration, and rotation (Backup)
|
|
50
|
+
- **Animated Website Creator** (Website Builder) — Video-driven scrolling websites (Animated)
|
|
46
51
|
|
|
47
52
|
## Skills
|
|
48
53
|
|
|
@@ -103,19 +108,27 @@ Agents MUST follow these behavioral principles:
|
|
|
103
108
|
- `.agents/memory/patterns.md` — Write when a reusable pattern is validated
|
|
104
109
|
- `.agents/memory/context.md` — Update at session end with project state
|
|
105
110
|
|
|
111
|
+
## Framework updates
|
|
112
|
+
|
|
113
|
+
Once per session, check the installed framework before starting project work. If this is the BMAD+ source checkout, use `node tools/cli/bmad-plus-cli.js update-check --json`; otherwise use `npx --no-install bmad-plus update-check --json` from the project root.
|
|
114
|
+
If the command is unavailable or the result is off, unknown, offline or stale, continue the user task. Do not install a CLI just to perform this check or claim that an offline version is current.
|
|
115
|
+
When `updateAvailable` is true and `canAutoApply` is true, run the same CLI with `update --latest --auto`. This follows the project update policy; it does not grant permission to expand that policy.
|
|
116
|
+
When an update is available but automatic application is not eligible, explain the version and reason. An explicit request to update can be fulfilled with `update --latest --yes`; do not change the policy, overwrite customized files, or resolve conflicts without the user request covering that action.
|
|
117
|
+
After a successful update, reread the project spine and relevant installed skills, or start a fresh session if the client cannot reload them. Respect preserved local instructions. Check only once even when several adapters include this section.
|
|
118
|
+
|
|
106
119
|
## Registry facts (computed from registry.yaml — never hand-typed)
|
|
107
120
|
|
|
108
|
-
- Product: BMAD+ v0.
|
|
121
|
+
- Product: BMAD+ v0.13.0 (derived from BMAD-METHOD v6.6.0)
|
|
109
122
|
- Models supported: claude, gpt, gemini, local (model-agnostic by contract)
|
|
110
123
|
- Packs (9): Core, OSINT, Maker, Shield, SEO, Memory, Dev Studio, Backup, Animated
|
|
111
124
|
- Installer agents (14 across all packs):
|
|
112
125
|
- Core (required): 4 installer agents — Core agents & skills
|
|
113
126
|
- OSINT: 1 installer agent — OSINT & investigation — 2 compliance frameworks
|
|
114
127
|
- Maker: 1 installer agent — Agent creation toolkit
|
|
115
|
-
- Shield: 1 installer agent — GRC compliance (
|
|
128
|
+
- Shield: 1 installer agent — GRC compliance (26 frameworks) — 27 specialized agents, 11 workflows, 26 compliance frameworks
|
|
116
129
|
- SEO: 3 installer agents — SEO audit & optimization — 1 compliance frameworks
|
|
117
130
|
- Memory: 1 installer agent — Persistent cross-session memory
|
|
118
|
-
- Dev Studio: 1 installer agent — SDLC automation (6 agents,
|
|
131
|
+
- Dev Studio: 1 installer agent — SDLC automation (6 agents, specialized workflows) — 6 sub-agents, 38 workflows
|
|
119
132
|
- Backup: 1 installer agent — Backup & restore
|
|
120
133
|
- Animated: 1 installer agent — Animated website agents
|
|
121
134
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Hand-authored project questions and compatibility. Pack facts are generated from registry.yaml.
|
|
2
|
+
code: bmad-plus
|
|
3
|
+
name: BMAD+ Streamlined AI-Driven Development
|
|
4
|
+
description: Augmented BMAD framework with multi-role agents, autopilot mode, and parallel execution
|
|
5
|
+
default_selected: true
|
|
6
|
+
extends: bmm
|
|
7
|
+
compatibility:
|
|
8
|
+
min_core_version: 6.0.0
|
|
9
|
+
max_core_version: 7.0.0
|
|
10
|
+
replaces_modules:
|
|
11
|
+
- bmm
|
|
12
|
+
keeps_core_skills: true
|
|
13
|
+
install_packs:
|
|
14
|
+
prompt:
|
|
15
|
+
- Quels packs additionnels souhaites-tu installer ?
|
|
16
|
+
- Core est toujours inclus.
|
|
17
|
+
default: none
|
|
18
|
+
result: '{value}'
|
|
19
|
+
project_name:
|
|
20
|
+
prompt: What is your project called?
|
|
21
|
+
default: '{directory_name}'
|
|
22
|
+
result: '{value}'
|
|
23
|
+
user_skill_level:
|
|
24
|
+
prompt:
|
|
25
|
+
- What is your development experience level?
|
|
26
|
+
- This affects how agents explain concepts in chat.
|
|
27
|
+
default: expert
|
|
28
|
+
result: '{value}'
|
|
29
|
+
single-select:
|
|
30
|
+
- value: beginner
|
|
31
|
+
label: Beginner - Explain things clearly
|
|
32
|
+
- value: intermediate
|
|
33
|
+
label: Intermediate - Balance detail with speed
|
|
34
|
+
- value: expert
|
|
35
|
+
label: Expert - Be direct and technical
|
|
36
|
+
execution_mode:
|
|
37
|
+
prompt:
|
|
38
|
+
- How do you want to work with BMAD+ agents?
|
|
39
|
+
- 'Manual: you call agents when needed. Autopilot: orchestrator manages everything.'
|
|
40
|
+
default: manual
|
|
41
|
+
result: '{value}'
|
|
42
|
+
single-select:
|
|
43
|
+
- value: manual
|
|
44
|
+
label: Manual - Call agents yourself
|
|
45
|
+
- value: autopilot
|
|
46
|
+
label: Autopilot - Orchestrator manages the pipeline
|
|
47
|
+
- value: hybrid
|
|
48
|
+
label: Hybrid - Autopilot with frequent checkpoints
|
|
49
|
+
auto_role_activation:
|
|
50
|
+
prompt: Enable intelligent auto-activation of agent roles based on context?
|
|
51
|
+
default: 'true'
|
|
52
|
+
result: '{value}'
|
|
53
|
+
single-select:
|
|
54
|
+
- value: 'true'
|
|
55
|
+
label: Yes - Agents auto-switch roles when context demands it
|
|
56
|
+
- value: 'false'
|
|
57
|
+
label: No - Only switch roles when I explicitly ask
|
|
58
|
+
parallel_execution:
|
|
59
|
+
prompt: Enable parallel multi-agent execution for independent tasks?
|
|
60
|
+
default: 'true'
|
|
61
|
+
result: '{value}'
|
|
62
|
+
single-select:
|
|
63
|
+
- value: 'true'
|
|
64
|
+
label: Yes - Run independent tasks in parallel
|
|
65
|
+
- value: 'false'
|
|
66
|
+
label: No - Sequential execution only
|
|
67
|
+
planning_artifacts:
|
|
68
|
+
prompt: Where should planning artifacts be stored? (Discovery phase output)
|
|
69
|
+
default: '{output_folder}/discovery'
|
|
70
|
+
result: '{project-root}/{value}'
|
|
71
|
+
implementation_artifacts:
|
|
72
|
+
prompt: Where should implementation artifacts be stored? (Build & Ship phase output)
|
|
73
|
+
default: '{output_folder}/build'
|
|
74
|
+
result: '{project-root}/{value}'
|
|
75
|
+
project_knowledge:
|
|
76
|
+
prompt: Where should long-term project knowledge be stored?
|
|
77
|
+
default: docs
|
|
78
|
+
result: '{project-root}/{value}'
|
|
79
|
+
directories:
|
|
80
|
+
- '{planning_artifacts}'
|
|
81
|
+
- '{implementation_artifacts}'
|
|
82
|
+
- '{project_knowledge}'
|
|
@@ -48,6 +48,9 @@ installCmd.action(install.action);
|
|
|
48
48
|
const uninstallCmd = program
|
|
49
49
|
.command('uninstall')
|
|
50
50
|
.description('Remove BMAD+ from your project');
|
|
51
|
+
for (const option of uninstall.options || []) {
|
|
52
|
+
uninstallCmd.option(...option);
|
|
53
|
+
}
|
|
51
54
|
uninstallCmd.action(uninstall.action);
|
|
52
55
|
|
|
53
56
|
// Update command
|
|
@@ -112,7 +115,19 @@ for (const option of autoconfig.options || []) {
|
|
|
112
115
|
}
|
|
113
116
|
autoconfigCmd.action(autoconfig.action);
|
|
114
117
|
|
|
115
|
-
|
|
118
|
+
// Version discovery and explicit per-project update policy.
|
|
119
|
+
for (const modulePath of ['./commands/update-check', './commands/update-policy']) {
|
|
120
|
+
const command = require(modulePath);
|
|
121
|
+
const configured = program.command(command.command).description(command.description);
|
|
122
|
+
for (const option of command.options || []) configured.option(...option);
|
|
123
|
+
configured.action(command.action);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Await asynchronous registry checks and updates before completing the CLI.
|
|
127
|
+
program.parseAsync(process.argv).catch(error => {
|
|
128
|
+
console.error(`BMAD+: ${error.message}`);
|
|
129
|
+
process.exitCode = 1;
|
|
130
|
+
});
|
|
116
131
|
|
|
117
132
|
if (process.argv.slice(2).length === 0) {
|
|
118
133
|
program.outputHelp();
|
|
@@ -10,7 +10,8 @@ const fs = require('node:fs');
|
|
|
10
10
|
const clack = require('@clack/prompts');
|
|
11
11
|
const pc = require('picocolors');
|
|
12
12
|
const { t } = require('../i18n');
|
|
13
|
-
const {
|
|
13
|
+
const { EXPECTED_AGENTS } = require('../lib/packs');
|
|
14
|
+
const { readInstallManifest } = require('../lib/install-manifest');
|
|
14
15
|
|
|
15
16
|
module.exports = {
|
|
16
17
|
command: 'doctor',
|
|
@@ -39,8 +40,16 @@ module.exports = {
|
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
let manifest;
|
|
44
|
+
try {
|
|
45
|
+
manifest = readInstallManifest(manifestPath);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
const i = t(options.lang || 'en');
|
|
48
|
+
clack.log.error(i.manifest_invalid(err.message));
|
|
49
|
+
clack.outro(pc.red(i.manifest_repair));
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
44
53
|
clack.log.success(`✅ Manifest found — v${manifest.version}`);
|
|
45
54
|
passed++;
|
|
46
55
|
|
|
@@ -170,43 +179,6 @@ module.exports = {
|
|
|
170
179
|
}
|
|
171
180
|
}
|
|
172
181
|
|
|
173
|
-
// ── Check 9: PACKS ↔ module.yaml sync ──
|
|
174
|
-
checks++;
|
|
175
|
-
try {
|
|
176
|
-
const yaml = require('js-yaml');
|
|
177
|
-
const moduleYamlSrc = path.join(__dirname, '..', '..', '..', 'src', 'bmad-plus', 'module.yaml');
|
|
178
|
-
if (fs.existsSync(moduleYamlSrc)) {
|
|
179
|
-
const moduleContent = yaml.load(fs.readFileSync(moduleYamlSrc, 'utf8'));
|
|
180
|
-
const modulePackIds = Object.keys(moduleContent.packs || {});
|
|
181
|
-
|
|
182
|
-
// Use shared PACKS module instead of fragile regex on install.js source
|
|
183
|
-
const cliPackIds = Object.keys(PACKS);
|
|
184
|
-
|
|
185
|
-
// Find mismatches
|
|
186
|
-
const missingInCLI = modulePackIds.filter(p => !cliPackIds.includes(p));
|
|
187
|
-
const missingInModule = cliPackIds.filter(p => !modulePackIds.includes(p));
|
|
188
|
-
|
|
189
|
-
if (missingInCLI.length === 0 && missingInModule.length === 0) {
|
|
190
|
-
clack.log.success(`✅ PACKS ↔ module.yaml in sync (${modulePackIds.length} packs)`);
|
|
191
|
-
passed++;
|
|
192
|
-
} else {
|
|
193
|
-
if (missingInCLI.length > 0) {
|
|
194
|
-
clack.log.warn(`⚠️ Packs in module.yaml but missing from CLI PACKS: ${missingInCLI.join(', ')}`);
|
|
195
|
-
}
|
|
196
|
-
if (missingInModule.length > 0) {
|
|
197
|
-
clack.log.warn(`⚠️ Packs in CLI PACKS but missing from module.yaml: ${missingInModule.join(', ')}`);
|
|
198
|
-
}
|
|
199
|
-
warnings++;
|
|
200
|
-
}
|
|
201
|
-
} else {
|
|
202
|
-
clack.log.info(pc.dim('ℹ️ PACKS↔module.yaml check skipped (source not available in npx context)'));
|
|
203
|
-
passed++; // Not a failure — just unavailable
|
|
204
|
-
}
|
|
205
|
-
} catch (e) {
|
|
206
|
-
clack.log.info(pc.dim(`ℹ️ PACKS↔module.yaml check skipped: ${e.message}`));
|
|
207
|
-
passed++; // Graceful skip
|
|
208
|
-
}
|
|
209
|
-
|
|
210
182
|
// ── Summary ──
|
|
211
183
|
const summaryColor = errors > 0 ? pc.red : warnings > 0 ? pc.yellow : pc.green;
|
|
212
184
|
const summaryIcon = errors > 0 ? '❌' : warnings > 0 ? '⚠️' : '✅';
|