siesa-agents 2.1.18 → 2.1.19-dev.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 CHANGED
@@ -1,4 +1,4 @@
1
- # SIESA Agents
1
+ # SIESA BMAD Agents
2
2
 
3
3
  Paquete para instalar y configurar agentes SIESA en tu proyecto.
4
4
 
@@ -52,7 +52,6 @@ El paquete instala las siguientes carpetas en tu directorio actual:
52
52
  - **`.bmad-core/`** - Archivos principales del sistema BMAD
53
53
  - **`.vscode/`** - Configuración de Visual Studio Code
54
54
  - **`.github/`** - Configuración de GitHub Actions y workflows
55
- - **`.claude/`** - Configuración de Claude Code Commands y workflows
56
55
 
57
56
  ## Características
58
57
 
@@ -71,17 +70,22 @@ El paquete instala las siguientes carpetas en tu directorio actual:
71
70
 
72
71
  Para actualizar una instalación existente, simplemente ejecuta el comando nuevamente:
73
72
 
73
+ **Versión estable (recomendado):**
74
74
  ```bash
75
75
  npx siesa-agents
76
76
  ```
77
77
 
78
+ **Versión de desarrollo:**
79
+ ```bash
80
+ npx siesa-agents@dev
81
+ ```
82
+
78
83
  El sistema detectará automáticamente que ya existe una instalación y la actualizará.
79
84
 
80
85
  ## Requisitos
81
86
 
82
87
  - Node.js >= 14.0.0
83
88
  - npm >= 6.0.0
84
- - Python >= 3.7 (requerido para hooks de Claude Code)
85
89
 
86
90
  ## Estructura de archivos instalados
87
91
 
@@ -95,6 +99,8 @@ tu-proyecto/
95
99
  └── [workflows y configuración de GitHub]
