ma-agents 3.18.0-beta.2 → 3.18.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/README.md +2 -2
- package/bin/cli.js +29 -32
- package/docs/architecture.md +2 -2
- package/lib/bmad-cache/cache-manifest.json +0 -12
- package/lib/bmad-extension-plugin/.claude-plugin/marketplace.json +1 -1
- package/lib/bmad.js +33 -34
- package/package.json +1 -1
- package/scripts/build-bmad-cache.js +18 -9
- package/lib/bmad-cache/gds/.claude-plugin/marketplace.json +0 -56
- package/lib/bmad-cache/gds/.markdownlint-cli2.yaml +0 -35
- package/lib/bmad-cache/gds/.nvmrc +0 -1
- package/lib/bmad-cache/gds/.prettierignore +0 -9
- package/lib/bmad-cache/gds/CNAME +0 -1
- package/lib/bmad-cache/gds/LICENSE +0 -26
- package/lib/bmad-cache/gds/README.md +0 -134
- package/lib/bmad-cache/gds/_git_preserved/HEAD +0 -1
- package/lib/bmad-cache/gds/_git_preserved/config +0 -13
- package/lib/bmad-cache/gds/_git_preserved/description +0 -1
- package/lib/bmad-cache/gds/_git_preserved/hooks/applypatch-msg.sample +0 -15
- package/lib/bmad-cache/gds/_git_preserved/hooks/commit-msg.sample +0 -74
- package/lib/bmad-cache/gds/_git_preserved/hooks/fsmonitor-watchman.sample +0 -168
- package/lib/bmad-cache/gds/_git_preserved/hooks/post-update.sample +0 -8
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-applypatch.sample +0 -14
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-commit.sample +0 -49
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-merge-commit.sample +0 -13
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-push.sample +0 -53
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-rebase.sample +0 -169
- package/lib/bmad-cache/gds/_git_preserved/hooks/pre-receive.sample +0 -24
- package/lib/bmad-cache/gds/_git_preserved/hooks/prepare-commit-msg.sample +0 -42
- package/lib/bmad-cache/gds/_git_preserved/hooks/push-to-checkout.sample +0 -78
- package/lib/bmad-cache/gds/_git_preserved/hooks/sendemail-validate.sample +0 -77
- package/lib/bmad-cache/gds/_git_preserved/hooks/update.sample +0 -128
- package/lib/bmad-cache/gds/_git_preserved/index +0 -0
- package/lib/bmad-cache/gds/_git_preserved/info/exclude +0 -6
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-dcb7c556d9bb6b6b70d2301e094eaac6d7300552.idx +0 -0
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-dcb7c556d9bb6b6b70d2301e094eaac6d7300552.pack +0 -0
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-dcb7c556d9bb6b6b70d2301e094eaac6d7300552.rev +0 -0
- package/lib/bmad-cache/gds/_git_preserved/packed-refs +0 -2
- package/lib/bmad-cache/gds/_git_preserved/refs/heads/main +0 -1
- package/lib/bmad-cache/gds/_git_preserved/shallow +0 -1
- package/lib/bmad-cache/gds/eslint.config.mjs +0 -141
- package/lib/bmad-cache/gds/package.json +0 -91
- package/lib/bmad-cache/gds/prettier.config.mjs +0 -32
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-architect/customize.toml +0 -57
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-designer/customize.toml +0 -59
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-dev/customize.toml +0 -129
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-dev/gametest/qa-index.csv +0 -18
- package/lib/bmad-cache/gds/src/agents/gds-agent-game-solo-dev/customize.toml +0 -55
- package/lib/bmad-cache/gds/src/agents/gds-agent-tech-writer/customize.toml +0 -65
- package/lib/bmad-cache/gds/src/module-help.csv +0 -30
- package/lib/bmad-cache/gds/src/module.yaml +0 -113
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/gds-brainstorm-game/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/gds-brainstorm-game/game-brain-methods.csv +0 -26
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/gds-create-game-brief/customize.toml +0 -116
- package/lib/bmad-cache/gds/src/workflows/1-preproduction/research/gds-domain-research/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-create-narrative/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/assets/game-types.csv +0 -25
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/assets/genre-complexity.csv +0 -26
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/assets/validation-report-template.html +0 -190
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/customize.toml +0 -99
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-gdd/scripts/render-validation-html.py +0 -290
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-prd/assets/validation-report-template.html +0 -190
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-prd/customize.toml +0 -84
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-ux/assets/validation-report-template.html +0 -319
- package/lib/bmad-cache/gds/src/workflows/2-design/gds-ux/customize.toml +0 -101
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-check-implementation-readiness/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-create-epics-and-stories/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/architecture-patterns.yaml +0 -508
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/decision-catalog.yaml +0 -428
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/engine-mcps.yaml +0 -392
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-game-architecture/pattern-categories.csv +0 -13
- package/lib/bmad-cache/gds/src/workflows/3-technical/gds-generate-project-context/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-code-review/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-correct-course/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-create-story/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-dev-story/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-investigate/customize.toml +0 -62
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-retrospective/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-sprint-planning/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-sprint-planning/sprint-status-template.yaml +0 -55
- package/lib/bmad-cache/gds/src/workflows/4-production/gds-sprint-status/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-e2e-scaffold/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-performance-test/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-playtest-plan/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-automate/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-design/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-framework/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gametest/gds-test-review/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gds-document-project/customize.toml +0 -41
- package/lib/bmad-cache/gds/src/workflows/gds-document-project/documentation-requirements.csv +0 -12
- package/lib/bmad-cache/gds/src/workflows/gds-document-project/templates/project-scan-report-schema.json +0 -160
- package/lib/bmad-cache/gds/src/workflows/gds-quick-flow/gds-quick-dev/customize.toml +0 -41
- package/lib/bmad-cache/gds/tools/build-docs.mjs +0 -450
- package/lib/bmad-cache/gds/website/astro.config.mjs +0 -142
- package/lib/bmad-cache/gds/website/public/favicon.ico +0 -0
- package/lib/bmad-cache/gds/website/public/img/bmad-dark.png +0 -0
- package/lib/bmad-cache/gds/website/public/img/bmad-light.png +0 -0
- package/lib/bmad-cache/gds/website/src/components/Banner.astro +0 -71
- package/lib/bmad-cache/gds/website/src/components/Header.astro +0 -94
- package/lib/bmad-cache/gds/website/src/components/MobileMenuFooter.astro +0 -33
- package/lib/bmad-cache/gds/website/src/content/config.ts +0 -6
- package/lib/bmad-cache/gds/website/src/content/docs +0 -1
- package/lib/bmad-cache/gds/website/src/lib/site-url.mjs +0 -25
- package/lib/bmad-cache/gds/website/src/rehype-base-paths.js +0 -88
- package/lib/bmad-cache/gds/website/src/rehype-markdown-links.js +0 -117
- package/lib/bmad-cache/gds/website/src/styles/custom.css +0 -503
- package/lib/bmad-cache/wds/.claude-plugin/marketplace.json +0 -35
- package/lib/bmad-cache/wds/.markdownlint-cli2.yaml +0 -38
- package/lib/bmad-cache/wds/.nvmrc +0 -1
- package/lib/bmad-cache/wds/.prettierignore +0 -9
- package/lib/bmad-cache/wds/LICENSE +0 -27
- package/lib/bmad-cache/wds/README.md +0 -139
- package/lib/bmad-cache/wds/_git_preserved/HEAD +0 -1
- package/lib/bmad-cache/wds/_git_preserved/config +0 -13
- package/lib/bmad-cache/wds/_git_preserved/description +0 -1
- package/lib/bmad-cache/wds/_git_preserved/hooks/applypatch-msg.sample +0 -15
- package/lib/bmad-cache/wds/_git_preserved/hooks/commit-msg.sample +0 -74
- package/lib/bmad-cache/wds/_git_preserved/hooks/fsmonitor-watchman.sample +0 -168
- package/lib/bmad-cache/wds/_git_preserved/hooks/post-update.sample +0 -8
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-applypatch.sample +0 -14
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-commit.sample +0 -49
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-merge-commit.sample +0 -13
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-push.sample +0 -53
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-rebase.sample +0 -169
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-receive.sample +0 -24
- package/lib/bmad-cache/wds/_git_preserved/hooks/prepare-commit-msg.sample +0 -42
- package/lib/bmad-cache/wds/_git_preserved/hooks/push-to-checkout.sample +0 -78
- package/lib/bmad-cache/wds/_git_preserved/hooks/sendemail-validate.sample +0 -77
- package/lib/bmad-cache/wds/_git_preserved/hooks/update.sample +0 -128
- package/lib/bmad-cache/wds/_git_preserved/index +0 -0
- package/lib/bmad-cache/wds/_git_preserved/info/exclude +0 -6
- package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-656c3d8d5426e73043b6a7f45eedaab74e3c419e.idx +0 -0
- package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-656c3d8d5426e73043b6a7f45eedaab74e3c419e.pack +0 -0
- package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-656c3d8d5426e73043b6a7f45eedaab74e3c419e.rev +0 -0
- package/lib/bmad-cache/wds/_git_preserved/packed-refs +0 -2
- package/lib/bmad-cache/wds/_git_preserved/refs/heads/main +0 -1
- package/lib/bmad-cache/wds/_git_preserved/refs/tags/v0.4.3 +0 -1
- package/lib/bmad-cache/wds/_git_preserved/shallow +0 -1
- package/lib/bmad-cache/wds/eslint.config.mjs +0 -152
- package/lib/bmad-cache/wds/package.json +0 -82
- package/lib/bmad-cache/wds/prettier.config.mjs +0 -32
- package/lib/bmad-cache/wds/src/agents/wds-agent-freya-ux/customize.toml +0 -80
- package/lib/bmad-cache/wds/src/agents/wds-agent-mimir-builder/customize.toml +0 -52
- package/lib/bmad-cache/wds/src/agents/wds-agent-saga-analyst/customize.toml +0 -70
- package/lib/bmad-cache/wds/src/module-help.csv +0 -19
- package/lib/bmad-cache/wds/src/module.yaml +0 -173
- package/lib/bmad-cache/wds/src/scripts/README.md +0 -155
- package/lib/bmad-cache/wds/src/scripts/wds-add-object.js +0 -202
- package/lib/bmad-cache/wds/src/scripts/wds-add-spacing.js +0 -158
- package/lib/bmad-cache/wds/src/scripts/wds-init-page.js +0 -229
- package/lib/bmad-cache/wds/src/scripts/wds-init-scenario.js +0 -120
- package/lib/bmad-cache/wds/src/scripts/wds-nav.js +0 -201
- package/lib/bmad-cache/wds/src/scripts/wds-validate.js +0 -301
- package/lib/bmad-cache/wds/src/workflows/wds-0-project-setup/resources/wds-1-project-brief/templates/platform-requirements.template.yaml +0 -69
- package/lib/bmad-cache/wds/src/workflows/wds-0-project-setup/resources/wds-7-design-system/templates/catalog.template.html +0 -363
- package/lib/bmad-cache/wds/src/workflows/wds-1-project-brief/templates/platform-requirements.template.yaml +0 -69
- package/lib/bmad-cache/wds/src/workflows/wds-3-scenarios/workflow.xml +0 -450
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/templates/design-delivery.template.yaml +0 -104
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/templates/test-scenario.template.yaml +0 -192
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/workflow-specify.xml +0 -387
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.css +0 -164
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.html +0 -18
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.js +0 -430
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/demo-data-template.json +0 -63
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/page-template.html +0 -465
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/work-file-template.yaml +0 -264
- package/lib/bmad-cache/wds/src/workflows/wds-7-design-system/templates/catalog.template.html +0 -363
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
// wds-validate.js — WDS scaffold: validate page spec files for correctness
|
|
2
|
-
// Usage: node src/scripts/wds-validate.js --page "C-UX-Scenarios/01-onboarding/01-start/01-start.md"
|
|
3
|
-
// node src/scripts/wds-validate.js --scenario "01 Onboarding"
|
|
4
|
-
// node src/scripts/wds-validate.js --all
|
|
5
|
-
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const fs = require('node:fs');
|
|
9
|
-
const path = require('node:path');
|
|
10
|
-
|
|
11
|
-
function parseArgs(argv) {
|
|
12
|
-
const args = {};
|
|
13
|
-
for (let i = 0; i < argv.length; i++) {
|
|
14
|
-
if (argv[i].startsWith('--')) {
|
|
15
|
-
const key = argv[i].slice(2);
|
|
16
|
-
const value = argv[i + 1] && !argv[i + 1].startsWith('--') ? argv[i + 1] : true;
|
|
17
|
-
args[key] = value;
|
|
18
|
-
if (value !== true) i++;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return args;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function toSlug(str) {
|
|
25
|
-
return str.toLowerCase().replaceAll(/\s+/g, '-');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function printUsage() {
|
|
29
|
-
process.stdout.write(
|
|
30
|
-
[
|
|
31
|
-
'Usage: node src/scripts/wds-validate.js --page <path>',
|
|
32
|
-
' node src/scripts/wds-validate.js --scenario "01 Onboarding"',
|
|
33
|
-
' node src/scripts/wds-validate.js --all',
|
|
34
|
-
'',
|
|
35
|
-
'Options:',
|
|
36
|
-
' --page Path to a single page spec .md file',
|
|
37
|
-
' --scenario Scenario name or slug to validate all pages',
|
|
38
|
-
' --all Validate all scenarios',
|
|
39
|
-
' --output Base path (default: current directory)',
|
|
40
|
-
'',
|
|
41
|
-
].join('\n'),
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const REQUIRED_SECTIONS = [
|
|
46
|
-
'## Overview',
|
|
47
|
-
'## Page Metadata',
|
|
48
|
-
'## Layout Structure',
|
|
49
|
-
'## Spacing',
|
|
50
|
-
'## Typography',
|
|
51
|
-
'## Page Sections',
|
|
52
|
-
'## Page States',
|
|
53
|
-
'## Checklist',
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
const REQUIRED_METADATA_PROPS = ['Scenario', 'Page Number', 'Platform', 'Page Type', 'Viewport', 'Interaction', 'Visibility'];
|
|
57
|
-
|
|
58
|
-
const KEBAB_CASE_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
59
|
-
|
|
60
|
-
// Extract all OBJECT IDs from content: lines matching **OBJECT ID:** `...`
|
|
61
|
-
function extractObjectIds(content) {
|
|
62
|
-
const ids = [];
|
|
63
|
-
const re = /\*\*OBJECT ID:\*\*\s+`([^`]+)`/g;
|
|
64
|
-
let m;
|
|
65
|
-
while ((m = re.exec(content)) !== null) {
|
|
66
|
-
ids.push(m[1]);
|
|
67
|
-
}
|
|
68
|
-
return ids;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Extract all spacing IDs from content: lines matching #### ↕ `...`
|
|
72
|
-
function extractSpacingIds(content) {
|
|
73
|
-
const ids = [];
|
|
74
|
-
const re = /####\s+[↕↔]\s+`([^`]+)`/g;
|
|
75
|
-
let m;
|
|
76
|
-
while ((m = re.exec(content)) !== null) {
|
|
77
|
-
ids.push(m[1]);
|
|
78
|
-
}
|
|
79
|
-
return ids;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Count nav rows: lines starting with '←'
|
|
83
|
-
function countNavRows(content) {
|
|
84
|
-
const lines = content.split('\n');
|
|
85
|
-
return lines.filter((l) => l.trim().startsWith('←')).length;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Check Swedish + English content: for each object block, look for SE and EN rows
|
|
89
|
-
function checkObjectContent(content) {
|
|
90
|
-
const missing = [];
|
|
91
|
-
// Split into object blocks by #### heading
|
|
92
|
-
const blocks = content.split(/(?=#### )/);
|
|
93
|
-
for (const block of blocks) {
|
|
94
|
-
const idMatch = block.match(/\*\*OBJECT ID:\*\*\s+`([^`]+)`/);
|
|
95
|
-
if (!idMatch) continue;
|
|
96
|
-
const objectId = idMatch[1];
|
|
97
|
-
// Check for SE row
|
|
98
|
-
if (block.includes('| SE |')) {
|
|
99
|
-
const seMatch = block.match(/\| SE \| "([^"]*)"/);
|
|
100
|
-
if (!seMatch || seMatch[1].trim() === '' || seMatch[1].trim() === '—') {
|
|
101
|
-
missing.push(`Object "${objectId}" has empty SE content`);
|
|
102
|
-
}
|
|
103
|
-
} else {
|
|
104
|
-
missing.push(`Object "${objectId}" missing SE content field`);
|
|
105
|
-
}
|
|
106
|
-
// Check for EN row
|
|
107
|
-
if (block.includes('| EN |')) {
|
|
108
|
-
const enMatch = block.match(/\| EN \| "([^"]*)"/);
|
|
109
|
-
if (!enMatch || enMatch[1].trim() === '' || enMatch[1].trim() === '—') {
|
|
110
|
-
missing.push(`Object "${objectId}" has empty EN content`);
|
|
111
|
-
}
|
|
112
|
-
} else {
|
|
113
|
-
missing.push(`Object "${objectId}" missing EN content field`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return missing;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function validatePage(filePath) {
|
|
120
|
-
const errors = [];
|
|
121
|
-
const warnings = [];
|
|
122
|
-
|
|
123
|
-
if (!fs.existsSync(filePath)) {
|
|
124
|
-
return { errors: [`File not found: ${filePath}`], warnings: [], objectCount: 0, spacingCount: 0 };
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
let content;
|
|
128
|
-
try {
|
|
129
|
-
content = fs.readFileSync(filePath, 'utf8');
|
|
130
|
-
} catch (error) {
|
|
131
|
-
return { errors: [`Cannot read file: ${error.message}`], warnings: [], objectCount: 0, spacingCount: 0 };
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const pageSlug = path.basename(filePath, '.md');
|
|
135
|
-
// Derive page prefix (strip leading number): "01-start" -> "start"
|
|
136
|
-
const slugParts = pageSlug.split('-');
|
|
137
|
-
const pagePrefix = slugParts.length > 1 ? slugParts.slice(1).join('-') : pageSlug;
|
|
138
|
-
|
|
139
|
-
// 1. Required sections
|
|
140
|
-
for (const section of REQUIRED_SECTIONS) {
|
|
141
|
-
if (!content.includes(section)) {
|
|
142
|
-
errors.push(`Missing section: ${section}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// 2. Object IDs — kebab-case and prefix
|
|
147
|
-
const objectIds = extractObjectIds(content);
|
|
148
|
-
const seenIds = new Set();
|
|
149
|
-
|
|
150
|
-
for (const id of objectIds) {
|
|
151
|
-
// Kebab-case check
|
|
152
|
-
if (!KEBAB_CASE_RE.test(id)) {
|
|
153
|
-
errors.push(`Object ID not in kebab-case: \`${id}\``);
|
|
154
|
-
}
|
|
155
|
-
// Prefix check
|
|
156
|
-
if (!id.startsWith(pagePrefix + '-')) {
|
|
157
|
-
errors.push(`Object ID missing prefix: \`${id}\` (expected prefix: ${pagePrefix}-)`);
|
|
158
|
-
}
|
|
159
|
-
// Duplicate check
|
|
160
|
-
if (seenIds.has(id)) {
|
|
161
|
-
errors.push(`Duplicate Object ID: \`${id}\``);
|
|
162
|
-
}
|
|
163
|
-
seenIds.add(id);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// 3. Navigation rows (expect 3)
|
|
167
|
-
const navCount = countNavRows(content);
|
|
168
|
-
if (navCount < 3) {
|
|
169
|
-
errors.push(`Navigation rows: found ${navCount}, expected 3`);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// 4. Metadata table properties
|
|
173
|
-
for (const prop of REQUIRED_METADATA_PROPS) {
|
|
174
|
-
if (!content.includes(`| ${prop} |`)) {
|
|
175
|
-
errors.push(`Metadata table missing property: ${prop}`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// 5. Sketches folder
|
|
180
|
-
const sketchesDir = path.join(path.dirname(filePath), 'sketches');
|
|
181
|
-
if (!fs.existsSync(sketchesDir)) {
|
|
182
|
-
warnings.push('Sketches folder does not exist');
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// 6. Swedish + English content check
|
|
186
|
-
const contentWarnings = checkObjectContent(content);
|
|
187
|
-
for (const w of contentWarnings) {
|
|
188
|
-
warnings.push(w);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Spacing IDs
|
|
192
|
-
const spacingIds = extractSpacingIds(content);
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
errors,
|
|
196
|
-
warnings,
|
|
197
|
-
objectCount: objectIds.length,
|
|
198
|
-
spacingCount: spacingIds.length,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function formatResult(label, result) {
|
|
203
|
-
const { errors, warnings, objectCount, spacingCount } = result;
|
|
204
|
-
if (errors.length === 0 && warnings.length === 0) {
|
|
205
|
-
return `✓ ${label} — valid (${objectCount} objects, ${spacingCount} spacing objects)\n`;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const lines = [];
|
|
209
|
-
if (errors.length > 0) {
|
|
210
|
-
lines.push(`✗ ${label} — ${errors.length} error(s):`);
|
|
211
|
-
for (const e of errors) lines.push(` - ${e}`);
|
|
212
|
-
}
|
|
213
|
-
if (warnings.length > 0) {
|
|
214
|
-
lines.push(` ${warnings.length} warning(s):`);
|
|
215
|
-
for (const w of warnings) lines.push(` ! ${w}`);
|
|
216
|
-
}
|
|
217
|
-
return lines.join('\n') + '\n';
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function getPageFiles(scenarioDir) {
|
|
221
|
-
let entries;
|
|
222
|
-
try {
|
|
223
|
-
entries = fs.readdirSync(scenarioDir, { withFileTypes: true });
|
|
224
|
-
} catch {
|
|
225
|
-
return [];
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return entries
|
|
229
|
-
.filter((e) => e.isDirectory())
|
|
230
|
-
.map((e) => {
|
|
231
|
-
const mdFile = path.join(scenarioDir, e.name, `${e.name}.md`);
|
|
232
|
-
return fs.existsSync(mdFile) ? mdFile : null;
|
|
233
|
-
})
|
|
234
|
-
.filter(Boolean)
|
|
235
|
-
.sort();
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function main() {
|
|
239
|
-
const args = parseArgs(process.argv.slice(2));
|
|
240
|
-
|
|
241
|
-
if (args.help) {
|
|
242
|
-
printUsage();
|
|
243
|
-
process.exit(0);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (!args.page && !args.scenario && !args.all) {
|
|
247
|
-
process.stderr.write('Error: --page, --scenario, or --all is required.\n\n');
|
|
248
|
-
printUsage();
|
|
249
|
-
process.exit(1);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const outputBase = args.output || process.cwd();
|
|
253
|
-
const scenariosBase = path.join(outputBase, 'C-UX-Scenarios');
|
|
254
|
-
|
|
255
|
-
let filesToValidate = [];
|
|
256
|
-
|
|
257
|
-
if (args.page) {
|
|
258
|
-
filesToValidate = [path.resolve(args.page)];
|
|
259
|
-
} else if (args.scenario) {
|
|
260
|
-
const scenarioSlug = toSlug(args.scenario);
|
|
261
|
-
const scenarioDir = path.join(scenariosBase, scenarioSlug);
|
|
262
|
-
filesToValidate = getPageFiles(scenarioDir);
|
|
263
|
-
if (filesToValidate.length === 0) {
|
|
264
|
-
process.stdout.write(`No pages found in scenario: ${scenarioSlug}\n`);
|
|
265
|
-
process.exit(0);
|
|
266
|
-
}
|
|
267
|
-
} else if (args.all) {
|
|
268
|
-
if (!fs.existsSync(scenariosBase)) {
|
|
269
|
-
process.stderr.write(`Error: C-UX-Scenarios not found at: ${scenariosBase}\n`);
|
|
270
|
-
process.exit(1);
|
|
271
|
-
}
|
|
272
|
-
let entries;
|
|
273
|
-
try {
|
|
274
|
-
entries = fs.readdirSync(scenariosBase, { withFileTypes: true });
|
|
275
|
-
} catch (error) {
|
|
276
|
-
process.stderr.write(`Error reading scenarios: ${error.message}\n`);
|
|
277
|
-
process.exit(1);
|
|
278
|
-
}
|
|
279
|
-
for (const e of entries.filter((e) => e.isDirectory()).sort()) {
|
|
280
|
-
const pages = getPageFiles(path.join(scenariosBase, e.name));
|
|
281
|
-
filesToValidate.push(...pages);
|
|
282
|
-
}
|
|
283
|
-
if (filesToValidate.length === 0) {
|
|
284
|
-
process.stdout.write('No page specs found.\n');
|
|
285
|
-
process.exit(0);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
let hasErrors = false;
|
|
290
|
-
|
|
291
|
-
for (const filePath of filesToValidate) {
|
|
292
|
-
const label = path.basename(filePath);
|
|
293
|
-
const result = validatePage(filePath);
|
|
294
|
-
process.stdout.write(formatResult(label, result));
|
|
295
|
-
if (result.errors.length > 0) hasErrors = true;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
process.exit(hasErrors ? 1 : 0);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
main();
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# WDS Platform Requirements Template
|
|
2
|
-
# Save to: A-Project-Brief/platform-requirements.yaml
|
|
3
|
-
|
|
4
|
-
project:
|
|
5
|
-
name: "Project Name"
|
|
6
|
-
type: "mobile_app" # mobile_app | web_app | desktop_app | api
|
|
7
|
-
wds_version: "6.0"
|
|
8
|
-
created_at: "YYYY-MM-DDTHH:MM:SSZ"
|
|
9
|
-
|
|
10
|
-
platform:
|
|
11
|
-
frontend:
|
|
12
|
-
framework: "framework-name" # react_native | react | vue | angular | svelte
|
|
13
|
-
version: "X.X"
|
|
14
|
-
state_management: "library" # zustand | redux | mobx | context
|
|
15
|
-
navigation: "library" # react_navigation | react_router | vue_router
|
|
16
|
-
styling: "approach" # tailwind | styled_components | css_modules
|
|
17
|
-
ui_library: "library" # shadcn | mui | chakra (optional)
|
|
18
|
-
|
|
19
|
-
backend:
|
|
20
|
-
framework: "framework-name" # supabase | firebase | express | fastapi | django
|
|
21
|
-
version: "X.X"
|
|
22
|
-
auth: "auth-provider" # supabase_auth | firebase_auth | auth0 | custom
|
|
23
|
-
database: "database-type" # postgresql | mysql | mongodb | firestore
|
|
24
|
-
storage: "storage-provider" # supabase_storage | s3 | cloudinary
|
|
25
|
-
api: "api-type" # rest | graphql | grpc
|
|
26
|
-
|
|
27
|
-
database:
|
|
28
|
-
type: "database-type" # postgresql | mysql | mongodb
|
|
29
|
-
version: "XX"
|
|
30
|
-
orm: "orm-library" # prisma | typeorm | mongoose (optional)
|
|
31
|
-
|
|
32
|
-
deployment:
|
|
33
|
-
frontend: "platform" # expo_eas | vercel | netlify | aws
|
|
34
|
-
backend: "platform" # supabase_cloud | firebase | heroku | aws
|
|
35
|
-
ci_cd: "platform" # github_actions | gitlab_ci | circle_ci
|
|
36
|
-
hosting: "platform" # vercel | netlify | aws (if web app)
|
|
37
|
-
|
|
38
|
-
integrations:
|
|
39
|
-
- name: "integration-name"
|
|
40
|
-
provider: "provider-name"
|
|
41
|
-
required: true # true | false
|
|
42
|
-
purpose: "[Why this integration is needed]"
|
|
43
|
-
|
|
44
|
-
- name: "integration-name"
|
|
45
|
-
provider: "provider-name"
|
|
46
|
-
required: false
|
|
47
|
-
purpose: "[Why this integration is needed]"
|
|
48
|
-
|
|
49
|
-
constraints:
|
|
50
|
-
- "[Technical constraint 1]"
|
|
51
|
-
- "[Technical constraint 2]"
|
|
52
|
-
- "[Business constraint 1]"
|
|
53
|
-
- "[Regulatory constraint 1]"
|
|
54
|
-
|
|
55
|
-
performance_requirements:
|
|
56
|
-
- "[Performance requirement 1]"
|
|
57
|
-
- "[Performance requirement 2]"
|
|
58
|
-
- "[Performance requirement 3]"
|
|
59
|
-
|
|
60
|
-
security_requirements:
|
|
61
|
-
- "[Security requirement 1]"
|
|
62
|
-
- "[Security requirement 2]"
|
|
63
|
-
- "[Security requirement 3]"
|
|
64
|
-
|
|
65
|
-
wds_metadata:
|
|
66
|
-
project_brief: "A-Project-Brief/project-brief.md"
|
|
67
|
-
trigger_map: "B-Trigger-Map/trigger-map.md"
|
|
68
|
-
scenarios: "C-UX-Scenarios/"
|
|
69
|
-
design_system: "D-Design-System/"
|