@nikkory/vibe-cli 2.2.1 → 2.3.1
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 +261 -138
- package/dist/index.js +515 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,193 +1,307 @@
|
|
|
1
1
|
# @nikkory/vibe-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Production-ready code in seconds** - Generate enterprise-grade UI components, sections, and pages with the Nikkory Vibe CLI.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@nikkory/vibe-cli)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **169 Components** - Buttons, cards, inputs, modals, and more
|
|
11
|
+
- **50 Sections** - Hero sections, pricing tables, testimonials, features
|
|
12
|
+
- **12 Design Systems** - Material Design, iOS HIG, Glassmorphism, and more
|
|
13
|
+
- **3 Quality Tiers** - Basic (prototype), Standard (production), Enterprise (mission-critical)
|
|
14
|
+
- **Smart Generation** - 24-factor matrix system for infinite variations
|
|
15
|
+
- **Section Orchestrator** - Slot-based composition with automatic component generation
|
|
16
|
+
- **Page Builder** - Multi-section composition for complete pages
|
|
4
17
|
|
|
5
18
|
## Installation
|
|
6
19
|
|
|
7
20
|
```bash
|
|
8
|
-
#
|
|
21
|
+
# npm
|
|
22
|
+
npm install -g @nikkory/vibe-cli
|
|
23
|
+
|
|
24
|
+
# pnpm
|
|
9
25
|
pnpm add -g @nikkory/vibe-cli
|
|
10
26
|
|
|
11
|
-
#
|
|
12
|
-
|
|
27
|
+
# yarn
|
|
28
|
+
yarn global add @nikkory/vibe-cli
|
|
13
29
|
```
|
|
14
30
|
|
|
15
31
|
## Quick Start
|
|
16
32
|
|
|
17
33
|
```bash
|
|
18
34
|
# Initialize new project
|
|
19
|
-
vibe init my-app
|
|
35
|
+
nikkory-vibe init my-app
|
|
36
|
+
|
|
37
|
+
# Add a component
|
|
38
|
+
nikkory-vibe add button
|
|
20
39
|
|
|
21
|
-
#
|
|
22
|
-
vibe
|
|
40
|
+
# Add a section
|
|
41
|
+
nikkory-vibe add:section hero-centered
|
|
23
42
|
|
|
24
|
-
#
|
|
25
|
-
vibe
|
|
43
|
+
# Add a full page
|
|
44
|
+
nikkory-vibe add:page landing
|
|
45
|
+
|
|
46
|
+
# List available templates
|
|
47
|
+
nikkory-vibe list
|
|
26
48
|
```
|
|
27
49
|
|
|
28
50
|
## Commands
|
|
29
51
|
|
|
30
|
-
### `vibe
|
|
52
|
+
### `nikkory-vibe add` (aliases: `gen`, `generate`)
|
|
31
53
|
|
|
32
|
-
|
|
54
|
+
Generate UI components with the 24-factor Matrix system.
|
|
33
55
|
|
|
34
56
|
```bash
|
|
35
|
-
|
|
36
|
-
vibe
|
|
37
|
-
|
|
57
|
+
# Basic usage
|
|
58
|
+
nikkory-vibe add button
|
|
59
|
+
|
|
60
|
+
# With design system and tier
|
|
61
|
+
nikkory-vibe add button -s ios-hig -t enterprise
|
|
62
|
+
|
|
63
|
+
# With custom output path
|
|
64
|
+
nikkory-vibe add card -o src/components/Card.tsx
|
|
65
|
+
|
|
66
|
+
# With factor overrides (advanced)
|
|
67
|
+
nikkory-vibe add button --factor-overrides '{"borderRadius":"rounded-full"}'
|
|
38
68
|
```
|
|
39
69
|
|
|
70
|
+
**Arguments:**
|
|
71
|
+
- `<component>` - Component ID (button, input, card, modal, etc.)
|
|
72
|
+
|
|
40
73
|
**Options:**
|
|
41
|
-
- `-
|
|
42
|
-
- `-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
74
|
+
- `-s, --design-system <system>` - Design system (default: `material-design`)
|
|
75
|
+
- `-t, --tier <tier>` - Quality tier: basic, standard, enterprise (default: `standard`)
|
|
76
|
+
- `-f, --factor-overrides <json>` - Override specific design factors (JSON)
|
|
77
|
+
- `-o, --output <path>` - Output file path
|
|
78
|
+
|
|
79
|
+
**Available Components (169 total)**:
|
|
80
|
+
- **Forms**: button, input, textarea, checkbox, radio-group, switch, select, slider
|
|
81
|
+
- **Feedback**: alert, badge, chip, progress, spinner, skeleton, tooltip
|
|
82
|
+
- **Navigation**: tabs, menu, breadcrumb, pagination, stepper
|
|
83
|
+
- **Data Display**: card, table, list, accordion, avatar
|
|
84
|
+
- **Overlay**: modal, drawer, popover
|
|
85
|
+
- **Date/Time**: date-picker, calendar
|
|
86
|
+
- **Media**: audio, video, image, file
|
|
45
87
|
|
|
46
|
-
### `vibe
|
|
88
|
+
### `nikkory-vibe add:section` (alias: `section`)
|
|
47
89
|
|
|
48
|
-
Generate
|
|
90
|
+
Generate sections using the Section Orchestrator (composition-based).
|
|
49
91
|
|
|
50
92
|
```bash
|
|
51
93
|
# Basic usage
|
|
52
|
-
vibe
|
|
94
|
+
nikkory-vibe add:section hero-centered
|
|
95
|
+
|
|
96
|
+
# With design system and tier
|
|
97
|
+
nikkory-vibe add:section pricing-cards -s material-design -t enterprise
|
|
98
|
+
|
|
99
|
+
# With custom output path
|
|
100
|
+
nikkory-vibe add:section testimonials-grid -o src/sections/Testimonials.tsx
|
|
101
|
+
```
|
|
53
102
|
|
|
54
|
-
|
|
55
|
-
|
|
103
|
+
**Arguments:**
|
|
104
|
+
- `<section>` - Section ID (hero-centered, pricing-cards, etc.)
|
|
56
105
|
|
|
57
|
-
|
|
58
|
-
|
|
106
|
+
**Options:**
|
|
107
|
+
- `-s, --design-system <system>` - Design system (default: `material-design`)
|
|
108
|
+
- `-t, --tier <tier>` - Quality tier: basic, standard, enterprise (default: `standard`)
|
|
109
|
+
- `-o, --output <path>` - Output file path
|
|
59
110
|
|
|
60
|
-
|
|
61
|
-
|
|
111
|
+
**Available Sections (50 total)**:
|
|
112
|
+
- **Hero** (10): hero-centered, hero-split, hero-video-background, hero-gradient
|
|
113
|
+
- **Features** (8): features-grid, features-alternating, features-tabs
|
|
114
|
+
- **Testimonials** (6): testimonials-grid, testimonials-carousel, testimonials-wall
|
|
115
|
+
- **Pricing** (5): pricing-cards, pricing-table, pricing-toggle
|
|
116
|
+
- **CTA** (4): cta-centered, cta-split, cta-banner, cta-newsletter
|
|
117
|
+
- **FAQ** (3): faq-accordion, faq-two-column, faq-categorized
|
|
118
|
+
- **Team** (3): team-grid, team-carousel, team-leadership
|
|
119
|
+
- **Contact** (3): contact-form, contact-split, contact-info
|
|
120
|
+
- **Gallery** (3): gallery-masonry, gallery-grid, gallery-slider
|
|
121
|
+
- **Stats** (5): stats-numbers, stats-visual, stats-comparison
|
|
62
122
|
|
|
63
|
-
|
|
64
|
-
|
|
123
|
+
### `nikkory-vibe add:page` (alias: `page`)
|
|
124
|
+
|
|
125
|
+
Generate full pages with multi-section composition.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Basic usage
|
|
129
|
+
nikkory-vibe add:page landing
|
|
130
|
+
|
|
131
|
+
# With design system and tier
|
|
132
|
+
nikkory-vibe add:page dashboard -s ios-hig -t enterprise
|
|
133
|
+
|
|
134
|
+
# With custom output path
|
|
135
|
+
nikkory-vibe add:page auth -o src/pages/AuthPage.tsx
|
|
65
136
|
```
|
|
66
137
|
|
|
67
138
|
**Arguments:**
|
|
68
|
-
-
|
|
139
|
+
- `<page>` - Page ID (landing, dashboard, auth, etc.)
|
|
69
140
|
|
|
70
141
|
**Options:**
|
|
71
|
-
- `-
|
|
72
|
-
- `-t, --
|
|
73
|
-
- `-d, --design <system>` - Design system (default: material-design)
|
|
74
|
-
- `--tier <tier>` - Quality tier (basic, standard, enterprise) - default: standard
|
|
75
|
-
- `-f, --framework <framework>` - Framework (react, vue, etc.) - default: react
|
|
142
|
+
- `-s, --design-system <system>` - Design system (default: `material-design`)
|
|
143
|
+
- `-t, --tier <tier>` - Quality tier: basic, standard, enterprise (default: `standard`)
|
|
76
144
|
- `-o, --output <path>` - Output file path
|
|
77
|
-
- `--dry-run` - Preview generated code without writing
|
|
78
|
-
- `--interactive` - Interactive mode with prompts
|
|
79
145
|
|
|
80
|
-
|
|
146
|
+
**Page Types**:
|
|
147
|
+
- **Marketing**: landing, pricing, about
|
|
148
|
+
- **App**: dashboard, settings, profile
|
|
149
|
+
- **Auth**: login, signup, forgot-password
|
|
150
|
+
- **E-commerce**: product, cart, checkout
|
|
151
|
+
|
|
152
|
+
### `nikkory-vibe list` (alias: `ls`)
|
|
81
153
|
|
|
82
|
-
List available templates
|
|
154
|
+
List available templates, design systems, and tiers.
|
|
83
155
|
|
|
84
156
|
```bash
|
|
85
157
|
# List everything
|
|
86
|
-
vibe list
|
|
158
|
+
nikkory-vibe list
|
|
87
159
|
|
|
88
160
|
# List specific category
|
|
89
|
-
vibe list
|
|
90
|
-
vibe list
|
|
91
|
-
vibe list
|
|
92
|
-
vibe list
|
|
161
|
+
nikkory-vibe list components
|
|
162
|
+
nikkory-vibe list sections
|
|
163
|
+
nikkory-vibe list design-systems
|
|
164
|
+
nikkory-vibe list tiers
|
|
93
165
|
|
|
94
166
|
# JSON output
|
|
95
|
-
vibe list --json
|
|
167
|
+
nikkory-vibe list --json
|
|
96
168
|
```
|
|
97
169
|
|
|
98
170
|
**Arguments:**
|
|
99
|
-
- `[category]` - Category to list (
|
|
171
|
+
- `[category]` - Category to list (components, sections, design-systems, tiers, all)
|
|
100
172
|
|
|
101
173
|
**Options:**
|
|
102
174
|
- `--json` - Output as JSON
|
|
103
175
|
|
|
104
|
-
|
|
176
|
+
### `nikkory-vibe init`
|
|
105
177
|
|
|
106
|
-
|
|
178
|
+
Initialize a new Nikkory Vibe project with AI Agent Inspector.
|
|
107
179
|
|
|
108
180
|
```bash
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
181
|
+
# Basic usage
|
|
182
|
+
nikkory-vibe init my-app
|
|
183
|
+
|
|
184
|
+
# With options
|
|
185
|
+
nikkory-vibe init my-app --framework react --design material-design
|
|
113
186
|
```
|
|
114
187
|
|
|
115
|
-
|
|
188
|
+
**Arguments:**
|
|
189
|
+
- `[project-name]` - Project name (optional)
|
|
116
190
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
191
|
+
**Options:**
|
|
192
|
+
- `-f, --framework <framework>` - Frontend framework (react, vue, angular)
|
|
193
|
+
- `-d, --design <system>` - Default design system
|
|
194
|
+
- `--no-install` - Skip dependency installation
|
|
195
|
+
|
|
196
|
+
## Design Systems (12 available)
|
|
197
|
+
|
|
198
|
+
| Design System | ID | Description |
|
|
199
|
+
| ---------------- | ---------------- | -------------------------------- |
|
|
200
|
+
| Material Design | `material-design`| Google's design language |
|
|
201
|
+
| iOS HIG | `ios-hig` | Apple Human Interface Guidelines |
|
|
202
|
+
| Glassmorphism | `glassmorphism` | Frosted glass effect |
|
|
203
|
+
| Neumorphism | `neumorphism` | Soft UI with shadows |
|
|
204
|
+
| Brutalism | `brutalism` | Bold, raw aesthetic |
|
|
205
|
+
| Minimalism | `minimalism` | Clean, simple design |
|
|
206
|
+
| Fluent | `fluent` | Microsoft Fluent Design |
|
|
207
|
+
| Carbon | `carbon` | IBM Carbon Design System |
|
|
208
|
+
| Ant Design | `ant-design` | Ant Design (Alibaba) |
|
|
209
|
+
| Chakra | `chakra` | Chakra UI style |
|
|
210
|
+
| Atlassian | `atlassian` | Atlassian Design System |
|
|
211
|
+
| Blueprint | `blueprint` | Palantir Blueprint |
|
|
212
|
+
|
|
213
|
+
## Quality Tiers
|
|
214
|
+
|
|
215
|
+
| Tier | Purpose | Features | LOC |
|
|
216
|
+
| ---------- | ---------------- | ------------------------------------------- | ------- |
|
|
217
|
+
| Basic | Prototype, MVP | Core props, basic styling | 30-50 |
|
|
218
|
+
| Standard | Production apps | Multiple variants, sizes, forwardRef | 50-150 |
|
|
219
|
+
| Enterprise | Mission-critical | Analytics, memoization, accessibility, ARIA | 150-300 |
|
|
220
|
+
|
|
221
|
+
## Examples
|
|
123
222
|
|
|
124
|
-
###
|
|
223
|
+
### Generate a Material Design Button (Standard Tier)
|
|
125
224
|
|
|
126
225
|
```bash
|
|
127
|
-
vibe
|
|
226
|
+
nikkory-vibe add button -s material-design -t standard
|
|
128
227
|
```
|
|
129
228
|
|
|
130
|
-
|
|
131
|
-
-
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
229
|
+
**Output**:
|
|
230
|
+
- Full React component with forwardRef, displayName
|
|
231
|
+
- Multiple variants (filled, outlined, text)
|
|
232
|
+
- Sizes (sm, md, lg)
|
|
233
|
+
- TypeScript types
|
|
234
|
+
- ~150 lines of code
|
|
136
235
|
|
|
137
|
-
###
|
|
236
|
+
### Generate a Hero Section (Enterprise Tier)
|
|
138
237
|
|
|
139
238
|
```bash
|
|
140
|
-
vibe
|
|
239
|
+
nikkory-vibe add:section hero-centered -s ios-hig -t enterprise
|
|
141
240
|
```
|
|
142
241
|
|
|
143
|
-
|
|
242
|
+
**Output**:
|
|
243
|
+
- Composed section with multiple components (heading, text, buttons, image)
|
|
244
|
+
- Analytics tracking
|
|
245
|
+
- ARIA attributes
|
|
246
|
+
- Memoized components
|
|
247
|
+
- ~400+ lines of code
|
|
248
|
+
|
|
249
|
+
### Generate a Complete Landing Page
|
|
144
250
|
|
|
145
251
|
```bash
|
|
146
|
-
vibe
|
|
147
|
-
--framework react \
|
|
148
|
-
--design material-design \
|
|
149
|
-
--backend
|
|
252
|
+
nikkory-vibe add:page landing -s glassmorphism -t enterprise -o src/pages/Landing.tsx
|
|
150
253
|
```
|
|
151
254
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
-
|
|
157
|
-
- `card` - Content container cards
|
|
158
|
-
- `input` - Form input fields
|
|
159
|
-
- `modal` - Dialog/modal overlays
|
|
160
|
-
- `table` - Data tables
|
|
161
|
-
- `form` - Form layouts
|
|
162
|
-
- `navigation` - Nav bars and menus
|
|
163
|
-
- `hero` - Hero sections
|
|
164
|
-
- `feature` - Feature showcases
|
|
165
|
-
- `pricing` - Pricing tables
|
|
255
|
+
**Output**:
|
|
256
|
+
- Multi-section composition (hero + features + pricing + testimonials + CTA)
|
|
257
|
+
- Consistent design system across all sections
|
|
258
|
+
- All components automatically generated
|
|
259
|
+
- ~1000+ lines of production-ready code
|
|
166
260
|
|
|
167
|
-
###
|
|
261
|
+
### Generate with Custom Factors
|
|
168
262
|
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
- `retro` - Vintage aesthetics
|
|
263
|
+
```bash
|
|
264
|
+
nikkory-vibe add button --factor-overrides '{
|
|
265
|
+
"borderRadius": "rounded-full",
|
|
266
|
+
"shadowIntensity": "high",
|
|
267
|
+
"animation": "enabled"
|
|
268
|
+
}'
|
|
269
|
+
```
|
|
177
270
|
|
|
178
|
-
|
|
271
|
+
## Architecture
|
|
179
272
|
|
|
180
|
-
|
|
181
|
-
- `standard` - Production-ready (~200 LOC)
|
|
182
|
-
- `enterprise` - Mission-critical (~350 LOC)
|
|
273
|
+
### 3-Level Generation System
|
|
183
274
|
|
|
184
|
-
|
|
275
|
+
```
|
|
276
|
+
Page (7 factors)
|
|
277
|
+
↓ Factor Propagation
|
|
278
|
+
Section (13 factors)
|
|
279
|
+
↓ Factor Propagation
|
|
280
|
+
Component (24 factors)
|
|
281
|
+
```
|
|
185
282
|
|
|
186
|
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
190
|
-
-
|
|
283
|
+
**Component Level**: 24-factor matrix system
|
|
284
|
+
- Typography (4): font family, size, weight, line height
|
|
285
|
+
- Colors (3): primary, background, border
|
|
286
|
+
- Spacing (3): padding, margin, gap
|
|
287
|
+
- Effects (3): shadow, border radius, animation
|
|
288
|
+
- Layout (2): alignment, direction
|
|
289
|
+
- Interaction (3): hover, focus, active states
|
|
290
|
+
- Accessibility (2): ARIA, keyboard navigation
|
|
291
|
+
- Performance (2): lazy loading, memoization
|
|
292
|
+
- Analytics (2): tracking, events
|
|
293
|
+
|
|
294
|
+
**Section Level**: Slot-based composition
|
|
295
|
+
- Section factors (13) + inherited component factors (24)
|
|
296
|
+
- Automatic component generation for each slot
|
|
297
|
+
- CSS variable merging
|
|
298
|
+
- Layout wrapper generation
|
|
299
|
+
|
|
300
|
+
**Page Level**: Multi-section composition
|
|
301
|
+
- Page factors (7) + propagated section/component factors
|
|
302
|
+
- Parallel section generation
|
|
303
|
+
- Unified design system
|
|
304
|
+
- Complete page structure
|
|
191
305
|
|
|
192
306
|
## Configuration
|
|
193
307
|
|
|
@@ -197,54 +311,56 @@ Create `.viberc.json` in your project root:
|
|
|
197
311
|
{
|
|
198
312
|
"defaultDesignSystem": "material-design",
|
|
199
313
|
"defaultTier": "standard",
|
|
200
|
-
"
|
|
201
|
-
"outputDir": "src/components",
|
|
202
|
-
"fileExtension": "tsx"
|
|
314
|
+
"outputDir": "src/components"
|
|
203
315
|
}
|
|
204
316
|
```
|
|
205
317
|
|
|
206
|
-
##
|
|
318
|
+
## Statistics
|
|
207
319
|
|
|
208
|
-
-
|
|
209
|
-
-
|
|
320
|
+
- **169 Components** × 12 Design Systems × 3 Tiers = **6,084 variations**
|
|
321
|
+
- **50 Sections** × 12 Design Systems × 3 Tiers = **1,800 variations**
|
|
322
|
+
- **∞ Pages** (multi-section composition with infinite possibilities)
|
|
210
323
|
|
|
211
|
-
##
|
|
324
|
+
## CLI Shortcuts
|
|
212
325
|
|
|
213
|
-
|
|
326
|
+
You can use `vibe` as a shorter alias for `nikkory-vibe`:
|
|
214
327
|
|
|
215
328
|
```bash
|
|
216
|
-
|
|
217
|
-
|
|
329
|
+
# These are equivalent
|
|
330
|
+
nikkory-vibe add button
|
|
331
|
+
vibe add button
|
|
218
332
|
|
|
219
|
-
|
|
333
|
+
# Section generation
|
|
334
|
+
vibe add:section hero-centered
|
|
335
|
+
vibe section hero-centered
|
|
220
336
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
vibe
|
|
337
|
+
# Page generation
|
|
338
|
+
vibe add:page landing
|
|
339
|
+
vibe page landing
|
|
224
340
|
```
|
|
225
341
|
|
|
226
|
-
|
|
342
|
+
## Integration
|
|
227
343
|
|
|
228
|
-
|
|
344
|
+
### With React Projects
|
|
229
345
|
|
|
230
346
|
```bash
|
|
231
|
-
|
|
232
|
-
pnpm add -D @
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
## CLI Output
|
|
347
|
+
# Install CLI
|
|
348
|
+
pnpm add -D @nikkory/vibe-cli
|
|
236
349
|
|
|
237
|
-
|
|
350
|
+
# Add to package.json scripts
|
|
351
|
+
{
|
|
352
|
+
"scripts": {
|
|
353
|
+
"vibe": "nikkory-vibe",
|
|
354
|
+
"vibe:add": "nikkory-vibe add",
|
|
355
|
+
"vibe:section": "nikkory-vibe add:section"
|
|
356
|
+
}
|
|
357
|
+
}
|
|
238
358
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
- ℹ Blue info messages
|
|
243
|
-
- Spinners for loading states
|
|
244
|
-
- Boxed success messages
|
|
245
|
-
- Formatted tables
|
|
359
|
+
# Use in your project
|
|
360
|
+
pnpm vibe add button -o src/components/Button.tsx
|
|
361
|
+
```
|
|
246
362
|
|
|
247
|
-
|
|
363
|
+
### With VSCode
|
|
248
364
|
|
|
249
365
|
Install the Nikkory Vibe VSCode extension for:
|
|
250
366
|
- Command palette integration
|
|
@@ -252,10 +368,17 @@ Install the Nikkory Vibe VSCode extension for:
|
|
|
252
368
|
- Template preview
|
|
253
369
|
- Syntax highlighting
|
|
254
370
|
|
|
371
|
+
## Support
|
|
372
|
+
|
|
373
|
+
- **Website**: https://nikkory.com
|
|
374
|
+
- **Issues**: [GitHub Issues](https://github.com/kemonra/nikkory-vibe/issues)
|
|
375
|
+
- **Documentation**: [Full Docs](https://nikkory.com/docs)
|
|
376
|
+
|
|
255
377
|
## License
|
|
256
378
|
|
|
257
379
|
MIT
|
|
258
380
|
|
|
259
381
|
---
|
|
260
382
|
|
|
261
|
-
Powered by Nikkory
|
|
383
|
+
**Powered by Nikkory**
|
|
384
|
+
https://nikkory.com
|
package/dist/index.js
CHANGED
|
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
|
-
var
|
|
28
|
-
var
|
|
27
|
+
var import_commander6 = require("commander");
|
|
28
|
+
var import_chalk5 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// src/commands/init.ts
|
|
31
31
|
var fs = __toESM(require("fs/promises"));
|
|
@@ -1060,11 +1060,515 @@ var matrixGenerateCommand = new import_commander3.Command("add").alias("gen").al
|
|
|
1060
1060
|
}
|
|
1061
1061
|
});
|
|
1062
1062
|
|
|
1063
|
+
// src/commands/section-generate.ts
|
|
1064
|
+
var import_commander4 = require("commander");
|
|
1065
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
1066
|
+
var import_ora3 = __toESM(require("ora"));
|
|
1067
|
+
|
|
1068
|
+
// src/generators/section-generator.ts
|
|
1069
|
+
var path3 = __toESM(require("path"));
|
|
1070
|
+
|
|
1071
|
+
// src/generators/matrix-engine.ts
|
|
1072
|
+
var fs2 = __toESM(require("fs/promises"));
|
|
1073
|
+
var path2 = __toESM(require("path"));
|
|
1074
|
+
var import_handlebars = __toESM(require("handlebars"));
|
|
1075
|
+
var MatrixEngine = class {
|
|
1076
|
+
handlebars;
|
|
1077
|
+
constructor() {
|
|
1078
|
+
this.handlebars = import_handlebars.default.create();
|
|
1079
|
+
this.registerHelpers();
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Register Handlebars helpers for conditional logic
|
|
1083
|
+
*/
|
|
1084
|
+
registerHelpers() {
|
|
1085
|
+
this.handlebars.registerHelper("eq", (a, b) => a === b);
|
|
1086
|
+
this.handlebars.registerHelper("ne", (a, b) => a !== b);
|
|
1087
|
+
this.handlebars.registerHelper("or", (...args) => {
|
|
1088
|
+
const _options = args[args.length - 1];
|
|
1089
|
+
return args.slice(0, -1).some(Boolean);
|
|
1090
|
+
});
|
|
1091
|
+
this.handlebars.registerHelper("and", (...args) => {
|
|
1092
|
+
const _options = args[args.length - 1];
|
|
1093
|
+
return args.slice(0, -1).every(Boolean);
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Load matrix configuration from config.json
|
|
1098
|
+
*
|
|
1099
|
+
* @param templateDir - Path to template directory
|
|
1100
|
+
* @returns Matrix configuration
|
|
1101
|
+
* @throws Error if config.json not found or invalid
|
|
1102
|
+
*/
|
|
1103
|
+
async loadConfig(templateDir) {
|
|
1104
|
+
const configPath = path2.join(templateDir, "config.json");
|
|
1105
|
+
try {
|
|
1106
|
+
const content = await fs2.readFile(configPath, "utf-8");
|
|
1107
|
+
const config = JSON.parse(content);
|
|
1108
|
+
if (!config.templateName || !config.dimensions || !config.variables) {
|
|
1109
|
+
throw new Error("Invalid matrix config: missing required fields");
|
|
1110
|
+
}
|
|
1111
|
+
return config;
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
if (error.code === "ENOENT") {
|
|
1114
|
+
throw new Error(`Matrix config not found: ${configPath}`);
|
|
1115
|
+
}
|
|
1116
|
+
throw new Error(`Failed to load matrix config: ${error.message}`);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Validate dimension values against configuration
|
|
1121
|
+
*
|
|
1122
|
+
* @param dimensions - Dimension values to validate
|
|
1123
|
+
* @param config - Matrix configuration
|
|
1124
|
+
* @throws Error if invalid dimension values
|
|
1125
|
+
*/
|
|
1126
|
+
validateDimensions(dimensions, config) {
|
|
1127
|
+
for (const [dimName, dimValue] of Object.entries(dimensions)) {
|
|
1128
|
+
const dimDef = config.dimensions[dimName];
|
|
1129
|
+
if (!dimDef) {
|
|
1130
|
+
throw new Error(`Unknown dimension: ${dimName}`);
|
|
1131
|
+
}
|
|
1132
|
+
if (!dimDef.values.includes(dimValue)) {
|
|
1133
|
+
throw new Error(
|
|
1134
|
+
`Invalid value "${dimValue}" for dimension "${dimName}". Valid values: ${dimDef.values.join(", ")}`
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Validate variable values against configuration
|
|
1141
|
+
*
|
|
1142
|
+
* @param variables - Variable values to validate
|
|
1143
|
+
* @param config - Matrix configuration
|
|
1144
|
+
* @throws Error if required variables missing
|
|
1145
|
+
*/
|
|
1146
|
+
validateVariables(variables, config) {
|
|
1147
|
+
for (const [varName, varDef] of Object.entries(config.variables)) {
|
|
1148
|
+
if (varDef.required && !varDef.auto && !variables[varName]) {
|
|
1149
|
+
throw new Error(`Required variable missing: ${varName}`);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Apply defaults to dimensions
|
|
1155
|
+
*
|
|
1156
|
+
* @param dimensions - User-provided dimension values
|
|
1157
|
+
* @param config - Matrix configuration
|
|
1158
|
+
* @returns Dimensions with defaults applied
|
|
1159
|
+
*/
|
|
1160
|
+
applyDimensionDefaults(dimensions, config) {
|
|
1161
|
+
const result = { ...dimensions };
|
|
1162
|
+
for (const [dimName, dimDef] of Object.entries(config.dimensions)) {
|
|
1163
|
+
if (!result[dimName] && dimDef.default) {
|
|
1164
|
+
result[dimName] = dimDef.default;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return result;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Apply auto-filled variables (timestamp, templateVersion)
|
|
1171
|
+
*
|
|
1172
|
+
* @param variables - User-provided variables
|
|
1173
|
+
* @param config - Matrix configuration
|
|
1174
|
+
* @returns Variables with auto-filled values
|
|
1175
|
+
*/
|
|
1176
|
+
applyAutoVariables(variables, config) {
|
|
1177
|
+
const result = { ...variables };
|
|
1178
|
+
for (const [varName, varDef] of Object.entries(config.variables)) {
|
|
1179
|
+
if (varDef.auto) {
|
|
1180
|
+
if (varName === "timestamp") {
|
|
1181
|
+
result[varName] = (/* @__PURE__ */ new Date()).toISOString();
|
|
1182
|
+
} else if (varName === "templateVersion" && varDef.value) {
|
|
1183
|
+
result[varName] = varDef.value;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
return result;
|
|
1188
|
+
}
|
|
1189
|
+
/**
|
|
1190
|
+
* Determine which template file to use based on quality tier
|
|
1191
|
+
*
|
|
1192
|
+
* @param qualityTier - Quality tier (basic, standard, enterprise)
|
|
1193
|
+
* @param config - Matrix configuration
|
|
1194
|
+
* @returns Template definition
|
|
1195
|
+
* @throws Error if template not found
|
|
1196
|
+
*/
|
|
1197
|
+
selectTemplate(qualityTier, config) {
|
|
1198
|
+
const template = config.templates[qualityTier];
|
|
1199
|
+
if (!template) {
|
|
1200
|
+
throw new Error(`No template found for quality tier: ${qualityTier}`);
|
|
1201
|
+
}
|
|
1202
|
+
return template;
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Read and compile template file
|
|
1206
|
+
*
|
|
1207
|
+
* @param templateDir - Template directory path
|
|
1208
|
+
* @param templateFile - Template filename
|
|
1209
|
+
* @returns Compiled Handlebars template
|
|
1210
|
+
*/
|
|
1211
|
+
async compileTemplate(templateDir, templateFile) {
|
|
1212
|
+
const templatePath = path2.join(templateDir, templateFile);
|
|
1213
|
+
try {
|
|
1214
|
+
const content = await fs2.readFile(templatePath, "utf-8");
|
|
1215
|
+
return this.handlebars.compile(content);
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
throw new Error(`Failed to read template ${templateFile}: ${error.message}`);
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Generate code from template
|
|
1222
|
+
*
|
|
1223
|
+
* @param genConfig - Generation configuration
|
|
1224
|
+
* @returns Generation result with all files
|
|
1225
|
+
*/
|
|
1226
|
+
async generate(genConfig) {
|
|
1227
|
+
try {
|
|
1228
|
+
const config = await this.loadConfig(genConfig.templateDir);
|
|
1229
|
+
const dimensions = this.applyDimensionDefaults(genConfig.dimensions, config);
|
|
1230
|
+
this.validateDimensions(dimensions, config);
|
|
1231
|
+
const variables = this.applyAutoVariables(genConfig.variables, config);
|
|
1232
|
+
this.validateVariables(variables, config);
|
|
1233
|
+
const qualityTier = dimensions.qualityTier || "enterprise";
|
|
1234
|
+
const template = this.selectTemplate(qualityTier, config);
|
|
1235
|
+
const context = {
|
|
1236
|
+
...variables,
|
|
1237
|
+
...dimensions
|
|
1238
|
+
};
|
|
1239
|
+
const componentTemplate = await this.compileTemplate(
|
|
1240
|
+
genConfig.templateDir,
|
|
1241
|
+
template.file
|
|
1242
|
+
);
|
|
1243
|
+
const componentContent = componentTemplate(context);
|
|
1244
|
+
const files = [];
|
|
1245
|
+
const componentOutputDef = config.output.component;
|
|
1246
|
+
const componentFilename = this.handlebars.compile(componentOutputDef.pattern)(context);
|
|
1247
|
+
const componentPath = path2.join(
|
|
1248
|
+
genConfig.outputDir || componentOutputDef.path,
|
|
1249
|
+
componentFilename
|
|
1250
|
+
);
|
|
1251
|
+
files.push({
|
|
1252
|
+
type: "component",
|
|
1253
|
+
path: componentPath,
|
|
1254
|
+
content: componentContent,
|
|
1255
|
+
template: template.file
|
|
1256
|
+
});
|
|
1257
|
+
if (config.templates.types) {
|
|
1258
|
+
const typesTemplate = await this.compileTemplate(
|
|
1259
|
+
genConfig.templateDir,
|
|
1260
|
+
config.templates.types.file
|
|
1261
|
+
);
|
|
1262
|
+
const typesContent = typesTemplate(context);
|
|
1263
|
+
const typesOutputDef = config.output.types;
|
|
1264
|
+
const typesFilename = this.handlebars.compile(typesOutputDef.pattern)(context);
|
|
1265
|
+
const typesPath = path2.join(
|
|
1266
|
+
genConfig.outputDir || typesOutputDef.path,
|
|
1267
|
+
typesFilename
|
|
1268
|
+
);
|
|
1269
|
+
files.push({
|
|
1270
|
+
type: "types",
|
|
1271
|
+
path: typesPath,
|
|
1272
|
+
content: typesContent,
|
|
1273
|
+
template: config.templates.types.file
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
if (config.templates.test) {
|
|
1277
|
+
const testTemplate = await this.compileTemplate(
|
|
1278
|
+
genConfig.templateDir,
|
|
1279
|
+
config.templates.test.file
|
|
1280
|
+
);
|
|
1281
|
+
const testContent = testTemplate(context);
|
|
1282
|
+
const testOutputDef = config.output.test;
|
|
1283
|
+
const testFilename = this.handlebars.compile(testOutputDef.pattern)(context);
|
|
1284
|
+
const testPath = path2.join(
|
|
1285
|
+
genConfig.outputDir || testOutputDef.path,
|
|
1286
|
+
testFilename
|
|
1287
|
+
);
|
|
1288
|
+
files.push({
|
|
1289
|
+
type: "test",
|
|
1290
|
+
path: testPath,
|
|
1291
|
+
content: testContent,
|
|
1292
|
+
template: config.templates.test.file
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
return {
|
|
1296
|
+
success: true,
|
|
1297
|
+
files,
|
|
1298
|
+
config,
|
|
1299
|
+
metadata: {
|
|
1300
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1301
|
+
dimensions,
|
|
1302
|
+
variables
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
} catch (error) {
|
|
1306
|
+
return {
|
|
1307
|
+
success: false,
|
|
1308
|
+
files: [],
|
|
1309
|
+
error: error.message,
|
|
1310
|
+
config: {},
|
|
1311
|
+
metadata: {
|
|
1312
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1313
|
+
dimensions: genConfig.dimensions,
|
|
1314
|
+
variables: genConfig.variables
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Write generated files to disk
|
|
1321
|
+
*
|
|
1322
|
+
* @param result - Generation result
|
|
1323
|
+
* @returns Array of written file paths
|
|
1324
|
+
*/
|
|
1325
|
+
async writeFiles(result) {
|
|
1326
|
+
if (!result.success) {
|
|
1327
|
+
throw new Error(`Cannot write files: ${result.error}`);
|
|
1328
|
+
}
|
|
1329
|
+
const writtenPaths = [];
|
|
1330
|
+
for (const file of result.files) {
|
|
1331
|
+
const dir = path2.dirname(file.path);
|
|
1332
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
1333
|
+
await fs2.writeFile(file.path, file.content, "utf-8");
|
|
1334
|
+
writtenPaths.push(file.path);
|
|
1335
|
+
}
|
|
1336
|
+
return writtenPaths;
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1340
|
+
// src/generators/section-generator.ts
|
|
1341
|
+
var SectionGenerator = class {
|
|
1342
|
+
engine;
|
|
1343
|
+
templateDir;
|
|
1344
|
+
constructor(templateDir) {
|
|
1345
|
+
this.engine = new MatrixEngine();
|
|
1346
|
+
this.templateDir = templateDir || path3.join(process.cwd(), ".claude", "templates", "settings-section");
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Generate settings section component
|
|
1350
|
+
*
|
|
1351
|
+
* @param options - Section generation options
|
|
1352
|
+
* @returns Generation result
|
|
1353
|
+
*/
|
|
1354
|
+
async generate(options) {
|
|
1355
|
+
const dimensions = {
|
|
1356
|
+
sectionType: options.sectionType,
|
|
1357
|
+
dataPattern: options.dataPattern || "global-inheritance",
|
|
1358
|
+
uiComplexity: options.uiComplexity || "medium",
|
|
1359
|
+
qualityTier: options.qualityTier || "enterprise",
|
|
1360
|
+
framework: options.framework || "react"
|
|
1361
|
+
};
|
|
1362
|
+
const variables = {
|
|
1363
|
+
SectionName: options.sectionName,
|
|
1364
|
+
SectionTitle: options.sectionTitle,
|
|
1365
|
+
Icon: options.icon,
|
|
1366
|
+
DataType: options.dataType,
|
|
1367
|
+
apiMethod: options.apiMethod,
|
|
1368
|
+
saveMethod: options.saveMethod,
|
|
1369
|
+
sectionName: this.toKebabCase(options.sectionName),
|
|
1370
|
+
...options.additionalVariables
|
|
1371
|
+
};
|
|
1372
|
+
const genConfig = {
|
|
1373
|
+
templateDir: this.templateDir,
|
|
1374
|
+
dimensions,
|
|
1375
|
+
variables,
|
|
1376
|
+
outputDir: options.outputDir
|
|
1377
|
+
};
|
|
1378
|
+
return await this.engine.generate(genConfig);
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Write generated files to disk
|
|
1382
|
+
*
|
|
1383
|
+
* @param result - Generation result
|
|
1384
|
+
* @returns Array of written file paths
|
|
1385
|
+
*/
|
|
1386
|
+
async write(result) {
|
|
1387
|
+
return await this.engine.writeFiles(result);
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Convert PascalCase to kebab-case
|
|
1391
|
+
*
|
|
1392
|
+
* @param str - PascalCase string
|
|
1393
|
+
* @returns kebab-case string
|
|
1394
|
+
*
|
|
1395
|
+
* @example
|
|
1396
|
+
* ```typescript
|
|
1397
|
+
* toKebabCase('AIProviderSettings') // 'ai-provider-settings'
|
|
1398
|
+
* ```
|
|
1399
|
+
*/
|
|
1400
|
+
toKebabCase(str) {
|
|
1401
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
// src/commands/section-generate.ts
|
|
1406
|
+
var sectionGenerateCommand = new import_commander4.Command("add:section").alias("section").description("Add/Generate section using Orchestrator (50 sections, composition-based)").argument("<section>", "Section ID (e.g., hero-centered, pricing-cards)").option(
|
|
1407
|
+
"-s, --design-system <system>",
|
|
1408
|
+
"Design system (material-design, ios-hig, glassmorphism, neumorphism, brutalism, minimalism, fluent, carbon, ant-design, chakra, atlassian, blueprint)",
|
|
1409
|
+
"material-design"
|
|
1410
|
+
).option(
|
|
1411
|
+
"-t, --tier <tier>",
|
|
1412
|
+
"Quality tier (basic, standard, enterprise)",
|
|
1413
|
+
"standard"
|
|
1414
|
+
).option(
|
|
1415
|
+
"-o, --output <path>",
|
|
1416
|
+
"Output file path"
|
|
1417
|
+
).action(async (sectionId, options) => {
|
|
1418
|
+
const spinner = (0, import_ora3.default)("Generating section...").start();
|
|
1419
|
+
try {
|
|
1420
|
+
const generator = new SectionGenerator();
|
|
1421
|
+
const result = await generator.generate({
|
|
1422
|
+
sectionId,
|
|
1423
|
+
designSystem: options.designSystem,
|
|
1424
|
+
tier: options.tier
|
|
1425
|
+
});
|
|
1426
|
+
if (!result.success) {
|
|
1427
|
+
spinner.fail(import_chalk3.default.red("Section generation failed"));
|
|
1428
|
+
result.errors.forEach((error) => {
|
|
1429
|
+
console.error(import_chalk3.default.gray(` \u2022 ${error}`));
|
|
1430
|
+
});
|
|
1431
|
+
process.exit(1);
|
|
1432
|
+
}
|
|
1433
|
+
if (options.output) {
|
|
1434
|
+
await generator.writeToFile(options.output, result.composedCode);
|
|
1435
|
+
spinner.succeed(import_chalk3.default.green(`Generated ${result.metadata.sectionId} \u2192 ${options.output}`));
|
|
1436
|
+
} else {
|
|
1437
|
+
spinner.succeed(import_chalk3.default.green(`Generated ${result.metadata.sectionId}`));
|
|
1438
|
+
console.log(result.composedCode);
|
|
1439
|
+
}
|
|
1440
|
+
console.log(import_chalk3.default.cyan("\nSection Info:"));
|
|
1441
|
+
console.log(` ${import_chalk3.default.gray("ID:")} ${result.metadata.sectionId}`);
|
|
1442
|
+
console.log(` ${import_chalk3.default.gray("Type:")} ${result.metadata.sectionType}`);
|
|
1443
|
+
console.log(` ${import_chalk3.default.gray("Tier:")} ${result.metadata.tier}`);
|
|
1444
|
+
console.log(` ${import_chalk3.default.gray("Design System:")} ${result.metadata.designSystem}`);
|
|
1445
|
+
console.log(` ${import_chalk3.default.gray("Components:")} ${result.metadata.componentsGenerated}`);
|
|
1446
|
+
console.log(` ${import_chalk3.default.gray("Lines of Code:")} ${result.metadata.totalLinesOfCode}`);
|
|
1447
|
+
console.log("");
|
|
1448
|
+
} catch (error) {
|
|
1449
|
+
spinner.fail(import_chalk3.default.red(`Error: ${error.message}`));
|
|
1450
|
+
process.exit(1);
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
|
|
1454
|
+
// src/commands/page-generate.ts
|
|
1455
|
+
var import_commander5 = require("commander");
|
|
1456
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
1457
|
+
var import_ora4 = __toESM(require("ora"));
|
|
1458
|
+
|
|
1459
|
+
// src/generators/page-generator.ts
|
|
1460
|
+
var path4 = __toESM(require("path"));
|
|
1461
|
+
var PageGenerator = class {
|
|
1462
|
+
engine;
|
|
1463
|
+
templateDir;
|
|
1464
|
+
constructor(templateDir) {
|
|
1465
|
+
this.engine = new MatrixEngine();
|
|
1466
|
+
this.templateDir = templateDir || path4.join(process.cwd(), ".claude", "templates", "page");
|
|
1467
|
+
}
|
|
1468
|
+
/**
|
|
1469
|
+
* Generate page component
|
|
1470
|
+
*
|
|
1471
|
+
* @param options - Page generation options
|
|
1472
|
+
* @returns Generation result
|
|
1473
|
+
*/
|
|
1474
|
+
async generate(options) {
|
|
1475
|
+
const dimensions = {
|
|
1476
|
+
pageType: options.pageType,
|
|
1477
|
+
qualityTier: options.qualityTier || "enterprise",
|
|
1478
|
+
framework: options.framework || "react"
|
|
1479
|
+
};
|
|
1480
|
+
const variables = {
|
|
1481
|
+
PageName: options.pageName,
|
|
1482
|
+
PageTitle: options.pageTitle,
|
|
1483
|
+
PageDescription: options.pageDescription || "",
|
|
1484
|
+
pageName: this.toKebabCase(options.pageName),
|
|
1485
|
+
sectionsArray: JSON.stringify(options.sections || []),
|
|
1486
|
+
...options.additionalVariables
|
|
1487
|
+
};
|
|
1488
|
+
const genConfig = {
|
|
1489
|
+
templateDir: this.templateDir,
|
|
1490
|
+
dimensions,
|
|
1491
|
+
variables,
|
|
1492
|
+
outputDir: options.outputDir
|
|
1493
|
+
};
|
|
1494
|
+
return await this.engine.generate(genConfig);
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* Write generated files to disk
|
|
1498
|
+
*
|
|
1499
|
+
* @param result - Generation result
|
|
1500
|
+
* @returns Array of written file paths
|
|
1501
|
+
*/
|
|
1502
|
+
async write(result) {
|
|
1503
|
+
return await this.engine.writeFiles(result);
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Convert PascalCase to kebab-case
|
|
1507
|
+
*
|
|
1508
|
+
* @param str - PascalCase string
|
|
1509
|
+
* @returns kebab-case string
|
|
1510
|
+
*/
|
|
1511
|
+
toKebabCase(str) {
|
|
1512
|
+
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
// src/commands/page-generate.ts
|
|
1517
|
+
var pageGenerateCommand = new import_commander5.Command("add:page").alias("page").description("Add/Generate full page (multi-section composition)").argument("<page>", "Page ID (e.g., landing, dashboard, auth)").option(
|
|
1518
|
+
"-s, --design-system <system>",
|
|
1519
|
+
"Design system (material-design, ios-hig, glassmorphism, neumorphism, brutalism, minimalism, fluent, carbon, ant-design, chakra, atlassian, blueprint)",
|
|
1520
|
+
"material-design"
|
|
1521
|
+
).option(
|
|
1522
|
+
"-t, --tier <tier>",
|
|
1523
|
+
"Quality tier (basic, standard, enterprise)",
|
|
1524
|
+
"standard"
|
|
1525
|
+
).option(
|
|
1526
|
+
"-o, --output <path>",
|
|
1527
|
+
"Output file path"
|
|
1528
|
+
).action(async (pageId, options) => {
|
|
1529
|
+
const spinner = (0, import_ora4.default)("Generating page...").start();
|
|
1530
|
+
try {
|
|
1531
|
+
const generator = new PageGenerator();
|
|
1532
|
+
const result = await generator.generate({
|
|
1533
|
+
pageId,
|
|
1534
|
+
designSystem: options.designSystem,
|
|
1535
|
+
tier: options.tier
|
|
1536
|
+
});
|
|
1537
|
+
if (!result.success) {
|
|
1538
|
+
spinner.fail(import_chalk4.default.red("Page generation failed"));
|
|
1539
|
+
result.errors.forEach((error) => {
|
|
1540
|
+
console.error(import_chalk4.default.gray(` \u2022 ${error}`));
|
|
1541
|
+
});
|
|
1542
|
+
process.exit(1);
|
|
1543
|
+
}
|
|
1544
|
+
if (options.output) {
|
|
1545
|
+
await generator.writeToFile(options.output, result.composedCode);
|
|
1546
|
+
spinner.succeed(import_chalk4.default.green(`Generated ${result.metadata.pageId} \u2192 ${options.output}`));
|
|
1547
|
+
} else {
|
|
1548
|
+
spinner.succeed(import_chalk4.default.green(`Generated ${result.metadata.pageId}`));
|
|
1549
|
+
console.log(result.composedCode);
|
|
1550
|
+
}
|
|
1551
|
+
console.log(import_chalk4.default.cyan("\nPage Info:"));
|
|
1552
|
+
console.log(` ${import_chalk4.default.gray("ID:")} ${result.metadata.pageId}`);
|
|
1553
|
+
console.log(` ${import_chalk4.default.gray("Type:")} ${result.metadata.pageType}`);
|
|
1554
|
+
console.log(` ${import_chalk4.default.gray("Tier:")} ${result.metadata.tier}`);
|
|
1555
|
+
console.log(` ${import_chalk4.default.gray("Design System:")} ${result.metadata.designSystem}`);
|
|
1556
|
+
console.log(` ${import_chalk4.default.gray("Sections:")} ${result.metadata.sectionsGenerated}`);
|
|
1557
|
+
console.log(` ${import_chalk4.default.gray("Components:")} ${result.metadata.componentsGenerated}`);
|
|
1558
|
+
console.log(` ${import_chalk4.default.gray("Lines of Code:")} ${result.metadata.totalLinesOfCode}`);
|
|
1559
|
+
console.log("");
|
|
1560
|
+
} catch (error) {
|
|
1561
|
+
spinner.fail(import_chalk4.default.red(`Error: ${error.message}`));
|
|
1562
|
+
process.exit(1);
|
|
1563
|
+
}
|
|
1564
|
+
});
|
|
1565
|
+
|
|
1063
1566
|
// src/index.ts
|
|
1064
1567
|
var componentCount = 169;
|
|
1568
|
+
var sectionCount = 50;
|
|
1065
1569
|
var designSystemCount = 12;
|
|
1066
1570
|
var tierCount = 3;
|
|
1067
|
-
var y =
|
|
1571
|
+
var y = import_chalk5.default.hex("#fcb800");
|
|
1068
1572
|
var banner = `
|
|
1069
1573
|
${y.bold("\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557")}
|
|
1070
1574
|
${y.bold("\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D")}
|
|
@@ -1080,16 +1584,18 @@ ${y.bold(" \u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D\u2588\u
|
|
|
1080
1584
|
${y.bold(" \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 ")}
|
|
1081
1585
|
${y.bold(" \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D ")}
|
|
1082
1586
|
|
|
1083
|
-
${y(" happy together")} ${
|
|
1587
|
+
${y(" happy together")} ${import_chalk5.default.white("\u2022 v2.3.1")}
|
|
1084
1588
|
|
|
1085
|
-
${
|
|
1086
|
-
${
|
|
1589
|
+
${import_chalk5.default.gray(" Production-ready code in seconds")}
|
|
1590
|
+
${import_chalk5.default.gray(" https://nikkory.com")}
|
|
1087
1591
|
|
|
1088
|
-
${y(` ${componentCount} Components`)} ${
|
|
1592
|
+
${y(` ${componentCount} Components`)} ${import_chalk5.default.gray("+")} ${y(`${sectionCount} Sections`)} ${import_chalk5.default.gray("\xD7")} ${y(`${designSystemCount} Systems`)} ${import_chalk5.default.gray("\xD7")} ${y(`${tierCount} Tiers`)}
|
|
1089
1593
|
`;
|
|
1090
|
-
var program = new
|
|
1091
|
-
program.name("nikkory-vibe").description("Nikkory Vibe - Production-ready code in seconds").version("2.
|
|
1594
|
+
var program = new import_commander6.Command();
|
|
1595
|
+
program.name("nikkory-vibe").description("Nikkory Vibe - Production-ready code in seconds").version("2.3.1").addHelpText("before", banner);
|
|
1092
1596
|
program.addCommand(matrixGenerateCommand);
|
|
1597
|
+
program.addCommand(sectionGenerateCommand);
|
|
1598
|
+
program.addCommand(pageGenerateCommand);
|
|
1093
1599
|
program.addCommand(listCommand);
|
|
1094
1600
|
program.addCommand(initCommand);
|
|
1095
1601
|
program.parse(process.argv);
|