96
100
  ```
97
101
 
102
+
103
+
98
104
  ## Soporte
99
105
 
100
106
  Si encuentras algún problema durante la instalación, por favor verifica:
@@ -109,7 +115,4 @@ MIT
109
115
 
110
116
  ## Autor
111
117
 
112
- SIESA - Sistemas de Información Empresarial
113
-
114
- ---
115
- *Versión actualizada automáticamente por CI/CD*
118
+ SIESA - Sistemas de Información Empresarial
package/bin/install.js CHANGED
@@ -11,20 +11,12 @@ class SiesaBmadInstaller {
11
11
  { source: 'bmad-core', target: '.bmad-core' },
12
12
  { source: 'vscode', target: '.vscode' },
13
13
  { source: 'github', target: '.github' },
14
- { source: 'claude', target: '.claude' }
14
+ { source: 'claude', target: '.claude' },
15
+ { source: 'resources', target: '.resources' }
15
16
  ];
16
-
17
- // Lista de archivos que se preservan automáticamente (no se crean backups)
18
- this.ignoredFiles = [
19
- 'data/technical-preferences.md'
20
- ];
21
-
22
17
  this.targetDir = process.cwd();
23
18
  // Intentar múltiples ubicaciones posibles para el paquete
24
19
  this.packageDir = this.findPackageDir();
25
-
26
- // Almacenamiento temporal para contenido de archivos ignorados
27
- this.preservedContent = new Map();
28
20
  }
29
21
 
30
22
  showBanner() {
@@ -35,7 +27,8 @@ class SiesaBmadInstaller {
35
27
  console.log('╚════██║██║██╔══╝ ╚════██║██╔══██║ ██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║');
36
28
  console.log('███████║██║███████╗███████║██║ ██║ ██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████║');
37
29
  console.log('╚══════╝╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝');
38
- console.log('');
30
+ console.log('Version de Desarrollador');
31
+ console.log('\n');
39
32
  }
40
33
 
41
34
  findPackageDir() {
@@ -132,8 +125,7 @@ class SiesaBmadInstaller {
132
125
  modifiedFiles.push({
133
126
  folder: mapping.target,
134
127
  file: relativePath,
135
- fullPath: targetFile,
136
- is_ignored: this.ignoredFiles.includes(relativePath)
128
+ fullPath: targetFile
137
129
  });
138
130
  }
139
131
  } catch (error) {
@@ -145,8 +137,7 @@ class SiesaBmadInstaller {
145
137
  modifiedFiles.push({
146
138
  folder: mapping.target,
147
139
  file: relativePath,
148
- fullPath: targetFile,
149
- is_ignored: this.ignoredFiles.includes(relativePath)
140
+ fullPath: targetFile
150
141
  });
151
142
  }
152
143
  }
@@ -177,10 +168,6 @@ class SiesaBmadInstaller {
177
168
  }
178
169
 
179
170
  async promptUser(modifiedFiles) {
180
-
181
- const hasNonIgnoredFiles = modifiedFiles.some(file => file.is_ignored == false)
182
- if (!hasNonIgnoredFiles) return '2'
183
-
184
171
  console.log('\n⚠️ Se detectaron archivos modificados:');
185
172
 
186
173
  // Agrupar por carpeta
@@ -221,12 +208,6 @@ class SiesaBmadInstaller {
221
208
  console.log('\n🔄 Creando backup de archivos modificados...');
222
209
 
223
210
  for (const item of modifiedFiles) {
224
- // No crear backup de archivos ignorados
225
- if (item.is_ignored) {
226
- console.log(`✓ Preservando: ${item.file} (sin backup)`);
227
- continue;
228
- }
229
-
230
211
  const originalPath = item.fullPath;
231
212
  const backupPath = this.getBackupPath(originalPath);
232
213
 
@@ -291,19 +272,10 @@ class SiesaBmadInstaller {
291
272
  // Obtener todos los archivos backup existentes
292
273
  const backupFiles = await this.findBackupFiles(targetPath);
293
274
 
294
- // Copiar la carpeta preservando technical-preferences.md
275
+ // Copiar la carpeta completa sobrescribiendo
295
276
  await fs.copy(sourcePath, targetPath, {
296
277
  overwrite: true,
297
- recursive: true,
298
- filter: (src) => {
299
- const relativePath = path.relative(sourcePath, src);
300
- // No sobrescribir archivos ignorados si ya existen
301
- if (this.ignoredFiles.includes(relativePath)) {
302
- const targetFile = path.join(targetPath, relativePath);
303
- return !fs.existsSync(targetFile);
304
- }
305
- return true;
306
- }
278
+ recursive: true
307
279
  });
308
280
 
309
281
  // Restaurar los archivos backup
@@ -358,16 +330,7 @@ class SiesaBmadInstaller {
358
330
  if (fs.existsSync(sourcePath)) {
359
331
  await fs.copy(sourcePath, targetPath, {
360
332
  overwrite: true,
361
- recursive: true,
362
- filter: (src) => {
363
- const relativePath = path.relative(sourcePath, src);
364
- // No sobrescribir archivos ignorados si ya existen
365
- if (this.ignoredFiles.includes(relativePath)) {
366
- const targetFile = path.join(targetPath, relativePath);
367
- return !fs.existsSync(targetFile);
368
- }
369
- return true;
370
- }
333
+ recursive: true
371
334
  });
372
335
  } else {
373
336
  console.warn(`⚠️ Carpeta ${mapping.source} no encontrada en el paquete`);
@@ -403,9 +366,6 @@ class SiesaBmadInstaller {
403
366
  await this.performUpdateWithBackups();
404
367
  } else {
405
368
  // Si no hay backups, hacer actualización normal (remover y copiar)
406
- // Pero primero preservar archivos ignorados
407
- await this.preserveIgnoredFiles();
408
-
409
369
  for (const mapping of this.folderMappings) {
410
370
  const targetPath = path.join(this.targetDir, mapping.target);
411
371
 
@@ -416,66 +376,9 @@ class SiesaBmadInstaller {
416
376
 
417
377
  // Realizar instalación nueva
418
378
  await this.performInstallation();
419
-
420
- // Restaurar archivos ignorados
421
- await this.restoreIgnoredFiles();
422
379
  }
423
380
  }
424
381
 
425
- async preserveIgnoredFiles() {
426
- console.log('🔒 Preservando archivos de configuración...');
427
-
428
- for (const mapping of this.folderMappings) {
429
- const targetFolderPath = path.join(this.targetDir, mapping.target);
430
-
431
- if (!fs.existsSync(targetFolderPath)) {
432
- continue;
433
- }
434
-
435
- for (const ignoredFile of this.ignoredFiles) {
436
- const filePath = path.join(targetFolderPath, ignoredFile);
437
-
438
- if (fs.existsSync(filePath)) {
439
- try {
440
- const content = await fs.readFile(filePath, 'utf8');
441
- const key = `${mapping.target}/${ignoredFile}`;
442
- this.preservedContent.set(key, content);
443
- console.log(`✓ Preservando: ${ignoredFile}`);
444
- } catch (error) {
445
- console.warn(`⚠️ Error leyendo ${ignoredFile}: ${error.message}`);
446
- }
447
- }
448
- }
449
- }
450
- }
451
-
452
- async restoreIgnoredFiles() {
453
- if (this.preservedContent.size === 0) {
454
- return;
455
- }
456
-
457
- console.log('🔄 Restaurando archivos de configuración...');
458
-
459
- for (const [key, content] of this.preservedContent) {
460
- const [targetFolder, ...filePathParts] = key.split('/');
461
- const filePath = path.join(this.targetDir, targetFolder, ...filePathParts);
462
-
463
- try {
464
- // Asegurar que el directorio existe
465
- await fs.ensureDir(path.dirname(filePath));
466
-
467
- // Restaurar el contenido
468
- await fs.writeFile(filePath, content, 'utf8');
469
- console.log(`✓ Restaurado: ${filePathParts.join('/')}`);
470
- } catch (error) {
471
- console.warn(`⚠️ Error restaurando ${filePathParts.join('/')}: ${error.message}`);
472
- }
473
- }
474
-
475
- // Limpiar el mapa después de restaurar
476
- this.preservedContent.clear();
477
- }
478
-
479
382
  showPostInstallMessage() {
480
383
  console.log('\n📚 Carpetas instaladas:');
481
384
  this.folderMappings.forEach(mapping => {
@@ -81,8 +81,6 @@ dependencies:
81
81
  - architect-checklist.md
82
82
  data:
83
83
  - technical-preferences.md
84
- - technology-stack.md
85
- - architecture-patterns.md
86
84
  tasks:
87
85
  - create-deep-research-prompt.md
88
86
  - create-doc.md
@@ -60,7 +60,7 @@ commands:
60
60
  dependencies:
61
61
  data:
62
62
  - technical-preferences.md
63
- - technology-stack.md
63
+ - technical-preferences-ux.md
64
64
  tasks:
65
65
  - create-doc.md
66
66
  - execute-checklist.md
@@ -263,6 +263,7 @@ src/
263
263
  │ └── registration/ # FEATURE
264
264
  ├── shared/
265
265
  │ ├── components/ # Shadcn/ui components
266
+ │ │ └── ui/ # Base UI Kit components from proyecto/components/ui/
266
267
  │ ├── hooks/
267
268
  │ ├── utils/
268
269
  │ ├── types/
@@ -276,7 +277,20 @@ src/
276
277
  │ ├── api/ # API configuration
277
278
  │ ├── storage/ # IndexedDB, localStorage
278
279
  │ └── pwa/ # PWA configuration
279
- └── assets/
280
+ ├── assets/
281
+ │ ├── fonts/ # Fonts from proyecto/public/fonts/
282
+ │ │ ├── SiesaBT-Light.otf
283
+ │ │ ├── SiesaBT-Regular.otf
284
+ │ │ └── SiesaBT-Bold.otf
285
+ │ ├── images/
286
+ │ │ └── logos/ # Logos from proyecto/public/images/logos/
287
+ │ │ ├── Siesa_Logosimbolo_Azul.svg
288
+ │ │ ├── Siesa_Logosimbolo_Blanco.svg
289
+ │ │ ├── Siesa_Simbolo_Azul.svg
290
+ │ │ └── Siesa_Simbolo_Blanco.svg
291
+ │ └── favicon.ico # Favicon from proyecto/public/favicon.ico
292
+ └── styles/
293
+ └── globals.css # Consolidated styles + Tailwind + WCAG from proyecto/styles/globals.css
280
294
  ```
281
295
 
282
296
  ### Import Organization
