@vudovn/ag-kit 1.0.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/LICENSE +21 -0
- package/README.md +0 -0
- package/bin/index.js +294 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Do Van Vu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
Binary file
|
package/bin/index.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import { downloadTemplate } from 'giget';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import readline from 'readline';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
// Get package.json for version
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// CONSTANTS
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
const REPO = 'github:vudovn/antigravity-kit';
|
|
22
|
+
const AGENT_FOLDER = '.agent';
|
|
23
|
+
const TEMP_FOLDER = '.temp_ag_kit';
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// UTILITIES
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Display ASCII banner
|
|
31
|
+
* @param {boolean} quiet - Skip banner if true
|
|
32
|
+
*/
|
|
33
|
+
const showBanner = (quiet = false) => {
|
|
34
|
+
if (quiet) return;
|
|
35
|
+
console.log(chalk.blueBright(`
|
|
36
|
+
╔══════════════════════════════════════╗
|
|
37
|
+
║ ANTIGRAVITY KIT CLI ║
|
|
38
|
+
╚══════════════════════════════════════╝
|
|
39
|
+
`));
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Log message if not in quiet mode
|
|
44
|
+
* @param {string} message - Message to log
|
|
45
|
+
* @param {boolean} quiet - Skip logging if true
|
|
46
|
+
*/
|
|
47
|
+
const log = (message, quiet = false) => {
|
|
48
|
+
if (!quiet) console.log(message);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Ask user for confirmation
|
|
53
|
+
* @param {string} question - Question to ask
|
|
54
|
+
* @returns {Promise<boolean>}
|
|
55
|
+
*/
|
|
56
|
+
const confirm = (question) => {
|
|
57
|
+
const rl = readline.createInterface({
|
|
58
|
+
input: process.stdin,
|
|
59
|
+
output: process.stdout,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return new Promise((resolve) => {
|
|
63
|
+
rl.question(chalk.yellow(`${question} (y/N): `), (answer) => {
|
|
64
|
+
rl.close();
|
|
65
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Clean up temporary directory
|
|
72
|
+
* @param {string} tempDir - Temp directory path
|
|
73
|
+
*/
|
|
74
|
+
const cleanup = (tempDir) => {
|
|
75
|
+
if (fs.existsSync(tempDir)) {
|
|
76
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Copy .agent folder from temp to destination
|
|
82
|
+
* @param {string} tempDir - Temp directory
|
|
83
|
+
* @param {string} destDir - Destination directory
|
|
84
|
+
*/
|
|
85
|
+
const copyAgentFolder = (tempDir, destDir) => {
|
|
86
|
+
const sourceAgent = path.join(tempDir, AGENT_FOLDER);
|
|
87
|
+
|
|
88
|
+
if (!fs.existsSync(sourceAgent)) {
|
|
89
|
+
throw new Error(`Could not find ${AGENT_FOLDER} folder in source repository!`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fs.cpSync(sourceAgent, destDir, { recursive: true });
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// COMMANDS
|
|
98
|
+
// ============================================================================
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Initialize .agent folder in project
|
|
102
|
+
*/
|
|
103
|
+
const initCommand = async (options) => {
|
|
104
|
+
const quiet = options.quiet || false;
|
|
105
|
+
const dryRun = options.dryRun || false;
|
|
106
|
+
|
|
107
|
+
showBanner(quiet);
|
|
108
|
+
|
|
109
|
+
const targetDir = path.resolve(options.path || process.cwd());
|
|
110
|
+
const tempDir = path.join(targetDir, TEMP_FOLDER);
|
|
111
|
+
const agentDir = path.join(targetDir, AGENT_FOLDER);
|
|
112
|
+
|
|
113
|
+
// Dry run mode - show what would be done
|
|
114
|
+
if (dryRun) {
|
|
115
|
+
console.log(chalk.blueBright('\n[Dry Run] No changes will be made\n'));
|
|
116
|
+
console.log(chalk.white('Would perform the following actions:'));
|
|
117
|
+
console.log(chalk.gray('────────────────────────────────────────'));
|
|
118
|
+
console.log(` 1. Download from: ${chalk.cyan(REPO)}${options.branch ? `#${options.branch}` : ''}`);
|
|
119
|
+
console.log(` 2. Install to: ${chalk.cyan(agentDir)}`);
|
|
120
|
+
if (fs.existsSync(agentDir)) {
|
|
121
|
+
console.log(` 3. ${chalk.yellow('Overwrite existing .agent folder')}`);
|
|
122
|
+
}
|
|
123
|
+
console.log(chalk.gray('────────────────────────────────────────\n'));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Check if .agent already exists
|
|
128
|
+
if (fs.existsSync(agentDir)) {
|
|
129
|
+
if (!options.force) {
|
|
130
|
+
log(chalk.yellow(`Warning: Folder ${AGENT_FOLDER} already exists at: ${agentDir}`), quiet);
|
|
131
|
+
const shouldOverwrite = await confirm('Do you want to overwrite it?');
|
|
132
|
+
|
|
133
|
+
if (!shouldOverwrite) {
|
|
134
|
+
log(chalk.gray('Operation cancelled.'), quiet);
|
|
135
|
+
process.exit(0);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
log(chalk.gray(`Overwriting ${AGENT_FOLDER} folder...`), quiet);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const spinner = quiet ? null : ora({
|
|
142
|
+
text: 'Downloading...',
|
|
143
|
+
color: 'cyan',
|
|
144
|
+
}).start();
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
// Download repository using giget
|
|
148
|
+
const repoSource = options.branch ? `${REPO}#${options.branch}` : REPO;
|
|
149
|
+
await downloadTemplate(repoSource, {
|
|
150
|
+
dir: tempDir,
|
|
151
|
+
force: true,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
if (spinner) spinner.text = 'Installing...';
|
|
155
|
+
|
|
156
|
+
// Delete old .agent folder if exists (always clean install)
|
|
157
|
+
if (fs.existsSync(agentDir)) {
|
|
158
|
+
fs.rmSync(agentDir, { recursive: true, force: true });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Copy .agent folder
|
|
162
|
+
copyAgentFolder(tempDir, agentDir);
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
// Cleanup
|
|
166
|
+
cleanup(tempDir);
|
|
167
|
+
|
|
168
|
+
if (spinner) {
|
|
169
|
+
spinner.succeed(chalk.green('Installation successful!'));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Success message
|
|
173
|
+
if (!quiet) {
|
|
174
|
+
console.log(chalk.gray('\n────────────────────────────────────────'));
|
|
175
|
+
console.log(chalk.white('Result:'));
|
|
176
|
+
console.log(` ${chalk.cyan(AGENT_FOLDER)} → ${chalk.gray(agentDir)}`);
|
|
177
|
+
console.log(chalk.gray('────────────────────────────────────────'));
|
|
178
|
+
console.log(chalk.green('\nHappy coding!\n'));
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
if (spinner) {
|
|
182
|
+
spinner.fail(chalk.red(`Error: ${error.message}`));
|
|
183
|
+
} else {
|
|
184
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
185
|
+
}
|
|
186
|
+
cleanup(tempDir);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Update existing .agent folder
|
|
193
|
+
*/
|
|
194
|
+
const updateCommand = async (options) => {
|
|
195
|
+
const quiet = options.quiet || false;
|
|
196
|
+
|
|
197
|
+
showBanner(quiet);
|
|
198
|
+
|
|
199
|
+
const targetDir = path.resolve(options.path || process.cwd());
|
|
200
|
+
const agentDir = path.join(targetDir, AGENT_FOLDER);
|
|
201
|
+
|
|
202
|
+
// Check if .agent exists
|
|
203
|
+
if (!fs.existsSync(agentDir)) {
|
|
204
|
+
console.log(chalk.red(`Error: Could not find ${AGENT_FOLDER} folder at: ${targetDir}`));
|
|
205
|
+
console.log(chalk.yellow(`Tip: Run ${chalk.cyan('ag-kit init')} to install first.`));
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!options.force && !quiet) {
|
|
210
|
+
log(chalk.yellow(`Warning: Update will overwrite the entire ${AGENT_FOLDER} folder`), quiet);
|
|
211
|
+
const shouldUpdate = await confirm('Are you sure you want to continue?');
|
|
212
|
+
|
|
213
|
+
if (!shouldUpdate) {
|
|
214
|
+
log(chalk.gray('Operation cancelled.'), quiet);
|
|
215
|
+
process.exit(0);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Call init with force option
|
|
220
|
+
await initCommand({ ...options, force: true });
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Show status of .agent folder
|
|
225
|
+
*/
|
|
226
|
+
const statusCommand = (options) => {
|
|
227
|
+
const targetDir = path.resolve(options.path || process.cwd());
|
|
228
|
+
const agentDir = path.join(targetDir, AGENT_FOLDER);
|
|
229
|
+
|
|
230
|
+
console.log(chalk.blueBright('\nAntigravity Kit Status\n'));
|
|
231
|
+
|
|
232
|
+
if (fs.existsSync(agentDir)) {
|
|
233
|
+
const stats = fs.statSync(agentDir);
|
|
234
|
+
const files = fs.readdirSync(agentDir, { recursive: true });
|
|
235
|
+
|
|
236
|
+
console.log(chalk.green('[OK] Installed'));
|
|
237
|
+
console.log(chalk.gray('────────────────────────────────────────'));
|
|
238
|
+
console.log(`Path: ${chalk.cyan(agentDir)}`);
|
|
239
|
+
console.log(`Modified: ${chalk.gray(stats.mtime.toLocaleString('en-US'))}`);
|
|
240
|
+
console.log(`Files: ${chalk.yellow(files.length)} items`);
|
|
241
|
+
console.log(chalk.gray('────────────────────────────────────────\n'));
|
|
242
|
+
} else {
|
|
243
|
+
console.log(chalk.red('[X] Not installed'));
|
|
244
|
+
console.log(chalk.yellow(`Run ${chalk.cyan('ag-kit init')} to install.\n`));
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// ============================================================================
|
|
249
|
+
// CLI DEFINITION
|
|
250
|
+
// ============================================================================
|
|
251
|
+
|
|
252
|
+
const program = new Command();
|
|
253
|
+
|
|
254
|
+
program
|
|
255
|
+
.name('ag-kit')
|
|
256
|
+
.description('CLI tool to install and manage Antigravity Kit')
|
|
257
|
+
.version(pkg.version, '-v, --version', 'Display version number');
|
|
258
|
+
|
|
259
|
+
// Command: init
|
|
260
|
+
program
|
|
261
|
+
.command('init')
|
|
262
|
+
.description('Install .agent folder into your project')
|
|
263
|
+
.option('-f, --force', 'Overwrite if folder already exists', false)
|
|
264
|
+
.option('-p, --path <dir>', 'Path to the project directory', process.cwd())
|
|
265
|
+
.option('-b, --branch <name>', 'Select repository branch')
|
|
266
|
+
.option('-q, --quiet', 'Suppress output (for CI/CD)', false)
|
|
267
|
+
.option('--dry-run', 'Show what would be done without executing', false)
|
|
268
|
+
.action(initCommand);
|
|
269
|
+
|
|
270
|
+
// Command: update
|
|
271
|
+
program
|
|
272
|
+
.command('update')
|
|
273
|
+
.description('Update .agent folder to the latest version')
|
|
274
|
+
.option('-f, --force', 'Skip confirmation prompt', false)
|
|
275
|
+
.option('-p, --path <dir>', 'Path to the project directory', process.cwd())
|
|
276
|
+
.option('-b, --branch <name>', 'Select repository branch')
|
|
277
|
+
.option('-q, --quiet', 'Suppress output (for CI/CD)', false)
|
|
278
|
+
.option('--dry-run', 'Show what would be done without executing', false)
|
|
279
|
+
.action(updateCommand);
|
|
280
|
+
|
|
281
|
+
// Command: status
|
|
282
|
+
program
|
|
283
|
+
.command('status')
|
|
284
|
+
.description('Check installation status')
|
|
285
|
+
.option('-p, --path <dir>', 'Path to the project directory', process.cwd())
|
|
286
|
+
.action(statusCommand);
|
|
287
|
+
|
|
288
|
+
// Parse arguments
|
|
289
|
+
program.parse(process.argv);
|
|
290
|
+
|
|
291
|
+
// Show help if no command provided
|
|
292
|
+
if (!process.argv.slice(2).length) {
|
|
293
|
+
program.outputHelp();
|
|
294
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vudovn/ag-kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool to install Antigravity Kit - AI Agent templates",
|
|
5
|
+
"main": "bin/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=18"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "node --test test/*.test.js"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"ag-kit": "bin/index.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/vudovn/ag-kit.git"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/vudovn/ag-kit#readme",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/vudovn/ag-kit/issues"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"antigravity",
|
|
29
|
+
"cli",
|
|
30
|
+
"ai",
|
|
31
|
+
"agent",
|
|
32
|
+
"gemini",
|
|
33
|
+
"skills"
|
|
34
|
+
],
|
|
35
|
+
"author": "Do Van Vu",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"chalk": "^5.6.2",
|
|
39
|
+
"commander": "^12.1.0",
|
|
40
|
+
"fs-extra": "^11.3.3",
|
|
41
|
+
"giget": "^2.0.0",
|
|
42
|
+
"ora": "^8.2.0"
|
|
43
|
+
}
|
|
44
|
+
}
|