create-auto-app 0.10.5 → 0.11.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-auto-app",
3
- "version": "0.10.5",
3
+ "version": "0.11.0",
4
4
  "description": "Create Auto Engineer apps with no configuration",
5
5
  "type": "module",
6
6
  "bin": {
@@ -28,7 +28,7 @@
28
28
  "fs-extra": "^11.2.0",
29
29
  "inquirer": "^9.2.15",
30
30
  "ora": "^8.0.1",
31
- "@auto-engineer/id": "0.10.5"
31
+ "@auto-engineer/id": "0.11.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/fs-extra": "^11.0.4",
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": ["Bash(pnpm start:*)"],
4
+ "deny": [],
5
+ "ask": []
6
+ }
7
+ }
@@ -1,186 +1,158 @@
1
- import { experience, flow, specs, should } from '@auto-engineer/flow';
2
-
3
- flow('Home Screen', () => {
1
+ import { experience, flow, should, specs } from '@auto-engineer/flow';
2
+ flow('Home Screen', 'AUTO-cDAZP41Kb', () => {
4
3
  experience('Active Surveys Summary', 'AUTO-aifPcU3hw').client(() => {
5
4
  specs(() => {
6
5
  should('show active surveys summary and response rate overview');
7
6
  });
8
7
  });
9
-
10
8
  experience('Recent Survey Responses', 'AUTO-B2gF5k9Xj').client(() => {
11
9
  specs(() => {
12
10
  should('display recent survey responses list');
13
11
  });
14
12
  });
15
-
16
13
  experience('Completion Rate Progress', 'AUTO-C3hG6l0Yk').client(() => {
17
14
  specs(() => {
18
15
  should('show visual progress of completion rate goals');
19
16
  });
20
17
  });
21
-
22
18
  experience('Quick Access Actions', 'AUTO-D4iH7m1Zl').client(() => {
23
19
  specs(() => {
24
20
  should('show quick access buttons for Create Survey, Analytics, Templates');
25
21
  });
26
22
  });
27
23
  });
28
-
29
- flow('Create Survey', () => {
24
+ flow('Create Survey', 'AUTO-OnuAvj45V', () => {
30
25
  experience('Create Survey Form', 'AUTO-MPviTMrQC').client(() => {
31
26
  specs(() => {
32
27
  should('allow entering survey title, description, and question types');
33
28
  });
34
29
  });
35
-
36
30
  experience('Question Templates Selection', 'AUTO-E5jI8n2Am').client(() => {
37
31
  specs(() => {
38
32
  should('show recent/frequent question templates for quick selection');
39
33
  });
40
34
  });
41
-
42
35
  experience('Survey Creation Confirmation', 'AUTO-F6kJ9o3Bn').client(() => {
43
36
  specs(() => {
44
37
  should('display confirmation toast after creating survey');
45
38
  });
46
39
  });
47
-
48
40
  experience('Real-time Dashboard Updates', 'AUTO-G7lK0p4Co').client(() => {
49
41
  specs(() => {
50
42
  should('update survey dashboard and analytics in real-time');
51
43
  });
52
44
  });
53
45
  });
54
-
55
- flow('Response Analytics', () => {
46
+ flow('Response Analytics', 'AUTO-dRYuxORz0', () => {
56
47
  experience('Response Rate Charts', 'AUTO-eME978Euk').client(() => {
57
48
  specs(() => {
58
- should('show daily and weekly response rate charts');
49
+ should('show daily response rate charts');
50
+ should('show weekly response rate charts');
59
51
  });
60
52
  });
61
-
62
53
  experience('High Engagement Survey Highlights', 'AUTO-H8mL1q5Dp').client(() => {
63
54
  specs(() => {
64
55
  should('highlight surveys with highest engagement');
65
56
  });
66
57
  });
67
-
68
58
  experience('Analytics Filtering', 'AUTO-I9nM2r6Eq').client(() => {
69
59
  specs(() => {
70
60
  should('allow filtering by survey type or date range');
71
61
  });
72
62
  });
73
-
74
63
  experience('Real-time Analytics Updates', 'AUTO-J0oN3s7Fr').client(() => {
75
64
  specs(() => {
76
65
  should('update dynamically when new responses are received');
77
66
  });
78
67
  });
79
68
  });
80
-
81
- flow('Manage Templates', () => {
69
+ flow('Manage Templates', 'AUTO-KFxx8k1ul', () => {
82
70
  experience('Templates List View', 'AUTO-TRJBgM1JS').client(() => {
83
71
  specs(() => {
84
72
  should('list all survey templates with usage count and last modified date');
85
73
  });
86
74
  });
87
-
88
75
  experience('Template Management Actions', 'AUTO-K1pO4t8Gs').client(() => {
89
76
  specs(() => {
90
77
  should('allow creating, editing, and deleting survey templates');
91
78
  });
92
79
  });
93
-
94
80
  experience('Template Usage Statistics', 'AUTO-L2qP5u9Ht').client(() => {
95
81
  specs(() => {
96
82
  should('show monthly summary of template usage statistics');
97
83
  });
98
84
  });
99
-
100
85
  experience('Popular Templates Highlights', 'AUTO-M3rQ6v0Iu').client(() => {
101
86
  specs(() => {
102
87
  should('highlight most popular and recently used templates');
103
88
  });
104
89
  });
105
90
  });
106
-
107
- flow('Survey Completion Tracker', () => {
91
+ flow('Survey Completion Tracker', 'AUTO-wXdtfGpFr', () => {
108
92
  experience('Completion Rate Progress View', 'AUTO-oDBBOUNzr').client(() => {
109
93
  specs(() => {
110
94
  should('show current completion rate and target progress');
111
95
  });
112
96
  });
113
-
114
97
  experience('Target Setting Interface', 'AUTO-N4sR7w1Jv').client(() => {
115
98
  specs(() => {
116
99
  should('allow setting completion rate targets');
117
100
  });
118
101
  });
119
-
120
102
  experience('Automatic Completion Tracking', 'AUTO-O5tS8x2Kw').client(() => {
121
103
  specs(() => {
122
104
  should('automatically track new survey completions');
123
105
  });
124
106
  });
125
-
126
107
  experience('Shell Progress Bar Display', 'AUTO-P6uT9y3Lx').client(() => {
127
108
  specs(() => {
128
109
  should('display visual completion progress bar consistently in shell');
129
110
  });
130
111
  });
131
112
  });
132
-
133
- flow('Response Goals Tracker', () => {
113
+ flow('Response Goals Tracker', 'AUTO-W8dytm3oC', () => {
134
114
  experience('Response Target Setting', 'AUTO-Idmim68Yf').client(() => {
135
115
  specs(() => {
136
116
  should('allow setting monthly/weekly response targets');
137
117
  });
138
118
  });
139
-
140
119
  experience('Response Target Progress Bar', 'AUTO-Q7vU0z4My').client(() => {
141
120
  specs(() => {
142
121
  should('show remaining response targets as a progress bar');
143
122
  });
144
123
  });
145
-
146
124
  experience('Underperforming Survey Highlights', 'AUTO-R8wV1a5Nz').client(() => {
147
125
  specs(() => {
148
126
  should('highlight underperforming surveys');
149
127
  });
150
128
  });
151
-
152
129
  experience('Real-time Goals Updates', 'AUTO-S9xW2b6Oa').client(() => {
153
130
  specs(() => {
154
131
  should('update in real-time when responses are received');
155
132
  });
156
133
  });
157
134
  });
158
-
159
- flow('Response History', () => {
135
+ flow('Response History', 'AUTO-JizW21yrr', () => {
160
136
  experience('Response History List', 'AUTO-cIpwPlqRq').client(() => {
161
137
  specs(() => {
162
138
  should('allow viewing full response history');
163
139
  });
164
140
  });
165
-
166
141
  experience('Response History Filtering', 'AUTO-T0yX3c7Pb').client(() => {
167
142
  specs(() => {
168
143
  should('filter by survey type, date, or completion status');
169
144
  });
170
145
  });
171
-
172
146
  experience('Detailed Response View', 'AUTO-U1zY4d8Qc').client(() => {
173
147
  specs(() => {
174
148
  should('view detailed response data and export individual responses');
175
149
  });
176
150
  });
177
-
178
151
  experience('Response Export Functionality', 'AUTO-V2aZ5e9Rd').client(() => {
179
152
  specs(() => {
180
153
  should('export individual responses');
181
154
  });
182
155
  });
183
-
184
156
  experience('Response Engagement Contribution', 'AUTO-W3ba6f0Se').client(() => {
185
157
  specs(() => {
186
158
  should('show contribution of each response to daily/weekly/monthly engagement totals');
@@ -1,8 +1,7 @@
1
1
  import { experience, flow, should, specs } from '@auto-engineer/flow';
2
-
3
- flow('App Structure', () => {
2
+ flow('App Structure', 'AUTO-vLkxrmhz6', () => {
4
3
  experience('App Structure', 'AUTO-k6JkQZQnc').client(() => {
5
- specs('', () => {
4
+ specs(() => {
6
5
  should('display persistent sidebar on left for navigation');
7
6
  should(
8
7
  'sidebar includes links: Home, Create Survey, Analytics, Templates, Completion Tracker, Response Goals, Response History',
@@ -1,32 +1,40 @@
1
1
  import { autoConfig, on, dispatch } from '@auto-engineer/cli';
2
- import type { ExportSchemaCommand, ExportSchemaEvents } from '@auto-engineer/flow';
2
+ import type { ExportSchemaEvents } from '@auto-engineer/flow';
3
3
  import type { GenerateServerCommand, GenerateServerEvents } from '@auto-engineer/server-generator-apollo-emmett';
4
- import type {
5
- ImplementServerCommand,
6
- ImplementServerEvents,
7
- ImplementSliceEvents,
8
- ImplementSliceCommand,
9
- } from '@auto-engineer/server-implementer';
4
+ import type { ImplementSliceEvents, ImplementSliceCommand } from '@auto-engineer/server-implementer';
10
5
  import type {
11
6
  CheckTestsCommand,
12
- CheckTestsEvents,
13
7
  CheckTypesCommand,
14
- CheckTypesEvents,
15
8
  CheckLintCommand,
16
- CheckLintEvents,
17
9
  TestsCheckFailedEvent,
10
+ TypeCheckFailedEvent,
11
+ LintCheckFailedEvent,
18
12
  } from '@auto-engineer/server-checks';
19
13
  import type { GenerateIACommand, GenerateIAEvents } from '@auto-engineer/information-architect';
20
- import type { ImplementClientCommand, ImplementClientEvents } from '@auto-engineer/frontend-implementer';
14
+ import type { ImplementClientCommand } from '@auto-engineer/frontend-implementer';
21
15
  import type { GenerateClientCommand, GenerateClientEvents } from '@auto-engineer/frontend-generator-react-graphql';
22
- import {
23
- CheckClientCommand,
24
- CheckClientEvents,
25
- ClientCheckFailedEvent,
26
- } from '../../packages/frontend-checks/dist/src/commands/check-client';
16
+ import type { CheckClientEvents } from '../../packages/frontend-checks/dist/src/commands/check-client';
17
+ import { SliceGeneratedEvent } from '../../packages/server-generator-apollo-emmett/dist/src/commands/generate-server';
18
+
19
+ const sliceRetryState = new Map<string, number>();
20
+ const MAX_RETRIES = 3;
21
+
22
+ interface CheckFailures {
23
+ testsCheckFailed?: TestsCheckFailedEvent;
24
+ typeCheckFailed?: TypeCheckFailedEvent;
25
+ lintCheckFailed?: LintCheckFailedEvent;
26
+ }
27
+
28
+ type EventsType = Record<
29
+ string,
30
+ Array<{
31
+ type: string;
32
+ data: { targetDirectory?: string; errors?: string };
33
+ }>
34
+ >;
27
35
 
28
36
  export default autoConfig({
29
- fileId: 'test33333', // unique 9-character base62 canvas file id where all flows in this project will be shown
37
+ fileId: 'todoK4nB2',
30
38
 
31
39
  plugins: [
32
40
  '@auto-engineer/server-checks',
@@ -45,9 +53,82 @@ export default autoConfig({
45
53
  },
46
54
  pipeline: () => {
47
55
  on<ExportSchemaEvents>('SchemaExported', () =>
56
+ dispatch<GenerateServerCommand>('GenerateServer', {
57
+ modelPath: './.context/schema.json',
58
+ destination: '.',
59
+ }),
60
+ );
61
+ on<SliceGeneratedEvent>('SliceGenerated', (e) =>
62
+ dispatch<ImplementSliceCommand>('ImplementSlice', {
63
+ slicePath: e.data.slicePath,
64
+ context: {
65
+ previousOutputs: 'errors',
66
+ attemptNumber: 0,
67
+ },
68
+ }),
69
+ );
70
+
71
+ on<ImplementSliceEvents>('SliceImplemented', (e) =>
72
+ dispatch<CheckTestsCommand>('CheckTests', {
73
+ targetDirectory: e.data.slicePath,
74
+ scope: 'slice',
75
+ }),
76
+ );
77
+
78
+ on<ImplementSliceEvents>('SliceImplemented', (e) =>
79
+ dispatch<CheckTypesCommand>('CheckTypes', {
80
+ targetDirectory: e.data.slicePath,
81
+ scope: 'slice',
82
+ }),
83
+ );
84
+
85
+ on<ImplementSliceEvents>('SliceImplemented', (e) =>
86
+ dispatch<CheckLintCommand>('CheckLint', {
87
+ targetDirectory: e.data.slicePath,
88
+ scope: 'slice',
89
+ fix: true,
90
+ }),
91
+ );
92
+
93
+ on.settled<CheckTestsCommand, CheckTypesCommand, CheckLintCommand>(
94
+ ['CheckTests', 'CheckTypes', 'CheckLint'],
95
+ dispatch<ImplementSliceCommand>(['ImplementSlice'], (events, send) => {
96
+ const failures = findCheckFailures(events);
97
+ const slicePath = getSlicePath(failures, events);
98
+
99
+ if (!hasAnyFailures(failures)) {
100
+ sliceRetryState.delete(slicePath);
101
+ return { persist: false };
102
+ }
103
+
104
+ const currentAttempt = sliceRetryState.get(slicePath) ?? 0;
105
+
106
+ if (currentAttempt >= MAX_RETRIES) {
107
+ sliceRetryState.delete(slicePath);
108
+ return { persist: false };
109
+ }
110
+
111
+ sliceRetryState.set(slicePath, currentAttempt + 1);
112
+
113
+ send({
114
+ type: 'ImplementSlice',
115
+ data: {
116
+ slicePath,
117
+ context: {
118
+ previousOutputs: collectErrorMessages(failures),
119
+ attemptNumber: currentAttempt + 1,
120
+ },
121
+ },
122
+ });
123
+
124
+ return { persist: true };
125
+ }),
126
+ );
127
+
128
+ on<GenerateServerEvents>('ServerGenerated', () =>
48
129
  dispatch<GenerateIACommand>('GenerateIA', {
49
- outputDir: './.context',
50
130
  modelPath: './.context/schema.json',
131
+ outputDir: './.context',
51
132
  }),
52
133
  );
53
134
 
@@ -69,12 +150,12 @@ export default autoConfig({
69
150
  }),
70
151
  );
71
152
 
72
- on<ImplementClientEvents>('ClientImplemented', () =>
73
- dispatch<CheckClientCommand>('CheckClient', {
74
- clientDirectory: './client',
75
- skipBrowserChecks: true,
76
- }),
77
- );
153
+ // on<ImplementClientEvents>('ClientImplemented', () =>
154
+ // dispatch<CheckClientCommand>('CheckClient', {
155
+ // clientDirectory: './client',
156
+ // skipBrowserChecks: true,
157
+ // }),
158
+ // );
78
159
 
79
160
  on<CheckClientEvents>('ClientChecked', (e) => {
80
161
  if (e.type === 'ClientChecked') {
@@ -98,6 +179,56 @@ export default autoConfig({
98
179
  },
99
180
  });
100
181
 
182
+ function findCheckFailures(events: EventsType): CheckFailures {
183
+ const checkTests = events.CheckTests as Array<
184
+ TestsCheckFailedEvent | { type: string; data: { targetDirectory: string } }
185
+ >;
186
+ const checkTypes = events.CheckTypes as Array<
187
+ TypeCheckFailedEvent | { type: string; data: { targetDirectory: string } }
188
+ >;
189
+ const checkLint = events.CheckLint as Array<
190
+ LintCheckFailedEvent | { type: string; data: { targetDirectory: string } }
191
+ >;
192
+
193
+ return {
194
+ testsCheckFailed: checkTests.find((e): e is TestsCheckFailedEvent => e.type === 'TestsCheckFailed'),
195
+ typeCheckFailed: checkTypes.find((e): e is TypeCheckFailedEvent => e.type === 'TypeCheckFailed'),
196
+ lintCheckFailed: checkLint.find((e): e is LintCheckFailedEvent => e.type === 'LintCheckFailed'),
197
+ };
198
+ }
199
+
200
+ function hasAnyFailures(failures: CheckFailures): boolean {
201
+ return (
202
+ failures.testsCheckFailed !== undefined ||
203
+ failures.typeCheckFailed !== undefined ||
204
+ failures.lintCheckFailed !== undefined
205
+ );
206
+ }
207
+
208
+ function getSlicePath(failures: CheckFailures, events: EventsType): string {
209
+ return (
210
+ failures.testsCheckFailed?.data.targetDirectory ??
211
+ failures.typeCheckFailed?.data.targetDirectory ??
212
+ failures.lintCheckFailed?.data.targetDirectory ??
213
+ (events.CheckTests[0]?.data.targetDirectory as string) ??
214
+ ''
215
+ );
216
+ }
217
+
218
+ function collectErrorMessages(failures: CheckFailures): string {
219
+ const errorMessages: string[] = [];
220
+ if (failures.testsCheckFailed !== undefined) {
221
+ errorMessages.push(failures.testsCheckFailed.data.errors);
222
+ }
223
+ if (failures.typeCheckFailed !== undefined) {
224
+ errorMessages.push(failures.typeCheckFailed.data.errors);
225
+ }
226
+ if (failures.lintCheckFailed !== undefined) {
227
+ errorMessages.push(failures.lintCheckFailed.data.errors);
228
+ }
229
+ return errorMessages.join('\n');
230
+ }
231
+
101
232
  /*
102
233
 
103
234
  rm -rf server client .context/schema.json .context/schema.graphql .context/auto-ia-scheme.json
@@ -0,0 +1,142 @@
1
+ import { experience, flow, should, specs } from '@auto-engineer/flow';
2
+
3
+ flow('Todo Dashboard', 'AUTO-H6i9Rs2Gz', () => {
4
+ experience('Kanban Board View', 'AUTO-K7j0St3Hz').client(() => {
5
+ specs(() => {
6
+ should('display three distinct columns: To Do, In Progress, and Done');
7
+ should('show elegant column headers with gradient backgrounds');
8
+ should('display count badges on each column showing number of tasks');
9
+ should('support drag-and-drop of task cards between columns');
10
+ should('animate smooth transitions when tasks move between columns');
11
+ should('show visual feedback during drag operations with shadow elevation');
12
+ should('display task cards with glass morphism effect and subtle backdrop blur');
13
+ should('add hover effects with gentle scale and shadow transitions');
14
+ should('show empty state with beautiful illustrations when columns are empty');
15
+ should('maintain consistent card spacing and grid alignment');
16
+ });
17
+ });
18
+
19
+ experience('Task Cards', 'AUTO-T8k1Uu4Iz').client(() => {
20
+ specs(() => {
21
+ should('display task description with clear readable typography');
22
+ should('show status indicator with color-coded dot or icon');
23
+ should('display creation timestamp in subtle text');
24
+ should('show completion timestamp for completed tasks');
25
+ should('include quick action buttons appearing on hover');
26
+ should('support click to expand for future task details');
27
+ should('apply strike-through animation for completed tasks');
28
+ should('use gradient borders matching task status');
29
+ });
30
+ });
31
+
32
+ experience('Completion Progress Ring', 'AUTO-P9l2Vv5Jz').client(() => {
33
+ specs(() => {
34
+ should('display circular progress ring with gradient stroke');
35
+ should('show completion percentage prominently in center');
36
+ should('animate progress changes with smooth easing');
37
+ should('display total task count below percentage');
38
+ should('use vibrant colors for high completion rates');
39
+ should('show subtle pulse animation on milestone achievements');
40
+ should('position prominently at top of dashboard or sidebar');
41
+ });
42
+ });
43
+
44
+ experience('Quick Add Todo Widget', 'AUTO-Q0m3Ww6Kz').client(() => {
45
+ specs(() => {
46
+ should('display floating action button with plus icon');
47
+ should('position fixed in bottom-right corner for easy access');
48
+ should('expand into input form with smooth scale animation on click');
49
+ should('include elegant input field with placeholder text');
50
+ should('show submit button with icon when text is entered');
51
+ should('support keyboard shortcut (Ctrl/Cmd + K) to focus input');
52
+ should('auto-focus input when opened');
53
+ should('clear and collapse after successful task addition');
54
+ should('show loading state during task submission');
55
+ });
56
+ });
57
+
58
+ experience('Statistics Dashboard', 'AUTO-S1n4Xx7Lz').client(() => {
59
+ specs(() => {
60
+ should('show total tasks count with large prominent number');
61
+ should('display tasks completed today with celebration icon');
62
+ should('show breakdown: pending, in-progress, completed counts');
63
+ should('display completion percentage with visual indicator');
64
+ should('use card-based layout with glass morphism styling');
65
+ should('include subtle icons for each statistic');
66
+ should('update in real-time when tasks change status');
67
+ should('animate number changes with counting effect');
68
+ });
69
+ });
70
+
71
+ experience('Recent Activity Feed', 'AUTO-R2o5Yy8Mz').client(() => {
72
+ specs(() => {
73
+ should('display recent task completions in chronological order');
74
+ should('show completion timestamp in relative format');
75
+ should('limit to last 5 completed tasks');
76
+ should('include task description with completed styling');
77
+ should('show subtle celebration icon for each completion');
78
+ should('use minimalist list design with dividers');
79
+ should('support click to view task details');
80
+ should('auto-scroll new completions into view with smooth animation');
81
+ });
82
+ });
83
+
84
+ experience('View Toggle Controls', 'AUTO-V3p6Zz9Nz').client(() => {
85
+ specs(() => {
86
+ should('provide toggle between Kanban and List views');
87
+ should('use segmented control or tab-style switcher');
88
+ should('position in top toolbar for easy access');
89
+ should('highlight active view with accent color');
90
+ should('animate view transitions with fade and slide effects');
91
+ should('preserve scroll position when switching views');
92
+ should('remember user preference in local storage');
93
+ });
94
+ });
95
+
96
+ experience('Theme Toggle', 'AUTO-T4q7Aa0Oz').client(() => {
97
+ specs(() => {
98
+ should('support light and dark theme modes');
99
+ should('display sun/moon icon toggle in top bar');
100
+ should('transition smoothly between themes with fade animation');
101
+ should('adjust all colors including gradients for theme');
102
+ should('maintain high contrast and readability in both modes');
103
+ should('remember user preference in local storage');
104
+ should('use system preference as default');
105
+ });
106
+ });
107
+
108
+ experience('Celebration Animations', 'AUTO-C5r8Bb1Pz').client(() => {
109
+ specs(() => {
110
+ should('trigger confetti animation when task is completed');
111
+ should('show satisfying checkmark animation');
112
+ should('play subtle success sound effect (optional, user configurable)');
113
+ should('display special animation for completing all tasks');
114
+ should('show streak celebration for consecutive daily completions');
115
+ should('use particle effects that do not obstruct UI');
116
+ should('respect reduced motion preferences for accessibility');
117
+ });
118
+ });
119
+
120
+ experience('Column Management', 'AUTO-M6s9Cc2Qz').client(() => {
121
+ specs(() => {
122
+ should('allow reordering tasks within same column via drag-and-drop');
123
+ should('auto-scroll columns when dragging near edges');
124
+ should('show drop zones with visual indicators');
125
+ should('prevent invalid drops with visual feedback');
126
+ should('support keyboard-based task movement for accessibility');
127
+ should('show task count updates immediately on column changes');
128
+ should('maintain smooth 60fps animations during all interactions');
129
+ });
130
+ });
131
+
132
+ experience('Empty States', 'AUTO-E7t0Dd3Rz').client(() => {
133
+ specs(() => {
134
+ should('display welcoming illustration when no tasks exist');
135
+ should('show encouraging message to add first task');
136
+ should('provide quick-add button directly in empty state');
137
+ should('show column-specific empty states with relevant illustrations');
138
+ should('use consistent visual style matching overall design system');
139
+ should('include helpful tips for new users');
140
+ });
141
+ });
142
+ });