@@ -0,0 +1,423 @@
1
+ # Technical Preferences - UX Configuration
2
+
3
+ ## Project Setup Configuration
4
+ Based on Frontend Development Standards and Clean Architecture Implementation
5
+
6
+ ### Technology Stack
7
+ - **Framework**: Next.js 14+ with App Router
8
+ - **Language**: TypeScript (strict mode)
9
+ - **Styling**: TailwindCSS + Shadcn/ui + Radix UI
10
+ - **State Management**: Zustand
11
+ - **Testing**: Vitest + React Testing Library
12
+ - **Architecture**: Clean Architecture with DDD patterns
13
+ - **Loading States**: React Loading Skeleton (for placeholders/preloading)
14
+
15
+ ### Resources
16
+ Project assets are centralized in the [resources/](../../../resources/) directory at the root level:
17
+
18
+ ```
19
+ resources/
20
+ ├── fonts/ # SiesaBT font family files
21
+ └── images/ # Brand assets, logos, and graphics
22
+ ```
23
+
24
+ **Usage**:
25
+ - Reference fonts from `@/resources/fonts/`
26
+ - Reference images from `@/resources/images/`
27
+ - Logo assets available in `resources/images/logos/`
28
+
29
+ ---
30
+
31
+
32
+ ## Design System Foundation
33
+
34
+ ### Color Palette
35
+
36
+ #### Primary Colors (Brand)
37
+ ```css
38
+ :root {
39
+ /* Primary Color: #0E79FD */
40
+ --color-primary-50: #eff8ff;
41
+ --color-primary-100: #dbf0ff;
42
+ --color-primary-200: #bfe3ff;
43
+ --color-primary-300: #93d2ff;
44
+ --color-primary-400: #60b6ff;
45
+ --color-primary-500: #0E79FD; /* Main Primary Color */
46
+ --color-primary-600: #0b6ae6;
47
+ --color-primary-700: #0959c2;
48
+ --color-primary-800: #0e4a9e;
49
+ --color-primary-900: #123f80;
50
+ --color-primary-950: #11274d;
51
+ }
52
+ ```
53
+
54
+ #### Secondary Colors (Brand)
55
+ ```css
56
+ :root {
57
+ /* Secondary Color: #000000 (Black) - Brand Secondary, NOT for grays/backgrounds */
58
+ --color-secondary-50: #f8f8f8;
59
+ --color-secondary-100: #f0f0f0;
60
+ --color-secondary-200: #e4e4e4;
61
+ --color-secondary-300: #d1d1d1;
62
+ --color-secondary-400: #b4b4b4;
63
+ --color-secondary-500: #9a9a9a;
64
+ --color-secondary-600: #818181;
65
+ --color-secondary-700: #6a6a6a;
66
+ --color-secondary-800: #5a5a5a;
67
+ --color-secondary-900: #4e4e4e;
68
+ --color-secondary-950: #000000; /* Main Secondary Color */
69
+ }
70
+ ```
71
+
72
+ #### Tertiary Colors (Brand)
73
+ ```css
74
+ :root {
75
+ /* Tertiary Color: #154ca9 */
76
+ --color-tertiary-50: #eff6ff;
77
+ --color-tertiary-100: #dbeafe;
78
+ --color-tertiary-200: #bfdbfe;
79
+ --color-tertiary-300: #93c5fd;
80
+ --color-tertiary-400: #60a5fa;
81
+ --color-tertiary-500: #3b82f6;
82
+ --color-tertiary-600: #2563eb;
83
+ --color-tertiary-700: #154ca9; /* Main Tertiary Color */
84
+ --color-tertiary-800: #1e3a8a;
85
+ --color-tertiary-900: #1e3a8a;
86
+ --color-tertiary-950: #172554;
87
+ }
88
+ ```
89
+
90
+ #### Semantic Colors & Usage Guidelines
91
+ ```css
92
+ :root {
93
+ /* Use Tailwind default semantic colors */
94
+ /* Success: theme('colors.green.500') | Warning: theme('colors.amber.500') */
95
+ /* Error: theme('colors.red.500') | Info: theme('colors.cyan.500') */
96
+ /* Neutrals: theme('colors.slate.*') - NOT secondary brand colors */
97
+ }
98
+ ```
99
+
100
+ ```yaml
101
+ color_rules:
102
+ tailwind_first: "Use theme() for system colors"
103
+ brand_only: "Hex codes for brand colors (#0E79FD, #154ca9, #000000)"
104
+ css: "theme() in custom properties"
105
+ classes: "Direct utility classes (bg-slate-200)"
106
+ ```
107
+
108
+ #### Background & Surface Colors
109
+ ```css
110
+ :root {
111
+ /* Light Theme - Using Tailwind variables */
112
+ --color-background: theme('colors.white'); /* white */
113
+ --color-surface: theme('colors.slate.50'); /* slate-50 */
114
+ --color-surface-secondary: theme('colors.slate.100'); /* slate-100 */
115
+ --color-border: theme('colors.slate.200'); /* slate-200 */
116
+ --color-border-secondary: theme('colors.slate.300'); /* slate-300 */
117
+
118
+ /* Dark Theme Support - Using Tailwind variables */
119
+ --color-background-dark: theme('colors.slate.950'); /* slate-950 */
120
+ --color-surface-dark: theme('colors.slate.900'); /* slate-900 */
121
+ --color-surface-secondary-dark: theme('colors.slate.800'); /* slate-800 */
122
+ --color-border-dark: theme('colors.slate.700'); /* slate-700 */
123
+ --color-border-secondary-dark: theme('colors.slate.600'); /* slate-600 */
124
+
125
+ /* Note: Secondary brand color (#000000) is for brand elements, not backgrounds */
126
+ }
127
+ ```
128
+
129
+ ### Dark Mode Implementation
130
+
131
+ #### Configuration
132
+ ```yaml
133
+ dark_mode:
134
+ method: "class" # Tailwind class-based
135
+ selector: "html" # Root element
136
+ framework: "next-themes" # SSR-safe theme switching
137
+ default: "system" # Follow system preference
138
+ ```
139
+
140
+ #### Brand Colors Dark Mode Adaptation
141
+ ```css
142
+ .dark {
143
+ /* Primary - Enhanced contrast for dark backgrounds */
144
+ --color-primary-400: #60b6ff;
145
+ --color-primary-500: #3b9eff;
146
+ --color-primary-600: #0E79FD;
147
+
148
+ /* Secondary alternatives for dark mode visibility */
149
+ --color-secondary-alt-50: theme('colors.slate.50');
150
+ --color-secondary-alt-100: theme('colors.slate.200');
151
+ --color-secondary-alt-200: theme('colors.slate.300');
152
+
153
+ /* Tertiary - Optimized for dark mode */
154
+ --color-tertiary-400: #60a5fa;
155
+ --color-tertiary-500: #3b82f6;
156
+ --color-tertiary-600: #154ca9;
157
+ }
158
+ ```
159
+
160
+ #### Tailwind Classes for Dark Mode
161
+ ```yaml
162
+ text_colors:
163
+ primary: "text-gray-900 dark:text-gray-50"
164
+ secondary: "text-gray-700 dark:text-gray-300"
165
+ muted: "text-gray-500 dark:text-gray-400"
166
+ disabled: "text-gray-400 dark:text-gray-600"
167
+
168
+ brand_colors:
169
+ primary: "text-primary-600 dark:text-primary-400"
170
+ secondary: "text-secondary-950 dark:text-slate-50"
171
+ tertiary: "text-tertiary-700 dark:text-tertiary-400"
172
+
173
+ surfaces:
174
+ page: "bg-white dark:bg-slate-950"
175
+ card: "bg-slate-50 dark:bg-slate-900"
176
+ elevated: "bg-white dark:bg-slate-800"
177
+ input: "bg-white dark:bg-slate-900"
178
+
179
+ borders:
180
+ subtle: "border-slate-200 dark:border-slate-700"
181
+ prominent: "border-slate-300 dark:border-slate-600"
182
+ focus: "ring-primary-500 dark:ring-primary-400"
183
+
184
+ buttons:
185
+ primary: "bg-primary-500 text-white hover:bg-primary-600 dark:bg-primary-600 dark:hover:bg-primary-500"
186
+ secondary: "bg-slate-200 text-slate-900 hover:bg-slate-300 dark:bg-slate-700 dark:text-slate-100 dark:hover:bg-slate-600"
187
+ ghost: "text-slate-700 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-800"
188
+
189
+ navigation:
190
+ navbar: "bg-white border-slate-200 dark:bg-slate-900 dark:border-slate-700"
191
+ sidebar: "bg-slate-50 border-slate-200 dark:bg-slate-900 dark:border-slate-700"
192
+ active: "bg-primary-50 text-primary-700 border-primary-200 dark:bg-primary-950 dark:text-primary-300 dark:border-primary-800"
193
+
194
+ feedback:
195
+ success: "bg-green-50 text-green-800 border-green-200 dark:bg-green-950 dark:text-green-300 dark:border-green-800"
196
+ warning: "bg-amber-50 text-amber-800 border-amber-200 dark:bg-amber-950 dark:text-amber-300 dark:border-amber-800"
197
+ error: "bg-red-50 text-red-800 border-red-200 dark:bg-red-950 dark:text-red-300 dark:border-red-800"
198
+ ```
199
+
200
+ #### Tailwind Configuration
201
+ ```javascript
202
+ // tailwind.config.js
203
+ module.exports = {
204
+ darkMode: 'class',
205
+ theme: {
206
+ extend: {
207
+ colors: {
208
+ primary: {
209
+ 50: '#eff8ff',
210
+ 100: '#dbf0ff',
211
+ 200: '#bfe3ff',
212
+ 300: '#93d2ff',
213
+ 400: '#60b6ff', // Enhanced for dark mode
214
+ 500: '#0E79FD', // Main brand color
215
+ 600: '#0b6ae6',
216
+ 700: '#0959c2',
217
+ 800: '#0e4a9e',
218
+ 900: '#123f80',
219
+ 950: '#11274d',
220
+ },
221
+ secondary: {
222
+ // Custom neutral scale for brand secondary
223
+ 50: '#f8f8f8',
224
+ 100: '#f0f0f0',
225
+ 200: '#e4e4e4',
226
+ 300: '#d1d1d1',
227
+ 400: '#b4b4b4',
228
+ 500: '#9a9a9a',
229
+ 600: '#818181',
230
+ 700: '#6a6a6a',
231
+ 800: '#5a5a5a',
232
+ 900: '#4e4e4e',
233
+ 950: '#000000', // Main secondary color
234
+ },
235
+ tertiary: {
236
+ // Keep original tertiary color scale as defined
237
+ 50: '#eff6ff',
238
+ 100: '#dbeafe',
239
+ 200: '#bfdbfe',
240
+ 300: '#93c5fd',
241
+ 400: '#60a5fa',
242
+ 500: '#3b82f6',
243
+ 600: '#2563eb',
244
+ 700: '#154ca9', // Main tertiary color (custom)
245
+ 800: '#1e3a8a',
246
+ 900: '#1e3a8a',
247
+ 950: '#172554',
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
253
+ ```
254
+
255
+ ### Typography System
256
+
257
+ #### Font Configuration
258
+ ```css
259
+ :root {
260
+ /* Siesa Brand Fonts - 3 weights available */
261
+ --font-primary: 'SiesaBT-Regular', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
262
+ --font-light: 'SiesaBT-Light', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
263
+ --font-bold: 'SiesaBT-Bold', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
264
+ --font-mono: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
265
+
266
+ /* Tailwind font weight mapping */
267
+ --font-weight-light: 300; /* SiesaBT-Light */
268
+ --font-weight-normal: 400; /* SiesaBT-Regular */
269
+ --font-weight-medium: 400; /* SiesaBT-Regular */
270
+ --font-weight-semibold: 700; /* SiesaBT-Bold */
271
+ --font-weight-bold: 700; /* SiesaBT-Bold */
272
+ --font-weight-extrabold: 700; /* SiesaBT-Bold */
273
+ --font-weight-black: 700; /* SiesaBT-Bold */
274
+ }
275
+ ```
276
+
277
+ #### Typography Scale
278
+ ```yaml
279
+ typography:
280
+ headings:
281
+ h1: "text-4xl font-bold leading-tight"
282
+ h2: "text-3xl font-bold leading-tight"
283
+ h3: "text-2xl font-semibold leading-snug"
284
+ h4: "text-xl font-semibold leading-snug"
285
+ h5: "text-lg font-medium leading-normal"
286
+ h6: "text-base font-medium leading-normal"
287
+
288
+ body:
289
+ paragraph: "text-base font-normal leading-relaxed"
290
+ large: "text-lg font-normal leading-relaxed"
291
+ small: "text-sm font-normal leading-normal"
292
+ caption: "text-xs font-light leading-normal"
293
+
294
+ interactive:
295
+ label: "text-sm font-medium leading-normal"
296
+ button_primary: "text-base font-semibold leading-none"
297
+ button_secondary: "text-sm font-medium leading-none"
298
+ link: "text-base font-normal leading-normal"
299
+ link_emphasis: "text-base font-semibold leading-normal"
300
+
301
+ utility:
302
+ code: "text-sm font-normal leading-normal font-mono"
303
+ badge: "text-xs font-semibold leading-none"
304
+ tooltip: "text-sm font-normal leading-snug"
305
+ ```
306
+
307
+ ### Assets & Systems Configuration
308
+
309
+ #### Logo Assets
310
+ ```yaml
311
+ logos:
312
+ paths:
313
+ assets: "assets/images/logos/"
314
+ public: "/images/logos/"
315
+
316
+ variants:
317
+ full_blue: "Siesa_Logosimbolo_Azul.svg"
318
+ full_white: "Siesa_Logosimbolo_Blanco.svg"
319
+ symbol_blue: "Siesa_Simbolo_Azul.svg"
320
+ symbol_white: "Siesa_Simbolo_Blanco.svg"
321
+
322
+ usage:
323
+ header: "symbol_blue"
324
+ footer: "full_blue"
325
+ dark_theme: "full_white"
326
+ favicon: "symbol_blue"
327
+
328
+ specs:
329
+ min_size_full: "120px"
330
+ min_size_symbol: "24px"
331
+ format: "SVG"
332
+ ```
333
+
334
+ #### Icons
335
+ ```yaml
336
+ icons:
337
+ primary: "Heroicons"
338
+ secondary: "Font Awesome 6.5+"
339
+
340
+ sizes:
341
+ small: "w-4 h-4"
342
+ default: "w-5 h-5"
343
+ medium: "w-6 h-6"
344
+ large: "w-8 h-8"
345
+
346
+ colors:
347
+ inherit: "text-current"
348
+ primary: "text-primary-500"
349
+ secondary: "text-secondary-600"
350
+ neutral: "text-gray-500"
351
+ ```
352
+
353
+ #### Loading States
354
+ ```yaml
355
+ skeleton:
356
+ library: "react-loading-skeleton ^3.4.0"
357
+ theming:
358
+ light: "base: theme('colors.slate.200'), highlight: theme('colors.slate.100')"
359
+ dark: "base: theme('colors.slate.700'), highlight: theme('colors.slate.600')"
360
+ radius: "rounded-md"
361
+ duration: "1.5s"
362
+ ```
363
+
364
+ ---
365
+
366
+ ## Standards & Guidelines
367
+
368
+ ### Accessibility
369
+ ```yaml
370
+ accessibility:
371
+ color_contrast: "4.5:1 minimum (WCAG 2.1 AA)"
372
+ large_text_contrast: "3.1:1 minimum"
373
+ focus_indicators: "2px solid var(--color-primary-500)"
374
+ touch_targets: "44px minimum"
375
+ font_size_minimum: "16px"
376
+ line_length_maximum: "75ch"
377
+
378
+ requirements:
379
+ landmarks: true
380
+ headings: true
381
+ labels: true
382
+ alt_text: true
383
+ skip_links: true
384
+ ```
385
+
386
+ ### Performance Targets
387
+ ```yaml
388
+ bundle_limits:
389
+ initial: "< 500KB gzipped"
390
+ routes: "< 200KB gzipped"
391
+ components: "< 100KB gzipped"
392
+
393
+ metrics:
394
+ fcp: "< 1.5s"
395
+ lcp: "< 2.5s"
396
+ cls: "< 0.1"
397
+ tti: "< 3s"
398
+ ```
399
+
400
+ ### Architecture
401
+ ```yaml
402
+ components:
403
+ base: "Shadcn/ui from MCP registry"
404
+ composite: "Feature-specific compositions"
405
+ layout: "Page and section layouts"
406
+ utility: "Helpers and wrappers"
407
+
408
+ state_management:
409
+ global: "Authentication, theme, app settings"
410
+ feature: "Domain-specific data and UI state"
411
+ local: "Component-specific temporary state"
412
+ server: "API data with caching"
413
+
414
+ naming:
415
+ components: "PascalCase"
416
+ files: "kebab-case"
417
+ directories: "kebab-case"
418
+ assets: "kebab-case"
419
+ ```
420
+
421
+ ---
422
+
423
+ ## This configuration serves as the foundation for all UX decisions and component implementation.
@@ -0,0 +1,51 @@
1
+ import sys
2
+ import json
3
+ import os
4
+
5
+ try:
6
+ # Leer JSON desde stdin
7
+ data = json.load(sys.stdin)
8
+
9
+ # Obtener información del archivo y sesión
10
+ file_path = data.get('tool_input', {}).get('file_path', '')
11
+ extension = os.path.splitext(file_path)[1].lower() if file_path else ''
12
+ session_id = data.get('session_id', '')
13
+ cwd = data.get('cwd', '')
14
+
15
+ # Construir ruta relativa al log desde el cwd
16
+ log_file = os.path.join(cwd, '.claude', 'logs', 'active_agents.json')
17
+
18
+ # Agentes que solo pueden escribir markdown
19
+ MARKDOWN_ONLY_AGENTS = ['PO', 'SM', 'PM', 'ANALYST', 'ARCHITECT', 'UX-EXPERT']
20
+
21
+ # Verificar si la sesión actual tiene un agente activo
22
+ if session_id and os.path.exists(log_file):
23
+ try:
24
+ with open(log_file, 'r', encoding='utf-8') as f:
25
+ active_agents = json.load(f)
26
+
27
+ # Si la sesión actual tiene un agente activo
28
+ if session_id in active_agents:
29
+ agent_type = active_agents[session_id]['agent']
30
+
31
+ # Si el agente está en la lista de solo markdown
32
+ if agent_type in MARKDOWN_ONLY_AGENTS:
33
+ # Solo permitir archivos markdown
34
+ if extension != '.md':
35
+ result = {
36
+ "hookSpecificOutput": {
37
+ "hookEventName": "PreToolUse",
38
+ "permissionDecision": "deny",
39
+ "permissionDecisionReason": f"⛔ El agente de tipo {agent_type} solo puede redactar archivos markdown"
40
+ }
41
+ }
42
+ print(json.dumps(result))
43
+ sys.exit(0)
44
+ except:
45
+ # Si hay error leyendo el log, permitir la operación
46
+ pass
47
+
48
+ # Si no está bloqueado, permitir la operación (no imprimir nada)
49
+ except Exception as e:
50
+ # En caso de error, permitir la operación
51
+ pass
@@ -0,0 +1,67 @@
1
+ import sys
2
+ import json
3
+ import os
4
+ from datetime import datetime
5
+
6
+ try:
7
+ # Leer JSON desde stdin
8
+ data = json.load(sys.stdin)
9
+
10
+ session_id = data.get('session_id', '')
11
+ prompt = data.get('prompt', '').lower()
12
+ cwd = data.get('cwd', '')
13
+
14
+ # Construir ruta relativa al log desde el cwd
15
+ log_file = os.path.join(cwd, '.claude', 'logs', 'active_agents.json')
16
+
17
+ # Crear directorio si no existe
18
+ log_dir = os.path.dirname(log_file)
19
+ os.makedirs(log_dir, exist_ok=True)
20
+
21
+ # Lista completa de agentes disponibles
22
+ agent_identifiers = {
23
+ 'agents:po': 'PO',
24
+ 'agents:sm': 'SM',
25
+ 'agents:pm': 'PM',
26
+ 'agents:analyst': 'ANALYST',
27
+ 'agents:architect': 'ARCHITECT',
28
+ 'agents:dev': 'DEV',
29
+ 'agents:backend': 'BACKEND',
30
+ 'agents:frontend': 'FRONTEND',
31
+ 'agents:qa': 'QA',
32
+ 'agents:ux-expert': 'UX-EXPERT',
33
+ 'agents:bmad-master': 'BMAD-MASTER',
34
+ 'agents:bmad-orchestrator': 'BMAD-ORCHESTRATOR'
35
+ }
36
+
37
+ # Detectar si se está invocando un agente
38
+ agent_type = None
39
+ for identifier, agent_name in agent_identifiers.items():
40
+ if identifier in prompt or f'/bmad:{identifier}' in prompt:
41
+ agent_type = agent_name
42
+ break
43
+
44
+ if agent_type and session_id:
45
+ # Leer log existente
46
+ active_agents = {}
47
+ if os.path.exists(log_file):
48
+ try:
49
+ with open(log_file, 'r', encoding='utf-8') as f:
50
+ active_agents = json.load(f)
51
+ except:
52
+ active_agents = {}
53
+
54
+ # Actualizar o agregar la sesión con el agente actual
55
+ active_agents[session_id] = {
56
+ 'agent': agent_type,
57
+ 'timestamp': datetime.now().isoformat(),
58
+ 'last_prompt': prompt[:100] # Guardar inicio del prompt para debug
59
+ }
60
+
61
+ # Guardar log actualizado
62
+ with open(log_file, 'w', encoding='utf-8') as f:
63
+ json.dump(active_agents, f, indent=2, ensure_ascii=False)
64
+
65
+ except Exception as e:
66
+ # En caso de error, no bloquear la operación
67
+ pass
@@ -16,5 +16,41 @@
16
16
  ],
