grg-kit-cli 0.1.2 ā 0.2.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 +29 -11
- package/bin/grg.js +15 -2
- package/commands/interactive.js +223 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -11,22 +11,40 @@ npm install -g grg-kit-cli
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
#
|
|
15
|
-
grg
|
|
14
|
+
# Interactive mode (easiest way to get started)
|
|
15
|
+
grg
|
|
16
|
+
# or
|
|
17
|
+
grg interactive
|
|
18
|
+
grg i
|
|
19
|
+
|
|
20
|
+
# Or use direct commands
|
|
21
|
+
grg init # Initialize with theme
|
|
22
|
+
grg add theme:claude # Add specific resources
|
|
23
|
+
grg list # Browse available resources
|
|
24
|
+
```
|
|
16
25
|
|
|
17
|
-
|
|
18
|
-
grg init --theme claude
|
|
26
|
+
## Commands
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
grg list
|
|
28
|
+
### `grg` or `grg interactive` or `grg i`
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
grg
|
|
30
|
+
Interactive mode - browse and add resources with a guided interface.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
grg
|
|
34
|
+
grg interactive
|
|
35
|
+
grg i
|
|
27
36
|
```
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
**What it does:**
|
|
39
|
+
- Presents a simple menu to choose actions
|
|
40
|
+
- Browse resources with descriptions
|
|
41
|
+
- Select multiple examples at once
|
|
42
|
+
- Minimal surface area, focused experience
|
|
43
|
+
|
|
44
|
+
**Perfect for:**
|
|
45
|
+
- First-time users
|
|
46
|
+
- Exploring available resources
|
|
47
|
+
- Quick resource selection
|
|
30
48
|
|
|
31
49
|
### `grg init`
|
|
32
50
|
|
package/bin/grg.js
CHANGED
|
@@ -5,13 +5,21 @@ const { add } = require('../commands/add');
|
|
|
5
5
|
const { list } = require('../commands/list');
|
|
6
6
|
const { init } = require('../commands/init');
|
|
7
7
|
const { metadata } = require('../commands/metadata');
|
|
8
|
+
const { interactive } = require('../commands/interactive');
|
|
8
9
|
|
|
9
10
|
const program = new Command();
|
|
10
11
|
|
|
11
12
|
program
|
|
12
13
|
.name('grg')
|
|
13
14
|
.description('GRG Kit CLI - Pull themes, components, and examples into your Angular project')
|
|
14
|
-
.version('0.1.
|
|
15
|
+
.version('0.1.2');
|
|
16
|
+
|
|
17
|
+
// Interactive command (default if no args)
|
|
18
|
+
program
|
|
19
|
+
.command('interactive', { isDefault: false })
|
|
20
|
+
.alias('i')
|
|
21
|
+
.description('Interactive mode - browse and add resources with a guided interface')
|
|
22
|
+
.action(interactive);
|
|
15
23
|
|
|
16
24
|
// Init command
|
|
17
25
|
program
|
|
@@ -40,4 +48,9 @@ program
|
|
|
40
48
|
.option('-f, --format <type>', 'Output format (json, yaml)', 'json')
|
|
41
49
|
.action(metadata);
|
|
42
50
|
|
|
43
|
-
|
|
51
|
+
// If no command provided, run interactive mode
|
|
52
|
+
if (process.argv.length === 2) {
|
|
53
|
+
interactive();
|
|
54
|
+
} else {
|
|
55
|
+
program.parse();
|
|
56
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
const inquirer = require('inquirer');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const { RESOURCES } = require('../config/resources');
|
|
4
|
+
const { add } = require('./add');
|
|
5
|
+
const { init } = require('./init');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Interactive mode - minimal surface area, focused experience
|
|
9
|
+
*/
|
|
10
|
+
async function interactive() {
|
|
11
|
+
console.log(chalk.bold.cyan('\n⨠GRG Kit Interactive Mode\n'));
|
|
12
|
+
|
|
13
|
+
// Main menu - keep it simple
|
|
14
|
+
const { action } = await inquirer.prompt([
|
|
15
|
+
{
|
|
16
|
+
type: 'list',
|
|
17
|
+
name: 'action',
|
|
18
|
+
message: 'What would you like to do?',
|
|
19
|
+
choices: [
|
|
20
|
+
{ name: 'šØ Initialize with a theme', value: 'init' },
|
|
21
|
+
{ name: 'ā Add a resource', value: 'add' },
|
|
22
|
+
{ name: 'š Add examples', value: 'examples' },
|
|
23
|
+
{ name: 'ā Exit', value: 'exit' }
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
if (action === 'exit') {
|
|
29
|
+
console.log(chalk.gray('\nGoodbye! š\n'));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
switch (action) {
|
|
34
|
+
case 'init':
|
|
35
|
+
await interactiveInit();
|
|
36
|
+
break;
|
|
37
|
+
case 'add':
|
|
38
|
+
await interactiveAdd();
|
|
39
|
+
break;
|
|
40
|
+
case 'examples':
|
|
41
|
+
await interactiveExamples();
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Ask if they want to do more
|
|
46
|
+
const { more } = await inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'confirm',
|
|
49
|
+
name: 'more',
|
|
50
|
+
message: 'Would you like to do something else?',
|
|
51
|
+
default: false
|
|
52
|
+
}
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
if (more) {
|
|
56
|
+
await interactive();
|
|
57
|
+
} else {
|
|
58
|
+
console.log(chalk.gray('\nGoodbye! š\n'));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Interactive init - choose a theme
|
|
64
|
+
*/
|
|
65
|
+
async function interactiveInit() {
|
|
66
|
+
const themeChoices = RESOURCES.themes.map(theme => ({
|
|
67
|
+
name: `${theme.title} - ${chalk.gray(theme.description)}`,
|
|
68
|
+
value: theme.name,
|
|
69
|
+
short: theme.title
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
const { theme } = await inquirer.prompt([
|
|
73
|
+
{
|
|
74
|
+
type: 'list',
|
|
75
|
+
name: 'theme',
|
|
76
|
+
message: 'Choose a theme:',
|
|
77
|
+
choices: themeChoices,
|
|
78
|
+
pageSize: 10
|
|
79
|
+
}
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
await init({ theme });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Interactive add - choose category then resource
|
|
87
|
+
*/
|
|
88
|
+
async function interactiveAdd() {
|
|
89
|
+
const { category } = await inquirer.prompt([
|
|
90
|
+
{
|
|
91
|
+
type: 'list',
|
|
92
|
+
name: 'category',
|
|
93
|
+
message: 'What type of resource?',
|
|
94
|
+
choices: [
|
|
95
|
+
{ name: `šØ Theme (${RESOURCES.themes.length} available)`, value: 'theme' },
|
|
96
|
+
{ name: `š§© Component (${RESOURCES.components.length} available)`, value: 'component' },
|
|
97
|
+
{ name: `š Layout (${RESOURCES.layouts.length} available)`, value: 'layout' },
|
|
98
|
+
{ name: 'ā Back', value: 'back' }
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
if (category === 'back') {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let choices = [];
|
|
108
|
+
let resources = [];
|
|
109
|
+
|
|
110
|
+
switch (category) {
|
|
111
|
+
case 'theme':
|
|
112
|
+
resources = RESOURCES.themes;
|
|
113
|
+
break;
|
|
114
|
+
case 'component':
|
|
115
|
+
resources = RESOURCES.components;
|
|
116
|
+
break;
|
|
117
|
+
case 'layout':
|
|
118
|
+
resources = RESOURCES.layouts;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
choices = resources.map(resource => ({
|
|
123
|
+
name: `${resource.title} - ${chalk.gray(resource.description)}`,
|
|
124
|
+
value: resource.name,
|
|
125
|
+
short: resource.title
|
|
126
|
+
}));
|
|
127
|
+
|
|
128
|
+
const { resource } = await inquirer.prompt([
|
|
129
|
+
{
|
|
130
|
+
type: 'list',
|
|
131
|
+
name: 'resource',
|
|
132
|
+
message: `Choose a ${category}:`,
|
|
133
|
+
choices: [...choices, { name: 'ā Back', value: 'back' }],
|
|
134
|
+
pageSize: 10
|
|
135
|
+
}
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
if (resource === 'back') {
|
|
139
|
+
return interactiveAdd();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await add(`${category}:${resource}`, {});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Interactive examples - all or specific
|
|
147
|
+
*/
|
|
148
|
+
async function interactiveExamples() {
|
|
149
|
+
const { choice } = await inquirer.prompt([
|
|
150
|
+
{
|
|
151
|
+
type: 'list',
|
|
152
|
+
name: 'choice',
|
|
153
|
+
message: 'Which examples would you like?',
|
|
154
|
+
choices: [
|
|
155
|
+
{
|
|
156
|
+
name: `š¦ All examples (${RESOURCES.examples.components.length}+ components)`,
|
|
157
|
+
value: 'all'
|
|
158
|
+
},
|
|
159
|
+
{ name: 'š Choose specific examples', value: 'specific' },
|
|
160
|
+
{ name: 'ā Back', value: 'back' }
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
]);
|
|
164
|
+
|
|
165
|
+
if (choice === 'back') {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (choice === 'all') {
|
|
170
|
+
await add('examples:all', {});
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Specific examples - show popular ones first
|
|
175
|
+
const popularExamples = ['button', 'card', 'dialog', 'form-field', 'input', 'table'];
|
|
176
|
+
const otherExamples = RESOURCES.examples.components
|
|
177
|
+
.filter(ex => !popularExamples.includes(ex.name))
|
|
178
|
+
.map(ex => ex.name);
|
|
179
|
+
|
|
180
|
+
const choices = [
|
|
181
|
+
{ name: chalk.bold('Popular'), disabled: true },
|
|
182
|
+
...popularExamples.map(name => {
|
|
183
|
+
const ex = RESOURCES.examples.components.find(e => e.name === name);
|
|
184
|
+
return {
|
|
185
|
+
name: ` ${ex.title} - ${chalk.gray(ex.description)}`,
|
|
186
|
+
value: name,
|
|
187
|
+
short: ex.title
|
|
188
|
+
};
|
|
189
|
+
}),
|
|
190
|
+
{ name: chalk.bold('\nOther Components'), disabled: true },
|
|
191
|
+
...otherExamples.map(name => {
|
|
192
|
+
const ex = RESOURCES.examples.components.find(e => e.name === name);
|
|
193
|
+
return {
|
|
194
|
+
name: ` ${ex.title} - ${chalk.gray(ex.description)}`,
|
|
195
|
+
value: name,
|
|
196
|
+
short: ex.title
|
|
197
|
+
};
|
|
198
|
+
})
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
const { examples } = await inquirer.prompt([
|
|
202
|
+
{
|
|
203
|
+
type: 'checkbox',
|
|
204
|
+
name: 'examples',
|
|
205
|
+
message: 'Select examples (space to select, enter to confirm):',
|
|
206
|
+
choices,
|
|
207
|
+
pageSize: 15,
|
|
208
|
+
validate: (answer) => {
|
|
209
|
+
if (answer.length < 1) {
|
|
210
|
+
return 'You must choose at least one example.';
|
|
211
|
+
}
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
]);
|
|
216
|
+
|
|
217
|
+
// Add selected examples
|
|
218
|
+
for (const example of examples) {
|
|
219
|
+
await add(`examples:${example}`, {});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = { interactive };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "grg-kit-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI tool for pulling GRG Kit resources into your Angular project",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,9 +27,10 @@
|
|
|
27
27
|
"directory": "cli"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"chalk": "^4.1.2",
|
|
30
31
|
"commander": "^11.1.0",
|
|
31
32
|
"degit": "^2.8.4",
|
|
32
|
-
"
|
|
33
|
+
"inquirer": "^8.2.7",
|
|
33
34
|
"ora": "^5.4.1"
|
|
34
35
|
},
|
|
35
36
|
"engines": {
|