bmad-plus 0.20.0 → 0.22.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 +41 -0
- package/README.md +14 -14
- package/SECURITY.md +62 -0
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/_http.py +68 -24
- package/package.json +1 -1
- package/readme-international/README.de.md +14 -14
- package/readme-international/README.es.md +14 -14
- package/readme-international/README.fr.md +14 -14
- package/src/bmad-plus/agents/agent-quality/SKILL.md +1 -1
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/code-review.md +26 -5
- package/src/bmad-plus/packs/pack-seo/SKILL.md +3 -1
- package/src/bmad-plus/packs/pack-seo/ref/cwv-thresholds.md +2 -2
- package/src/bmad-plus/packs/pack-seo/requirements.txt +1 -1
- package/src/bmad-plus/packs/pack-seo/scripts/seo_apis.py +72 -30
- package/src/bmad-plus/packs/pack-seo/scripts/seo_crawl.py +36 -24
- package/src/bmad-plus/packs/pack-seo/scripts/seo_fetch.py +179 -59
- package/src/bmad-plus/packs/pack-seo/scripts/seo_report.py +5 -6
- package/src/bmad-plus/packs/pack-seo/scripts/seo_screenshot.py +176 -14
- package/src/bmad-plus/packs/pack-shield/README.md +12 -0
- package/src/bmad-plus/packs/pack-shield/SKILL.md +7 -1
- package/src/bmad-plus/packs/pack-shield/review-rules/access-control.md +10 -0
- package/src/bmad-plus/packs/pack-shield/review-rules/ai-integrations.md +10 -0
- package/src/bmad-plus/packs/pack-shield/review-rules/change-and-supply-chain.md +10 -0
- package/src/bmad-plus/packs/pack-shield/review-rules/cryptography.md +10 -0
- package/src/bmad-plus/packs/pack-shield/review-rules/index.yaml +134 -0
- package/src/bmad-plus/packs/pack-shield/review-rules/logging.md +10 -0
- package/src/bmad-plus/packs/pack-shield/review-rules/personal-data.md +10 -0
- package/src/bmad-plus/packs/pack-shield/shared/ai-processing-register-template.yaml +53 -0
- package/src/bmad-plus/packs/pack-shield/shared/ai-processing-register.md +32 -0
- package/src/bmad-plus/packs/pack-shield/shared/assurance-case-template.yaml +87 -0
- package/src/bmad-plus/packs/pack-shield/shared/assurance-case.md +50 -0
- package/src/bmad-plus/packs/pack-shield/shield-orchestrator.md +24 -1
- package/src/bmad-plus/skills/bmad-plus-uat/SKILL.md +1 -0
- package/src/bmad-plus/skills/bmad-plus-uat/template/page.html +5 -4
- package/tools/build/generate-adapters.js +7 -0
- package/tools/build/generate.js +14 -0
- package/tools/cli/bmad-plus-cli.js +2 -0
- package/tools/cli/commands/ai-register.js +63 -0
- package/tools/cli/commands/assurance.js +162 -0
- package/tools/cli/commands/review.js +141 -7
- package/tools/cli/lib/ai-register.js +393 -0
- package/tools/cli/lib/assurance.js +822 -0
- package/tools/cli/lib/control-refs.js +132 -0
- package/tools/cli/lib/installation-health.js +17 -0
- package/tools/cli/lib/packs.js +60 -2
- package/tools/cli/lib/page-origins.js +582 -0
- package/tools/cli/lib/review-rules.js +124 -26
- package/tools/cli/lib/review.js +493 -10
- package/tools/cli/lib/uat.js +22 -5
- package/tools/cli/review-rules/index.yaml +9 -0
package/tools/cli/lib/uat.js
CHANGED
|
@@ -5,6 +5,7 @@ const fs = require('node:fs');
|
|
|
5
5
|
const path = require('node:path');
|
|
6
6
|
const crypto = require('node:crypto');
|
|
7
7
|
const { redactFields } = require('./redact');
|
|
8
|
+
const { foreignAddresses } = require('./page-origins');
|
|
8
9
|
|
|
9
10
|
const SPEC_SCHEMA = 'bmad-plus/uat-spec/2';
|
|
10
11
|
const RESULTS_SCHEMA = 'bmad-plus/uat-results/2';
|
|
@@ -176,6 +177,9 @@ function checkMarkup(value, where, errors) {
|
|
|
176
177
|
rest = rest.replace(match[0], '');
|
|
177
178
|
}
|
|
178
179
|
if (rest.includes('<')) errors.push(`${where}: a "<" is left outside any allowed tag`);
|
|
180
|
+
// The page renders this text as markup: it is read as the template is, so the page loads
|
|
181
|
+
// nothing from another origin whatever the allowed tags come to be.
|
|
182
|
+
for (const found of foreignAddresses(value)) errors.push(`${where}: ${found}`);
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
function eachMarkup(spec, visit) {
|
|
@@ -575,22 +579,34 @@ const PAGE_GUARANTEES = [
|
|
|
575
579
|
what: 'the exported JSON is the run as answered, and nothing is exported before a run exists',
|
|
576
580
|
markers: ['download(runId + ".json", JSON.stringify(run, null, 2))'],
|
|
577
581
|
},
|
|
582
|
+
{
|
|
583
|
+
id: 'no-third-party-requests',
|
|
584
|
+
what: 'opening and using the page asks nothing of any origin but its own: no remote font, stylesheet, script, image or frame',
|
|
585
|
+
markers: [],
|
|
586
|
+
// An absence has no marker: the template is read as a browser reads it, and every address
|
|
587
|
+
// it would reach on another origin, in markup, style or script, is refused by name.
|
|
588
|
+
refuses: foreignAddresses,
|
|
589
|
+
},
|
|
578
590
|
];
|
|
579
591
|
|
|
580
592
|
/**
|
|
581
593
|
* Which guarantees a template carries: every marker present, in the required order where one
|
|
582
|
-
* is set. Checked on the TEMPLATE, never on the built page: a recipe's
|
|
583
|
-
* able to satisfy or defeat a marker.
|
|
594
|
+
* is set, and nothing it refuses. Checked on the TEMPLATE, never on the built page: a recipe's
|
|
595
|
+
* own text must not be able to satisfy or defeat a marker.
|
|
584
596
|
*/
|
|
585
597
|
function pageGuarantees(template) {
|
|
586
598
|
const missing = [];
|
|
587
599
|
for (const guarantee of PAGE_GUARANTEES) {
|
|
588
|
-
const lost = guarantee.markers
|
|
600
|
+
const lost = guarantee.markers
|
|
601
|
+
.filter((marker) => !template.includes(marker))
|
|
602
|
+
.map((marker) => `missing ${marker}`);
|
|
589
603
|
if (!lost.length && guarantee.order) {
|
|
590
604
|
const positions = guarantee.order.map((marker) => template.indexOf(marker));
|
|
591
605
|
if (positions.some((at) => at < 0) || positions.some((at, i) => i && at < positions[i - 1]))
|
|
592
|
-
lost.push(`order ${guarantee.order.join(' → ')}`);
|
|
606
|
+
lost.push(`missing order ${guarantee.order.join(' → ')}`);
|
|
593
607
|
}
|
|
608
|
+
if (guarantee.refuses)
|
|
609
|
+
for (const found of guarantee.refuses(template)) lost.push(`carries ${found}`);
|
|
594
610
|
if (lost.length) missing.push({ id: guarantee.id, what: guarantee.what, lost });
|
|
595
611
|
}
|
|
596
612
|
const carried = PAGE_GUARANTEES.map((g) => g.id).filter(
|
|
@@ -607,7 +623,7 @@ function buildPage(spec, options = {}) {
|
|
|
607
623
|
if (!guarantees.ok) {
|
|
608
624
|
throw new Error(
|
|
609
625
|
`the page template (${options.template ? 'the template given' : TEMPLATE}) lost a guarantee — not built: ${guarantees.missing
|
|
610
|
-
.map((entry) => `${entry.id}: ${entry.what} —
|
|
626
|
+
.map((entry) => `${entry.id}: ${entry.what} — ${entry.lost.join(', ')}`)
|
|
611
627
|
.join('; ')}`
|
|
612
628
|
);
|
|
613
629
|
}
|
|
@@ -1013,6 +1029,7 @@ module.exports = {
|
|
|
1013
1029
|
TRIAGE_SCHEMA,
|
|
1014
1030
|
DEFAULT_DIR,
|
|
1015
1031
|
DEFAULT_BUDGET,
|
|
1032
|
+
ALLOWED_TAGS,
|
|
1016
1033
|
STATES,
|
|
1017
1034
|
TRIAGE_CLASSES,
|
|
1018
1035
|
TRIAGE_DECISIONS,
|
|
@@ -1,36 +1,45 @@
|
|
|
1
1
|
# Built-in review checklists, applied by path. Every matching rule applies to a file.
|
|
2
2
|
# A project adds, replaces (same id) or disables rules in _bmad/review-rules.yaml.
|
|
3
|
+
# A group is a rule family: parallel reviewers can split one unit by group.
|
|
3
4
|
schema: bmad-plus/review-rules/1
|
|
4
5
|
rules:
|
|
5
6
|
- id: general
|
|
6
7
|
title: Every change
|
|
8
|
+
group: code
|
|
7
9
|
globs: ['**']
|
|
8
10
|
doc: general.md
|
|
9
11
|
- id: javascript-typescript
|
|
10
12
|
title: JavaScript and TypeScript
|
|
13
|
+
group: code
|
|
11
14
|
globs: ['**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}', '**/*.{vue,svelte}']
|
|
12
15
|
doc: javascript-typescript.md
|
|
13
16
|
- id: python
|
|
14
17
|
title: Python
|
|
18
|
+
group: code
|
|
15
19
|
globs: ['**/*.{py,pyi}']
|
|
16
20
|
doc: python.md
|
|
17
21
|
- id: sql-and-migrations
|
|
18
22
|
title: SQL, queries and migrations
|
|
23
|
+
group: data
|
|
19
24
|
globs: ['**/*.sql', '**/{migrations,migrate,db/migrate}/**', '**/*.prisma', '**/schema.rb']
|
|
20
25
|
doc: sql-and-migrations.md
|
|
21
26
|
- id: shell
|
|
22
27
|
title: Shell and PowerShell scripts
|
|
28
|
+
group: code
|
|
23
29
|
globs: ['**/*.{sh,bash,zsh,ps1,psm1}', '**/{Makefile,makefile}']
|
|
24
30
|
doc: shell.md
|
|
25
31
|
- id: ci-workflows
|
|
26
32
|
title: CI workflows
|
|
33
|
+
group: delivery
|
|
27
34
|
globs: ['.github/workflows/**/*.{yml,yaml}', '**/.gitlab-ci.yml', '**/{bitbucket-pipelines.yml,azure-pipelines.yml}']
|
|
28
35
|
doc: ci-workflows.md
|
|
29
36
|
- id: containers
|
|
30
37
|
title: Containers and deployment manifests
|
|
38
|
+
group: delivery
|
|
31
39
|
globs: ['**/{Dockerfile,Containerfile}', '**/*.dockerfile', '**/{docker-,}compose*.{yml,yaml}', '**/{k8s,kubernetes,helm,charts}/**/*.{yml,yaml}']
|
|
32
40
|
doc: containers.md
|
|
33
41
|
- id: configuration
|
|
34
42
|
title: Configuration and dependency manifests
|
|
43
|
+
group: delivery
|
|
35
44
|
globs: ['**/*.{json,yml,yaml,toml,ini,properties}', '**/.env.example', '**/{package.json,pyproject.toml,requirements*.txt,go.mod,Cargo.toml,composer.json}']
|
|
36
45
|
doc: configuration.md
|