17
17
  "deny": [],
18
18
  "ask": []
19
- }
19
+ },
20
+ "hooks": {
21
+ "UserPromptSubmit": [
22
+ {
23
+ "matcher": ".*",
24
+ "hooks": [
25
+ {
26
+ "type": "command",
27
+ "command": "python .claude/hooks/track-agent.py"
28
+ }
29
+ ]
30
+ }
31
+ ],
32
+ "PreToolUse": [
33
+ {
34
+ "matcher": "Write|Edit",
35
+ "hooks": [
36
+ {
37
+ "type": "command",
38
+ "command": "python .claude/hooks/file-restriction-hook.py"
39
+ }
40
+ ]
41
+ }
42
+ ],
43
+ "SessionEnd": [
44
+ {
45
+ "matcher": ".*",
46
+ "hooks": [
47
+ {
48
+ "type": "command",
49
+ "command": "python .claude/hooks/cleanup-agent.py"
50
+ }
51
+ ]
52
+ }
53
+ ]
54
+ },
55
+ "disableAllHooks": false
20
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siesa-agents",
3
- "version": "2.1.18",
3
+ "version": "2.1.19-dev.0",
4
4
  "description": "Paquete para instalar y configurar agentes SIESA en tu proyecto",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -25,6 +25,7 @@
