grg-kit-cli 0.6.10 ā 0.6.11
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 +51 -0
- package/bin/grg.js +9 -0
- package/commands/add.js +154 -1
- package/commands/init.js +39 -8
- package/commands/list.js +3 -3
- package/commands/llm-setup.js +4 -3
- package/config/.catalog-cache.json +1 -0
- package/package.json +1 -1
- package/scripts/generate-resources.js +10 -0
package/README.md
CHANGED
|
@@ -21,6 +21,10 @@ grg init
|
|
|
21
21
|
# Or with a specific theme
|
|
22
22
|
grg init --theme claude
|
|
23
23
|
|
|
24
|
+
# Add or switch theme
|
|
25
|
+
grg add theme claude
|
|
26
|
+
grg add theme modern-minimal
|
|
27
|
+
|
|
24
28
|
# Add blocks (all files)
|
|
25
29
|
grg add block auth
|
|
26
30
|
grg add block shell
|
|
@@ -32,10 +36,14 @@ grg add block shell sidebar
|
|
|
32
36
|
# Add all blocks
|
|
33
37
|
grg add block --all
|
|
34
38
|
|
|
39
|
+
# Add components
|
|
40
|
+
grg add component file-upload
|
|
41
|
+
|
|
35
42
|
# List available resources
|
|
36
43
|
grg list
|
|
37
44
|
grg list blocks
|
|
38
45
|
grg list themes
|
|
46
|
+
grg list components
|
|
39
47
|
```
|
|
40
48
|
|
|
41
49
|
## Commands
|
|
@@ -77,6 +85,25 @@ Examples:
|
|
|
77
85
|
- `amber-minimal` - Warm amber accents
|
|
78
86
|
- `mocks` - Theme for mockups and prototypes
|
|
79
87
|
|
|
88
|
+
### `grg add theme`
|
|
89
|
+
|
|
90
|
+
Add or switch theme in an existing project.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
grg add theme <themeName>
|
|
94
|
+
|
|
95
|
+
Options:
|
|
96
|
+
-o, --output <path> Custom themes directory (default: "src/themes")
|
|
97
|
+
|
|
98
|
+
Examples:
|
|
99
|
+
grg add theme claude # Download and set claude theme
|
|
100
|
+
grg add theme modern-minimal # Download and set modern-minimal
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**What it does:**
|
|
104
|
+
- Downloads the theme CSS file to `src/themes/`
|
|
105
|
+
- Updates `src/styles.css` to import the new theme (replaces existing theme import)
|
|
106
|
+
|
|
80
107
|
### `grg add block`
|
|
81
108
|
|
|
82
109
|
Add blocks or specific block files to your project.
|
|
@@ -97,6 +124,22 @@ Examples:
|
|
|
97
124
|
grg add block --all # All blocks
|
|
98
125
|
```
|
|
99
126
|
|
|
127
|
+
### `grg add component`
|
|
128
|
+
|
|
129
|
+
Add GRG Kit components to your project.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
grg add component <componentName>
|
|
133
|
+
|
|
134
|
+
Options:
|
|
135
|
+
--all Add all components
|
|
136
|
+
-o, --output <path> Custom output directory
|
|
137
|
+
|
|
138
|
+
Examples:
|
|
139
|
+
grg add component file-upload # Download file-upload component
|
|
140
|
+
grg add component --all # All components
|
|
141
|
+
```
|
|
142
|
+
|
|
100
143
|
**Available blocks and files:**
|
|
101
144
|
|
|
102
145
|
| Block | Files |
|
|
@@ -195,6 +238,10 @@ cd my-app
|
|
|
195
238
|
grg init # Default theme
|
|
196
239
|
grg init --theme claude # Custom theme
|
|
197
240
|
|
|
241
|
+
# Add/switch theme
|
|
242
|
+
grg add theme claude # Switch to claude theme
|
|
243
|
+
grg add theme modern-minimal # Switch to modern-minimal
|
|
244
|
+
|
|
198
245
|
# Add blocks (all files)
|
|
199
246
|
grg add block auth # All auth files
|
|
200
247
|
grg add block shell # All shell layouts
|
|
@@ -205,10 +252,14 @@ grg add block auth login # Just login
|
|
|
205
252
|
grg add block shell sidebar # Just sidebar shell
|
|
206
253
|
grg add block --all # All blocks
|
|
207
254
|
|
|
255
|
+
# Add components
|
|
256
|
+
grg add component file-upload # File upload component
|
|
257
|
+
|
|
208
258
|
# List resources
|
|
209
259
|
grg list # Overview
|
|
210
260
|
grg list blocks # Available blocks
|
|
211
261
|
grg list themes # Available themes
|
|
262
|
+
grg list components # Available components
|
|
212
263
|
|
|
213
264
|
# AI setup
|
|
214
265
|
grg llm-setup # Generate AI rules
|
package/bin/grg.js
CHANGED
|
@@ -41,6 +41,15 @@ addCommand
|
|
|
41
41
|
await addComponent(componentName, options);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
+
addCommand
|
|
45
|
+
.command('theme [themeName]')
|
|
46
|
+
.description('Add or switch theme (e.g., grg add theme claude)')
|
|
47
|
+
.option('-o, --output <path>', 'Custom themes directory', 'src/themes')
|
|
48
|
+
.action(async (themeName, options) => {
|
|
49
|
+
const { addTheme } = require('../commands/add');
|
|
50
|
+
await addTheme(themeName, options);
|
|
51
|
+
});
|
|
52
|
+
|
|
44
53
|
// List command
|
|
45
54
|
program
|
|
46
55
|
.command('list [category]')
|
package/commands/add.js
CHANGED
|
@@ -292,4 +292,157 @@ function showComponentUsage(RESOURCES) {
|
|
|
292
292
|
console.log(chalk.gray('\nRun'), chalk.cyan('grg list components'), chalk.gray('for more details'));
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
/**
|
|
296
|
+
* Add theme command - downloads and sets up a theme
|
|
297
|
+
* Format: grg add theme <themeName>
|
|
298
|
+
* Examples:
|
|
299
|
+
* grg add theme claude # Download and set claude theme
|
|
300
|
+
* grg add theme modern-minimal # Download and set modern-minimal theme
|
|
301
|
+
*/
|
|
302
|
+
async function addTheme(themeName, options) {
|
|
303
|
+
// Fetch catalog dynamically (with caching)
|
|
304
|
+
const spinner = ora('Fetching catalog...').start();
|
|
305
|
+
const RESOURCES = await fetchCatalog({ silent: true });
|
|
306
|
+
spinner.stop();
|
|
307
|
+
|
|
308
|
+
// Validate theme name
|
|
309
|
+
if (!themeName) {
|
|
310
|
+
showThemeUsage(RESOURCES);
|
|
311
|
+
process.exit(1);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const theme = RESOURCES.themes.find(t => t.name === themeName);
|
|
315
|
+
if (!theme) {
|
|
316
|
+
console.error(chalk.red(`\nError: Theme "${themeName}" not found`));
|
|
317
|
+
console.log(chalk.yellow('\nAvailable themes:'));
|
|
318
|
+
RESOURCES.themes.forEach(t => {
|
|
319
|
+
console.log(chalk.cyan(` ${t.name}`), chalk.gray(`- ${t.description}`));
|
|
320
|
+
});
|
|
321
|
+
process.exit(1);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
await downloadTheme(theme, options.output);
|
|
325
|
+
console.log(chalk.bold.green('⨠Done!'));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Download a theme file
|
|
330
|
+
*/
|
|
331
|
+
async function downloadTheme(theme, customOutput) {
|
|
332
|
+
const downloadSpinner = ora();
|
|
333
|
+
const themesDir = customOutput || 'src/themes';
|
|
334
|
+
const outputPath = path.join(themesDir, theme.file);
|
|
335
|
+
|
|
336
|
+
// Ensure themes directory exists
|
|
337
|
+
await fs.mkdir(themesDir, { recursive: true });
|
|
338
|
+
|
|
339
|
+
downloadSpinner.start(`Downloading ${theme.title} theme...`);
|
|
340
|
+
|
|
341
|
+
try {
|
|
342
|
+
const themeUrl = `https://raw.githubusercontent.com/${REPO}/main/${theme.path}`;
|
|
343
|
+
await downloadFileToPath(themeUrl, outputPath);
|
|
344
|
+
|
|
345
|
+
downloadSpinner.succeed(chalk.green(`ā ${theme.title} theme downloaded`));
|
|
346
|
+
console.log(chalk.gray(` Location: ${outputPath}`));
|
|
347
|
+
|
|
348
|
+
} catch (error) {
|
|
349
|
+
downloadSpinner.fail(chalk.red(`Failed to download ${theme.title}`));
|
|
350
|
+
console.error(chalk.red(error.message));
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Update styles.css
|
|
355
|
+
downloadSpinner.start('Updating src/styles.css...');
|
|
356
|
+
try {
|
|
357
|
+
const stylesPath = 'src/styles.css';
|
|
358
|
+
let stylesContent = '';
|
|
359
|
+
|
|
360
|
+
try {
|
|
361
|
+
stylesContent = await fs.readFile(stylesPath, 'utf-8');
|
|
362
|
+
} catch (error) {
|
|
363
|
+
// File doesn't exist, will create it
|
|
364
|
+
stylesContent = '';
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const themeImport = `@import './themes/${theme.file}';`;
|
|
368
|
+
|
|
369
|
+
// Check if any theme is already imported
|
|
370
|
+
const themeImportRegex = /@import\s+['"]\.\/themes\/[^'"]+['"];?\n?/g;
|
|
371
|
+
const existingThemeImports = stylesContent.match(themeImportRegex);
|
|
372
|
+
|
|
373
|
+
if (existingThemeImports && existingThemeImports.length > 0) {
|
|
374
|
+
// Remove ALL existing theme imports first
|
|
375
|
+
stylesContent = stylesContent.replace(themeImportRegex, '');
|
|
376
|
+
// Clean up any resulting double blank lines
|
|
377
|
+
stylesContent = stylesContent.replace(/\n{3,}/g, '\n\n');
|
|
378
|
+
// Add the new theme import after the spartan preset import
|
|
379
|
+
const spartanImport = '@import "@spartan-ng/brain/hlm-tailwind-preset.css";';
|
|
380
|
+
if (stylesContent.includes(spartanImport)) {
|
|
381
|
+
stylesContent = stylesContent.replace(spartanImport, `${spartanImport}\n\n${themeImport}`);
|
|
382
|
+
} else {
|
|
383
|
+
// Fallback: add at the beginning
|
|
384
|
+
stylesContent = themeImport + '\n' + stylesContent;
|
|
385
|
+
}
|
|
386
|
+
await fs.writeFile(stylesPath, stylesContent);
|
|
387
|
+
downloadSpinner.succeed(chalk.green(`ā Updated theme import in src/styles.css`));
|
|
388
|
+
} else if (!stylesContent.includes(themeImport)) {
|
|
389
|
+
// No theme import exists, add required imports
|
|
390
|
+
const requiredImports = [
|
|
391
|
+
'@import "@angular/cdk/overlay-prebuilt.css";',
|
|
392
|
+
'@import "tailwindcss";',
|
|
393
|
+
'@import "@spartan-ng/brain/hlm-tailwind-preset.css";',
|
|
394
|
+
'',
|
|
395
|
+
themeImport
|
|
396
|
+
];
|
|
397
|
+
|
|
398
|
+
const newContent = requiredImports.join('\n') + '\n';
|
|
399
|
+
await fs.writeFile(stylesPath, newContent);
|
|
400
|
+
downloadSpinner.succeed(chalk.green('ā Created src/styles.css with theme import'));
|
|
401
|
+
} else {
|
|
402
|
+
downloadSpinner.succeed(chalk.green('ā Theme already imported in src/styles.css'));
|
|
403
|
+
}
|
|
404
|
+
} catch (error) {
|
|
405
|
+
downloadSpinner.warn(chalk.yellow('Could not update src/styles.css automatically'));
|
|
406
|
+
console.log(chalk.gray('\nPlease add the following to your src/styles.css:'));
|
|
407
|
+
console.log(chalk.cyan(` @import './themes/${theme.file}';`));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
console.log();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Download file to a specific path
|
|
415
|
+
*/
|
|
416
|
+
function downloadFileToPath(url, outputPath) {
|
|
417
|
+
return new Promise((resolve, reject) => {
|
|
418
|
+
https.get(url, (res) => {
|
|
419
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
420
|
+
// Follow redirect
|
|
421
|
+
https.get(res.headers.location, (res2) => {
|
|
422
|
+
handleResponse(res2, outputPath, resolve, reject);
|
|
423
|
+
}).on('error', reject);
|
|
424
|
+
} else {
|
|
425
|
+
handleResponse(res, outputPath, resolve, reject);
|
|
426
|
+
}
|
|
427
|
+
}).on('error', reject);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Show theme usage help
|
|
433
|
+
*/
|
|
434
|
+
function showThemeUsage(RESOURCES) {
|
|
435
|
+
console.log(chalk.yellow('\nUsage: grg add theme <themeName>\n'));
|
|
436
|
+
console.log(chalk.bold('Examples:'));
|
|
437
|
+
console.log(chalk.cyan(' grg add theme claude'), chalk.gray(' # Download and set claude theme'));
|
|
438
|
+
console.log(chalk.cyan(' grg add theme modern-minimal'), chalk.gray(' # Download and set modern-minimal'));
|
|
439
|
+
|
|
440
|
+
console.log(chalk.bold('\nAvailable themes:'));
|
|
441
|
+
RESOURCES.themes.forEach(t => {
|
|
442
|
+
console.log(chalk.cyan(` ${t.name}`), chalk.gray(`- ${t.description}`));
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
console.log(chalk.gray('\nRun'), chalk.cyan('grg list themes'), chalk.gray('for more details'));
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
module.exports = { add, addComponent, addTheme };
|
package/commands/init.js
CHANGED
|
@@ -2,6 +2,7 @@ const fs = require('fs').promises;
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { exec } = require('child_process');
|
|
4
4
|
const { promisify } = require('util');
|
|
5
|
+
const https = require('https');
|
|
5
6
|
const degit = require('degit');
|
|
6
7
|
const chalk = require('chalk');
|
|
7
8
|
const ora = require('ora');
|
|
@@ -9,6 +10,28 @@ const { RESOURCES, REPO } = require('../config/resources');
|
|
|
9
10
|
|
|
10
11
|
const execAsync = promisify(exec);
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Download a file from a URL
|
|
15
|
+
*/
|
|
16
|
+
function downloadFile(url) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
https.get(url, (res) => {
|
|
19
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
20
|
+
// Follow redirect
|
|
21
|
+
return downloadFile(res.headers.location).then(resolve).catch(reject);
|
|
22
|
+
}
|
|
23
|
+
if (res.statusCode !== 200) {
|
|
24
|
+
reject(new Error(`HTTP ${res.statusCode}`));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let data = '';
|
|
29
|
+
res.on('data', chunk => data += chunk);
|
|
30
|
+
res.on('end', () => resolve(data));
|
|
31
|
+
}).on('error', reject);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
12
35
|
/**
|
|
13
36
|
* Init command - initializes GRG Kit in an existing Angular project
|
|
14
37
|
* Installs Tailwind CSS v4, runs spartan-ng ui, downloads theme
|
|
@@ -45,7 +68,18 @@ async function init(options) {
|
|
|
45
68
|
console.log(chalk.bold.cyan('\nš Initializing GRG Kit\n'));
|
|
46
69
|
console.log(chalk.gray(` Theme: ${theme.title}\n`));
|
|
47
70
|
|
|
48
|
-
// Step 1:
|
|
71
|
+
// Step 1: Fresh install of packages
|
|
72
|
+
spinner.start('Cleaning node_modules and reinstalling packages...');
|
|
73
|
+
try {
|
|
74
|
+
await execAsync('rm -rf node_modules && npm install');
|
|
75
|
+
spinner.succeed(chalk.green('ā Fresh package install complete'));
|
|
76
|
+
} catch (error) {
|
|
77
|
+
spinner.fail(chalk.red('Failed to reinstall packages'));
|
|
78
|
+
console.error(chalk.gray(error.message));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Step 2: Install Tailwind CSS v4
|
|
49
83
|
spinner.start('Installing Tailwind CSS v4...');
|
|
50
84
|
try {
|
|
51
85
|
await execAsync('npm install tailwindcss @tailwindcss/postcss postcss --force');
|
|
@@ -227,15 +261,12 @@ async function init(options) {
|
|
|
227
261
|
spinner.warn(chalk.yellow('Themes directory may already exist'));
|
|
228
262
|
}
|
|
229
263
|
|
|
230
|
-
// Step 10: Download theme
|
|
264
|
+
// Step 10: Download theme file
|
|
231
265
|
spinner.start(`Downloading ${theme.title} theme...`);
|
|
232
266
|
try {
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
verbose: false,
|
|
237
|
-
});
|
|
238
|
-
await emitter.clone(theme.defaultOutput);
|
|
267
|
+
const themeUrl = `https://raw.githubusercontent.com/${REPO}/main/${theme.path}`;
|
|
268
|
+
const themeContent = await downloadFile(themeUrl);
|
|
269
|
+
await fs.writeFile(theme.defaultOutput, themeContent);
|
|
239
270
|
spinner.succeed(chalk.green(`ā Downloaded ${theme.title} theme`));
|
|
240
271
|
} catch (error) {
|
|
241
272
|
spinner.fail(chalk.red('Failed to download theme'));
|
package/commands/list.js
CHANGED
|
@@ -25,7 +25,7 @@ async function list(category) {
|
|
|
25
25
|
console.log(chalk.gray(' Run: grg list components\n'));
|
|
26
26
|
|
|
27
27
|
console.log(chalk.bold('Themes') + chalk.gray(` (${RESOURCES.themes.length} available)`));
|
|
28
|
-
console.log(chalk.gray('
|
|
28
|
+
console.log(chalk.gray(' Add with: grg add theme <name>'));
|
|
29
29
|
console.log(chalk.gray(' Run: grg list themes\n'));
|
|
30
30
|
|
|
31
31
|
return;
|
|
@@ -67,11 +67,11 @@ async function list(category) {
|
|
|
67
67
|
|
|
68
68
|
case 'themes':
|
|
69
69
|
console.log(chalk.bold.cyan('\nšØ Available Themes\n'));
|
|
70
|
-
console.log(chalk.gray(' Use with: grg
|
|
70
|
+
console.log(chalk.gray(' Use with: grg add theme <name>\n'));
|
|
71
71
|
RESOURCES.themes.forEach(theme => {
|
|
72
72
|
console.log(chalk.bold(` ${theme.name}`));
|
|
73
73
|
console.log(chalk.gray(` ${theme.description}`));
|
|
74
|
-
console.log(chalk.yellow(` grg
|
|
74
|
+
console.log(chalk.yellow(` grg add theme ${theme.name}`));
|
|
75
75
|
if (theme.tags && theme.tags.length > 0) {
|
|
76
76
|
console.log(chalk.gray(` Tags: ${theme.tags.join(', ')}`));
|
|
77
77
|
}
|
package/commands/llm-setup.js
CHANGED
|
@@ -861,10 +861,11 @@ AI Workflow:
|
|
|
861
861
|
1. mcp2_list_available_resources({ category: "themes" })
|
|
862
862
|
ā Show: claude, amber-minimal, etc.
|
|
863
863
|
|
|
864
|
-
2.
|
|
865
|
-
ā
|
|
864
|
+
2. mcp2_install_resource({ resource: "claude" })
|
|
865
|
+
ā Returns command: "grg add theme claude"
|
|
866
866
|
|
|
867
|
-
3.
|
|
867
|
+
3. Run the command via run_command tool
|
|
868
|
+
ā Theme is downloaded and styles.css is updated automatically
|
|
868
869
|
\`\`\`
|
|
869
870
|
|
|
870
871
|
### Example 4: User Wants a Form Component
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"timestamp":1765262345803,"data":{"themes":[{"name":"amber-minimal","title":"Amber Minimal","description":"Warm amber accents","file":"amber-minimal.css","tags":["minimal","warm","amber","orange"],"features":["dark-mode","tailwind-v4","spartan-ng","oklch"],"path":"templates/ui/themes/amber-minimal.css","defaultOutput":"src/themes/amber-minimal.css"},{"name":"claude","title":"Claude","description":"Claude-inspired warm tones","file":"claude.css","tags":["warm","orange","brown","claude"],"features":["dark-mode","tailwind-v4","spartan-ng","oklch"],"path":"templates/ui/themes/claude.css","defaultOutput":"src/themes/claude.css"},{"name":"clean-slate","title":"Clean Slate","description":"Minimal grayscale palette","file":"clean-slate.css","tags":["minimal","grayscale","neutral","clean"],"features":["dark-mode","tailwind-v4","spartan-ng","oklch"],"path":"templates/ui/themes/clean-slate.css","defaultOutput":"src/themes/clean-slate.css"},{"name":"grg-theme","title":"Grg Theme","description":"Default theme with purple/orange accents","file":"grg-theme.css","tags":["default","purple","orange","colorful"],"features":["dark-mode","tailwind-v4","spartan-ng","oklch"],"path":"templates/ui/themes/grg-theme.css","defaultOutput":"src/themes/grg-theme.css"},{"name":"mocks","title":"Mocks","description":"Theme for mockups and prototypes","file":"mocks.css","tags":["mockup","prototype","design"],"features":["dark-mode","tailwind-v4","spartan-ng","oklch"],"path":"templates/ui/themes/mocks.css","defaultOutput":"src/themes/mocks.css"},{"name":"modern-minimal","title":"Modern Minimal","description":"Contemporary minimal design","file":"modern-minimal.css","tags":["minimal","modern","contemporary","clean"],"features":["dark-mode","tailwind-v4","spartan-ng","oklch"],"path":"templates/ui/themes/modern-minimal.css","defaultOutput":"src/themes/modern-minimal.css"}],"components":[{"name":"file-upload","title":"File Upload","description":"Drag and drop file upload component","tags":["file","upload","form","drag-drop"],"dependencies":["@spartan-ng/helm/button"],"path":"templates/ui/components/file-upload","defaultOutput":"src/app/components/file-upload"}],"blocks":[{"name":"auth","title":"Auth","description":"Authentication pages (login, signup, forgot password)","tags":["auth","login","signup","authentication","form"],"dependencies":["@spartan-ng/helm/button","@spartan-ng/helm/card","@spartan-ng/helm/form-field"],"files":[{"id":"forgot-password","file":"forgot-password.component.ts","title":"Forgot Password","description":"Forgot Password"},{"id":"login","file":"login.component.ts","title":"Login","description":"Login"},{"id":"register","file":"register.component.ts","title":"Register","description":"Register"}],"path":"templates/ui/blocks/auth","defaultOutput":"src/app/blocks/auth"},{"name":"settings","title":"Settings","description":"Settings pages: profile, notifications, security, danger zone","tags":["settings","preferences","account","profile","security"],"dependencies":["@spartan-ng/helm/button","@spartan-ng/helm/card","@spartan-ng/helm/form-field","@spartan-ng/helm/switch"],"files":[{"id":"danger-zone","file":"danger-zone.component.ts","title":"Danger Zone","description":"Danger Zone"},{"id":"notification","file":"notification-settings.component.ts","title":"Notification Settings","description":"Notification Settings"},{"id":"profile","file":"profile-settings.component.ts","title":"Profile Settings","description":"Profile Settings"},{"id":"security","file":"security-settings.component.ts","title":"Security Settings","description":"Security Settings"}],"path":"templates/ui/blocks/settings","defaultOutput":"src/app/blocks/settings"},{"name":"shell","title":"Shell","description":"Application shell layouts: sidebar, topnav, collapsible - each with optional footer variant","tags":["shell","layout","sidebar","header","footer","navigation","topnav","collapsible"],"dependencies":["@spartan-ng/helm/button","@spartan-ng/helm/icon","@spartan-ng/helm/dropdown-menu"],"files":[{"id":"collapsible-footer","file":"collapsible-shell-footer.component.ts","title":"Collapsible Shell Footer","description":"Collapsible Shell Footer"},{"id":"collapsible","file":"collapsible-shell.component.ts","title":"Collapsible Shell","description":"Collapsible Shell"},{"id":"sidebar-footer","file":"sidebar-shell-footer.component.ts","title":"Sidebar Shell Footer","description":"Sidebar Shell Footer"},{"id":"sidebar","file":"sidebar-shell.component.ts","title":"Sidebar Shell","description":"Sidebar Shell"},{"id":"topnav-footer","file":"topnav-shell-footer.component.ts","title":"Topnav Shell Footer","description":"Topnav Shell Footer"},{"id":"topnav","file":"topnav-shell.component.ts","title":"Topnav Shell","description":"Topnav Shell"}],"path":"templates/ui/blocks/shell","defaultOutput":"src/app/blocks/shell"}]}}
|
package/package.json
CHANGED
|
@@ -314,11 +314,21 @@ module.exports = { RESOURCES, REPO };
|
|
|
314
314
|
description: 'Initialize GRG Kit in current Angular project',
|
|
315
315
|
themeFlag: '--theme'
|
|
316
316
|
},
|
|
317
|
+
addTheme: {
|
|
318
|
+
usage: 'grg add theme <themeName>',
|
|
319
|
+
description: 'Add or switch theme in existing project',
|
|
320
|
+
validThemes: catalogThemes.map(t => t.name)
|
|
321
|
+
},
|
|
317
322
|
addBlock: {
|
|
318
323
|
usage: 'grg add block <blockName> [fileIds...]',
|
|
319
324
|
description: 'Add blocks to your project',
|
|
320
325
|
validBlocks: catalogBlocks.map(b => b.name)
|
|
321
326
|
},
|
|
327
|
+
addComponent: {
|
|
328
|
+
usage: 'grg add component <componentName>',
|
|
329
|
+
description: 'Add GRG components to your project',
|
|
330
|
+
validComponents: catalogComponents.map(c => c.name)
|
|
331
|
+
},
|
|
322
332
|
list: {
|
|
323
333
|
usage: 'grg list [category]',
|
|
324
334
|
description: 'List available resources'
|