@ai.all/ds7 1.0.0 → 2.0.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/SPEC.md CHANGED
@@ -1,58 +1,102 @@
1
- # DS7 Technical Specification & Standards
1
+ # DS7 Technical Specification
2
2
 
3
- ## 1. Стек технологий
4
- - **Framework:** Nuxt 4 (Vue 3.5+, Composition API `<script setup lang="ts">`).
5
- - **Styling:** Tailwind CSS v4 + Semantic CSS Custom Properties (Design Tokens in `theme.css`).
6
- - **Rendering:** Full Static Generation (`npx nuxt generate`), Nitro prerendering for all routes, sitemap.xml, robots.txt.
7
- - **i18n:** `@nuxtjs/i18n` (prefix-except-default strategy, single hub in `i18n/locales/`).
8
- - **Typing:** Strict TypeScript (`typescript: { strict: true }`).
9
- - **Testing:** Vitest (unit tests) + Playwright (end-to-end and visual regression).
3
+ > **How it fits with AI-ALL.** [AI-ALL](https://github.com/ai-all-ai/aiall) (`@ai.all/aiall`) creates the agent entrypoints and the routing file, and keeps them in sync. This document is delivered to agents as the `ds7` pack of AI-ALL. AI-ALL works without DS7; for web projects, install both.
4
+
5
+
6
+ Version 1.1.0. This document is the technical baseline. Rules for agents are in `ALL.md`; this file describes the stack, the layout and the quality gates.
10
7
 
11
8
  ---
12
9
 
13
- ## 2. Иерархия директорий эталонного проекта
10
+ ## 1. Stack
11
+
12
+ - **Framework:** Nuxt 4, Vue 3.5+, Composition API with `<script setup lang="ts">`.
13
+ - **Styling:** Tailwind CSS v4 and CSS custom properties defined in `theme.css`.
14
+ - **Rendering:** static generation (`nuxt generate`), prerendered routes, `sitemap.xml`, `robots.txt`.
15
+ - **i18n:** `@nuxtjs/i18n`, prefix-except-default strategy, one locale hub in `i18n/locales/`.
16
+ - **Types:** strict TypeScript.
17
+ - **Tests:** Vitest for unit and composable tests; Playwright for flows and browser checks; axe for accessibility.
18
+ - **Quality tooling:** a single `qa` script runs the gates listed in section 5.
19
+
20
+ ---
21
+
22
+ ## 2. Directory layout
14
23
 
15
24
  ```
16
25
  project-root/
17
26
  ├── app/
18
- │ ├── app.vue # Корневой шаблон приложения
27
+ │ ├── app.vue
19
28
  │ ├── assets/css/
20
- │ │ ├── main.css # Точка сборки стилей
21
- │ │ ├── theme.css # Дизайн-токены (цвета, шрифты, отступы, тени)
22
- │ │ ├── base.css # Глобальный ресет и теги
23
- │ │ └── components.css # Базовые классы и модификаторы компонентов
29
+ │ │ ├── main.css # entry point for styles
30
+ │ │ ├── theme.css # foundations: tokens
31
+ │ │ ├── base.css # reset and element defaults
32
+ │ │ └── components.css # base classes and modifiers
24
33
  │ ├── components/
25
- │ │ ├── ui/ # Атомы и Молекулы (UiButton, UiProductCard, UiPrice...)
26
- │ │ ├── sections/ # Автономные секции и Организмы (UiCardSlider, CalcSection...)
27
- │ │ └── site/ # Каркас сайта (SiteHeader, SiteFooter, SiteModalHost...)
28
- │ ├── composables/ # Переиспользуемая логика (usePageSeo, useModal, useCalc...)
29
- │ ├── data/ # Бизнес-данные и схемы (каталог, статьи, FAQ, маршруты)
30
- │ ├── domain/ # Чистая бизнес-математика (калькуляторы без привязки к Vue)
31
- │ └── pages/ # Маршруты Nuxt (только связка данных с секциями)
34
+ │ │ ├── ui/ # atoms and molecules
35
+ │ │ ├── sections/ # sections and organisms
36
+ │ │ └── site/ # site shell: header, footer, modal host
37
+ │ ├── composables/ # reusable logic
38
+ │ ├── data/ # business data and schemas
39
+ │ ├── domain/ # pure business maths, no Vue imports
40
+ │ └── pages/ # routes: data in, sections out
32
41
  ├── i18n/
33
- │ └── locales/ # Единый хаб локализации ({es,en,uk,de}.ts)
34
- ├── public/ # Статические ассеты (картинки, шрифты, favicon, лого)
35
- ├── docs/ # Документация проекта для человека и команды
36
- └── nuxt.config.ts # Конфигурация Nuxt 4
42
+ │ └── locales/ # one file per language, same keys
43
+ ├── public/ # static assets: images, fonts, favicon
44
+ ├── docs/ # project documentation
45
+ │ ├── ARCHITECTURE.md # layer map and browser storage keys
46
+ │ ├── DECISIONS.md # dated decisions and reasons
47
+ │ └── METRICS.md # dated measurements, with machine and build
48
+ └── nuxt.config.ts
37
49
  ```
38
50
 
39
51
  ---
40
52
 
41
- ## 3. Матрица соглашений по именованию классов (CSS Naming)
53
+ ## 3. Class naming
42
54
 
43
- | Роль | Формат имени | Пример |
55
+ | Role | Format | Example |
44
56
  |---|---|---|
45
- | **Базовый компонент** | Короткий семантический кебаб-кейс | `.p-card`, `.btn`, `.slider`, `.field` |
46
- | **Элемент компонента** | Двойное подчеркивание (BEM-light) | `.p-card__title`, `.p-card__price`, `.btn__icon` |
47
- | **Модификатор** | Отдельный класс с дефисом | `.-top`, `.-new`, `.-dark`, `.-compact`, `.-outline` |
48
- | **Состояние** | Префикс `is-` | `.is-active`, `.is-open`, `.is-loading` |
49
- | **Контекст страницы** | Класс на теге `body` | `body.page-home`, `body.page-hogares`, `body.page-empresas` |
57
+ | Base component | short kebab-case | `.p-card`, `.btn`, `.field` |
58
+ | Element | double underscore | `.p-card__title` |
59
+ | Modifier | separate class with a leading dash | `.-top`, `.-compact`, `.-lg` |
60
+ | State | `is-` prefix | `.is-open`, `.is-active` |
61
+ | Page context | class on `<body>` | `body.page-home` |
62
+
63
+ ---
64
+
65
+ ## 4. Targets
66
+
67
+ These are design targets for a finished page on a mid-range phone over a 4G connection. They are not measured results. Measure them on the target device and record the results in `docs/METRICS.md`.
68
+
69
+ | Metric | Target |
70
+ |---|---|
71
+ | Lighthouse Performance | ≥ 95 |
72
+ | Lighthouse Accessibility | ≥ 95 |
73
+ | Lighthouse Best Practices | ≥ 95 |
74
+ | Lighthouse SEO | 100 |
75
+ | First Contentful Paint | ≤ 1.0 s |
76
+ | Largest Contentful Paint | ≤ 2.5 s |
77
+ | Cumulative Layout Shift | ≤ 0.01 (CLS 0 is the aim) |
78
+ | Total Blocking Time | ≤ 200 ms |
79
+ | Interaction to Next Paint | ≤ 200 ms |
80
+
81
+ Lab tools in CI or in a sandbox do not produce reliable LCP or INP values. Use them for regressions only, not as proof.
82
+
83
+ ---
84
+
85
+ ## 5. Quality gates
86
+
87
+ A change is done when these pass:
88
+
89
+ 1. Unit and composable tests.
90
+ 2. Type check.
91
+ 3. Locale parity: every key exists in every locale.
92
+ 4. Asset references: every `/images/…` and `/fonts/…` path exists in `public/`.
93
+ 5. HTML check: valid markup on every generated page.
94
+ 6. Console check: no errors or warnings on load.
95
+ 7. Accessibility: axe reports 0 violations at 390, 820 and 1440 px.
96
+ 8. Build: `nuxt generate` completes.
50
97
 
51
98
  ---
52
99
 
53
- ## 4. Контрольные показатели качества (Quality Gates)
100
+ ## 6. Versioning and release
54
101
 
55
- 1. **Lighthouse:** Performance ≥ 95, Accessibility ≥ 95, Best Practices ≥ 95, SEO = 100.
56
- 2. **Core Web Vitals:** FCP ≤ 0.4s, LCP ≤ 1.2s, CLS = 0.000, TBT ≤ 50ms, INP ≤ 50ms.
57
- 3. **A11y (Доступность):** 0 ошибок axe-core, строгий контраст текста (WCAG AA), уникальные `useId()` для SVG/фильтров.
58
- 4. **Bundle Size:** Нулевой избыточный JS/CSS на первом экране, 100% покрытие шрифтов прелоадом.
102
+ See `ALL.md` section 11 and `README.md`. Summary: semantic versions, one changelog entry per user-visible change, tag `vX.Y.Z` on release, publish by the maintainer.
package/bin/ds7.js CHANGED
@@ -1,141 +1,224 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- // DS7 CLI — bootstraps the DS7 architecture standard in any project.
5
- // Usage: npx @ai-all-ai/ds7 [init|sync|update|--version]
4
+ // DS7 CLI. Installs the DS7 standard into ds7/ and enables it as the `ds7`
5
+ // pack of AI-ALL (@ai.all/aiall). The agent entrypoints and the root ALL.md
6
+ // belong to AI-ALL; this CLI never writes them.
7
+ //
8
+ // Usage: npx @ai.all/ds7 [init|sync|update|--version|--help]
9
+ //
10
+ // Ownership:
11
+ // ds7/** the standard, vendored; overwritten by `update`
12
+ // ds7/aiall-pack.json pack manifest, generated from this version; overwritten by `update`
13
+ // ds7/VERSION installed version; written by `init` and `update`
14
+ // ALL.md (project root) AI-ALL routing file; its packs block is managed by AI-ALL,
15
+ // the text outside that block is the project's own
6
16
 
7
17
  const fs = require('fs');
8
18
  const path = require('path');
9
19
  const { spawnSync } = require('child_process');
10
20
 
11
- // ─── ANSI colours ──────────────────────────────────────────────────────────
12
21
  const C = {
13
- reset: '\x1b[0m',
14
- bold: '\x1b[1m',
15
- dim: '\x1b[2m',
16
- green: '\x1b[32m',
17
- yellow: '\x1b[33m',
18
- cyan: '\x1b[36m',
19
- red: '\x1b[31m',
22
+ reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
23
+ green: '\x1b[32m', yellow: '\x1b[33m', cyan: '\x1b[36m', red: '\x1b[31m',
20
24
  };
21
25
  const ok = (s) => console.log(` ${C.green}✓${C.reset} ${s}`);
22
- const skip = (s) => console.log(` ${C.dim}· ${s} (exists, skipped)${C.reset}`);
26
+ const skip = (s) => console.log(` ${C.dim}· ${s} (exists, kept)${C.reset}`);
23
27
  const info = (s) => console.log(` ${C.yellow}→${C.reset} ${s}`);
24
28
  const err = (s) => console.log(` ${C.red}✗${C.reset} ${s}`);
25
29
 
26
- // ─── Paths ──────────────────────────────────────────────────────────────────
27
- const PKG = path.resolve(__dirname, '..'); // package root (ds7/)
28
- const TARGET = process.cwd(); // user's project root
30
+ const PKG = path.resolve(__dirname, '..');
31
+ const TARGET = process.cwd();
32
+ const DS7 = path.join(TARGET, 'ds7');
33
+ const PACK_REF = 'ds7/aiall-pack.json';
29
34
 
30
35
  const { version } = require(path.join(PKG, 'package.json'));
31
36
 
32
- // ─── Helpers ────────────────────────────────────────────────────────────────
33
- function copyDir(src, dest) {
34
- fs.mkdirSync(dest, { recursive: true });
35
- for (const e of fs.readdirSync(src, { withFileTypes: true })) {
36
- const s = path.join(src, e.name);
37
- const d = path.join(dest, e.name);
38
- if (e.isDirectory()) copyDir(s, d);
39
- else if (!fs.existsSync(d)) { fs.copyFileSync(s, d); return true; }
40
- }
41
- }
42
-
43
- function copyFile(src, dest) {
44
- if (fs.existsSync(dest)) { skip(path.relative(TARGET, dest)); return false; }
45
- fs.mkdirSync(path.dirname(dest), { recursive: true });
46
- fs.copyFileSync(src, dest);
47
- ok(path.relative(TARGET, dest));
48
- return true;
49
- }
50
-
51
- // ─── Directories published to npm (not meta files) ──────────────────────────
37
+ // Folders that make up the standard (copied into ds7/).
52
38
  const DS7_DIRS = [
53
39
  '01-architecture', '02-design-system', '03-performance-web-vitals',
54
40
  '04-seo-ai-optimization', '05-internationalization', '06-business-conversion',
55
41
  '07-testing', '08-token-optimization', 'templates',
56
42
  ];
57
- const DS7_FILES = ['README.md', 'SPEC.md', 'ALL.md', 'ANDALUSIA.md', 'ff.md'];
43
+ // Root-level documents of the standard (copied into ds7/).
44
+ const DS7_FILES = ['README.md', 'SPEC.md', 'ALL.md', 'CHANGELOG.md'];
45
+
46
+ // Collect every file under a folder of the package, as paths relative to PKG.
47
+ function listFiles(relDir) {
48
+ const out = [];
49
+ const walk = (abs, rel) => {
50
+ for (const e of fs.readdirSync(abs, { withFileTypes: true })) {
51
+ const a = path.join(abs, e.name);
52
+ const r = path.join(rel, e.name);
53
+ if (e.isDirectory()) walk(a, r);
54
+ else out.push(r);
55
+ }
56
+ };
57
+ walk(path.join(PKG, relDir), relDir);
58
+ return out;
59
+ }
58
60
 
59
- // ─── Commands ────────────────────────────────────────────────────────────────
60
- function cmdInit() {
61
- console.log(`\n${C.bold}${C.cyan}⚡ DS7 v${version} — Architecture Setup${C.reset}\n`);
61
+ // Copy one file. `overwrite` decides whether an existing file is replaced.
62
+ function copyOne(relFromPkg, destAbs, overwrite) {
63
+ const label = path.relative(TARGET, destAbs);
64
+ if (fs.existsSync(destAbs) && !overwrite) { skip(label); return false; }
65
+ fs.mkdirSync(path.dirname(destAbs), { recursive: true });
66
+ fs.copyFileSync(path.join(PKG, relFromPkg), destAbs);
67
+ ok(label);
68
+ return true;
69
+ }
62
70
 
63
- // 1. Copy ds7/ docs structure
64
- const ds7Target = path.join(TARGET, 'ds7');
65
- let copied = 0;
71
+ // Every file of the standard, as [relative path in package, destination].
72
+ function standardFiles() {
73
+ const pairs = [];
66
74
  for (const dir of DS7_DIRS) {
67
- const src = path.join(PKG, dir);
68
- const dest = path.join(ds7Target, dir);
69
- if (!fs.existsSync(src)) continue;
70
- const entries = fs.readdirSync(src, { withFileTypes: true });
71
- fs.mkdirSync(dest, { recursive: true });
72
- for (const e of entries) {
73
- const s = path.join(src, e.name);
74
- const d = path.join(dest, e.name);
75
- if (e.isDirectory()) {
76
- if (copyDir(s, d)) copied++;
77
- } else if (!fs.existsSync(d)) {
78
- fs.copyFileSync(s, d);
79
- ok(`ds7/${dir}/${e.name}`);
80
- copied++;
81
- } else {
82
- skip(`ds7/${dir}/${e.name}`);
83
- }
84
- }
85
- }
86
- for (const f of DS7_FILES) {
87
- if (copyFile(path.join(PKG, f), path.join(ds7Target, f))) copied++;
75
+ if (!fs.existsSync(path.join(PKG, dir))) continue;
76
+ for (const rel of listFiles(dir)) pairs.push([rel, path.join(DS7, rel)]);
88
77
  }
78
+ for (const f of DS7_FILES) pairs.push([f, path.join(DS7, f)]);
79
+ return pairs;
80
+ }
81
+
82
+ // The pack manifest that AI-ALL reads. Paths are project-relative, because the
83
+ // standard is vendored into ds7/ and AI-ALL links to them from the project's ALL.md.
84
+ function packManifest() {
85
+ const doc = (p) => `ds7/${p}`;
86
+ return {
87
+ name: '@ai.all/ds7',
88
+ version,
89
+ title: 'DS7 web architecture standard',
90
+ directives: [
91
+ { id: 'ds7.rules', title: 'DS7 agent rules',
92
+ summary: 'Read before any change in a DS7 web project: ground rules, build order, components and the pre-finish checklist.',
93
+ doc: doc('ALL.md') },
94
+ { id: 'ds7.spec', title: 'DS7 stack and quality gates',
95
+ summary: 'Read for the stack, directory layout, naming, performance targets and quality gates.',
96
+ doc: doc('SPEC.md') },
97
+ { id: 'ds7.architecture', title: 'Atomic architecture',
98
+ summary: 'Read before creating or changing components, variants or modifiers.',
99
+ doc: doc('01-architecture/COMPONENT-ANATOMY.md') },
100
+ { id: 'ds7.brand', title: 'Brand tokens and brandbook',
101
+ summary: 'Read before changing colours, type, spacing or the brandbook page.',
102
+ doc: doc('02-design-system/TOKENS-SPEC.md') },
103
+ { id: 'ds7.i18n', title: 'Internationalisation',
104
+ summary: 'Read before adding a locale, a route or a translated string.',
105
+ doc: doc('05-internationalization/I18N-ARCHITECTURE.md') },
106
+ { id: 'ds7.testing', title: 'Testing strategy',
107
+ summary: 'Read before adding or changing tests or quality checks.',
108
+ doc: doc('07-testing/TESTING-STRATEGY.md') },
109
+ ],
110
+ };
111
+ }
112
+
113
+ function writePackManifest(overwrite) {
114
+ const dest = path.join(DS7, 'aiall-pack.json');
115
+ if (fs.existsSync(dest) && !overwrite) { skip(path.relative(TARGET, dest)); return; }
116
+ fs.mkdirSync(DS7, { recursive: true });
117
+ fs.writeFileSync(dest, `${JSON.stringify(packManifest(), null, 2)}\n`);
118
+ ok(path.relative(TARGET, dest));
119
+ }
89
120
 
90
- // 2. Create ALL.md in project root if missing
91
- copyFile(path.join(PKG, 'ALL.md'), path.join(TARGET, 'ALL.md'));
121
+ function writeVersion() {
122
+ fs.mkdirSync(DS7, { recursive: true });
123
+ fs.writeFileSync(path.join(DS7, 'VERSION'), `${version}\n`);
124
+ }
125
+
126
+ // Run an AI-ALL command with the @ai.all/aiall version this package depends on.
127
+ // The dependency is pinned, so the tested version is the one that runs.
128
+ function runAiall(args) {
129
+ let bin;
130
+ try { bin = require.resolve('@ai.all/aiall/bin/cli.js'); }
131
+ catch { err('@ai.all/aiall is not installed. Reinstall with: npm i -D @ai.all/ds7'); return false; }
132
+ const r = spawnSync(process.execPath, [bin, ...args, '--path', TARGET], { stdio: 'inherit' });
133
+ return r.status === 0;
134
+ }
135
+
136
+ // True when .ai/aiall.json already lists the DS7 pack.
137
+ function packEnabled() {
138
+ try {
139
+ const cfg = JSON.parse(fs.readFileSync(path.join(TARGET, '.ai', 'aiall.json'), 'utf8'));
140
+ return Array.isArray(cfg.packs) && cfg.packs.includes(PACK_REF);
141
+ } catch { return false; }
142
+ }
92
143
 
93
- console.log(`\n${C.yellow}⚡ Syncing AI agent entrypoints...${C.reset}`);
144
+ function enablePack() {
145
+ if (packEnabled()) { skip(`pack ${PACK_REF}`); return true; }
146
+ if (!runAiall(['packs', 'add', PACK_REF])) return false;
147
+ ok(`pack ${PACK_REF} enabled`);
148
+ return true;
149
+ }
94
150
 
95
- // 3. Run @ai.all/aiall
96
- const r = spawnSync('npx', ['--yes', '@ai.all/aiall'], {
97
- stdio: 'inherit', cwd: TARGET, shell: true,
98
- });
99
- if (r.status !== 0) {
100
- info("Could not run @ai.all/aiall automatically.");
101
- info("Run manually: npx @ai.all/aiall");
151
+ // Warn about files left by DS7 1.x. Nothing is deleted or rewritten automatically.
152
+ function legacyWarnings() {
153
+ const rootAll = path.join(TARGET, 'ALL.md');
154
+ if (fs.existsSync(rootAll) && fs.readFileSync(rootAll, 'utf8').includes('Agent Rules for DS7 Projects')) {
155
+ info('Root ALL.md still holds the DS7 1.x rules. Those rules now live in ds7/ALL.md.');
156
+ info('Remove the copied rules from root ALL.md and keep the aiall packs block.');
157
+ }
158
+ if (fs.existsSync(path.join(TARGET, 'ALL.project.md'))) {
159
+ info('ALL.project.md is from DS7 1.x and is no longer used. Move its project values into');
160
+ info('root ALL.md (below the aiall packs block), then delete the file.');
102
161
  }
162
+ }
163
+
164
+ function cmdInit() {
165
+ console.log(`\n${C.bold}${C.cyan}DS7 v${version} — setup${C.reset}\n`);
166
+
167
+ for (const [rel, dest] of standardFiles()) copyOne(rel, dest, false);
168
+ writePackManifest(false);
169
+ writeVersion();
170
+
171
+ console.log(`\n${C.yellow}Configuring AI-ALL…${C.reset}\n`);
172
+ if (!runAiall(['init'])) { err('AI-ALL init failed. Run: npx @ai.all/aiall init'); process.exitCode = 1; return; }
173
+ if (!enablePack()) { err(`Could not enable the pack. Run: npx @ai.all/aiall packs add ${PACK_REF}`); process.exitCode = 1; return; }
174
+ legacyWarnings();
103
175
 
104
- console.log(`\n${C.bold}${C.green}✅ DS7 ready.${C.reset}`);
105
- console.log(` Open ${C.cyan}ds7/README.md${C.reset} to explore the standard.`);
106
- console.log(` Open ${C.cyan}ALL.md${C.reset} to review and customise agent rules.\n`);
176
+ console.log(`\n${C.bold}${C.green}DS7 is installed.${C.reset}`);
177
+ console.log(` 1. Read ${C.cyan}ds7/README.md${C.reset} for the standard and the build order.`);
178
+ console.log(` 2. Add this project's values to the root ${C.cyan}ALL.md${C.reset}, below the aiall packs block.`);
179
+ console.log(` 3. Run ${C.cyan}npx @ai.all/ds7 update${C.reset} to get new versions of the standard.\n`);
107
180
  }
108
181
 
109
182
  function cmdSync() {
110
- console.log(`\n${C.yellow}⚡ Syncing agent entrypoints via @ai.all/aiall...${C.reset}\n`);
111
- const r = spawnSync('npx', ['--yes', '@ai.all/aiall'], {
112
- stdio: 'inherit', cwd: TARGET, shell: true,
113
- });
114
- if (r.status !== 0) err('Sync failed — run npx @ai.all/aiall manually.');
115
- else ok('All agent entrypoints are in sync.');
183
+ console.log(`\n${C.yellow}Syncing agent entrypoints…${C.reset}\n`);
184
+ if (runAiall(['sync'])) ok('Agent entrypoints are in sync.');
185
+ else { err('Sync failed. Run: npx @ai.all/aiall sync'); process.exitCode = 1; }
116
186
  }
117
187
 
118
188
  function cmdUpdate() {
119
- console.log(`\n${C.yellow}↑ Updating ds7/ from package v${version}...${C.reset}\n`);
120
- const ds7Target = path.join(TARGET, 'ds7');
121
- for (const dir of DS7_DIRS) {
122
- const src = path.join(PKG, dir);
123
- if (!fs.existsSync(src)) continue;
124
- copyDir(src, path.join(ds7Target, dir));
125
- ok(`ds7/${dir}/`);
189
+ console.log(`\n${C.yellow}Updating the standard to v${version}…${C.reset}\n`);
190
+ if (!fs.existsSync(DS7)) {
191
+ err('ds7/ not found. Run `npx @ai.all/ds7` (init) first.');
192
+ process.exitCode = 1;
193
+ return;
126
194
  }
127
- console.log(`\n${C.green}✅ ds7/ updated to v${version}.${C.reset}\n`);
195
+ for (const [rel, dest] of standardFiles()) copyOne(rel, dest, true);
196
+ writePackManifest(true);
197
+ writeVersion();
198
+
199
+ if (!runAiall(['sync'])) { err('Sync failed. Run: npx @ai.all/aiall sync'); process.exitCode = 1; return; }
200
+ if (!enablePack()) { process.exitCode = 1; return; }
201
+ legacyWarnings();
202
+
203
+ console.log(`\n${C.green}Standard updated to v${version}. See ds7/CHANGELOG.md for what changed.${C.reset}`);
204
+ info('The root ALL.md outside the aiall packs block was not changed.\n');
128
205
  }
129
206
 
130
- // ─── Dispatch ────────────────────────────────────────────────────────────────
131
- const cmd = process.argv[2];
132
- if (cmd === '--version' || cmd === '-v') {
133
- console.log(version);
134
- } else if (cmd === 'sync') {
135
- cmdSync();
136
- } else if (cmd === 'update') {
137
- cmdUpdate();
138
- } else {
139
- // default: init
140
- cmdInit();
207
+ function cmdHelp() {
208
+ console.log(`
209
+ DS7 ${version}
210
+
211
+ npx @ai.all/ds7 install the standard and enable the ds7 pack (init)
212
+ npx @ai.all/ds7 sync sync agent entrypoints (AI-ALL sync)
213
+ npx @ai.all/ds7 update update ds7/ to this version and refresh the pack
214
+ npx @ai.all/ds7 --version print the version
215
+ `);
141
216
  }
217
+
218
+ const cmd = process.argv[2];
219
+ if (cmd === '--version' || cmd === '-v') console.log(version);
220
+ else if (cmd === '--help' || cmd === '-h' || cmd === 'help') cmdHelp();
221
+ else if (cmd === 'sync') cmdSync();
222
+ else if (cmd === 'update') cmdUpdate();
223
+ else if (!cmd || cmd === 'init') cmdInit();
224
+ else { err(`Unknown command: ${cmd}`); cmdHelp(); process.exitCode = 1; }
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@ai.all/ds7",
3
- "version": "1.0.0",
4
- "description": "AI-ready architecture standard for web projects — structured for humans, optimized for AI agents",
3
+ "version": "2.0.0",
4
+ "description": "AI-ready architecture standard for web projects: brand-first foundations, Atomic Design and agent rules in one place",
5
5
  "keywords": [
6
6
  "architecture",
7
7
  "design-system",
8
+ "design-tokens",
9
+ "brandbook",
8
10
  "atomic-design",
9
11
  "nuxt",
10
12
  "vue",
@@ -13,8 +15,7 @@
13
15
  "ai",
14
16
  "agents",
15
17
  "i18n",
16
- "performance",
17
- "lighthouse"
18
+ "accessibility"
18
19
  ],
19
20
  "homepage": "https://github.com/ai-all-ai/ds7#readme",
20
21
  "repository": {
@@ -25,7 +26,7 @@
25
26
  "url": "https://github.com/ai-all-ai/ds7/issues"
26
27
  },
27
28
  "license": "MIT",
28
- "author": "Igor Orlov & The Human-AI Crafting Collective",
29
+ "author": "Igor Orlov",
29
30
  "bin": {
30
31
  "ds7": "bin/ds7.js"
31
32
  },
@@ -41,24 +42,22 @@
41
42
  "08-token-optimization/",
42
43
  "templates/",
43
44
  "ALL.md",
44
- "AIALL.md",
45
- "ANDALUSIA.md",
45
+ "CHANGELOG.md",
46
46
  "README.md",
47
- "SPEC.md",
48
- "ff.md"
47
+ "SPEC.md"
49
48
  ],
50
49
  "engines": {
51
50
  "node": ">=18"
52
51
  },
53
52
  "dependencies": {
54
- "@ai.all/aiall": "^0.2.0"
53
+ "@ai.all/aiall": "^0.3.0"
55
54
  },
56
55
  "publishConfig": {
57
56
  "access": "public",
58
57
  "registry": "https://registry.npmjs.org/"
59
58
  },
60
59
  "scripts": {
61
- "test": "node bin/ds7.js --version",
60
+ "test": "node bin/ds7.js --version && node bin/ds7.js --help > /dev/null && node --test test/integration.test.js",
62
61
  "prepublishOnly": "npm test"
63
62
  }
64
63
  }
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  /**
3
- * DS7 Component Template
4
- * Эталонная структура Vue 3 SFC (Composition API, Atomic Design, Container Queries)
3
+ * DS7 component template: product card molecule (CARD-01).
4
+ * Atomic level: molecule. Modifiers: -top, -new, -compact, -dark.
5
5
  */
6
6
 
7
7
  interface SpecItem {
@@ -9,14 +9,12 @@ interface SpecItem {
9
9
  value: string
10
10
  }
11
11
 
12
- // 1. Типизированные пропсы с модификаторами
13
12
  const props = withDefaults(defineProps<{
14
13
  title: string
15
14
  description?: string
16
15
  price?: number | null
17
16
  badge?: 'top' | 'new' | 'sale'
18
17
  specs?: SpecItem[]
19
- // Булевые пропсы-модификаторы:
20
18
  top?: boolean
21
19
  compact?: boolean
22
20
  dark?: boolean
@@ -26,27 +24,26 @@ const props = withDefaults(defineProps<{
26
24
  specs: () => [],
27
25
  top: false,
28
26
  compact: false,
29
- dark: false
27
+ dark: false,
30
28
  })
31
29
 
32
- // 2. Вычисление минималистичных классов
33
30
  const classes = computed(() => [
34
31
  'p-card',
35
32
  props.top && '-top',
36
33
  props.compact && '-compact',
37
34
  props.dark && '-dark',
38
- props.badge && `-${props.badge}`
35
+ props.badge && `-${props.badge}`,
39
36
  ])
40
37
  </script>
41
38
 
42
39
  <template>
43
40
  <article :class="classes" data-ref="CARD-01">
44
- <!-- Слот для графики или логотипа -->
41
+ <!-- Artwork or logo slot -->
45
42
  <div class="p-card__art">
46
43
  <slot name="art" />
47
44
  </div>
48
45
 
49
- <!-- Текстовое тело -->
46
+ <!-- Text body -->
50
47
  <div class="p-card__body">
51
48
  <h3 class="p-card__title">{{ title }}</h3>
52
49
  <p v-if="description" class="p-card__desc">{{ description }}</p>
@@ -59,7 +56,7 @@ const classes = computed(() => [
59
56
  </dl>
60
57
  </div>
61
58
 
62
- <!-- Футер с ценой и действием -->
59
+ <!-- Footer: price and action. The price is formatted by the project's price atom. -->
63
60
  <div class="p-card__footer">
64
61
  <div v-if="price !== null" class="p-card__price">
65
62
  <span class="p-card__price-val">{{ price }} €</span>
@@ -70,8 +67,9 @@ const classes = computed(() => [
70
67
  </template>
71
68
 
72
69
  <style>
73
- /*
74
- * Стили компонента: изолируются через префикс и используют CSS Custom Properties
70
+ /*
71
+ * Component styles. Not scoped: the prefix isolates them, and parents can
72
+ * override the custom properties. Values come from the tokens in theme.css.
75
73
  */
76
74
  .p-card {
77
75
  --card-bg: var(--color-white, #fff);
@@ -89,7 +87,6 @@ const classes = computed(() => [
89
87
  transition: transform 0.2s ease, box-shadow 0.2s ease;
90
88
  }
91
89
 
92
- /* Модификатор TOP */
93
90
  .p-card.-top {
94
91
  --card-border: var(--color-sun, #ffd84d);
95
92
  box-shadow: var(--shadow-lift);
@@ -98,19 +95,16 @@ const classes = computed(() => [
98
95
  font-weight: 700;
99
96
  }
100
97
 
101
- /* Модификатор Dark */
102
98
  .p-card.-dark {
103
99
  --card-bg: var(--color-ink-950, #12100d);
104
100
  --card-ink: #ffffff;
105
101
  --card-border: rgba(255, 255, 255, 0.12);
106
102
  }
107
103
 
108
- /* Модификатор Compact */
109
104
  .p-card.-compact {
110
105
  padding: var(--space-2, 8px);
111
106
  }
112
107
 
113
- /* Контейнерная адаптивность */
114
108
  @container (max-width: 320px) {
115
109
  .p-card {
116
110
  padding: var(--space-2, 8px);