chati-dev 4.3.1 → 4.4.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 +18 -13
- package/bin/chati.js +12 -4
- package/framework/agents/build/dev.md +5 -1
- package/framework/agents/discover/greenfield-wu.md +16 -1
- package/framework/agents/plan/tasks.md +31 -0
- package/framework/agents/plan/ux-brand-architect.md +21 -2
- package/framework/agents/plan/ux-component-engineer.md +10 -0
- package/framework/agents/quality/qa-implementation.md +1 -1
- package/framework/agents/quality/qa-planning.md +1 -1
- package/framework/agents/quality/qa-visual.md +24 -21
- package/framework/config.yaml +5 -4
- package/framework/constitution.md +58 -11
- package/framework/context/governance.md +12 -10
- package/framework/context/root.md +2 -2
- package/framework/data/entity-registry.yaml +12 -4
- package/framework/data/qa-rubrics.yaml +335 -0
- package/framework/domains/constitution.yaml +3 -3
- package/framework/executors/json-validate.js +80 -0
- package/framework/executors/npm-script.js +72 -0
- package/framework/executors/path-check.js +67 -0
- package/framework/executors/registry.yaml +36 -0
- package/framework/hooks/advance-trigger.js +47 -3
- package/framework/hooks/constitution-guard.js +9 -4
- package/framework/hooks/git-push-authority.js +113 -0
- package/framework/hooks/license-guard.js +59 -9
- package/framework/hooks/model-governance.js +40 -17
- package/framework/hooks/prism-engine.js +78 -11
- package/framework/hooks/session-digest.js +12 -3
- package/framework/hooks/settings.json +7 -3
- package/framework/hooks/style-guard.js +52 -3
- package/framework/hooks/team-quality-gate.js +43 -5
- package/framework/i18n/en.yaml +3 -3
- package/framework/i18n/es.yaml +3 -3
- package/framework/i18n/fr.yaml +3 -3
- package/framework/i18n/pt.yaml +3 -3
- package/framework/intelligence/confidence.yaml +85 -6
- package/framework/intelligence/context-engine.md +9 -5
- package/framework/intelligence/decision-engine.md +1 -1
- package/framework/orchestrator/chati-router.js +1 -1
- package/framework/orchestrator/chati-update.md +19 -3
- package/framework/orchestrator/chati.md +19 -1
- package/framework/quality-gates/planning-gate.md +2 -0
- package/framework/scaffold/motion-premium/scaffold.yaml +2 -1
- package/framework/scaffold/motion-premium-3d/components/webgl/WebGLContext.tsx.template +1 -1
- package/framework/scaffold/saas-dashboard/README.md +58 -0
- package/framework/scaffold/saas-dashboard/app/dashboard/page.tsx.template +546 -0
- package/framework/scaffold/saas-dashboard/app/globals.css.template +746 -0
- package/framework/scaffold/saas-dashboard/app/layout.tsx.template +192 -0
- package/framework/scaffold/saas-dashboard/app/shell.css.template +1070 -0
- package/framework/scaffold/saas-dashboard/components/data/Chart.tsx.template +725 -0
- package/framework/scaffold/saas-dashboard/components/data/DataTable.tsx.template +623 -0
- package/framework/scaffold/saas-dashboard/components/data/DataTable.types.ts.template +104 -0
- package/framework/scaffold/saas-dashboard/components/data/DataTablePagination.tsx.template +234 -0
- package/framework/scaffold/saas-dashboard/components/data/SkeletonBlock.tsx.template +111 -0
- package/framework/scaffold/saas-dashboard/components/data/StatCard.tsx.template +393 -0
- package/framework/scaffold/saas-dashboard/components/data/StatCardGrid.tsx.template +121 -0
- package/framework/scaffold/saas-dashboard/components/feedback/EmptyState.tsx.template +281 -0
- package/framework/scaffold/saas-dashboard/components/interaction/CommandPalette.tsx.template +767 -0
- package/framework/scaffold/saas-dashboard/components/interaction/Field.tsx.template +351 -0
- package/framework/scaffold/saas-dashboard/components/interaction/Form.tsx.template +424 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Badge.tsx.template +193 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Button.tsx.template +261 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Card.tsx.template +287 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Input.tsx.template +310 -0
- package/framework/scaffold/saas-dashboard/components/primitives/Spinner.tsx.template +135 -0
- package/framework/scaffold/saas-dashboard/components/primitives/index.ts.template +60 -0
- package/framework/scaffold/saas-dashboard/components/shell/AppShell.tsx.template +174 -0
- package/framework/scaffold/saas-dashboard/components/shell/Breadcrumb.tsx.template +186 -0
- package/framework/scaffold/saas-dashboard/components/shell/Container.tsx.template +86 -0
- package/framework/scaffold/saas-dashboard/components/shell/NavItem.tsx.template +147 -0
- package/framework/scaffold/saas-dashboard/components/shell/Sidebar.tsx.template +378 -0
- package/framework/scaffold/saas-dashboard/components/shell/SidebarContext.tsx.template +169 -0
- package/framework/scaffold/saas-dashboard/components/shell/ThemeToggle.tsx.template +128 -0
- package/framework/scaffold/saas-dashboard/components/shell/Topbar.tsx.template +301 -0
- package/framework/scaffold/saas-dashboard/lib/brand.ts.template +324 -0
- package/framework/scaffold/saas-dashboard/scaffold.yaml +225 -0
- package/framework/schemas/session.schema.json +5 -0
- package/framework/schemas/task.schema.json +9 -0
- package/framework/scripts/visual-qa.js +87 -1
- package/framework/tasks/orchestrator-health.md +4 -4
- package/framework/tasks/qa-impl-verdict.md +11 -5
- package/framework/templates/qa-gate-tmpl.yaml +24 -11
- package/package.json +3 -3
- package/src/config/context-file-generator.js +0 -6
- package/src/dashboard/renderer.js +0 -36
- package/src/executors/runner.js +204 -0
- package/src/installer/core.js +2 -1
- package/src/installer/templates.js +5 -6
- package/src/intelligence/registry-manager.js +1 -1
- package/src/license/client.js +9 -3
- package/src/license/commands.js +12 -2
- package/src/license/machine-id.js +42 -1
- package/src/memory/gotchas.js +58 -40
- package/src/memory/magic-docs.js +1 -1
- package/src/memory/session-digest.js +9 -4
- package/src/orchestrator/cli.js +174 -14
- package/src/orchestrator/doctor.js +98 -16
- package/src/orchestrator/pipeline-manager.js +44 -22
- package/src/orchestrator/session-manager.js +56 -8
- package/src/telemetry/sender.js +7 -19
- package/src/terminal/run-team.js +3 -3
- package/src/upgrade/tracked-files-detector.js +34 -16
- package/src/utils/feature-flags.js +1 -1
- package/src/utils/flatten-entities.js +4 -40
- package/src/utils/schema-validator.js +0 -14
- package/src/wizard/i18n.js +3 -3
- package/src/api/index.js +0 -120
- package/src/autonomy/autonomous-gate.js +0 -294
- package/src/autonomy/build-loop.js +0 -281
- package/src/autonomy/build-state.js +0 -286
- package/src/autonomy/cause-analyzer.js +0 -177
- package/src/autonomy/escalation.js +0 -214
- package/src/autonomy/index.js +0 -51
- package/src/autonomy/mode-manager.js +0 -225
- package/src/autonomy/mode-suggester.js +0 -283
- package/src/autonomy/progress-reporter.js +0 -275
- package/src/autonomy/safety-net.js +0 -370
- package/src/config/agent-customizer.js +0 -231
- package/src/decision/analyzer.js +0 -291
- package/src/decision/engine.js +0 -250
- package/src/decision/index.js +0 -38
- package/src/decision/registry-healer.js +0 -468
- package/src/decision/registry-updater.js +0 -339
- package/src/extensions/loader.js +0 -145
- package/src/extensions/registry.js +0 -134
- package/src/gates/circuit-breaker.js +0 -151
- package/src/gates/g1-planning-complete.js +0 -154
- package/src/gates/g2-qa-planning.js +0 -156
- package/src/gates/g3-implementation.js +0 -215
- package/src/gates/g4-qa-implementation.js +0 -240
- package/src/gates/g5-deploy-ready.js +0 -181
- package/src/gates/gate-base.js +0 -185
- package/src/gates/index.js +0 -46
- package/src/health/auto-fix.js +0 -216
- package/src/health/engine.js +0 -246
- package/src/merger/semantic-merger.js +0 -292
- package/src/preview/detector.js +0 -238
- package/src/preview/index.js +0 -20
- package/src/preview/launcher.js +0 -235
- package/src/preview/log-buffer.js +0 -103
- package/src/quality/metrics-collector.js +0 -281
- package/src/quality/test-runner.js +0 -366
- package/src/tasks/executor.js +0 -195
- package/src/tasks/index.js +0 -4
- package/src/tasks/loader.js +0 -210
- package/src/tasks/router.js +0 -182
- package/src/utils/event-bus.js +0 -126
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* components/feedback/EmptyState.tsx
|
|
3
|
+
* SaaS Dashboard Preset -- D_interaction phase
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS
|
|
6
|
+
* ---------------
|
|
7
|
+
* Empty states are the most overlooked component in dashboard UIs.
|
|
8
|
+
* When data is absent, the screen goes blank, users panic ("Is it broken?"),
|
|
9
|
+
* and conversion to the first meaningful action drops. A well-crafted empty
|
|
10
|
+
* state communicates:
|
|
11
|
+
*
|
|
12
|
+
* 1. Context: what this section normally shows
|
|
13
|
+
* 2. Cause: why it's empty (first visit vs. filtered vs. no data)
|
|
14
|
+
* 3. Path: exactly one clear next action
|
|
15
|
+
*
|
|
16
|
+
* DESIGN DECISIONS
|
|
17
|
+
* ----------------
|
|
18
|
+
* 1. Illustration area reserved at 128px height (--space-32) before any
|
|
19
|
+
* content loads. This prevents layout shift when the illustration
|
|
20
|
+
* (icon or custom slot) appears. The PERFORMANCE requirement in the
|
|
21
|
+
* spec mandates reserving space before content arrives.
|
|
22
|
+
*
|
|
23
|
+
* 2. Icon vs. illustration slot: the `icon` prop renders a Lucide icon at
|
|
24
|
+
* 48px in a circle container. The `illustration` prop (ReactNode) overrides
|
|
25
|
+
* `icon` for custom SVGs or images, using the same reserved space.
|
|
26
|
+
*
|
|
27
|
+
* 3. Description max-width: 40ch. Prose in an empty state should be short
|
|
28
|
+
* and direct -- 40 characters keeps it scannable at a single glance.
|
|
29
|
+
*
|
|
30
|
+
* 4. Secondary action: rendered as a ghost button below the primary action.
|
|
31
|
+
* Used for "Learn more" or "Import from CSV" type escape hatches.
|
|
32
|
+
*
|
|
33
|
+
* 5. Centered layout: always centered, regardless of container width.
|
|
34
|
+
* Empty states are spatial declarations -- they own the viewport slice
|
|
35
|
+
* they occupy. Off-center empty states feel like layout bugs.
|
|
36
|
+
*
|
|
37
|
+
* ANIMATION
|
|
38
|
+
* ---------
|
|
39
|
+
* A gentle entrance stagger: icon scales up from 0.8 to 1 with ease-spring
|
|
40
|
+
* (delightful overshoot), then title and description fade in sequentially.
|
|
41
|
+
* This is reduced to opacity-only fade when prefers-reduced-motion is active.
|
|
42
|
+
* All transitions use transform and opacity only, never layout properties.
|
|
43
|
+
*
|
|
44
|
+
* TOKEN USAGE
|
|
45
|
+
* -----------
|
|
46
|
+
* All colors: CSS custom properties from globals.css.
|
|
47
|
+
* All spacing: CSS custom properties.
|
|
48
|
+
* No raw values in component styles.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
'use client';
|
|
52
|
+
|
|
53
|
+
import { type ReactNode } from 'react';
|
|
54
|
+
import { motion, useReducedMotion } from 'framer-motion';
|
|
55
|
+
import { DURATION, EASING } from '@/lib/brand';
|
|
56
|
+
import { Button } from '@/components/primitives/Button';
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Types
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
export interface EmptyStateAction {
|
|
63
|
+
label: string;
|
|
64
|
+
onClick: () => void;
|
|
65
|
+
/** Href converts button to a link. */
|
|
66
|
+
href?: string;
|
|
67
|
+
/** Lucide icon node (16px) */
|
|
68
|
+
icon?: ReactNode;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface EmptyStateProps {
|
|
72
|
+
/** Lucide icon rendered at 48px inside a circle container. */
|
|
73
|
+
icon?: ReactNode;
|
|
74
|
+
/** Custom illustration. Overrides `icon` when provided. */
|
|
75
|
+
illustration?: ReactNode;
|
|
76
|
+
/** Required heading. Uses type-h3 scale. */
|
|
77
|
+
title: string;
|
|
78
|
+
/** Supporting description. Capped at 40ch per spec. */
|
|
79
|
+
description?: string;
|
|
80
|
+
/** Primary call-to-action. */
|
|
81
|
+
primaryAction?: EmptyStateAction;
|
|
82
|
+
/** Secondary action (ghost style). */
|
|
83
|
+
secondaryAction?: EmptyStateAction;
|
|
84
|
+
/** Additional class on the container. */
|
|
85
|
+
className?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Component
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
export function EmptyState({
|
|
93
|
+
icon,
|
|
94
|
+
illustration,
|
|
95
|
+
title,
|
|
96
|
+
description,
|
|
97
|
+
primaryAction,
|
|
98
|
+
secondaryAction,
|
|
99
|
+
className,
|
|
100
|
+
}: EmptyStateProps) {
|
|
101
|
+
const shouldReduceMotion = useReducedMotion();
|
|
102
|
+
|
|
103
|
+
const iconVariants = {
|
|
104
|
+
hidden: { opacity: 0, scale: shouldReduceMotion ? 1 : 0.8 },
|
|
105
|
+
visible: {
|
|
106
|
+
opacity: 1,
|
|
107
|
+
scale: 1,
|
|
108
|
+
transition: {
|
|
109
|
+
duration: shouldReduceMotion ? 0.08 : DURATION.medium / 1000,
|
|
110
|
+
ease: shouldReduceMotion ? EASING.out : EASING.spring,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const textVariants = {
|
|
116
|
+
hidden: { opacity: 0, y: shouldReduceMotion ? 0 : 8 },
|
|
117
|
+
visible: {
|
|
118
|
+
opacity: 1,
|
|
119
|
+
y: 0,
|
|
120
|
+
transition: {
|
|
121
|
+
duration: shouldReduceMotion ? 0.08 : DURATION.normal / 1000,
|
|
122
|
+
ease: EASING.out,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const actionsVariants = {
|
|
128
|
+
hidden: { opacity: 0, y: shouldReduceMotion ? 0 : 8 },
|
|
129
|
+
visible: {
|
|
130
|
+
opacity: 1,
|
|
131
|
+
y: 0,
|
|
132
|
+
transition: {
|
|
133
|
+
duration: shouldReduceMotion ? 0.08 : DURATION.normal / 1000,
|
|
134
|
+
ease: EASING.out,
|
|
135
|
+
delay: shouldReduceMotion ? 0 : 0.08,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<div
|
|
142
|
+
className={className}
|
|
143
|
+
style={{
|
|
144
|
+
display: 'flex',
|
|
145
|
+
flexDirection: 'column',
|
|
146
|
+
alignItems: 'center',
|
|
147
|
+
justifyContent: 'center',
|
|
148
|
+
textAlign: 'center',
|
|
149
|
+
padding: 'var(--spacing-section) var(--spacing-card-pad)',
|
|
150
|
+
gap: 'var(--space-4)',
|
|
151
|
+
}}
|
|
152
|
+
>
|
|
153
|
+
{/* Illustration area: reserved height prevents layout shift */}
|
|
154
|
+
<motion.div
|
|
155
|
+
variants={iconVariants}
|
|
156
|
+
initial="hidden"
|
|
157
|
+
animate="visible"
|
|
158
|
+
style={{
|
|
159
|
+
height: 'var(--space-32)', // 128px reserved
|
|
160
|
+
width: '128px',
|
|
161
|
+
display: 'flex',
|
|
162
|
+
alignItems: 'center',
|
|
163
|
+
justifyContent: 'center',
|
|
164
|
+
flexShrink: 0,
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
{illustration ? (
|
|
168
|
+
// Custom illustration slot: uses the full reserved area
|
|
169
|
+
<div
|
|
170
|
+
style={{
|
|
171
|
+
width: '100%',
|
|
172
|
+
height: '100%',
|
|
173
|
+
display: 'flex',
|
|
174
|
+
alignItems: 'center',
|
|
175
|
+
justifyContent: 'center',
|
|
176
|
+
}}
|
|
177
|
+
>
|
|
178
|
+
{illustration}
|
|
179
|
+
</div>
|
|
180
|
+
) : icon ? (
|
|
181
|
+
// Icon in circle container
|
|
182
|
+
<div
|
|
183
|
+
aria-hidden="true"
|
|
184
|
+
style={{
|
|
185
|
+
width: '72px',
|
|
186
|
+
height: '72px',
|
|
187
|
+
borderRadius: 'var(--radius-circle)',
|
|
188
|
+
backgroundColor: 'var(--color-bg-raised)',
|
|
189
|
+
border: '1px solid var(--color-border-default)',
|
|
190
|
+
display: 'flex',
|
|
191
|
+
alignItems: 'center',
|
|
192
|
+
justifyContent: 'center',
|
|
193
|
+
color: 'var(--color-text-muted)',
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
196
|
+
{icon}
|
|
197
|
+
</div>
|
|
198
|
+
) : null}
|
|
199
|
+
</motion.div>
|
|
200
|
+
|
|
201
|
+
{/* Text content */}
|
|
202
|
+
<motion.div
|
|
203
|
+
variants={textVariants}
|
|
204
|
+
initial="hidden"
|
|
205
|
+
animate="visible"
|
|
206
|
+
style={{
|
|
207
|
+
display: 'flex',
|
|
208
|
+
flexDirection: 'column',
|
|
209
|
+
alignItems: 'center',
|
|
210
|
+
gap: 'var(--space-2)',
|
|
211
|
+
}}
|
|
212
|
+
>
|
|
213
|
+
<h3
|
|
214
|
+
style={{
|
|
215
|
+
fontSize: 'var(--type-h3)',
|
|
216
|
+
lineHeight: 'var(--type-h3-lh)',
|
|
217
|
+
letterSpacing: 'var(--type-h3-ls)',
|
|
218
|
+
fontWeight: 600,
|
|
219
|
+
color: 'var(--color-text-primary)',
|
|
220
|
+
margin: 0,
|
|
221
|
+
}}
|
|
222
|
+
>
|
|
223
|
+
{title}
|
|
224
|
+
</h3>
|
|
225
|
+
{description && (
|
|
226
|
+
<p
|
|
227
|
+
style={{
|
|
228
|
+
fontSize: 'var(--type-body)',
|
|
229
|
+
lineHeight: 'var(--type-body-lh)',
|
|
230
|
+
color: 'var(--color-text-secondary)',
|
|
231
|
+
maxWidth: '40ch',
|
|
232
|
+
margin: 0,
|
|
233
|
+
}}
|
|
234
|
+
>
|
|
235
|
+
{description}
|
|
236
|
+
</p>
|
|
237
|
+
)}
|
|
238
|
+
</motion.div>
|
|
239
|
+
|
|
240
|
+
{/* Actions */}
|
|
241
|
+
{(primaryAction || secondaryAction) && (
|
|
242
|
+
<motion.div
|
|
243
|
+
variants={actionsVariants}
|
|
244
|
+
initial="hidden"
|
|
245
|
+
animate="visible"
|
|
246
|
+
style={{
|
|
247
|
+
display: 'flex',
|
|
248
|
+
flexDirection: 'column',
|
|
249
|
+
alignItems: 'center',
|
|
250
|
+
gap: 'var(--space-3)',
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
{primaryAction && (
|
|
254
|
+
<Button
|
|
255
|
+
variant="primary"
|
|
256
|
+
size="md"
|
|
257
|
+
href={primaryAction.href}
|
|
258
|
+
onClick={primaryAction.onClick}
|
|
259
|
+
iconLeft={primaryAction.icon}
|
|
260
|
+
>
|
|
261
|
+
{primaryAction.label}
|
|
262
|
+
</Button>
|
|
263
|
+
)}
|
|
264
|
+
{secondaryAction && (
|
|
265
|
+
<Button
|
|
266
|
+
variant="ghost"
|
|
267
|
+
size="sm"
|
|
268
|
+
href={secondaryAction.href}
|
|
269
|
+
onClick={secondaryAction.onClick}
|
|
270
|
+
iconLeft={secondaryAction.icon}
|
|
271
|
+
>
|
|
272
|
+
{secondaryAction.label}
|
|
273
|
+
</Button>
|
|
274
|
+
)}
|
|
275
|
+
</motion.div>
|
|
276
|
+
)}
|
|
277
|
+
</div>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export default EmptyState;
|