@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 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
+ }