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 CHANGED
@@ -11,22 +11,40 @@ npm install -g grg-kit-cli
11
11
  ## Quick Start
12
12
 
13
13
  ```bash
14
- # Initialize GRG Kit with a theme
15
- grg init
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
- # Or choose a specific theme
18
- grg init --theme claude
26
+ ## Commands
19
27
 
20
- # List available resources
21
- grg list
28
+ ### `grg` or `grg interactive` or `grg i`
22
29
 
23
- # Add resources
24
- grg add theme:claude
25
- grg add component:stepper
26
- grg add examples:all
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
- ## Commands
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.0');
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
- program.parse();
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.1.2",
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
- "chalk": "^4.1.2",
33
+ "inquirer": "^8.2.7",
33
34
  "ora": "^5.4.1"
34
35
  },
35
36
  "engines": {