25
25
  "github/**/*",
26
26
  "claude/**/*",
27
27
  "bin/**/*",
28
+ "resources/**/*",
28
29
  "README.md"
29
30
  ],
30
31
  "engines": {
Binary file
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Siesa_Logosimbolos" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1999.86 500">
3
+ <!-- Generator: Adobe Illustrator 29.8.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 2) -->
4
+ <defs>
5
+ <style>
6
+ .st0 {
7
+ fill: #0e79fd;
8
+ }
9
+ </style>
10
+ </defs>
11
+ <g>
12
+ <path class="st0" d="M812.95,404.07c-165.79,0-171.25-110.18-171.25-115.7h52.63s-.61,74.35,119.46,74.35h1.25c64.32,0,104-20.88,104-55.55v-1.67c0-27.57-23.81-38.43-95.65-47.2l-49.7-6.27c-76.85-9.61-123.63-33.41-123.63-90.64v-2.09c0-64.74,59.73-98.57,151.62-98.57h.84c161.01,0,161.4,108.26,161.4,108.26h-51.68s1.14-66.9-110.55-66.9h-.84c-61.82,0-98.16,20.47-98.16,55.13v1.67c0,27.15,22.14,43.44,91.89,52.21l47.2,5.85c89.8,10.86,130.74,37.17,130.74,87.71v2.09c0,64.74-64.74,97.32-158.72,97.32h-.85Z"/>
13
+ <path class="st0" d="M1560.56,404.07c-142.87,0-142.85-87.71-142.85-87.71h49.07c0,4.14,13.22,50.96,97.96,50.96h.84c53.88,0,80.61-12.11,80.61-36.76v-1.25c0-22.56-23.39-30.07-69.34-34.67l-55.13-5.01c-59.31-5.43-100.24-22.55-100.24-67.66v-1.67c0-47.62,48.87-74.77,131.15-74.77h.84c126.87,0,134.91,71.8,134.91,86.46h-50.12s2.54-49.7-84.79-49.7h-.84c-49.29,0-81.03,14.2-81.03,39.26v.84c0,22.97,27.57,30.91,73.93,35.5l57.22,5.43c65.16,6.68,93.98,26.73,93.98,64.74v2.09c0,48.87-45.95,73.93-135.33,73.93h-.84Z"/>
14
+ <g>
15
+ <rect class="st0" x="1014.63" y="168.99" width="47.02" height="230.9"/>
16
+ <rect class="st0" x="1012.55" y="65.58" width="51.18" height="51.18"/>
17
+ </g>
18
+ <path class="st0" d="M1984.7,190.65c-10.2-15.12-25.5-26.43-45.89-33.91-20.4-7.47-46.41-11.22-78.02-11.22-94.51,0-129.22,41.19-133.11,86.46h50.32c1.68-35.05,41.78-49.7,81.77-49.7,31.62,0,54.73,3.6,69.35,13.11,14.61,9.52,21.93,23.8,21.93,42.84v15.07c-108.47-.19-227.95-1.17-227.95,79.57,0,69.38,81.08,71.4,99.44,71.4,80.19,0,127.96-48.44,127.96-48.44l.04,43.8h49.47v-155.17c0-20.73-5.1-38.67-15.3-53.8h-.01ZM1935.49,326.23c-10.37,12.24-24.57,21.85-42.58,28.81-18.02,6.97-37.91,10.45-59.66,10.45-13.26,0-59.16-5.05-59.16-33.66,0-21.16,11.93-42.1,176.9-43.02-.54,13.38-5.71,25.85-15.5,37.41h0Z"/>
19
+ <path class="st0" d="M1390.14,272.08c-2.09-79.78-53.88-126.56-141.18-126.56h-.84c-90.22,0-144.52,47.2-144.52,126.14v2.09c0,81.45,55.97,130.32,149.53,130.32h.84c64.52,0,117.2-37.61,130.2-87.71l-48.33-.11c-8.77,26.73-35.5,48.15-81.87,48.15h-.84c-60.15,0-95.23-25.48-100.24-75.6h236.61c.71-4.3.63-16.71.63-16.71h0ZM1247.29,182.28h.84c53.21,0,85.14,26.08,91.91,72.32h-186.73c6.81-46.24,39.97-72.32,93.99-72.32h-.01Z"/>
20
+ </g>
21
+ <polygon class="st0" points="0 300 0 0 300 0 0 300"/>
22
+ <polygon class="st0" points="0 500 0 300 200 300 0 500"/>
23
+ <polygon class="st0" points="500 0 500 300 200 300 500 0"/>
24
+ <polygon class="st0" points="500 300 500 500 300 500 500 300"/>
25
+ </svg>
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Siesa_Logosimbolos" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 2000.01 500">
3
+ <!-- Generator: Adobe Illustrator 29.8.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 2) -->
4
+ <defs>
5
+ <style>
6
+ .st0 {
7
+ fill: #fff;
8
+ }
9
+ </style>
10
+ </defs>
11
+ <g>
12
+ <path class="st0" d="M813.02,404.07c-165.79,0-171.25-110.18-171.25-115.7h52.63s-.61,74.35,119.46,74.35h1.25c64.32,0,104-20.88,104-55.55v-1.67c0-27.57-23.81-38.43-95.65-47.2l-49.7-6.27c-76.85-9.61-123.63-33.41-123.63-90.64v-2.09c0-64.74,59.73-98.57,151.62-98.57h.84c161.01,0,161.4,108.26,161.4,108.26h-51.68s1.14-66.9-110.55-66.9h-.84c-61.82,0-98.16,20.47-98.16,55.13v1.67c0,27.15,22.14,43.44,91.89,52.21l47.2,5.85c89.8,10.86,130.74,37.17,130.74,87.71v2.09c0,64.74-64.74,97.32-158.72,97.32h-.85Z"/>
13
+ <path class="st0" d="M1560.63,404.07c-142.87,0-142.85-87.71-142.85-87.71h49.07c0,4.14,13.22,50.96,97.96,50.96h.84c53.88,0,80.61-12.11,80.61-36.76v-1.25c0-22.56-23.39-30.07-69.34-34.67l-55.13-5.01c-59.31-5.43-100.24-22.55-100.24-67.66v-1.67c0-47.62,48.87-74.77,131.15-74.77h.84c126.87,0,134.91,71.8,134.91,86.46h-50.12s2.54-49.7-84.79-49.7h-.84c-49.29,0-81.03,14.2-81.03,39.26v.84c0,22.97,27.57,30.91,73.93,35.5l57.22,5.43c65.16,6.68,93.98,26.73,93.98,64.74v2.09c0,48.87-45.95,73.93-135.33,73.93h-.84Z"/>
14
+ <g>
15
+ <rect class="st0" x="1014.7" y="168.99" width="47.02" height="230.9"/>
16
+ <rect class="st0" x="1012.62" y="65.58" width="51.18" height="51.18"/>
17
+ </g>
18
+ <path class="st0" d="M1984.77,190.65c-10.2-15.12-25.5-26.43-45.89-33.91-20.4-7.47-46.41-11.22-78.02-11.22-94.51,0-129.22,41.19-133.11,86.46h50.32c1.68-35.05,41.78-49.7,81.77-49.7,31.62,0,54.73,3.6,69.35,13.11,14.61,9.52,21.93,23.8,21.93,42.84v15.07c-108.47-.19-227.95-1.17-227.95,79.57,0,69.38,81.08,71.4,99.44,71.4,80.19,0,127.96-48.44,127.96-48.44l.04,43.8h49.47v-155.17c0-20.73-5.1-38.67-15.3-53.8h-.01ZM1935.56,326.23c-10.37,12.24-24.57,21.85-42.58,28.81-18.02,6.97-37.91,10.45-59.66,10.45-13.26,0-59.16-5.05-59.16-33.66,0-21.16,11.93-42.1,176.9-43.02-.54,13.38-5.71,25.85-15.5,37.41h0Z"/>
19
+ <path class="st0" d="M1390.21,272.08c-2.09-79.78-53.88-126.56-141.18-126.56h-.84c-90.22,0-144.52,47.2-144.52,126.14v2.09c0,81.45,55.97,130.32,149.53,130.32h.84c64.52,0,117.2-37.61,130.2-87.71l-48.33-.11c-8.77,26.73-35.5,48.15-81.87,48.15h-.84c-60.15,0-95.23-25.48-100.24-75.6h236.61c.71-4.3.63-16.71.63-16.71h0ZM1247.36,182.28h.84c53.21,0,85.14,26.08,91.91,72.32h-186.73c6.81-46.24,39.97-72.32,93.99-72.32h-.01Z"/>
20
+ </g>
21
+ <polygon class="st0" points=".07 300 .07 0 300.07 0 .07 300"/>
22
+ <polygon class="st0" points=".07 500 .07 300 200.07 300 .07 500"/>
23
+ <polygon class="st0" points="500.07 0 500.07 300 200.07 300 500.07 0"/>
24
+ <polygon class="st0" points="500.07 300 500.07 500 300.07 500 500.07 300"/>
25
+ </svg>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Siesa_Logosimbolos" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 500 500">
3
+ <!-- Generator: Adobe Illustrator 29.8.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 2) -->
4
+ <defs>
5
+ <style>
6
+ .st0 {
7
+ fill: #0e79fd;
8
+ }
9
+ </style>
10
+ </defs>
11
+ <polygon class="st0" points=".05 300 .05 0 300.05 0 .05 300"/>
12
+ <polygon class="st0" points=".05 500 .05 300 200.05 300 .05 500"/>
13
+ <polygon class="st0" points="500.05 0 500.05 300 200.05 300 500.05 0"/>
14
+ <polygon class="st0" points="500.05 300 500.05 500 300.05 500 500.05 300"/>
15
+ </svg>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Siesa_Logosimbolos" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 500 500">
3
+ <!-- Generator: Adobe Illustrator 29.8.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 2) -->
4
+ <defs>
5
+ <style>
6
+ .st0 {
7
+ fill: #fff;
8
+ }
9
+ </style>
10
+ </defs>
11
+ <polygon class="st0" points=".05 300 .05 0 300.05 0 .05 300"/>
12
+ <polygon class="st0" points=".05 500 .05 300 200.05 300 .05 500"/>
13
+ <polygon class="st0" points="500.05 0 500.05 300 200.05 300 500.05 0"/>
14
+ <polygon class="st0" points="500.05 300 500.05 500 300.05 500 500.05 300"/>
15
+ </svg>
@@ -1,114 +0,0 @@
1
- # Architecture Patterns & Design Decisions
2
-
3
- ## Frontend Architecture
4
-
5
- ### Architecture Style
6
- - **Clean Architecture** + **Domain-Driven Design (DDD)**
7
-
8
- ### Folder Structure
9
-
10
- Next.js 15 App Router Structure with Clean Architecture + DDD:
11
-
12
- ```
13
- ├── app/ # Next.js App Router directory
14
- │ ├── (dashboard)/ # Route groups for dashboard
15
- │ ├── sales/ # Routes for sales module
16
- │ │ ├── quotes/ # Quote management pages
17
- │ │ └── invoices/ # Invoice pages
18
- │ ├── inventory/ # Inventory routes
19
- │ ├── globals.css # Global styles
20
- │ ├── layout.tsx # Root layout component
21
- │ ├── page.tsx # Home page
22
- │ ├── loading.tsx # Global loading UI
23
- │ └── not-found.tsx # 404 page
24
-
25
- ├── src/
26
- │ ├── modules/ # Business modules following DDD
27
- │ │ ├── sales/ # Sales module
28
- │ │ │ ├── quotes/ # Quote domain
29
- │ │ │ │ ├── cart/ # Shopping cart feature
30
- │ │ │ │ │ ├── domain/
31
- │ │ │ │ │ │ ├── entities/
32
- │ │ │ │ │ │ ├── repositories/
33
- │ │ │ │ │ │ ├── services/
34
- │ │ │ │ │ │ └── types/
35
- │ │ │ │ │ ├── application/
36
- │ │ │ │ │ │ ├── use-cases/
37
- │ │ │ │ │ │ ├── hooks/
38
- │ │ │ │ │ │ └── store/
39
- │ │ │ │ │ ├── infrastructure/
40
- │ │ │ │ │ │ ├── repositories/
41
- │ │ │ │ │ │ ├── api/
42
- │ │ │ │ │ │ └── adapters/
43
- │ │ │ │ │ └── presentation/
44
- │ │ │ │ │ └── components/ # Only components, pages in app/
45
- │ │ │ │ └── products/ # Products feature
46
- │ │ │ └── billing/ # Billing domain
47
- │ │ ├── inventory/ # Inventory module
48
- │ │ └── users/ # User module
49
- │ │
50
- │ ├── shared/
51
- │ │ ├── components/ # Reusable UI components
52
- │ │ ├── hooks/ # Shared hooks
53
- │ │ ├── utils/ # Utility functions
54
- │ │ ├── types/ # Common TypeScript types
55
- │ │ └── constants/ # App constants
56
- │ │
57
- │ ├── providers/ # React context providers
58
- │ ├── store/ # Global Zustand stores
59
- │ └── middleware.ts # Next.js middleware
60
-
61
- ├── lib/ # Next.js utilities and configurations
62
- ├── components/ # Global UI components (alternative to src/shared)
63
- ├── public/ # Static assets and PWA manifest
64
- └── styles/ # Additional stylesheets
65
- ```
66
-
67
- ### Core Principles
68
-
69
- #### Clean Architecture First
70
- Strict separation of:
71
- - **Domain layer** - Business entities, repositories interfaces, domain services, and types
72
- - **Application layer** - Use cases, hooks, and state management (Zustand stores)
73
- - **Infrastructure layer** - Repository implementations, API clients, and adapters
74
- - **Presentation layer** - UI components (pages go in `app/`, components in `presentation/`)
75
-
76
- #### Domain-Driven Design
77
- Business logic drives architecture decisions. Organize by business modules and domains, not technical layers.
78
-
79
- #### Component Composition
80
- Build complex UIs from simple, reusable components.
81
-
82
- #### Type Safety
83
- Leverage TypeScript for compile-time safety and developer experience.
84
-
85
- #### Performance by Design
86
- - Lazy loading
87
- - Memoization
88
- - Bundle optimization
89
-
90
- #### Accessibility as Standard
91
- WCAG 2.1 AA compliance in all components.
92
-
93
- #### Test-Driven Development
94
- Unit tests for all use cases and components.
95
-
96
- #### Progressive Web App
97
- Offline-first approach with service workers.
98
-
99
- #### Minimal and Functional
100
- Only build what's explicitly requested, nothing more.
101
-
102
- #### User-Centered Design
103
- Start with user needs and work backward to implementation.
104
-
105
- #### MCP Shadcn Available
106
- Use MCP to install Shadcn components instead of creating manually.
107
-
108
- ### Framework Selection Rules
109
-
110
- **Default**: Always use Next.js 15 with App Router unless explicitly told otherwise.
111
-
112
- **Exceptions**: Only use pure React + Vite when user specifically mentions offline-first functionality or requests non-Next.js setup.
113
-
114
- **Reasoning**: Next.js provides better developer experience, built-in optimization, and easier deployment while maintaining PWA capabilities.
@@ -1,81 +0,0 @@
1
- # Technology Stack
2
-
3
- ## Frontend Stack
4
-
5
- ### Framework
6
- - **Next.js 15** with TypeScript (App Router)
7
- - Default framework unless explicitly told otherwise
8
- - Built-in Turbopack/Webpack for building
9
- - File-based routing with App Router
10
- - Exception: Use pure React + Vite only when user specifically mentions offline-first functionality or requests non-Next.js setup
11
-
12
- ### State Management
13
- - **Zustand**
14
-
15
- ### UI Framework & Styling
16
- - **Shadcn/ui** (component library)
17
- - **Radix UI** (primitives)
18
- - **TailwindCSS v4** (styling)
19
-
20
- ### Architecture
21
- - **Clean Architecture** + **Domain-Driven Design (DDD)**
22
-
23
- ### Testing
24
- - **Vitest** (test runner)
25
- - **React Testing Library** (component testing)
26
- - **MSW** (Mock Service Worker - API mocking)
27
-
28
- ### Forms & Validation
29
- - **React Hook Form** (form management)
30
- - **Zod** (schema validation)
31
-
32
- ### HTTP Client
33
- - **Axios** with interceptors
34
-
35
- ### Progressive Web App (PWA)
36
- - **Next.js PWA plugin**
37
- - **Workbox** (service worker library)
38
-
39
- ### Routing
40
- - **Next.js App Router** (file-based routing)
41
-
42
- ## Core Principles
43
-
44
- ### Clean Architecture First
45
- Strict separation of:
46
- - Domain layer
47
- - Application layer
48
- - Infrastructure layer
49
- - Presentation layer
50
-
51
- ### Domain-Driven Design
52
- Business logic drives architecture decisions
53
-
54
- ### Component Composition
55
- Build complex UIs from simple, reusable components
56
-
57
- ### Type Safety
58
- Leverage TypeScript for compile-time safety and developer experience
59
-
60
- ### Performance by Design
61
- - Lazy loading
62
- - Memoization
63
- - Bundle optimization
64
-
65
- ### Accessibility as Standard
66
- WCAG 2.1 AA compliance in all components
67
-
68
- ### Test-Driven Development
69
- Unit tests for all use cases and components
70
-
71
- ### Progressive Web App
72
- Offline-first approach with service workers
73
-
74
- ### Minimal and Functional
75
- Only build what's explicitly requested, nothing more
76
-
77
- ### User-Centered Design
78
- Start with user needs and work backward to implementation
79
-
80
- ### MCP Shadcn Available
81
- Use MCP to install Shadcn components instead of creating manually