siesa-agents 2.1.17 → 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 +10 -7
- package/bin/install.js +9 -106
- package/bmad-core/agents/architect.md +0 -2
- package/bmad-core/agents/ux-expert.md +1 -1
- package/bmad-core/data/frontend-standards.md +15 -1
- package/bmad-core/data/technical-preferences-ux.md +423 -0
- package/bmad-core/tasks/create-doc.md +54 -10
- package/claude/commands/BMad/tasks/create-doc.md +50 -10
- package/claude/hooks/file-restriction-hook.py +51 -0
- package/claude/hooks/track-agent.py +67 -0
- package/claude/settings.local.json +37 -1
- package/package.json +2 -1
- package/resources/fonts/SiesaBT-Bold.otf +0 -0
- package/resources/fonts/SiesaBT-Light.otf +0 -0
- package/resources/fonts/SiesaBT-Regular.otf +0 -0
- package/resources/images/Siesa_Logosimbolo_Azul.svg +25 -0
- package/resources/images/Siesa_Logosimbolo_Blanco.svg +25 -0
- package/resources/images/Siesa_Simbolo_Azul.svg +15 -0
- package/resources/images/Siesa_Simbolo_Blanco.svg +15 -0
- package/bmad-core/data/architecture-patterns.md +0 -114
- package/bmad-core/data/technology-stack.md +0 -81
|
@@ -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.
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# /create-doc Task
|
|
2
|
+
|
|
3
|
+
When this command is used, execute the following task:
|
|
4
|
+
|
|
1
5
|
<!-- Powered by BMAD™ Core -->
|
|
2
6
|
|
|
3
7
|
# Create Document from Template (YAML Driven)
|
|
@@ -40,15 +44,25 @@ If a YAML Template has not been provided, list all templates from .bmad-core/tem
|
|
|
40
44
|
## Processing Flow
|
|
41
45
|
|
|
42
46
|
1. **Parse YAML template** - Load template metadata and sections
|
|
43
|
-
2. **Set preferences** - Show current mode (Interactive), confirm output file
|
|
44
|
-
3. **
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
4. **
|
|
47
|
+
2. **Set preferences** - Show current mode (Interactive or YOLO), confirm output file
|
|
48
|
+
3. **If YOLO mode:**
|
|
49
|
+
- Count total sections
|
|
50
|
+
- Estimate optimal batch count based on section complexity
|
|
51
|
+
- Split document into 3-4 batches (~12-17 sections each)
|
|
52
|
+
- Process each batch → Save → STOP → Wait for "continue"
|
|
53
|
+
- Repeat until all batches complete
|
|
54
|
+
|
|
55
|
+
4. **If Interactive mode:**
|
|
56
|
+
- Process each section one at a time:
|
|
57
|
+
- Skip if condition unmet
|
|
58
|
+
- Check agent permissions (owner/editors)
|
|
59
|
+
- Draft content using section instruction
|
|
60
|
+
- Present content + detailed rationale
|
|
61
|
+
- **IF elicit: true** → MANDATORY 1-9 options format
|
|
62
|
+
- Save to file after section
|
|
63
|
+
- Wait for user response before next section
|
|
64
|
+
|
|
65
|
+
5. **Continue until all sections complete**
|
|
52
66
|
|
|
53
67
|
## Detailed Rationale Requirements
|
|
54
68
|
|
|
@@ -85,7 +99,37 @@ When processing sections with agent permission fields:
|
|
|
85
99
|
|
|
86
100
|
## YOLO Mode
|
|
87
101
|
|
|
88
|
-
User can type `#yolo` to toggle to YOLO mode (process
|
|
102
|
+
User can type `#yolo` to toggle to YOLO mode (process sections in batches without elicitation).
|
|
103
|
+
|
|
104
|
+
**MANDATORY BATCH WORKFLOW:**
|
|
105
|
+
|
|
106
|
+
1. **Automatic batch calculation:**
|
|
107
|
+
- Estimate: `sections × 600 tokens`
|
|
108
|
+
- Max per batch: **22,000 tokens** (safe 10K buffer - Claude can't measure in real-time)
|
|
109
|
+
- Batches needed: `total_estimate ÷ 22,000` (rounded up)
|
|
110
|
+
- If complex sections detected: multiply estimate × 1.5
|
|
111
|
+
|
|
112
|
+
2. **CRITICAL - Repeatable sections (epics, stories, etc.):**
|
|
113
|
+
- Count total repeatable items (e.g., 10 epics × 10 stories each)
|
|
114
|
+
- Estimate tokens per item: `epic ~7,000 tokens`, `story ~800 tokens`
|
|
115
|
+
- Calculate: `items × tokens_per_item = total_tokens`
|
|
116
|
+
- If `total_tokens > 22,000`: Split into sub-batches
|
|
117
|
+
- Example: 10 epics × 7K = 70K tokens → 4 sub-batches (3-3-2-2 epics)
|
|
118
|
+
- Process each sub-batch separately with pauses
|
|
119
|
+
|
|
120
|
+
3. **Process EACH batch:**
|
|
121
|
+
- Generate content for batch sections
|
|
122
|
+
- Save to file
|
|
123
|
+
- STOP and tell user: "✅ Batch X/Y complete: Sections A-B saved. Type 'continue'."
|
|
124
|
+
- WAIT for user to type "continue"
|
|
125
|
+
- Repeat until all batches complete
|
|
126
|
+
|
|
127
|
+
**Examples:**
|
|
128
|
+
- 30 sections (~18K tokens) → 1 batch (0 pauses)
|
|
129
|
+
- 50 sections (~30K tokens) → 2 batches (1 pause)
|
|
130
|
+
- 50 sections + 10 epics (~80K tokens) → 4 batches (3 pauses)
|
|
131
|
+
|
|
132
|
+
**THIS IS NON-NEGOTIABLE FOR YOLO MODE**
|
|
89
133
|
|
|
90
134
|
## CRITICAL REMINDERS
|
|
91
135
|
|
|
@@ -44,15 +44,25 @@ If a YAML Template has not been provided, list all templates from .bmad-core/tem
|
|
|
44
44
|
## Processing Flow
|
|
45
45
|
|
|
46
46
|
1. **Parse YAML template** - Load template metadata and sections
|
|
47
|
-
2. **Set preferences** - Show current mode (Interactive), confirm output file
|
|
48
|
-
3. **
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
4. **
|
|
47
|
+
2. **Set preferences** - Show current mode (Interactive or YOLO), confirm output file
|
|
48
|
+
3. **If YOLO mode:**
|
|
49
|
+
- Count total sections
|
|
50
|
+
- Estimate optimal batch count based on section complexity
|
|
51
|
+
- Split document into 3-4 batches (~12-17 sections each)
|
|
52
|
+
- Process each batch → Save → STOP → Wait for "continue"
|
|
53
|
+
- Repeat until all batches complete
|
|
54
|
+
|
|
55
|
+
4. **If Interactive mode:**
|
|
56
|
+
- Process each section one at a time:
|
|
57
|
+
- Skip if condition unmet
|
|
58
|
+
- Check agent permissions (owner/editors)
|
|
59
|
+
- Draft content using section instruction
|
|
60
|
+
- Present content + detailed rationale
|
|
61
|
+
- **IF elicit: true** → MANDATORY 1-9 options format
|
|
62
|
+
- Save to file after section
|
|
63
|
+
- Wait for user response before next section
|
|
64
|
+
|
|
65
|
+
5. **Continue until all sections complete**
|
|
56
66
|
|
|
57
67
|
## Detailed Rationale Requirements
|
|
58
68
|
|
|
@@ -89,7 +99,37 @@ When processing sections with agent permission fields:
|
|
|
89
99
|
|
|
90
100
|
## YOLO Mode
|
|
91
101
|
|
|
92
|
-
User can type `#yolo` to toggle to YOLO mode (process
|
|
102
|
+
User can type `#yolo` to toggle to YOLO mode (process sections in batches without elicitation).
|
|
103
|
+
|
|
104
|
+
**MANDATORY BATCH WORKFLOW:**
|
|
105
|
+
|
|
106
|
+
1. **Automatic batch calculation:**
|
|
107
|
+
- Estimate: `sections × 600 tokens`
|
|
108
|
+
- Max per batch: **22,000 tokens** (safe 10K buffer - Claude can't measure in real-time)
|
|
109
|
+
- Batches needed: `total_estimate ÷ 22,000` (rounded up)
|
|
110
|
+
- If complex sections detected: multiply estimate × 1.5
|
|
111
|
+
|
|
112
|
+
2. **CRITICAL - Repeatable sections (epics, stories, etc.):**
|
|
113
|
+
- Count total repeatable items (e.g., 10 epics × 10 stories each)
|
|
114
|
+
- Estimate tokens per item: `epic ~7,000 tokens`, `story ~800 tokens`
|
|
115
|
+
- Calculate: `items × tokens_per_item = total_tokens`
|
|
116
|
+
- If `total_tokens > 22,000`: Split into sub-batches
|
|
117
|
+
- Example: 10 epics × 7K = 70K tokens → 4 sub-batches (3-3-2-2 epics)
|
|
118
|
+
- Process each sub-batch separately with pauses
|
|
119
|
+
|
|
120
|
+
3. **Process EACH batch:**
|
|
121
|
+
- Generate content for batch sections
|
|
122
|
+
- Save to file
|
|
123
|
+
- STOP and tell user: "✅ Batch X/Y complete: Sections A-B saved. Type 'continue'."
|
|
124
|
+
- WAIT for user to type "continue"
|
|
125
|
+
- Repeat until all batches complete
|
|
126
|
+
|
|
127
|
+
**Examples:**
|
|
128
|
+
- 30 sections (~18K tokens) → 1 batch (0 pauses)
|
|
129
|
+
- 50 sections (~30K tokens) → 2 batches (1 pause)
|
|
130
|
+
- 50 sections + 10 epics (~80K tokens) → 4 batches (3 pauses)
|
|
131
|
+
|
|
132
|
+
**THIS IS NON-NEGOTIABLE FOR YOLO MODE**
|
|
93
133
|
|
|
94
134
|
## CRITICAL REMINDERS
|
|
95
135
|
|
|
@@ -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
|