grg-kit-cli 0.2.0 ā 0.3.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 +86 -161
- package/bin/grg.js +21 -30
- package/commands/add.js +59 -101
- package/commands/init.js +55 -16
- package/commands/list.js +26 -58
- package/commands/llm-prompts.js +706 -0
- package/package.json +1 -1
- package/commands/interactive.js +0 -223
- package/commands/metadata.js +0 -122
package/commands/interactive.js
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
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/commands/metadata.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const { RESOURCES } = require('../config/resources');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Metadata command - outputs structured information about all commands and resources
|
|
6
|
-
* This is designed to be consumed by MCP servers and LLMs
|
|
7
|
-
*/
|
|
8
|
-
async function metadata(options) {
|
|
9
|
-
const format = options.format || 'json';
|
|
10
|
-
|
|
11
|
-
const commandMetadata = {
|
|
12
|
-
version: '0.1.0',
|
|
13
|
-
name: 'grg-kit-cli',
|
|
14
|
-
description: 'CLI tool for pulling GRG Kit resources into Angular projects',
|
|
15
|
-
repository: 'https://github.com/Genesis-Research/grg-kit',
|
|
16
|
-
commands: [
|
|
17
|
-
{
|
|
18
|
-
name: 'init',
|
|
19
|
-
description: 'Initialize GRG Kit in your Angular project with themes directory and configuration',
|
|
20
|
-
usage: 'grg init [options]',
|
|
21
|
-
options: [
|
|
22
|
-
{
|
|
23
|
-
flag: '-t, --theme <name>',
|
|
24
|
-
description: 'Theme to install',
|
|
25
|
-
default: 'grg-theme',
|
|
26
|
-
choices: ['grg-theme', 'claude', 'clean-slate', 'modern-minimal', 'amber-minimal', 'mocks']
|
|
27
|
-
}
|
|
28
|
-
],
|
|
29
|
-
examples: [
|
|
30
|
-
'grg init',
|
|
31
|
-
'grg init --theme claude',
|
|
32
|
-
'grg init -t modern-minimal'
|
|
33
|
-
],
|
|
34
|
-
effects: [
|
|
35
|
-
'Creates src/themes directory',
|
|
36
|
-
'Downloads selected theme file',
|
|
37
|
-
'Updates src/styles.css with theme import'
|
|
38
|
-
]
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: 'add',
|
|
42
|
-
description: 'Add a GRG Kit resource to your project',
|
|
43
|
-
usage: 'grg add <resource> [options]',
|
|
44
|
-
options: [
|
|
45
|
-
{
|
|
46
|
-
flag: '-o, --output <path>',
|
|
47
|
-
description: 'Output directory for the resource',
|
|
48
|
-
default: 'Auto-determined based on resource type'
|
|
49
|
-
}
|
|
50
|
-
],
|
|
51
|
-
examples: [
|
|
52
|
-
'grg add theme:claude',
|
|
53
|
-
'grg add component:stepper',
|
|
54
|
-
'grg add layout:dashboard',
|
|
55
|
-
'grg add examples:button',
|
|
56
|
-
'grg add examples:all'
|
|
57
|
-
],
|
|
58
|
-
resourceFormat: '<category>:<name>',
|
|
59
|
-
categories: ['theme', 'component', 'layout', 'examples'],
|
|
60
|
-
effects: [
|
|
61
|
-
'Downloads the specified resource',
|
|
62
|
-
'Places it in the appropriate directory'
|
|
63
|
-
]
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
name: 'list',
|
|
67
|
-
description: 'List available GRG Kit resources',
|
|
68
|
-
usage: 'grg list [category]',
|
|
69
|
-
examples: [
|
|
70
|
-
'grg list',
|
|
71
|
-
'grg list themes',
|
|
72
|
-
'grg list components',
|
|
73
|
-
'grg list layouts',
|
|
74
|
-
'grg list examples'
|
|
75
|
-
],
|
|
76
|
-
categories: ['themes', 'components', 'layouts', 'examples'],
|
|
77
|
-
effects: [
|
|
78
|
-
'Displays available resources in the specified category'
|
|
79
|
-
]
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: 'metadata',
|
|
83
|
-
description: 'Output structured metadata about all available commands and resources (for MCP servers)',
|
|
84
|
-
usage: 'grg metadata [options]',
|
|
85
|
-
options: [
|
|
86
|
-
{
|
|
87
|
-
flag: '-f, --format <type>',
|
|
88
|
-
description: 'Output format',
|
|
89
|
-
default: 'json',
|
|
90
|
-
choices: ['json', 'yaml']
|
|
91
|
-
}
|
|
92
|
-
],
|
|
93
|
-
examples: [
|
|
94
|
-
'grg metadata',
|
|
95
|
-
'grg metadata --format json'
|
|
96
|
-
],
|
|
97
|
-
effects: [
|
|
98
|
-
'Outputs structured metadata in specified format'
|
|
99
|
-
]
|
|
100
|
-
}
|
|
101
|
-
],
|
|
102
|
-
resources: RESOURCES
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
if (format === 'json') {
|
|
106
|
-
console.log(JSON.stringify(commandMetadata, null, 2));
|
|
107
|
-
} else if (format === 'yaml') {
|
|
108
|
-
// Simple YAML output (could use a library for more complex cases)
|
|
109
|
-
console.log('# GRG Kit CLI Metadata');
|
|
110
|
-
console.log(`version: ${commandMetadata.version}`);
|
|
111
|
-
console.log(`name: ${commandMetadata.name}`);
|
|
112
|
-
console.log(`description: ${commandMetadata.description}`);
|
|
113
|
-
console.log('\ncommands:');
|
|
114
|
-
commandMetadata.commands.forEach(cmd => {
|
|
115
|
-
console.log(` - name: ${cmd.name}`);
|
|
116
|
-
console.log(` description: ${cmd.description}`);
|
|
117
|
-
console.log(` usage: ${cmd.usage}`);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
module.exports = { metadata };
|