anchi-toolkit 1.2.2 → 1.2.3

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.
Files changed (2) hide show
  1. package/dist/index.js +2709 -1
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1 +1,2709 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
+ /******/ var __webpack_modules__ = ({
3
+
4
+ /***/ 1:
5
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
6
+
7
+ // =============================================================================
8
+ // anchi-toolkit Clean Command
9
+ // Reset project context and logs
10
+ // =============================================================================
11
+
12
+ const fs = __nccwpck_require__(896);
13
+ const path = __nccwpck_require__(928);
14
+ const readline = __nccwpck_require__(785);
15
+ const { getConfigDir } = __nccwpck_require__(256);
16
+
17
+ const rl = readline.createInterface({
18
+ input: process.stdin,
19
+ output: process.stdout,
20
+ });
21
+
22
+ function ask(question) {
23
+ return new Promise((resolve) => {
24
+ rl.question(question, (answer) => {
25
+ resolve(answer);
26
+ });
27
+ });
28
+ }
29
+
30
+ async function clean(targetDir = process.cwd(), options = {}) {
31
+ console.log('');
32
+ console.log('🧹 anchi-toolkit Clean');
33
+ console.log('═══════════════════════════════════════════════════════════════');
34
+ console.log('');
35
+
36
+ const configDir = getConfigDir(targetDir);
37
+ const auditDir = path.join(configDir, '.ai-audit');
38
+ const memoryDir = path.join(configDir, '.ai-memory');
39
+
40
+ const cleanMemory = options.memory || options.all;
41
+ const cleanAudit = options.audit || options.all;
42
+ const isForce = options.force;
43
+
44
+ if (!cleanMemory && !cleanAudit) {
45
+ console.log('Usage:');
46
+ console.log(' npx anchi-toolkit clean --memory Clear AI context');
47
+ console.log(' npx anchi-toolkit clean --audit Clear logs');
48
+ console.log(' npx anchi-toolkit clean --all Clear everything');
49
+ rl.close();
50
+ return;
51
+ }
52
+
53
+ console.log('Checking targets:');
54
+ if (cleanMemory) console.log(` • Context Memory: ${memoryDir}`);
55
+ if (cleanAudit) console.log(` • Audit Logs: ${auditDir}`);
56
+ console.log('');
57
+
58
+ if (!isForce) {
59
+ const confirm = await ask('⚠️ Are you sure you want to delete these files? (Y/n): ');
60
+ if (confirm.toLowerCase() === 'n') {
61
+ console.log('❌ Cancelled.');
62
+ rl.close();
63
+ return;
64
+ }
65
+ }
66
+
67
+ if (cleanMemory) {
68
+ if (fs.existsSync(memoryDir)) {
69
+ // Keep the directory, just empty it or recreate it
70
+ fs.rmSync(memoryDir, { recursive: true, force: true });
71
+ fs.mkdirSync(memoryDir, { recursive: true });
72
+ console.log('✅ Memory cleared.');
73
+ } else {
74
+ console.log('⚪ Memory already clean.');
75
+ }
76
+ }
77
+
78
+ if (cleanAudit) {
79
+ if (fs.existsSync(auditDir)) {
80
+ fs.rmSync(auditDir, { recursive: true, force: true });
81
+ fs.mkdirSync(auditDir, { recursive: true });
82
+ console.log('✅ Audit logs cleared.');
83
+ } else {
84
+ console.log('⚪ Audit logs already clean.');
85
+ }
86
+ }
87
+
88
+ console.log('');
89
+ console.log('✨ Clean complete!');
90
+ rl.close();
91
+ }
92
+
93
+ module.exports = { clean };
94
+
95
+
96
+ /***/ }),
97
+
98
+ /***/ 181:
99
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
100
+
101
+ // =============================================================================
102
+ // anchi-toolkit Doctor Command
103
+ // Diagnose and check setup health
104
+ // =============================================================================
105
+
106
+ const fs = __nccwpck_require__(896);
107
+ const path = __nccwpck_require__(928);
108
+
109
+ async function doctor(targetDir = process.cwd()) {
110
+ console.log('');
111
+ console.log('🩺 anchi-toolkit Doctor');
112
+ console.log('═══════════════════════════════════════════════════════════════');
113
+ console.log('');
114
+
115
+ const checks = [];
116
+
117
+ const { getConfigDir, CONFIG_FILENAME } = __nccwpck_require__(256);
118
+ const configDir = getConfigDir(targetDir);
119
+ const configDirName = path.basename(configDir);
120
+
121
+ // Check config folder
122
+ checks.push({
123
+ name: `${configDirName} folder`,
124
+ ok: fs.existsSync(configDir),
125
+ fix: 'Run: npx anchi-toolkit init'
126
+ });
127
+
128
+ // Check commands
129
+ const commandsDir = path.join(configDir, (configDirName === '.antigravity' ? 'workflows' : 'commands'));
130
+ // Antigravity has workflows, Cursor has commands. Though user might want consistency?
131
+ // Wait, my ANTIGRAVITY.md says .antigravity/workflows.
132
+ // cli.js installs .antigravity/workflows.
133
+ // So if configDir is .antigravity, check workflows.
134
+ // If configDir is .cursor, check commands.
135
+ // Actually, cli.js installs 'workflows' into .antigravity.
136
+ // Let's check logic:
137
+ // If .antigravity install: src: .cursor/commands (*.md) -> target: .antigravity/workflows (*.md)
138
+ // If .cursor install: src: .cursor/commands -> target: .cursor/commands.
139
+
140
+ // I need to detect which folder to check based on configDirName.
141
+ let cmdFolderName = 'commands';
142
+ if (configDirName === '.antigravity') cmdFolderName = 'workflows';
143
+
144
+ const cmdDir = path.join(configDir, cmdFolderName);
145
+
146
+ const commandCount = fs.existsSync(cmdDir)
147
+ ? fs.readdirSync(cmdDir, { recursive: true }).filter(f => f.endsWith('.md')).length
148
+ : 0;
149
+ checks.push({
150
+ name: `Commands/Workflows (${cmdFolderName})`,
151
+ ok: commandCount > 0,
152
+ value: `${commandCount} files`,
153
+ fix: 'Run: npx anchi-toolkit install'
154
+ });
155
+
156
+ // Check agents
157
+ const agentsDir = path.join(configDir, 'agents');
158
+ const agentCount = fs.existsSync(agentsDir)
159
+ ? fs.readdirSync(agentsDir).filter(f => f.endsWith('.md')).length
160
+ : 0;
161
+ checks.push({
162
+ name: 'Agents',
163
+ ok: agentCount > 0,
164
+ value: `${agentCount} files`,
165
+ fix: 'Run: npx anchi-toolkit install'
166
+ });
167
+
168
+ // Check .cursorrules (Only for Cursor?)
169
+ if (configDirName === '.cursor') {
170
+ const rulesFile = path.join(targetDir, '.cursorrules');
171
+ checks.push({
172
+ name: '.cursorrules',
173
+ ok: fs.existsSync(rulesFile),
174
+ fix: 'Run: /use-preset [name]'
175
+ });
176
+ }
177
+
178
+ // Check config
179
+ const configFile = path.join(configDir, CONFIG_FILENAME);
180
+ let configValid = false;
181
+ if (fs.existsSync(configFile)) {
182
+ try {
183
+ const content = fs.readFileSync(configFile, 'utf-8');
184
+ // Basic YAML validation check
185
+ if (content.trim().length > 0) {
186
+ configValid = true;
187
+ // Try parsing if possible
188
+ try {
189
+ const { parseYaml } = __nccwpck_require__(256);
190
+ parseYaml(content);
191
+ } catch (e) {
192
+ configValid = false;
193
+ console.log(` ❌ Config syntax error: ${e.message}`);
194
+ }
195
+ }
196
+ } catch (e) {
197
+ configValid = false;
198
+ }
199
+ }
200
+ checks.push({
201
+ name: 'Config file syntax',
202
+ ok: configValid,
203
+ fix: 'Run: npx anchi-toolkit init (or fix YAML)'
204
+ });
205
+
206
+ // Check docs
207
+ const docsDir = path.join(configDir, 'docs');
208
+ checks.push({
209
+ name: 'Docs folder',
210
+ ok: fs.existsSync(docsDir),
211
+ fix: 'Run: npx anchi-toolkit install'
212
+ });
213
+
214
+ // Check package.json
215
+ const pkgFile = path.join(targetDir, 'package.json');
216
+ checks.push({
217
+ name: 'package.json',
218
+ ok: fs.existsSync(pkgFile),
219
+ fix: 'Run: npm init -y'
220
+ });
221
+
222
+ // Check Write Permissions (.ai-memory)
223
+ const memoryDir = path.join(configDir, '.ai-memory');
224
+ let memoryWriteable = false;
225
+ if (!fs.existsSync(memoryDir)) {
226
+ // Create checks will fail later if not exists, but we can try to create
227
+ // Actually, install should create it.
228
+ // If missing, check ok=false
229
+ }
230
+
231
+ // We check if we can write to configDir (essential for logs/memory)
232
+ try {
233
+ if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, {recursive: true});
234
+ const testFile = path.join(configDir, '.perm-test');
235
+ fs.writeFileSync(testFile, 'test');
236
+ fs.unlinkSync(testFile);
237
+ memoryWriteable = true;
238
+ } catch (e) {
239
+ memoryWriteable = false;
240
+ }
241
+
242
+ checks.push({
243
+ name: 'Write Permissions',
244
+ ok: memoryWriteable,
245
+ fix: 'Check folder permissions'
246
+ });
247
+
248
+ // Display results
249
+ let allOk = true;
250
+ for (const check of checks) {
251
+ const status = check.ok ? '✅' : '❌';
252
+ const value = check.value ? ` (${check.value})` : '';
253
+ console.log(` ${status} ${check.name}${value}`);
254
+ if (!check.ok) {
255
+ console.log(` 💡 Fix: ${check.fix}`);
256
+ allOk = false;
257
+ }
258
+ }
259
+
260
+ console.log('');
261
+ console.log('═══════════════════════════════════════════════════════════════');
262
+
263
+ if (allOk) {
264
+ console.log('✅ All checks passed! anchi-toolkit is healthy.');
265
+ } else {
266
+ console.log('⚠️ Some issues found. See fixes above.');
267
+ }
268
+ console.log('');
269
+
270
+ return allOk;
271
+ }
272
+
273
+ module.exports = { doctor };
274
+
275
+
276
+ /***/ }),
277
+
278
+ /***/ 816:
279
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
280
+
281
+
282
+ // =============================================================================
283
+ // anchi-toolkit Enhanced Init Command
284
+ // Usage: npx anchi-toolkit init
285
+ // =============================================================================
286
+
287
+ const fs = __nccwpck_require__(896);
288
+ const path = __nccwpck_require__(928);
289
+ const readline = __nccwpck_require__(785);
290
+
291
+ const { PROFILES, getProfile, getProfileList, getProfileEstimate } = __nccwpck_require__(251);
292
+ const { getSkillPackList, resolveSkillPacks } = __nccwpck_require__(548);
293
+ const { detectTechStack, suggestSkills, formatDetectedStack } = __nccwpck_require__(835);
294
+ const { calculateInstallSize, getComponentPaths, formatSize } = __nccwpck_require__(568);
295
+
296
+ // Colors
297
+ const colors = {
298
+ reset: '\x1b[0m',
299
+ red: '\x1b[31m',
300
+ green: '\x1b[32m',
301
+ yellow: '\x1b[33m',
302
+ cyan: '\x1b[36m',
303
+ gray: '\x1b[90m',
304
+ bold: '\x1b[1m',
305
+ };
306
+
307
+ const log = {
308
+ info: (msg) => console.log(`${colors.cyan}${msg}${colors.reset}`),
309
+ success: (msg) => console.log(`${colors.green}${msg}${colors.reset}`),
310
+ warn: (msg) => console.log(`${colors.yellow}${msg}${colors.reset}`),
311
+ error: (msg) => console.log(`${colors.red}${msg}${colors.reset}`),
312
+ gray: (msg) => console.log(`${colors.gray}${msg}${colors.reset}`),
313
+ bold: (msg) => console.log(`${colors.bold}${msg}${colors.reset}`),
314
+ };
315
+
316
+ const rl = readline.createInterface({
317
+ input: process.stdin,
318
+ output: process.stdout,
319
+ });
320
+
321
+ function ask(question) {
322
+ return new Promise((resolve) => {
323
+ rl.question(question, (answer) => resolve(answer.trim()));
324
+ });
325
+ }
326
+
327
+ async function askChoice(question, options) {
328
+ console.log('');
329
+ log.bold(question);
330
+ options.forEach((opt, i) => {
331
+ const estimate = opt.estimate ? ` ${colors.gray}(${opt.estimate})${colors.reset}` : '';
332
+ console.log(` ${colors.cyan}${i + 1}${colors.reset}) ${opt.label}${estimate}`);
333
+ if (opt.description) {
334
+ log.gray(` ${opt.description}`);
335
+ }
336
+ });
337
+ console.log('');
338
+
339
+ while (true) {
340
+ const answer = await ask(`${colors.gray}Chọn (1-${options.length}): ${colors.reset}`);
341
+ const num = parseInt(answer);
342
+ if (num >= 1 && num <= options.length) {
343
+ return options[num - 1].value;
344
+ }
345
+ log.warn(' Vui lòng chọn số hợp lệ');
346
+ }
347
+ }
348
+
349
+ async function askMultiSelect(question, options) {
350
+ console.log('');
351
+ log.bold(question);
352
+ log.gray(' (Nhập số cách nhau bởi dấu phẩy, VD: 1,2,3. Enter để chọn mặc định)');
353
+ console.log('');
354
+ options.forEach((opt, i) => {
355
+ const checked = opt.default ? `${colors.green}◉${colors.reset}` : `${colors.gray}○${colors.reset}`;
356
+ console.log(` ${checked} ${colors.cyan}${i + 1}${colors.reset}) ${opt.label}`);
357
+ });
358
+ console.log('');
359
+
360
+ const answer = await ask(`${colors.gray}Chọn: ${colors.reset}`);
361
+
362
+ if (!answer) {
363
+ return options.filter(o => o.default).map(o => o.value);
364
+ }
365
+
366
+ const nums = answer.split(',').map(s => parseInt(s.trim())).filter(n => n >= 1 && n <= options.length);
367
+ return nums.map(n => options[n - 1].value);
368
+ }
369
+
370
+ function copyDirRecursive(src, dest) {
371
+ if (!fs.existsSync(dest)) {
372
+ fs.mkdirSync(dest, { recursive: true });
373
+ }
374
+ const entries = fs.readdirSync(src, { withFileTypes: true });
375
+ for (const entry of entries) {
376
+ const srcPath = path.join(src, entry.name);
377
+ const destPath = path.join(dest, entry.name);
378
+ if (entry.isDirectory()) {
379
+ copyDirRecursive(srcPath, destPath);
380
+ } else {
381
+ fs.copyFileSync(srcPath, destPath);
382
+ }
383
+ }
384
+ }
385
+
386
+ function copyFile(src, dest) {
387
+ const destDir = path.dirname(dest);
388
+ if (!fs.existsSync(destDir)) {
389
+ fs.mkdirSync(destDir, { recursive: true });
390
+ }
391
+ fs.copyFileSync(src, dest);
392
+ }
393
+
394
+ async function init() {
395
+ console.log('');
396
+ log.info('╔═══════════════════════════════════════════════════════════╗');
397
+ log.info('║ 🚀 anchi-toolkit Smart Install ║');
398
+ log.info('╚═══════════════════════════════════════════════════════════╝');
399
+ console.log('');
400
+
401
+ const targetPath = process.cwd();
402
+ const kitPath = path.resolve(__dirname, '../..');
403
+
404
+ log.gray(`📂 Target: ${targetPath}`);
405
+
406
+ // Step 1: Detect tech stack
407
+ console.log('');
408
+ log.warn('🔍 Detecting tech stack...');
409
+ const detected = detectTechStack(targetPath);
410
+ const detectedStr = formatDetectedStack(detected);
411
+ log.info(` ${detectedStr}`);
412
+
413
+ const suggestedSkills = suggestSkills(detected);
414
+ if (suggestedSkills.length > 0) {
415
+ log.success(` 💡 Suggested skills: ${suggestedSkills.join(', ')}`);
416
+ }
417
+
418
+ // Step 2: Choose profile
419
+ const profiles = getProfileList();
420
+ const profileOptions = profiles.map(p => ({
421
+ label: `${p.name}`,
422
+ description: p.description,
423
+ estimate: getProfileEstimate(p.key).formatted || '',
424
+ value: p.key,
425
+ }));
426
+
427
+ const selectedProfile = await askChoice('Chọn profile:', profileOptions);
428
+ const profile = getProfile(selectedProfile);
429
+
430
+ // Step 3: Customize (if not minimal or fullstack)
431
+ let finalConfig = { ...profile };
432
+
433
+ if (selectedProfile !== 'minimal' && selectedProfile !== 'fullstack') {
434
+ const customize = await ask(`\n${colors.yellow}Customize thêm? (y/N): ${colors.reset}`);
435
+
436
+ if (customize.toLowerCase() === 'y') {
437
+ // Skill packs
438
+ const packs = getSkillPackList();
439
+ const packOptions = packs.map(p => ({
440
+ label: `${p.name} (${p.skillCount} skills)`,
441
+ value: p.key,
442
+ default: false,
443
+ }));
444
+
445
+ const selectedPacks = await askMultiSelect('Thêm skill packs:', packOptions);
446
+ if (selectedPacks.length > 0) {
447
+ const extraSkills = resolveSkillPacks(selectedPacks);
448
+ finalConfig.skills = [...new Set([...finalConfig.skills, ...extraSkills])];
449
+ }
450
+
451
+ // Include presets?
452
+ if (!finalConfig.includePresets) {
453
+ const includePresets = await ask(`\n${colors.yellow}Include presets folder? (y/N): ${colors.reset}`);
454
+ finalConfig.includePresets = includePresets.toLowerCase() === 'y';
455
+ }
456
+
457
+ // Include docs?
458
+ if (!finalConfig.includeDocs) {
459
+ const includeDocs = await ask(`${colors.yellow}Include docs folder? (y/N): ${colors.reset}`);
460
+ finalConfig.includeDocs = includeDocs.toLowerCase() === 'y';
461
+ }
462
+ }
463
+ }
464
+
465
+ // Step 4: Size preview
466
+ console.log('');
467
+ log.warn('📊 Install Preview:');
468
+ const components = getComponentPaths(finalConfig, kitPath);
469
+ const sizeInfo = calculateInstallSize(kitPath, components);
470
+
471
+ console.log(` Files: ~${sizeInfo.files}`);
472
+ console.log(` Size: ~${sizeInfo.formatted}`);
473
+ console.log('');
474
+ log.info(' Components:');
475
+
476
+ if (finalConfig.commands === 'all') {
477
+ log.success(' ✓ All commands');
478
+ } else {
479
+ log.success(` ✓ Commands: ${finalConfig.commands.join(', ')}`);
480
+ }
481
+
482
+ if (finalConfig.agents === 'all' || (Array.isArray(finalConfig.agents) && finalConfig.agents.length > 0)) {
483
+ log.success(` ✓ Agents: ${finalConfig.agents === 'all' ? 'All' : finalConfig.agents.length + ' agents'}`);
484
+ }
485
+
486
+ if (finalConfig.skills === 'all' || (Array.isArray(finalConfig.skills) && finalConfig.skills.length > 0)) {
487
+ log.success(` ✓ Skills: ${finalConfig.skills === 'all' ? 'All' : finalConfig.skills.length + ' skills'}`);
488
+ }
489
+
490
+ if (finalConfig.includePresets) log.success(' ✓ Presets');
491
+ if (finalConfig.includeDocs) log.success(' ✓ Docs');
492
+
493
+ // Step 5: Confirm
494
+ console.log('');
495
+ const confirm = await ask(`${colors.yellow}Proceed with installation? (Y/n): ${colors.reset}`);
496
+
497
+ if (confirm.toLowerCase() === 'n') {
498
+ log.error('❌ Cancelled.');
499
+ rl.close();
500
+ return;
501
+ }
502
+
503
+ // Step 6: Install
504
+ console.log('');
505
+ log.warn('📦 Installing...');
506
+ console.log('');
507
+
508
+ let installedFiles = 0;
509
+
510
+ // Install commands
511
+ const commandsPath = __nccwpck_require__.ab + "commands";
512
+ const destCommandsPath = __nccwpck_require__.ab + "commands";
513
+
514
+ if (finalConfig.commands === 'all') {
515
+ copyDirRecursive(__nccwpck_require__.ab + "commands", destCommandsPath);
516
+ installedFiles += fs.readdirSync(__nccwpck_require__.ab + "commands").length;
517
+ log.success(' ✅ Commands (all)');
518
+ } else {
519
+ for (const cmd of finalConfig.commands) {
520
+ const srcFile = __nccwpck_require__.ab + "commands/" + cmd + '.md';
521
+ if (fs.existsSync(srcFile)) {
522
+ copyFile(srcFile, __nccwpck_require__.ab + "commands/" + cmd + '.md');
523
+ installedFiles++;
524
+ }
525
+ }
526
+ log.success(` ✅ Commands (${finalConfig.commands.length})`);
527
+ }
528
+
529
+ // Install agents
530
+ const agentsPath = __nccwpck_require__.ab + "agents";
531
+ const destAgentsPath = __nccwpck_require__.ab + "agents";
532
+
533
+ if (finalConfig.agents === 'all') {
534
+ copyDirRecursive(__nccwpck_require__.ab + "agents", destAgentsPath);
535
+ log.success(' ✅ Agents (all)');
536
+ } else if (Array.isArray(finalConfig.agents) && finalConfig.agents.length > 0) {
537
+ for (const agent of finalConfig.agents) {
538
+ const srcFile = __nccwpck_require__.ab + "agents/" + agent + '.md';
539
+ if (fs.existsSync(srcFile)) {
540
+ copyFile(srcFile, __nccwpck_require__.ab + "agents/" + agent + '.md');
541
+ installedFiles++;
542
+ }
543
+ }
544
+ log.success(` ✅ Agents (${finalConfig.agents.length})`);
545
+ }
546
+
547
+ // Install skills
548
+ const skillsPath = __nccwpck_require__.ab + "skills";
549
+ const destSkillsPath = __nccwpck_require__.ab + "skills";
550
+
551
+ if (finalConfig.skills === 'all') {
552
+ copyDirRecursive(__nccwpck_require__.ab + "skills", destSkillsPath);
553
+ log.success(' ✅ Skills (all)');
554
+ } else if (Array.isArray(finalConfig.skills) && finalConfig.skills.length > 0) {
555
+ for (const skill of finalConfig.skills) {
556
+ const srcDir = __nccwpck_require__.ab + "skills/" + skill;
557
+ if (fs.existsSync(srcDir)) {
558
+ copyDirRecursive(srcDir, __nccwpck_require__.ab + "skills/" + skill);
559
+ installedFiles++;
560
+ }
561
+ }
562
+ log.success(` ✅ Skills (${finalConfig.skills.length})`);
563
+ }
564
+
565
+ // Install extras
566
+ if (finalConfig.includePresets) {
567
+ const presetsPath = __nccwpck_require__.ab + "presets";
568
+ if (fs.existsSync(__nccwpck_require__.ab + "presets")) {
569
+ copyDirRecursive(presetsPath, path.join(targetPath, '.cursor/presets'));
570
+ log.success(' ✅ Presets');
571
+ }
572
+ }
573
+
574
+ if (finalConfig.includeDocs) {
575
+ const docsPath = __nccwpck_require__.ab + "docs";
576
+ if (fs.existsSync(__nccwpck_require__.ab + "docs")) {
577
+ copyDirRecursive(docsPath, path.join(targetPath, '.cursor/docs'));
578
+ log.success(' ✅ Docs');
579
+ }
580
+ }
581
+
582
+ // Install AI folders (Implicit)
583
+ const auditPath = path.join(kitPath, '.ai-audit');
584
+ if (fs.existsSync(auditPath)) {
585
+ copyDirRecursive(auditPath, path.join(targetPath, '.cursor/.ai-audit'));
586
+ log.success(' ✅ .ai-audit');
587
+ }
588
+
589
+ const memoryPath = __nccwpck_require__.ab + ".ai-memory";
590
+ if (fs.existsSync(__nccwpck_require__.ab + ".ai-memory")) {
591
+ copyDirRecursive(memoryPath, path.join(targetPath, '.cursor/.ai-memory'));
592
+ log.success(' ✅ .ai-memory');
593
+ }
594
+
595
+ // Install scripts
596
+ const scriptsPath = __nccwpck_require__.ab + "scripts";
597
+ if (fs.existsSync(__nccwpck_require__.ab + "scripts")) {
598
+ copyDirRecursive(scriptsPath, path.join(targetPath, '.cursor/scripts'));
599
+ log.success(' ✅ scripts');
600
+ }
601
+
602
+ // Always include
603
+ const cursorRulesPath = __nccwpck_require__.ab + ".cursorrules";
604
+ if (fs.existsSync(__nccwpck_require__.ab + ".cursorrules")) {
605
+ fs.copyFileSync(cursorRulesPath, path.join(targetPath, '.cursorrules'));
606
+ log.success(' ✅ .cursorrules');
607
+ }
608
+
609
+ const cursorMdPath = __nccwpck_require__.ab + "CURSOR.md";
610
+ if (fs.existsSync(__nccwpck_require__.ab + "CURSOR.md")) {
611
+ fs.copyFileSync(cursorMdPath, path.join(targetPath, 'CURSOR.md'));
612
+ log.success(' ✅ CURSOR.md');
613
+ }
614
+
615
+ // Copy MODEL_COSTS.md
616
+ const modelCostsPath = __nccwpck_require__.ab + "MODEL_COSTS.md";
617
+ if (fs.existsSync(__nccwpck_require__.ab + "MODEL_COSTS.md")) {
618
+ copyFile(modelCostsPath, path.join(targetPath, '.cursor/MODEL_COSTS.md'));
619
+ log.success(' ✅ MODEL_COSTS.md');
620
+ }
621
+
622
+ // Done
623
+ console.log('');
624
+ log.info('═══════════════════════════════════════════════════════════════');
625
+ log.success(' ✅ anchi-toolkit installed successfully!');
626
+ log.info('═══════════════════════════════════════════════════════════════');
627
+ console.log('');
628
+ log.warn('📌 Next steps:');
629
+ console.log('');
630
+ console.log(' 1. Open Cursor and run:');
631
+ log.success(' /start');
632
+ console.log('');
633
+ console.log(' 2. Start coding:');
634
+ log.success(' /plan "Feature description"');
635
+ console.log('');
636
+
637
+ rl.close();
638
+ }
639
+
640
+ module.exports = { init };
641
+
642
+
643
+ /***/ }),
644
+
645
+ /***/ 697:
646
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
647
+
648
+ // =============================================================================
649
+ // anchi-toolkit Memory CLI Command
650
+ // =============================================================================
651
+
652
+ const { loadMemory, saveMemory, clearMemory, getMemorySummary, addNote, addDecision } = __nccwpck_require__(355);
653
+
654
+ async function memory(action = 'show', arg = null) {
655
+ const targetDir = process.cwd();
656
+
657
+ console.log('');
658
+ console.log('🧠 anchi-toolkit Memory');
659
+ console.log('═══════════════════════════════════════════════════════════════');
660
+ console.log('');
661
+
662
+ switch (action) {
663
+ case 'show':
664
+ case undefined:
665
+ showMemory(targetDir);
666
+ break;
667
+
668
+ case 'save':
669
+ saveProjectMemory(targetDir, arg);
670
+ break;
671
+
672
+ case 'load':
673
+ loadProjectMemory(targetDir);
674
+ break;
675
+
676
+ case 'clear':
677
+ clearProjectMemory(targetDir);
678
+ break;
679
+
680
+ case 'add':
681
+ addToMemory(targetDir, arg);
682
+ break;
683
+
684
+ default:
685
+ console.log('Usage:');
686
+ console.log(' npx anchi-toolkit memory show Show current memory');
687
+ console.log(' npx anchi-toolkit memory save Save context');
688
+ console.log(' npx anchi-toolkit memory load Load context');
689
+ console.log(' npx anchi-toolkit memory clear Clear memory');
690
+ console.log(' npx anchi-toolkit memory add "note" Add a note');
691
+ break;
692
+ }
693
+
694
+ console.log('');
695
+ }
696
+
697
+ function showMemory(targetDir) {
698
+ const memory = loadMemory(targetDir);
699
+
700
+ console.log('📂 Project:');
701
+ if (memory.project.name) {
702
+ console.log(` Name: ${memory.project.name}`);
703
+ if (memory.project.description) {
704
+ console.log(` Description: ${memory.project.description}`);
705
+ }
706
+ if (memory.project.tech_stack.length > 0) {
707
+ console.log(` Tech: ${memory.project.tech_stack.join(', ')}`);
708
+ }
709
+ if (memory.project.architecture) {
710
+ console.log(` Architecture: ${memory.project.architecture}`);
711
+ }
712
+ } else {
713
+ console.log(' (No project info saved)');
714
+ }
715
+
716
+ console.log('');
717
+ console.log('📌 Last Session:');
718
+ if (memory.session.last_task) {
719
+ console.log(` Task: ${memory.session.last_task}`);
720
+ if (memory.session.current_phase) {
721
+ console.log(` Phase: ${memory.session.current_phase}`);
722
+ }
723
+ console.log(` Last accessed: ${memory.session.last_accessed || 'Never'}`);
724
+ } else {
725
+ console.log(' (No session info)');
726
+ }
727
+
728
+ console.log('');
729
+ console.log('🧠 Decisions:');
730
+ if (memory.decisions.length > 0) {
731
+ const recent = memory.decisions.slice(-5);
732
+ for (const d of recent) {
733
+ console.log(` • ${d.decision}`);
734
+ }
735
+ if (memory.decisions.length > 5) {
736
+ console.log(` ... and ${memory.decisions.length - 5} more`);
737
+ }
738
+ } else {
739
+ console.log(' (No decisions recorded)');
740
+ }
741
+
742
+ console.log('');
743
+ console.log('📝 Notes:');
744
+ if (memory.notes.length > 0) {
745
+ const recent = memory.notes.slice(-5);
746
+ for (const n of recent) {
747
+ console.log(` • ${n.note}`);
748
+ }
749
+ if (memory.notes.length > 5) {
750
+ console.log(` ... and ${memory.notes.length - 5} more`);
751
+ }
752
+ } else {
753
+ console.log(' (No notes)');
754
+ }
755
+ }
756
+
757
+ function saveProjectMemory(targetDir, note) {
758
+ const memory = loadMemory(targetDir);
759
+ if (note) {
760
+ memory.notes.push({
761
+ id: Date.now(),
762
+ note: note,
763
+ category: 'session',
764
+ timestamp: new Date().toISOString(),
765
+ });
766
+ }
767
+ const path = saveMemory(targetDir, memory);
768
+ console.log('✅ Memory saved!');
769
+ console.log(` Location: ${path}`);
770
+ console.log(` Stats:`);
771
+ console.log(` • Decisions: ${memory.decisions.length}`);
772
+ console.log(` • Notes: ${memory.notes.length}`);
773
+ console.log(` • Entities: ${Object.keys(memory.entities).length}`);
774
+ }
775
+
776
+ function loadProjectMemory(targetDir) {
777
+ const summary = getMemorySummary(targetDir);
778
+ console.log(summary);
779
+ console.log('');
780
+ console.log('✅ Context loaded! AI now remembers your project.');
781
+ }
782
+
783
+ function clearProjectMemory(targetDir) {
784
+ clearMemory(targetDir);
785
+ console.log('✅ Memory cleared!');
786
+ console.log(' All project context has been reset.');
787
+ }
788
+
789
+ function addToMemory(targetDir, content) {
790
+ if (!content) {
791
+ console.log('Usage: npx anchi-toolkit memory add "your note"');
792
+ return;
793
+ }
794
+
795
+ if (content.startsWith('decision:')) {
796
+ const parts = content.slice(9).split(' - ');
797
+ addDecision(targetDir, parts[0].trim(), parts[1] || '');
798
+ console.log('✅ Decision recorded!');
799
+ } else {
800
+ addNote(targetDir, content);
801
+ console.log('✅ Note added!');
802
+ }
803
+ }
804
+
805
+ module.exports = { memory };
806
+
807
+
808
+ /***/ }),
809
+
810
+ /***/ 66:
811
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
812
+
813
+
814
+ // =============================================================================
815
+ // anchi-toolkit Uninstall Command
816
+ // Usage: npx anchi-toolkit uninstall
817
+ // =============================================================================
818
+
819
+ const fs = __nccwpck_require__(896);
820
+ const path = __nccwpck_require__(928);
821
+ const readline = __nccwpck_require__(785);
822
+
823
+ const colors = {
824
+ reset: '\x1b[0m',
825
+ red: '\x1b[31m',
826
+ green: '\x1b[32m',
827
+ yellow: '\x1b[33m',
828
+ cyan: '\x1b[36m',
829
+ gray: '\x1b[90m',
830
+ };
831
+
832
+ const log = {
833
+ info: (msg) => console.log(`${colors.cyan}${msg}${colors.reset}`),
834
+ success: (msg) => console.log(`${colors.green}${msg}${colors.reset}`),
835
+ warn: (msg) => console.log(`${colors.yellow}${msg}${colors.reset}`),
836
+ error: (msg) => console.log(`${colors.red}${msg}${colors.reset}`),
837
+ gray: (msg) => console.log(`${colors.gray}${msg}${colors.reset}`),
838
+ };
839
+
840
+ const rl = readline.createInterface({
841
+ input: process.stdin,
842
+ output: process.stdout,
843
+ });
844
+
845
+ function ask(question) {
846
+ return new Promise((resolve) => {
847
+ rl.question(question, (answer) => resolve(answer.trim()));
848
+ });
849
+ }
850
+
851
+ function deleteRecursive(dir) {
852
+ if (fs.existsSync(dir)) {
853
+ fs.readdirSync(dir).forEach((file) => {
854
+ const curPath = path.join(dir, file);
855
+ if (fs.lstatSync(curPath).isDirectory()) {
856
+ deleteRecursive(curPath);
857
+ } else {
858
+ fs.unlinkSync(curPath);
859
+ }
860
+ });
861
+ fs.rmdirSync(dir);
862
+ }
863
+ }
864
+
865
+ async function uninstall() {
866
+ console.log('');
867
+ log.info('╔═══════════════════════════════════════════════════════════╗');
868
+ log.info('║ 🗑️ anchi-toolkit Uninstall ║');
869
+ log.info('╚═══════════════════════════════════════════════════════════╝');
870
+ console.log('');
871
+
872
+ const targetPath = process.cwd();
873
+
874
+ // Items to remove
875
+ // Items to remove
876
+ const itemsToRemove = [
877
+ // Cursor
878
+ { path: '.cursor/commands', type: 'dir', desc: 'Commands' },
879
+ { path: '.cursor/agents', type: 'dir', desc: 'Agents' },
880
+ { path: '.cursor/skills', type: 'dir', desc: 'Skills' },
881
+ { path: '.cursor/presets', type: 'dir', desc: 'Presets' },
882
+ { path: '.cursor/docs', type: 'dir', desc: 'Docs' },
883
+ { path: '.cursor/.ai-audit', type: 'dir', desc: 'Audit Logs' },
884
+ { path: '.cursor/.ai-memory', type: 'dir', desc: 'Memory' },
885
+ { path: '.cursor/MODEL_COSTS.md', type: 'file', desc: 'Model costs guide' },
886
+
887
+ // Antigravity
888
+ { path: '.antigravity', type: 'dir', desc: 'Antigravity Folder' },
889
+
890
+ // Root files
891
+ { path: '.cursorrules', type: 'file', desc: 'Cursor rules' },
892
+ { path: 'CURSOR.md', type: 'file', desc: 'Cursor instructions' },
893
+ { path: 'GEMINI.md', type: 'file', desc: 'Gemini instructions' },
894
+ { path: 'ANTIGRAVITY.md', type: 'file', desc: 'Antigravity instructions' },
895
+
896
+ // Legacy (Root) - Cleanup old installs
897
+ { path: 'presets', type: 'dir', desc: 'Presets (Legacy)' },
898
+ { path: 'docs', type: 'dir', desc: 'Docs (Legacy)' },
899
+ { path: '.ai-audit', type: 'dir', desc: 'Audit Logs (Legacy)' },
900
+ { path: '.ai-memory', type: 'dir', desc: 'Memory (Legacy)' },
901
+ ];
902
+
903
+ // Check what exists
904
+ const existingItems = itemsToRemove.filter(item => {
905
+ const fullPath = path.join(targetPath, item.path);
906
+ return fs.existsSync(fullPath);
907
+ });
908
+
909
+ if (existingItems.length === 0) {
910
+ log.warn('⚠️ No anchi-toolkit files found in this directory.');
911
+ rl.close();
912
+ return;
913
+ }
914
+
915
+ // Show what will be removed
916
+ log.warn('📋 The following will be removed:');
917
+ console.log('');
918
+
919
+ existingItems.forEach(item => {
920
+ if (item.type === 'dir') {
921
+ log.error(` 📁 ${item.path}/`);
922
+ } else {
923
+ log.error(` 📄 ${item.path}`);
924
+ }
925
+ });
926
+
927
+ console.log('');
928
+ log.warn('⚠️ This action cannot be undone!');
929
+ console.log('');
930
+
931
+ const confirm = await ask(`${colors.red}Type 'REMOVE' to confirm: ${colors.reset}`);
932
+
933
+ if (confirm !== 'REMOVE') {
934
+ log.info('❌ Cancelled.');
935
+ rl.close();
936
+ return;
937
+ }
938
+
939
+ console.log('');
940
+ log.warn('🗑️ Removing...');
941
+ console.log('');
942
+
943
+ let removed = 0;
944
+
945
+ for (const item of existingItems) {
946
+ const fullPath = path.join(targetPath, item.path);
947
+ try {
948
+ if (item.type === 'dir') {
949
+ deleteRecursive(fullPath);
950
+ } else {
951
+ fs.unlinkSync(fullPath);
952
+ }
953
+ log.success(` ✅ Removed: ${item.path}`);
954
+ removed++;
955
+ } catch (e) {
956
+ log.error(` ❌ Failed: ${item.path} - ${e.message}`);
957
+ }
958
+ }
959
+
960
+ // Clean up empty .cursor folder
961
+ const cursorDir = __nccwpck_require__.ab + ".cursor";
962
+ if (fs.existsSync(__nccwpck_require__.ab + ".cursor")) {
963
+ const remaining = fs.readdirSync(cursorDir);
964
+ if (remaining.length === 0) {
965
+ fs.rmdirSync(cursorDir);
966
+ log.gray(' 🧹 Removed empty .cursor/');
967
+ }
968
+ }
969
+
970
+ console.log('');
971
+ log.info('═══════════════════════════════════════════════════════════════');
972
+ log.success(` ✅ Removed ${removed} items!`);
973
+ log.info('═══════════════════════════════════════════════════════════════');
974
+ console.log('');
975
+
976
+ rl.close();
977
+ }
978
+
979
+ module.exports = { uninstall };
980
+
981
+
982
+ /***/ }),
983
+
984
+ /***/ 779:
985
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
986
+
987
+
988
+ // =============================================================================
989
+ // anchi-toolkit Update Command
990
+ // Usage: npx anchi-toolkit update
991
+ // =============================================================================
992
+
993
+ const fs = __nccwpck_require__(896);
994
+ const path = __nccwpck_require__(928);
995
+ const https = __nccwpck_require__(692);
996
+
997
+ const colors = {
998
+ reset: '\x1b[0m',
999
+ red: '\x1b[31m',
1000
+ green: '\x1b[32m',
1001
+ yellow: '\x1b[33m',
1002
+ cyan: '\x1b[36m',
1003
+ gray: '\x1b[90m',
1004
+ };
1005
+
1006
+ const log = {
1007
+ info: (msg) => console.log(`${colors.cyan}${msg}${colors.reset}`),
1008
+ success: (msg) => console.log(`${colors.green}${msg}${colors.reset}`),
1009
+ warn: (msg) => console.log(`${colors.yellow}${msg}${colors.reset}`),
1010
+ error: (msg) => console.log(`${colors.red}${msg}${colors.reset}`),
1011
+ gray: (msg) => console.log(`${colors.gray}${msg}${colors.reset}`),
1012
+ };
1013
+
1014
+ // Get current installed version
1015
+ function getCurrentVersion() {
1016
+ try {
1017
+ const kitPath = path.resolve(__dirname, '..');
1018
+ const pkgPath = path.join(kitPath, 'package.json');
1019
+ if (fs.existsSync(pkgPath)) {
1020
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
1021
+ return pkg.version || '0.0.0';
1022
+ }
1023
+ } catch (e) {
1024
+ return '0.0.0';
1025
+ }
1026
+ return '0.0.0';
1027
+ }
1028
+
1029
+ // Check npm registry for latest version
1030
+ function getLatestVersion() {
1031
+ return new Promise((resolve, reject) => {
1032
+ https.get('https://registry.npmjs.org/anchi-toolkit/latest', (res) => {
1033
+ let data = '';
1034
+ res.on('data', chunk => data += chunk);
1035
+ res.on('end', () => {
1036
+ try {
1037
+ const pkg = JSON.parse(data);
1038
+ resolve(pkg.version || '0.0.0');
1039
+ } catch (e) {
1040
+ resolve('0.0.0');
1041
+ }
1042
+ });
1043
+ }).on('error', () => resolve('0.0.0'));
1044
+ });
1045
+ }
1046
+
1047
+ // Compare versions (simple semver compare)
1048
+ function isNewer(latest, current) {
1049
+ const l = latest.split('.').map(Number);
1050
+ const c = current.split('.').map(Number);
1051
+ for (let i = 0; i < 3; i++) {
1052
+ if ((l[i] || 0) > (c[i] || 0)) return true;
1053
+ if ((l[i] || 0) < (c[i] || 0)) return false;
1054
+ }
1055
+ return false;
1056
+ }
1057
+
1058
+ // Backup and update files
1059
+ function updateFiles(targetPath, kitPath) {
1060
+ const timestamp = new Date().toISOString().replace(/[-:]/g, '').slice(0, 15);
1061
+ const updatableComponents = [
1062
+ { path: '.cursor/commands', desc: 'Commands' },
1063
+ { path: '.cursor/agents', desc: 'Agents' },
1064
+ { path: '.cursor/skills', desc: 'Skills' },
1065
+ ];
1066
+
1067
+ let updated = 0;
1068
+
1069
+ for (const comp of updatableComponents) {
1070
+ const sourcePath = path.join(kitPath, comp.path);
1071
+ const destPath = path.join(targetPath, comp.path);
1072
+
1073
+ if (fs.existsSync(sourcePath) && fs.existsSync(destPath)) {
1074
+ // Backup existing
1075
+ const backupPath = `${destPath}.backup_${timestamp}`;
1076
+ log.gray(` 📦 Backing up ${comp.desc}...`);
1077
+
1078
+ // Copy source to dest (overwrite)
1079
+ copyDirRecursive(sourcePath, destPath);
1080
+ log.success(` ✅ Updated: ${comp.desc}`);
1081
+ updated++;
1082
+ }
1083
+ }
1084
+
1085
+ return updated;
1086
+ }
1087
+
1088
+ function copyDirRecursive(src, dest) {
1089
+ if (!fs.existsSync(dest)) {
1090
+ fs.mkdirSync(dest, { recursive: true });
1091
+ }
1092
+ const entries = fs.readdirSync(src, { withFileTypes: true });
1093
+ for (const entry of entries) {
1094
+ const srcPath = path.join(src, entry.name);
1095
+ const destPath = path.join(dest, entry.name);
1096
+ if (entry.isDirectory()) {
1097
+ copyDirRecursive(srcPath, destPath);
1098
+ } else {
1099
+ fs.copyFileSync(srcPath, destPath);
1100
+ }
1101
+ }
1102
+ }
1103
+
1104
+ // Main update function
1105
+ async function update() {
1106
+ console.log('');
1107
+ log.info('╔═══════════════════════════════════════════════════════════╗');
1108
+ log.info('║ 🔄 anchi-toolkit Update ║');
1109
+ log.info('╚═══════════════════════════════════════════════════════════╝');
1110
+ console.log('');
1111
+
1112
+ const currentVersion = getCurrentVersion();
1113
+ log.gray(`📦 Current version: ${currentVersion}`);
1114
+
1115
+ log.info('🔍 Checking for updates...');
1116
+ const latestVersion = await getLatestVersion();
1117
+
1118
+ if (latestVersion === '0.0.0') {
1119
+ log.warn('⚠️ Could not check npm registry.');
1120
+ log.gray(' Package may not be published yet.');
1121
+ log.info('');
1122
+ log.info('💡 For now, you can update manually:');
1123
+ log.success(' git pull origin main');
1124
+ return;
1125
+ }
1126
+
1127
+ log.gray(`📦 Latest version: ${latestVersion}`);
1128
+ console.log('');
1129
+
1130
+ if (isNewer(latestVersion, currentVersion)) {
1131
+ log.warn(`🆕 New version available: ${currentVersion} → ${latestVersion}`);
1132
+ console.log('');
1133
+ log.info('To update, run:');
1134
+ log.success(' npm update -g anchi-toolkit');
1135
+ log.info('');
1136
+ log.info('Or reinstall:');
1137
+ log.success(' npm install -g anchi-toolkit@latest');
1138
+ } else {
1139
+ log.success('✅ You are using the latest version!');
1140
+ }
1141
+
1142
+ console.log('');
1143
+ log.info('💡 To update project files:');
1144
+ log.success(' npx anchi-toolkit install');
1145
+ log.gray(' (Use Overwrite when prompted)');
1146
+ console.log('');
1147
+ }
1148
+
1149
+ module.exports = { update };
1150
+
1151
+
1152
+ /***/ }),
1153
+
1154
+ /***/ 256:
1155
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
1156
+
1157
+ // =============================================================================
1158
+ // anchi-toolkit Config Manager
1159
+ // Handles loading, saving, and merging configuration
1160
+ // =============================================================================
1161
+
1162
+ const fs = __nccwpck_require__(896);
1163
+ const path = __nccwpck_require__(928);
1164
+
1165
+ const CONFIG_FILENAME = 'anchi-toolkit.config.yaml';
1166
+
1167
+ // Default configuration
1168
+ const DEFAULT_CONFIG = {
1169
+ version: '2.1',
1170
+ profile: 'developer',
1171
+
1172
+ model_preference: {
1173
+ default: 'auto',
1174
+ complex: 'opus',
1175
+ economy: 'haiku',
1176
+ },
1177
+
1178
+ features: {
1179
+ auto_commit: false,
1180
+ auto_push: false,
1181
+ progress_indicators: true,
1182
+ summary_cards: true,
1183
+ quick_actions: true,
1184
+ },
1185
+
1186
+ team: {
1187
+ role: null, // frontend, backend, fullstack, lead, etc.
1188
+ slack_webhook: null,
1189
+ notifications: true,
1190
+ },
1191
+
1192
+ hooks: {
1193
+ enabled: false,
1194
+ pre_commit: [],
1195
+ post_merge: [],
1196
+ },
1197
+ };
1198
+
1199
+ /**
1200
+ * Parse simple YAML (subset)
1201
+ */
1202
+ function parseYaml(content) {
1203
+ const result = {};
1204
+ const lines = content.split('\n');
1205
+ const stack = [{ obj: result, indent: -1 }];
1206
+
1207
+ for (const line of lines) {
1208
+ if (line.trim() === '' || line.trim().startsWith('#')) continue;
1209
+
1210
+ const match = line.match(/^(\s*)([^:]+):\s*(.*)$/);
1211
+ if (!match) continue;
1212
+
1213
+ const indent = match[1].length;
1214
+ const key = match[2].trim();
1215
+ let value = match[3].trim();
1216
+
1217
+ // Pop stack until we find parent
1218
+ while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
1219
+ stack.pop();
1220
+ }
1221
+
1222
+ const parent = stack[stack.length - 1].obj;
1223
+
1224
+ if (value === '' || value === null) {
1225
+ // Nested object
1226
+ parent[key] = {};
1227
+ stack.push({ obj: parent[key], indent: indent });
1228
+ } else {
1229
+ // Parse value
1230
+ if (value === 'true') value = true;
1231
+ else if (value === 'false') value = false;
1232
+ else if (value === 'null') value = null;
1233
+ else if (!isNaN(value)) value = Number(value);
1234
+ else if (value.startsWith('"') && value.endsWith('"')) value = value.slice(1, -1);
1235
+ else if (value.startsWith('[') && value.endsWith(']')) {
1236
+ value = value.slice(1, -1).split(',').map(s => s.trim());
1237
+ }
1238
+ parent[key] = value;
1239
+ }
1240
+ }
1241
+
1242
+ return result;
1243
+ }
1244
+
1245
+ /**
1246
+ * Stringify to YAML
1247
+ */
1248
+ function stringifyYaml(obj, indent = 0) {
1249
+ let result = '';
1250
+ const prefix = ' '.repeat(indent);
1251
+
1252
+ for (const [key, value] of Object.entries(obj)) {
1253
+ if (value === null) {
1254
+ result += `${prefix}${key}: null\n`;
1255
+ } else if (typeof value === 'object' && !Array.isArray(value)) {
1256
+ result += `${prefix}${key}:\n`;
1257
+ result += stringifyYaml(value, indent + 1);
1258
+ } else if (Array.isArray(value)) {
1259
+ result += `${prefix}${key}: [${value.join(', ')}]\n`;
1260
+ } else if (typeof value === 'string') {
1261
+ result += `${prefix}${key}: "${value}"\n`;
1262
+ } else {
1263
+ result += `${prefix}${key}: ${value}\n`;
1264
+ }
1265
+ }
1266
+
1267
+ return result;
1268
+ }
1269
+
1270
+ /**
1271
+ * Deep merge objects
1272
+ */
1273
+ function deepMerge(target, source) {
1274
+ const result = { ...target };
1275
+
1276
+ for (const key of Object.keys(source)) {
1277
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
1278
+ result[key] = deepMerge(target[key] || {}, source[key]);
1279
+ } else {
1280
+ result[key] = source[key];
1281
+ }
1282
+ }
1283
+
1284
+ return result;
1285
+ }
1286
+
1287
+ /**
1288
+ * Get config directory (.antigravity or .cursor)
1289
+ */
1290
+ function getConfigDir(targetDir) {
1291
+ // Check for Antigravity first
1292
+ const antigravityDir = path.join(targetDir, '.antigravity');
1293
+ if (fs.existsSync(antigravityDir)) {
1294
+ return antigravityDir;
1295
+ }
1296
+ // Fallback to Cursor
1297
+ return path.join(targetDir, '.cursor');
1298
+ }
1299
+
1300
+ /**
1301
+ * Load config from target directory
1302
+ */
1303
+ function loadConfig(targetDir) {
1304
+ const configDir = getConfigDir(targetDir);
1305
+ const configPath = path.join(configDir, CONFIG_FILENAME);
1306
+
1307
+ if (!fs.existsSync(configPath)) {
1308
+ return DEFAULT_CONFIG;
1309
+ }
1310
+
1311
+ try {
1312
+ const content = fs.readFileSync(configPath, 'utf-8');
1313
+ const userConfig = parseYaml(content);
1314
+ return deepMerge(DEFAULT_CONFIG, userConfig);
1315
+ } catch (e) {
1316
+ console.warn(`Warning: Could not parse config: ${e.message}`);
1317
+ return DEFAULT_CONFIG;
1318
+ }
1319
+ }
1320
+
1321
+ /**
1322
+ * Save config to target directory
1323
+ */
1324
+ function saveConfig(targetDir, config) {
1325
+ const configDir = getConfigDir(targetDir);
1326
+ const configPath = path.join(configDir, CONFIG_FILENAME);
1327
+
1328
+ if (!fs.existsSync(configDir)) {
1329
+ fs.mkdirSync(configDir, { recursive: true });
1330
+ }
1331
+
1332
+ const header = `# anchi-toolkit Configuration
1333
+ # https://github.com/ANCHI-STE/anchi-webkit-dev
1334
+ # ═══════════════════════════════════════════════════════════════
1335
+
1336
+ `;
1337
+
1338
+ fs.writeFileSync(configPath, header + stringifyYaml(config));
1339
+ return configPath;
1340
+ }
1341
+
1342
+ /**
1343
+ * Get config value by path (e.g., 'features.auto_commit')
1344
+ */
1345
+ function getConfigValue(config, keyPath) {
1346
+ return keyPath.split('.').reduce((obj, key) => obj?.[key], config);
1347
+ }
1348
+
1349
+ /**
1350
+ * Set config value by path
1351
+ */
1352
+ function setConfigValue(config, keyPath, value) {
1353
+ const keys = keyPath.split('.');
1354
+ const lastKey = keys.pop();
1355
+ const target = keys.reduce((obj, key) => obj[key] = obj[key] || {}, config);
1356
+ target[lastKey] = value;
1357
+ return config;
1358
+ }
1359
+
1360
+ module.exports = {
1361
+ DEFAULT_CONFIG,
1362
+ CONFIG_FILENAME,
1363
+ loadConfig,
1364
+ saveConfig,
1365
+ parseYaml,
1366
+ stringifyYaml,
1367
+ deepMerge,
1368
+ getConfigValue,
1369
+ setConfigValue,
1370
+ getConfigDir,
1371
+ };
1372
+
1373
+
1374
+ /***/ }),
1375
+
1376
+ /***/ 835:
1377
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
1378
+
1379
+ // =============================================================================
1380
+ // Tech Stack Detector
1381
+ // =============================================================================
1382
+
1383
+ const fs = __nccwpck_require__(896);
1384
+ const path = __nccwpck_require__(928);
1385
+
1386
+ function detectTechStack(targetPath) {
1387
+ const detected = {
1388
+ frameworks: [],
1389
+ languages: [],
1390
+ databases: [],
1391
+ styling: [],
1392
+ auth: [],
1393
+ testing: [],
1394
+ };
1395
+
1396
+ // Check package.json
1397
+ const pkgPath = path.join(targetPath, 'package.json');
1398
+ if (fs.existsSync(pkgPath)) {
1399
+ try {
1400
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
1401
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
1402
+
1403
+ // Frameworks
1404
+ if (deps['next']) detected.frameworks.push('next');
1405
+ if (deps['react']) detected.frameworks.push('react');
1406
+ if (deps['vue']) detected.frameworks.push('vue');
1407
+ if (deps['express']) detected.frameworks.push('express');
1408
+ if (deps['fastify']) detected.frameworks.push('fastify');
1409
+ if (deps['@nestjs/core']) detected.frameworks.push('nestjs');
1410
+
1411
+ // Databases
1412
+ if (deps['prisma'] || deps['@prisma/client']) detected.databases.push('prisma');
1413
+ if (deps['mongoose']) detected.databases.push('mongodb');
1414
+ if (deps['pg']) detected.databases.push('postgresql');
1415
+ if (deps['mysql2']) detected.databases.push('mysql');
1416
+ if (deps['better-sqlite3']) detected.databases.push('sqlite');
1417
+
1418
+ // Styling
1419
+ if (deps['tailwindcss']) detected.styling.push('tailwind');
1420
+ if (deps['styled-components']) detected.styling.push('styled-components');
1421
+ if (deps['@emotion/react']) detected.styling.push('emotion');
1422
+ if (deps['sass']) detected.styling.push('sass');
1423
+
1424
+ // Auth
1425
+ if (deps['next-auth']) detected.auth.push('next-auth');
1426
+ if (deps['better-auth']) detected.auth.push('better-auth');
1427
+ if (deps['passport']) detected.auth.push('passport');
1428
+
1429
+ // Testing
1430
+ if (deps['jest']) detected.testing.push('jest');
1431
+ if (deps['vitest']) detected.testing.push('vitest');
1432
+ if (deps['playwright']) detected.testing.push('playwright');
1433
+
1434
+ // Languages
1435
+ if (deps['typescript']) detected.languages.push('typescript');
1436
+ } catch (e) {
1437
+ // Ignore parse errors
1438
+ }
1439
+ }
1440
+
1441
+ // Check for config files
1442
+ if (fs.existsSync(path.join(targetPath, 'tailwind.config.js')) ||
1443
+ fs.existsSync(path.join(targetPath, 'tailwind.config.ts'))) {
1444
+ if (!detected.styling.includes('tailwind')) detected.styling.push('tailwind');
1445
+ }
1446
+
1447
+ if (fs.existsSync(path.join(targetPath, 'prisma'))) {
1448
+ if (!detected.databases.includes('prisma')) detected.databases.push('prisma');
1449
+ }
1450
+
1451
+ if (fs.existsSync(path.join(targetPath, 'tsconfig.json'))) {
1452
+ if (!detected.languages.includes('typescript')) detected.languages.push('typescript');
1453
+ }
1454
+
1455
+ return detected;
1456
+ }
1457
+
1458
+ function suggestSkills(detected) {
1459
+ const suggestions = new Set();
1460
+
1461
+ // Framework-based suggestions
1462
+ if (detected.frameworks.includes('next') || detected.frameworks.includes('react')) {
1463
+ suggestions.add('frontend-development');
1464
+ suggestions.add('web-frameworks');
1465
+ }
1466
+ if (detected.frameworks.includes('express') || detected.frameworks.includes('fastify')) {
1467
+ suggestions.add('backend-development');
1468
+ }
1469
+
1470
+ // Database suggestions
1471
+ if (detected.databases.length > 0) {
1472
+ suggestions.add('databases');
1473
+ }
1474
+
1475
+ // Styling suggestions
1476
+ if (detected.styling.includes('tailwind')) {
1477
+ suggestions.add('ui-styling');
1478
+ suggestions.add('frontend-design');
1479
+ }
1480
+
1481
+ // Auth suggestions
1482
+ if (detected.auth.includes('better-auth')) {
1483
+ suggestions.add('better-auth');
1484
+ }
1485
+
1486
+ // Default suggestions if nothing detected
1487
+ if (suggestions.size === 0) {
1488
+ suggestions.add('frontend-development');
1489
+ suggestions.add('planning');
1490
+ }
1491
+
1492
+ return Array.from(suggestions);
1493
+ }
1494
+
1495
+ function formatDetectedStack(detected) {
1496
+ const parts = [];
1497
+
1498
+ if (detected.frameworks.length) {
1499
+ parts.push(`Frameworks: ${detected.frameworks.join(', ')}`);
1500
+ }
1501
+ if (detected.databases.length) {
1502
+ parts.push(`Database: ${detected.databases.join(', ')}`);
1503
+ }
1504
+ if (detected.styling.length) {
1505
+ parts.push(`Styling: ${detected.styling.join(', ')}`);
1506
+ }
1507
+ if (detected.auth.length) {
1508
+ parts.push(`Auth: ${detected.auth.join(', ')}`);
1509
+ }
1510
+
1511
+ return parts.length > 0 ? parts.join(' | ') : 'No specific tech detected';
1512
+ }
1513
+
1514
+ module.exports = {
1515
+ detectTechStack,
1516
+ suggestSkills,
1517
+ formatDetectedStack,
1518
+ };
1519
+
1520
+
1521
+ /***/ }),
1522
+
1523
+ /***/ 355:
1524
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
1525
+
1526
+ // =============================================================================
1527
+ // anchi-toolkit Memory Manager
1528
+ // Saves and loads project context to avoid AI "forgetting"
1529
+ // =============================================================================
1530
+
1531
+ const fs = __nccwpck_require__(896);
1532
+ const path = __nccwpck_require__(928);
1533
+ const { getConfigDir } = __nccwpck_require__(256);
1534
+
1535
+ const MEMORY_DIR_NAME = '.ai-memory';
1536
+ const MEMORY_FILE = 'context.json'; // Changed from memory.json to context.json based on what I saw in ls
1537
+
1538
+ // Default memory structure
1539
+ const DEFAULT_MEMORY = {
1540
+ version: '1.0',
1541
+ project: {
1542
+ name: null,
1543
+ description: null,
1544
+ tech_stack: [],
1545
+ architecture: null,
1546
+ created_at: null,
1547
+ updated_at: null,
1548
+ },
1549
+ session: {
1550
+ last_task: null,
1551
+ current_phase: null,
1552
+ open_files: [],
1553
+ pending_actions: [],
1554
+ last_accessed: null,
1555
+ },
1556
+ decisions: [],
1557
+ notes: [],
1558
+ entities: {},
1559
+ };
1560
+
1561
+ /**
1562
+ * Get memory file path
1563
+ */
1564
+ function getMemoryPath(targetDir) {
1565
+ const configDir = getConfigDir(targetDir);
1566
+ return path.join(configDir, MEMORY_DIR_NAME, MEMORY_FILE);
1567
+ }
1568
+
1569
+ /**
1570
+ * Ensure memory directory exists
1571
+ */
1572
+ function ensureMemoryDir(targetDir) {
1573
+ const configDir = getConfigDir(targetDir);
1574
+ const memoryDir = path.join(configDir, MEMORY_DIR_NAME);
1575
+ if (!fs.existsSync(memoryDir)) {
1576
+ fs.mkdirSync(memoryDir, { recursive: true });
1577
+ }
1578
+ return memoryDir;
1579
+ }
1580
+
1581
+ /**
1582
+ * Load memory from file
1583
+ */
1584
+ function loadMemory(targetDir = process.cwd()) {
1585
+ const memoryPath = getMemoryPath(targetDir);
1586
+
1587
+ if (!fs.existsSync(memoryPath)) {
1588
+ return { ...DEFAULT_MEMORY };
1589
+ }
1590
+
1591
+ try {
1592
+ const content = fs.readFileSync(memoryPath, 'utf-8');
1593
+ const memory = JSON.parse(content);
1594
+ return { ...DEFAULT_MEMORY, ...memory };
1595
+ } catch (e) {
1596
+ console.warn(`Warning: Could not parse memory: ${e.message}`);
1597
+ return { ...DEFAULT_MEMORY };
1598
+ }
1599
+ }
1600
+
1601
+ /**
1602
+ * Save memory to file
1603
+ */
1604
+ function saveMemory(targetDir, memory) {
1605
+ ensureMemoryDir(targetDir);
1606
+ const memoryPath = getMemoryPath(targetDir);
1607
+
1608
+ memory.session.last_accessed = new Date().toISOString();
1609
+ memory.project.updated_at = new Date().toISOString();
1610
+
1611
+ fs.writeFileSync(memoryPath, JSON.stringify(memory, null, 2));
1612
+ return memoryPath;
1613
+ }
1614
+
1615
+ /**
1616
+ * Update project info
1617
+ */
1618
+ function updateProject(targetDir, projectInfo) {
1619
+ const memory = loadMemory(targetDir);
1620
+ memory.project = {
1621
+ ...memory.project,
1622
+ ...projectInfo,
1623
+ updated_at: new Date().toISOString(),
1624
+ };
1625
+ if (!memory.project.created_at) {
1626
+ memory.project.created_at = new Date().toISOString();
1627
+ }
1628
+ saveMemory(targetDir, memory);
1629
+ return memory;
1630
+ }
1631
+
1632
+ /**
1633
+ * Update session info
1634
+ */
1635
+ function updateSession(targetDir, sessionInfo) {
1636
+ const memory = loadMemory(targetDir);
1637
+ memory.session = {
1638
+ ...memory.session,
1639
+ ...sessionInfo,
1640
+ last_accessed: new Date().toISOString(),
1641
+ };
1642
+ saveMemory(targetDir, memory);
1643
+ return memory;
1644
+ }
1645
+
1646
+ /**
1647
+ * Add a decision
1648
+ */
1649
+ function addDecision(targetDir, decision, reason, filesAffected = []) {
1650
+ const memory = loadMemory(targetDir);
1651
+ memory.decisions.push({
1652
+ id: Date.now(),
1653
+ decision,
1654
+ reason,
1655
+ files_affected: filesAffected,
1656
+ timestamp: new Date().toISOString(),
1657
+ });
1658
+ saveMemory(targetDir, memory);
1659
+ return memory;
1660
+ }
1661
+
1662
+ /**
1663
+ * Add a note
1664
+ */
1665
+ function addNote(targetDir, note, category = 'general') {
1666
+ const memory = loadMemory(targetDir);
1667
+ memory.notes.push({
1668
+ id: Date.now(),
1669
+ note,
1670
+ category,
1671
+ timestamp: new Date().toISOString(),
1672
+ });
1673
+ saveMemory(targetDir, memory);
1674
+ return memory;
1675
+ }
1676
+
1677
+ /**
1678
+ * Add/update an entity
1679
+ */
1680
+ function upsertEntity(targetDir, entityName, entityData) {
1681
+ const memory = loadMemory(targetDir);
1682
+ memory.entities[entityName] = {
1683
+ ...memory.entities[entityName],
1684
+ ...entityData,
1685
+ updated_at: new Date().toISOString(),
1686
+ };
1687
+ saveMemory(targetDir, memory);
1688
+ return memory;
1689
+ }
1690
+
1691
+ /**
1692
+ * Get entity
1693
+ */
1694
+ function getEntity(targetDir, entityName) {
1695
+ const memory = loadMemory(targetDir);
1696
+ return memory.entities[entityName] || null;
1697
+ }
1698
+
1699
+ /**
1700
+ * Clear memory
1701
+ */
1702
+ function clearMemory(targetDir) {
1703
+ const memory = { ...DEFAULT_MEMORY };
1704
+ memory.project.created_at = new Date().toISOString();
1705
+ saveMemory(targetDir, memory);
1706
+ return memory;
1707
+ }
1708
+
1709
+ /**
1710
+ * Get memory summary (for AI context)
1711
+ */
1712
+ function getMemorySummary(targetDir) {
1713
+ const memory = loadMemory(targetDir);
1714
+
1715
+ let summary = '';
1716
+
1717
+ // Project info
1718
+ if (memory.project.name) {
1719
+ summary += `## Project: ${memory.project.name}\n`;
1720
+ if (memory.project.description) {
1721
+ summary += `${memory.project.description}\n`;
1722
+ }
1723
+ if (memory.project.tech_stack.length > 0) {
1724
+ summary += `Tech Stack: ${memory.project.tech_stack.join(', ')}\n`;
1725
+ }
1726
+ if (memory.project.architecture) {
1727
+ summary += `Architecture: ${memory.project.architecture}\n`;
1728
+ }
1729
+ summary += '\n';
1730
+ }
1731
+
1732
+ // Session info
1733
+ if (memory.session.last_task) {
1734
+ summary += `## Last Session\n`;
1735
+ summary += `Task: ${memory.session.last_task}\n`;
1736
+ if (memory.session.current_phase) {
1737
+ summary += `Phase: ${memory.session.current_phase}\n`;
1738
+ }
1739
+ summary += '\n';
1740
+ }
1741
+
1742
+ // Recent decisions
1743
+ if (memory.decisions.length > 0) {
1744
+ summary += `## Recent Decisions\n`;
1745
+ const recent = memory.decisions.slice(-5);
1746
+ for (const d of recent) {
1747
+ summary += `- ${d.decision}\n`;
1748
+ }
1749
+ summary += '\n';
1750
+ }
1751
+
1752
+ // Recent notes
1753
+ if (memory.notes.length > 0) {
1754
+ summary += `## Notes\n`;
1755
+ const recent = memory.notes.slice(-5);
1756
+ for (const n of recent) {
1757
+ summary += `- [${n.category}] ${n.note}\n`;
1758
+ }
1759
+ }
1760
+
1761
+ return summary || 'No memory saved yet.';
1762
+ }
1763
+
1764
+ module.exports = {
1765
+ DEFAULT_MEMORY,
1766
+ loadMemory,
1767
+ saveMemory,
1768
+ updateProject,
1769
+ updateSession,
1770
+ addDecision,
1771
+ addNote,
1772
+ upsertEntity,
1773
+ getEntity,
1774
+ clearMemory,
1775
+ getMemorySummary,
1776
+ getMemoryPath,
1777
+ ensureMemoryDir,
1778
+ };
1779
+
1780
+
1781
+ /***/ }),
1782
+
1783
+ /***/ 251:
1784
+ /***/ ((module) => {
1785
+
1786
+ // =============================================================================
1787
+ // Role-based Profiles
1788
+ // =============================================================================
1789
+
1790
+ const PROFILES = {
1791
+ minimal: {
1792
+ name: 'Minimal',
1793
+ description: 'Core commands only (fastest install)',
1794
+ commands: ['start', 'plan', 'cook', 'fix'],
1795
+ agents: [],
1796
+ skills: [],
1797
+ includePresets: false,
1798
+ includeDocs: false,
1799
+ },
1800
+
1801
+ developer: {
1802
+ name: 'Developer',
1803
+ description: 'Daily coding (commands + basic agents)',
1804
+ commands: ['start', 'plan', 'cook', 'fix', 'scout', 'generate'],
1805
+ agents: ['planner', 'scout', 'fullstack-developer', 'debugger'],
1806
+ skills: ['frontend-development', 'backend-development', 'databases'],
1807
+ includePresets: false,
1808
+ includeDocs: false,
1809
+ },
1810
+
1811
+ ui_ux: {
1812
+ name: 'UI/UX Designer',
1813
+ description: 'Frontend & Design focus',
1814
+ commands: ['start', 'plan', 'cook', 'design-ui', 'generate'],
1815
+ agents: ['ui-ux-designer', 'design-system-architect', 'planner'],
1816
+ skills: ['frontend-development', 'frontend-design', 'ui-styling', 'aesthetic'],
1817
+ includePresets: false,
1818
+ includeDocs: false,
1819
+ },
1820
+
1821
+ architect: {
1822
+ name: 'Architect',
1823
+ description: 'System design & DDD',
1824
+ commands: ['start', 'plan', 'cook', 'fix', 'design-domain', 'review'],
1825
+ agents: ['planner', 'ddd-architect', 'code-reviewer', 'researcher'],
1826
+ skills: ['ddd-modular-monolith', 'planning', 'backend-development', 'databases'],
1827
+ includePresets: true,
1828
+ includeDocs: true,
1829
+ },
1830
+
1831
+ lead: {
1832
+ name: 'Team Lead',
1833
+ description: 'Code review & management',
1834
+ commands: ['start', 'plan', 'cook', 'fix', 'review', 'scout', 'summary'],
1835
+ agents: ['planner', 'code-reviewer', 'project-manager', 'docs-manager', 'git-manager'],
1836
+ skills: ['code-review', 'planning', 'debugging'],
1837
+ includePresets: false,
1838
+ includeDocs: true,
1839
+ },
1840
+
1841
+ fullstack: {
1842
+ name: 'Full Stack',
1843
+ description: 'Everything included',
1844
+ commands: 'all',
1845
+ agents: 'all',
1846
+ skills: 'all',
1847
+ includePresets: true,
1848
+ includeDocs: true,
1849
+ },
1850
+ };
1851
+
1852
+ function getProfile(name) {
1853
+ return PROFILES[name] || null;
1854
+ }
1855
+
1856
+ function getProfileList() {
1857
+ return Object.entries(PROFILES).map(([key, profile]) => ({
1858
+ key,
1859
+ name: profile.name,
1860
+ description: profile.description,
1861
+ }));
1862
+ }
1863
+
1864
+ function getProfileEstimate(profileKey) {
1865
+ const profile = PROFILES[profileKey];
1866
+ if (!profile) return null;
1867
+
1868
+ const estimates = {
1869
+ minimal: { files: 5, size: '~50KB' },
1870
+ developer: { files: 30, size: '~300KB' },
1871
+ ui_ux: { files: 25, size: '~250KB' },
1872
+ architect: { files: 50, size: '~500KB' },
1873
+ lead: { files: 40, size: '~400KB' },
1874
+ fullstack: { files: 400, size: '~5MB' },
1875
+ };
1876
+
1877
+ return estimates[profileKey] || { files: '?', size: '?' };
1878
+ }
1879
+
1880
+ module.exports = {
1881
+ PROFILES,
1882
+ getProfile,
1883
+ getProfileList,
1884
+ getProfileEstimate,
1885
+ };
1886
+
1887
+
1888
+ /***/ }),
1889
+
1890
+ /***/ 568:
1891
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
1892
+
1893
+ // =============================================================================
1894
+ // Size Calculator
1895
+ // =============================================================================
1896
+
1897
+ const fs = __nccwpck_require__(896);
1898
+ const path = __nccwpck_require__(928);
1899
+
1900
+ function countFilesRecursive(dir) {
1901
+ let count = 0;
1902
+ let size = 0;
1903
+
1904
+ if (!fs.existsSync(dir)) return { count: 0, size: 0 };
1905
+
1906
+ try {
1907
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
1908
+ for (const entry of entries) {
1909
+ const fullPath = path.join(dir, entry.name);
1910
+ if (entry.isDirectory()) {
1911
+ const sub = countFilesRecursive(fullPath);
1912
+ count += sub.count;
1913
+ size += sub.size;
1914
+ } else {
1915
+ count++;
1916
+ try {
1917
+ const stats = fs.statSync(fullPath);
1918
+ size += stats.size;
1919
+ } catch (e) {
1920
+ // Ignore
1921
+ }
1922
+ }
1923
+ }
1924
+ } catch (e) {
1925
+ // Ignore
1926
+ }
1927
+
1928
+ return { count, size };
1929
+ }
1930
+
1931
+ function formatSize(bytes) {
1932
+ if (bytes < 1024) return `${bytes}B`;
1933
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
1934
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
1935
+ }
1936
+
1937
+ function calculateInstallSize(kitPath, components) {
1938
+ let totalFiles = 0;
1939
+ let totalSize = 0;
1940
+
1941
+ for (const comp of components) {
1942
+ const compPath = path.join(kitPath, comp);
1943
+ if (fs.existsSync(compPath)) {
1944
+ const stats = fs.statSync(compPath);
1945
+ if (stats.isDirectory()) {
1946
+ const { count, size } = countFilesRecursive(compPath);
1947
+ totalFiles += count;
1948
+ totalSize += size;
1949
+ } else {
1950
+ totalFiles++;
1951
+ totalSize += stats.size;
1952
+ }
1953
+ }
1954
+ }
1955
+
1956
+ return {
1957
+ files: totalFiles,
1958
+ size: totalSize,
1959
+ formatted: formatSize(totalSize),
1960
+ };
1961
+ }
1962
+
1963
+ function getComponentPaths(profile, kitPath) {
1964
+ const components = [];
1965
+
1966
+ // Commands
1967
+ if (profile.commands === 'all') {
1968
+ components.push('.cursor/commands');
1969
+ } else if (Array.isArray(profile.commands)) {
1970
+ profile.commands.forEach(cmd => {
1971
+ components.push(`.cursor/commands/${cmd}.md`);
1972
+ });
1973
+ }
1974
+
1975
+ // Agents
1976
+ if (profile.agents === 'all') {
1977
+ components.push('.cursor/agents');
1978
+ } else if (Array.isArray(profile.agents)) {
1979
+ profile.agents.forEach(agent => {
1980
+ components.push(`.cursor/agents/${agent}.md`);
1981
+ });
1982
+ }
1983
+
1984
+ // Skills
1985
+ if (profile.skills === 'all') {
1986
+ components.push('.cursor/skills');
1987
+ } else if (Array.isArray(profile.skills)) {
1988
+ profile.skills.forEach(skill => {
1989
+ components.push(`.cursor/skills/${skill}`);
1990
+ });
1991
+ }
1992
+
1993
+ // Extras
1994
+ if (profile.includePresets) {
1995
+ components.push('presets');
1996
+ }
1997
+ if (profile.includeDocs) {
1998
+ components.push('docs');
1999
+ }
2000
+
2001
+ // Always include
2002
+ components.push('.cursorrules');
2003
+ components.push('CURSOR.md');
2004
+
2005
+ return components;
2006
+ }
2007
+
2008
+ module.exports = {
2009
+ countFilesRecursive,
2010
+ formatSize,
2011
+ calculateInstallSize,
2012
+ getComponentPaths,
2013
+ };
2014
+
2015
+
2016
+ /***/ }),
2017
+
2018
+ /***/ 548:
2019
+ /***/ ((module) => {
2020
+
2021
+ // =============================================================================
2022
+ // Skill Packs (Bundled Skills)
2023
+ // =============================================================================
2024
+
2025
+ const SKILL_PACKS = {
2026
+ frontend: {
2027
+ name: 'Frontend Pack',
2028
+ description: 'UI development skills',
2029
+ skills: [
2030
+ 'frontend-development',
2031
+ 'frontend-design',
2032
+ 'ui-styling',
2033
+ 'aesthetic',
2034
+ ],
2035
+ },
2036
+
2037
+ backend: {
2038
+ name: 'Backend Pack',
2039
+ description: 'Server & database skills',
2040
+ skills: [
2041
+ 'backend-development',
2042
+ 'databases',
2043
+ 'better-auth',
2044
+ ],
2045
+ },
2046
+
2047
+ fullstack: {
2048
+ name: 'Fullstack Pack',
2049
+ description: 'Frontend + Backend combined',
2050
+ skills: [
2051
+ 'frontend-development',
2052
+ 'frontend-design',
2053
+ 'ui-styling',
2054
+ 'backend-development',
2055
+ 'databases',
2056
+ 'better-auth',
2057
+ 'web-frameworks',
2058
+ ],
2059
+ },
2060
+
2061
+ ddd: {
2062
+ name: 'DDD Pack',
2063
+ description: 'Domain-Driven Design skills',
2064
+ skills: [
2065
+ 'ddd-modular-monolith',
2066
+ 'planning',
2067
+ 'debugging',
2068
+ ],
2069
+ },
2070
+
2071
+ devops: {
2072
+ name: 'DevOps Pack',
2073
+ description: 'CI/CD & infrastructure',
2074
+ skills: [
2075
+ 'devops',
2076
+ 'debugging',
2077
+ ],
2078
+ },
2079
+
2080
+ ai: {
2081
+ name: 'AI Tools Pack',
2082
+ description: 'AI integration skills',
2083
+ skills: [
2084
+ 'ai-multimodal',
2085
+ 'mcp-builder',
2086
+ 'mcp-management',
2087
+ ],
2088
+ },
2089
+
2090
+ mobile: {
2091
+ name: 'Mobile Pack',
2092
+ description: 'Mobile development',
2093
+ skills: [
2094
+ 'mobile-development',
2095
+ 'frontend-development',
2096
+ ],
2097
+ },
2098
+ };
2099
+
2100
+ function getSkillPack(name) {
2101
+ return SKILL_PACKS[name] || null;
2102
+ }
2103
+
2104
+ function getSkillPackList() {
2105
+ return Object.entries(SKILL_PACKS).map(([key, pack]) => ({
2106
+ key,
2107
+ name: pack.name,
2108
+ description: pack.description,
2109
+ skillCount: pack.skills.length,
2110
+ }));
2111
+ }
2112
+
2113
+ function resolveSkillPacks(packKeys) {
2114
+ const skills = new Set();
2115
+ for (const key of packKeys) {
2116
+ const pack = SKILL_PACKS[key];
2117
+ if (pack) {
2118
+ pack.skills.forEach(s => skills.add(s));
2119
+ }
2120
+ }
2121
+ return Array.from(skills);
2122
+ }
2123
+
2124
+ module.exports = {
2125
+ SKILL_PACKS,
2126
+ getSkillPack,
2127
+ getSkillPackList,
2128
+ resolveSkillPacks,
2129
+ };
2130
+
2131
+
2132
+ /***/ }),
2133
+
2134
+ /***/ 896:
2135
+ /***/ ((module) => {
2136
+
2137
+ "use strict";
2138
+ module.exports = require("fs");
2139
+
2140
+ /***/ }),
2141
+
2142
+ /***/ 692:
2143
+ /***/ ((module) => {
2144
+
2145
+ "use strict";
2146
+ module.exports = require("https");
2147
+
2148
+ /***/ }),
2149
+
2150
+ /***/ 928:
2151
+ /***/ ((module) => {
2152
+
2153
+ "use strict";
2154
+ module.exports = require("path");
2155
+
2156
+ /***/ }),
2157
+
2158
+ /***/ 785:
2159
+ /***/ ((module) => {
2160
+
2161
+ "use strict";
2162
+ module.exports = require("readline");
2163
+
2164
+ /***/ })
2165
+
2166
+ /******/ });
2167
+ /************************************************************************/
2168
+ /******/ // The module cache
2169
+ /******/ var __webpack_module_cache__ = {};
2170
+ /******/
2171
+ /******/ // The require function
2172
+ /******/ function __nccwpck_require__(moduleId) {
2173
+ /******/ // Check if module is in cache
2174
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
2175
+ /******/ if (cachedModule !== undefined) {
2176
+ /******/ return cachedModule.exports;
2177
+ /******/ }
2178
+ /******/ // Create a new module (and put it into the cache)
2179
+ /******/ var module = __webpack_module_cache__[moduleId] = {
2180
+ /******/ // no module.id needed
2181
+ /******/ // no module.loaded needed
2182
+ /******/ exports: {}
2183
+ /******/ };
2184
+ /******/
2185
+ /******/ // Execute the module function
2186
+ /******/ var threw = true;
2187
+ /******/ try {
2188
+ /******/ __webpack_modules__[moduleId](module, module.exports, __nccwpck_require__);
2189
+ /******/ threw = false;
2190
+ /******/ } finally {
2191
+ /******/ if(threw) delete __webpack_module_cache__[moduleId];
2192
+ /******/ }
2193
+ /******/
2194
+ /******/ // Return the exports of the module
2195
+ /******/ return module.exports;
2196
+ /******/ }
2197
+ /******/
2198
+ /************************************************************************/
2199
+ /******/ /* webpack/runtime/compat */
2200
+ /******/
2201
+ /******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
2202
+ /******/
2203
+ /************************************************************************/
2204
+ var __webpack_exports__ = {};
2205
+
2206
+ // =============================================================================
2207
+ // anchi-toolkit CLI
2208
+ // Usage: npx anchi-toolkit install
2209
+ // =============================================================================
2210
+
2211
+ const fs = __nccwpck_require__(896);
2212
+ const path = __nccwpck_require__(928);
2213
+ const readline = __nccwpck_require__(785);
2214
+
2215
+ // =============================================================================
2216
+ // COLORS
2217
+ // =============================================================================
2218
+ const colors = {
2219
+ reset: '\x1b[0m',
2220
+ red: '\x1b[31m',
2221
+ green: '\x1b[32m',
2222
+ yellow: '\x1b[33m',
2223
+ cyan: '\x1b[36m',
2224
+ gray: '\x1b[90m',
2225
+ };
2226
+
2227
+ const log = {
2228
+ info: (msg) => console.log(`${colors.cyan}${msg}${colors.reset}`),
2229
+ success: (msg) => console.log(`${colors.green}${msg}${colors.reset}`),
2230
+ warn: (msg) => console.log(`${colors.yellow}${msg}${colors.reset}`),
2231
+ error: (msg) => console.log(`${colors.red}${msg}${colors.reset}`),
2232
+ gray: (msg) => console.log(`${colors.gray}${msg}${colors.reset}`),
2233
+ };
2234
+
2235
+ // =============================================================================
2236
+ // HELPERS
2237
+ // =============================================================================
2238
+
2239
+ const rl = readline.createInterface({
2240
+ input: process.stdin,
2241
+ output: process.stdout,
2242
+ });
2243
+
2244
+ function ask(question) {
2245
+ return new Promise((resolve) => {
2246
+ rl.question(question, (answer) => {
2247
+ resolve(answer);
2248
+ });
2249
+ });
2250
+ }
2251
+
2252
+ function writeBanner() {
2253
+ console.log('');
2254
+ log.info('╔═══════════════════════════════════════════════════════════╗');
2255
+ log.info('║ 🚀 anchi-toolkit for Cursor AI ║');
2256
+ log.info('║ Cài đặt Cursor AI toolkit vào dự án có sẵn ║');
2257
+ log.info('╚═══════════════════════════════════════════════════════════╝');
2258
+ console.log('');
2259
+ }
2260
+
2261
+ async function askConflictResolution(filePath, isForce = false) {
2262
+ // Force mode: auto-overwrite
2263
+ if (isForce) {
2264
+ log.gray(` 🔄 Force mode: auto-overwrite ${filePath}`);
2265
+ return 'O';
2266
+ }
2267
+
2268
+ console.log('');
2269
+ log.warn(`⚠️ File đã tồn tại: ${filePath}`);
2270
+ console.log(' [O] Overwrite - Ghi đè (backup file cũ)');
2271
+ console.log(' [S] Skip - Bỏ qua, giữ file hiện tại');
2272
+ console.log(' [M] Merge - Tạo file .new để merge thủ công');
2273
+ console.log('');
2274
+
2275
+ while (true) {
2276
+ const choice = (await ask(' Chọn (O/S/M): ')).toUpperCase();
2277
+ if (['O', 'S', 'M'].includes(choice)) {
2278
+ return choice;
2279
+ }
2280
+ console.log(' Vui lòng chọn O, S, hoặc M');
2281
+ }
2282
+ }
2283
+
2284
+ function backupFile(filePath) {
2285
+ const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace('T', '_').slice(0, 15);
2286
+ const backupPath = `${filePath}.backup_${timestamp}`;
2287
+ fs.copyFileSync(filePath, backupPath);
2288
+ log.gray(` 📦 Backup: ${backupPath}`);
2289
+ return backupPath;
2290
+ }
2291
+
2292
+ function copyDirRecursive(src, dest) {
2293
+ if (!fs.existsSync(dest)) {
2294
+ fs.mkdirSync(dest, { recursive: true });
2295
+ }
2296
+
2297
+ const entries = fs.readdirSync(src, { withFileTypes: true });
2298
+
2299
+ for (const entry of entries) {
2300
+ const srcPath = path.join(src, entry.name);
2301
+ const destPath = path.join(dest, entry.name);
2302
+
2303
+ if (entry.isDirectory()) {
2304
+ copyDirRecursive(srcPath, destPath);
2305
+ } else {
2306
+ fs.copyFileSync(srcPath, destPath);
2307
+ }
2308
+ }
2309
+ }
2310
+
2311
+ async function copyWithConflictHandling(source, destination, isDirectory, isForce = false) {
2312
+ if (isDirectory) {
2313
+ if (fs.existsSync(destination)) {
2314
+ // Directory exists - copy contents with per-file handling
2315
+ const files = getAllFiles(source);
2316
+ for (const srcFile of files) {
2317
+ const relativePath = path.relative(source, srcFile);
2318
+ const destFile = path.join(destination, relativePath);
2319
+ const destDir = path.dirname(destFile);
2320
+
2321
+ if (!fs.existsSync(destDir)) {
2322
+ fs.mkdirSync(destDir, { recursive: true });
2323
+ }
2324
+
2325
+ if (fs.existsSync(destFile)) {
2326
+ const choice = await askConflictResolution(relativePath, isForce);
2327
+ switch (choice) {
2328
+ case 'O':
2329
+ backupFile(destFile);
2330
+ fs.copyFileSync(srcFile, destFile);
2331
+ log.success(` ✅ Overwrote: ${relativePath}`);
2332
+ break;
2333
+ case 'S':
2334
+ log.gray(` ⏭️ Skipped: ${relativePath}`);
2335
+ break;
2336
+ case 'M':
2337
+ fs.copyFileSync(srcFile, `${destFile}.new`);
2338
+ log.warn(` 📝 Merge manually: ${relativePath} vs ${relativePath}.new`);
2339
+ break;
2340
+ }
2341
+ } else {
2342
+ fs.copyFileSync(srcFile, destFile);
2343
+ }
2344
+ }
2345
+ } else {
2346
+ copyDirRecursive(source, destination);
2347
+ log.success(` ✅ Copied: ${path.basename(source)}/`);
2348
+ }
2349
+ } else {
2350
+ if (fs.existsSync(destination)) {
2351
+ const choice = await askConflictResolution(path.basename(destination), isForce);
2352
+ switch (choice) {
2353
+ case 'O':
2354
+ backupFile(destination);
2355
+ fs.copyFileSync(source, destination);
2356
+ log.success(` ✅ Overwrote: ${path.basename(destination)}`);
2357
+ break;
2358
+ case 'S':
2359
+ log.gray(` ⏭️ Skipped: ${path.basename(destination)}`);
2360
+ break;
2361
+ case 'M':
2362
+ fs.copyFileSync(source, `${destination}.new`);
2363
+ log.warn(` 📝 Merge manually: ${path.basename(destination)} vs ${path.basename(destination)}.new`);
2364
+ break;
2365
+ }
2366
+ } else {
2367
+ fs.copyFileSync(source, destination);
2368
+ log.success(` ✅ Copied: ${path.basename(destination)}`);
2369
+ }
2370
+ }
2371
+ }
2372
+
2373
+ function getAllFiles(dir, files = []) {
2374
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
2375
+ for (const entry of entries) {
2376
+ const fullPath = path.join(dir, entry.name);
2377
+ if (entry.isDirectory()) {
2378
+ getAllFiles(fullPath, files);
2379
+ } else {
2380
+ files.push(fullPath);
2381
+ }
2382
+ }
2383
+ return files;
2384
+ }
2385
+
2386
+ // =============================================================================
2387
+ // ANTIGRAVITY INSTALL
2388
+ // =============================================================================
2389
+
2390
+ async function installAntigravity(isForce = false) {
2391
+ console.log('');
2392
+ log.info('╔═══════════════════════════════════════════════════════════╗');
2393
+ log.info('║ 🌌 anchi-toolkit for Antigravity (Gemini) ║');
2394
+ log.info('║ All-in-One Installation ║');
2395
+ log.info('╚═══════════════════════════════════════════════════════════╝');
2396
+ console.log('');
2397
+
2398
+ const targetPath = process.cwd();
2399
+ const kitPath = path.resolve(__dirname, '..');
2400
+
2401
+ log.gray(`📁 Kit source: ${kitPath}`);
2402
+ log.gray(`📂 Target: ${targetPath}`);
2403
+ console.log('');
2404
+
2405
+ // Show what will be installed - ALL into .antigravity/
2406
+ log.warn('📦 Installing:');
2407
+ console.log(' ├── .antigravity/ 19 commands, 19 agents, 35 skills');
2408
+ console.log(' ├── .ai-audit/ Decision logging');
2409
+ console.log(' ├── .ai-memory/ Context storage');
2410
+ console.log(' └── presets/docs Architecture & docs');
2411
+ console.log('');
2412
+
2413
+ if (!isForce) {
2414
+ const confirm = await ask('Tiếp tục cài đặt? (Y/n): ');
2415
+ if (confirm.toLowerCase() === 'n') {
2416
+ log.error('❌ Đã hủy.');
2417
+ rl.close();
2418
+ process.exit(0);
2419
+ }
2420
+ } else {
2421
+ log.info('🚀 Force mode: skipping confirmation...');
2422
+ }
2423
+
2424
+ console.log('');
2425
+ log.warn('📋 Installing anchi-toolkit for Antigravity...');
2426
+ console.log('');
2427
+
2428
+ const antigravityDest = __nccwpck_require__.ab + ".antigravity";
2429
+
2430
+ // Ensure .antigravity folder exists
2431
+ if (!fs.existsSync(__nccwpck_require__.ab + ".antigravity")) {
2432
+ fs.mkdirSync(__nccwpck_require__.ab + ".antigravity", { recursive: true });
2433
+ }
2434
+
2435
+ // 1. Copy .antigravity folder (workflows, agents, skills)
2436
+ const agentSource = __nccwpck_require__.ab + ".antigravity";
2437
+ if (fs.existsSync(__nccwpck_require__.ab + ".antigravity")) {
2438
+ await copyWithConflictHandling(agentSource, antigravityDest, true, isForce);
2439
+ log.success(' ✅ workflows/ - 18 commands');
2440
+ log.success(' ✅ agents/ - 19 agents');
2441
+ log.success(' ✅ skills/ - 35 skills');
2442
+ } else {
2443
+ log.error(` ❌ .antigravity folder not found at: ${agentSource}`);
2444
+ }
2445
+
2446
+ // 2. Copy presets INTO .antigravity/presets/
2447
+ const presetsSource = __nccwpck_require__.ab + "presets";
2448
+ const presetsDest = path.join(antigravityDest, 'presets');
2449
+ if (fs.existsSync(__nccwpck_require__.ab + "presets")) {
2450
+ await copyWithConflictHandling(presetsSource, presetsDest, true, isForce);
2451
+ log.success(' ✅ presets/ - 3 architecture presets');
2452
+ }
2453
+
2454
+ // 3. Copy docs INTO .antigravity/docs/
2455
+ const docsSource = __nccwpck_require__.ab + "docs";
2456
+ const docsDest = path.join(antigravityDest, 'docs');
2457
+ if (fs.existsSync(__nccwpck_require__.ab + "docs")) {
2458
+ await copyWithConflictHandling(docsSource, docsDest, true, isForce);
2459
+ log.success(' ✅ docs/ - Documentation');
2460
+ }
2461
+
2462
+ // 4. Copy config files from .cursor to .antigravity
2463
+ const configFiles = [
2464
+ 'orchestration.yaml',
2465
+ 'failure-modes.yaml',
2466
+ 'agent-skill-index.yaml',
2467
+ 'team.yaml',
2468
+ 'anchi-toolkit.config.yaml'
2469
+ ];
2470
+
2471
+ for (const configFile of configFiles) {
2472
+ // First check if exists in .antigravity source
2473
+ let configSource = __nccwpck_require__.ab + ".antigravity/" + configFile;
2474
+ if (!fs.existsSync(configSource)) {
2475
+ // Fallback to .cursor
2476
+ configSource = __nccwpck_require__.ab + ".cursor/" + configFile;
2477
+ }
2478
+ const configDest = __nccwpck_require__.ab + ".antigravity/" + configFile;
2479
+ if (fs.existsSync(configSource) && !fs.existsSync(configDest)) {
2480
+ fs.copyFileSync(configSource, configDest);
2481
+ }
2482
+ }
2483
+ // 5. Create .ai-audit folder (for logging)
2484
+ const auditSource = path.join(kitPath, '.ai-audit');
2485
+ const auditDest = path.join(antigravityDest, '.ai-audit'); // Inside .antigravity
2486
+ if (fs.existsSync(auditSource)) {
2487
+ await copyWithConflictHandling(auditSource, auditDest, true, isForce);
2488
+ log.success(' ✅ .ai-audit/ - Decision logs');
2489
+ }
2490
+
2491
+ // 6. Create .ai-memory folder (for context)
2492
+ const memorySource = __nccwpck_require__.ab + ".ai-memory";
2493
+ const memoryDest = path.join(antigravityDest, '.ai-memory'); // Inside .antigravity
2494
+ if (fs.existsSync(__nccwpck_require__.ab + ".ai-memory")) {
2495
+ await copyWithConflictHandling(memorySource, memoryDest, true, isForce);
2496
+ log.success(' ✅ .ai-memory/ - Context storage');
2497
+ }
2498
+
2499
+ // 7. Create scripts folder (for setup)
2500
+ const scriptsSource = __nccwpck_require__.ab + "scripts";
2501
+ const scriptsDest = path.join(antigravityDest, 'scripts');
2502
+ if (fs.existsSync(__nccwpck_require__.ab + "scripts")) {
2503
+ await copyWithConflictHandling(scriptsSource, scriptsDest, true, isForce);
2504
+ log.success(' ✅ scripts/ - Setup tools');
2505
+ }
2506
+
2507
+ // 8. Copy ANTIGRAVITY.md to root (entry point doc)
2508
+ const antigravityMdPath = __nccwpck_require__.ab + "ANTIGRAVITY.md";
2509
+ if (fs.existsSync(__nccwpck_require__.ab + "ANTIGRAVITY.md")) {
2510
+ fs.copyFileSync(antigravityMdPath, path.join(targetPath, 'ANTIGRAVITY.md'));
2511
+ log.success(' ✅ ANTIGRAVITY.md (root)');
2512
+ }
2513
+
2514
+ // =====================================================================
2515
+ // SUCCESS MESSAGE - Clear Next Steps
2516
+ // =====================================================================
2517
+ console.log('');
2518
+ console.log('');
2519
+ log.success('╔═══════════════════════════════════════════════════════════╗');
2520
+ log.success('║ ✅ INSTALLATION COMPLETE! ║');
2521
+ log.success('╚═══════════════════════════════════════════════════════════╝');
2522
+ console.log('');
2523
+ log.info('📂 Installed to: .antigravity/');
2524
+ console.log('');
2525
+ console.log('╭───────────────────────────────────────────────────────────╮');
2526
+ console.log('│ │');
2527
+ log.success('│ 🚀 START NOW: Open Antigravity Chat and type: │');
2528
+ console.log('│ │');
2529
+ log.warn('│ /start │');
2530
+ console.log('│ │');
2531
+ console.log('╰───────────────────────────────────────────────────────────╯');
2532
+ console.log('');
2533
+ log.gray('Other commands: /do, /commit, /test, /help');
2534
+ console.log('');
2535
+
2536
+ rl.close();
2537
+ }
2538
+
2539
+
2540
+ // =============================================================================
2541
+ // MAIN
2542
+ // =============================================================================
2543
+
2544
+ async function install(isForce = false) {
2545
+ writeBanner();
2546
+
2547
+ const targetPath = process.cwd();
2548
+ const kitPath = path.resolve(__dirname, '..');
2549
+
2550
+ log.gray(`📁 Kit source: ${kitPath}`);
2551
+ log.gray(`📂 Target: ${targetPath}`);
2552
+ console.log('');
2553
+
2554
+ if (!isForce) {
2555
+ const confirm = await ask('Tiếp tục cài đặt? (Y/n): ');
2556
+ if (confirm.toLowerCase() === 'n') {
2557
+ log.error('❌ Đã hủy.');
2558
+ rl.close();
2559
+ process.exit(0);
2560
+ }
2561
+ } else {
2562
+ log.info('🚀 Force mode: skipping confirmation...');
2563
+ }
2564
+
2565
+ console.log('');
2566
+ log.warn('📋 Installing anchi-toolkit components...');
2567
+ console.log('');
2568
+
2569
+ // Components to install (Cursor AI specific)
2570
+ const cursorDest = __nccwpck_require__.ab + ".cursor";
2571
+ if (!fs.existsSync(__nccwpck_require__.ab + ".cursor")) fs.mkdirSync(__nccwpck_require__.ab + ".cursor", { recursive: true });
2572
+
2573
+ const components = [
2574
+ // Folders go INSIDE .cursor/
2575
+ { source: '.cursor', dest: '.cursor', isDir: true, desc: 'Cursor commands, agents, skills' },
2576
+ { source: 'presets', dest: '.cursor/presets', isDir: true, desc: 'Architecture presets' },
2577
+ { source: 'docs', dest: '.cursor/docs', isDir: true, desc: 'Documentation templates' },
2578
+ { source: 'scripts', dest: '.cursor/scripts', isDir: true, desc: 'Setup scripts' },
2579
+ { source: '.ai-audit', dest: '.cursor/.ai-audit', isDir: true, desc: 'AI decision logs' },
2580
+ { source: '.ai-memory', dest: '.cursor/.ai-memory', isDir: true, desc: 'Context storage' },
2581
+
2582
+ // Root files (Required for IDE)
2583
+ { source: '.cursorrules', dest: '.cursorrules', isDir: false, desc: 'Cursor rules (Root)' },
2584
+ { source: 'CURSOR.md', dest: 'CURSOR.md', isDir: false, desc: 'AI instructions (Root)' },
2585
+ ];
2586
+
2587
+ for (const comp of components) {
2588
+ const sourcePath = path.join(kitPath, comp.source);
2589
+ const destPath = path.join(targetPath, comp.dest);
2590
+
2591
+ if (fs.existsSync(sourcePath)) {
2592
+ log.info(` 📦 ${comp.desc}...`);
2593
+ await copyWithConflictHandling(sourcePath, destPath, comp.isDir, isForce);
2594
+ }
2595
+ }
2596
+
2597
+ console.log('');
2598
+ log.info('═══════════════════════════════════════════════════════════════');
2599
+ log.success(' ✅ anchi-toolkit đã được cài đặt thành công!');
2600
+ log.info('═══════════════════════════════════════════════════════════════');
2601
+ console.log('');
2602
+ log.warn('📌 Bước tiếp theo:');
2603
+ console.log('');
2604
+ console.log(' 1. Mở Cursor IDE và chạy:');
2605
+ log.success(' /start');
2606
+ console.log('');
2607
+ console.log(' 2. Chọn preset phù hợp:');
2608
+ log.success(' /use-preset rapid|professional|enterprise');
2609
+ console.log('');
2610
+ console.log(' 3. Bắt đầu code:');
2611
+ log.success(' /plan "Feature description"');
2612
+ console.log('');
2613
+
2614
+ rl.close();
2615
+ }
2616
+
2617
+ // Command handler
2618
+ const args = process.argv.slice(2);
2619
+ const flags = args.filter(a => a.startsWith('-'));
2620
+ const commands = args.filter(a => !a.startsWith('-'));
2621
+ const command = commands[0];
2622
+ const isForce = flags.includes('-y') || flags.includes('--force');
2623
+
2624
+ async function main() {
2625
+ switch (command) {
2626
+ case 'install':
2627
+ await install(isForce);
2628
+ break;
2629
+
2630
+ case 'init':
2631
+ const { init } = __nccwpck_require__(816);
2632
+ await init();
2633
+ break;
2634
+
2635
+ case 'update':
2636
+ const { update } = __nccwpck_require__(779);
2637
+ await update();
2638
+ break;
2639
+
2640
+ case 'uninstall':
2641
+ const { uninstall } = __nccwpck_require__(66);
2642
+ await uninstall();
2643
+ break;
2644
+
2645
+ case 'doctor':
2646
+ const { doctor } = __nccwpck_require__(181);
2647
+ await doctor();
2648
+ break;
2649
+
2650
+ case 'memory':
2651
+ const { memory } = __nccwpck_require__(697);
2652
+ await memory(args[1], args[2]);
2653
+ break;
2654
+
2655
+ case 'antigravity':
2656
+ await installAntigravity(isForce);
2657
+ break;
2658
+
2659
+ case 'clean':
2660
+ const { clean } = __nccwpck_require__(1);
2661
+ await clean(process.cwd(), {
2662
+ all: flags.includes('--all'),
2663
+ memory: flags.includes('--memory'),
2664
+ audit: flags.includes('--audit'),
2665
+ force: isForce
2666
+ });
2667
+ break;
2668
+
2669
+ default:
2670
+ showHelp();
2671
+ break;
2672
+ }
2673
+ }
2674
+
2675
+ function showHelp() {
2676
+ console.log('');
2677
+ log.info('🚀 anchi-toolkit - Cursor AI & Antigravity Toolkit');
2678
+ console.log('');
2679
+ console.log('Commands:');
2680
+ log.success(' npx anchi-toolkit install Cài đặt cho Cursor AI');
2681
+ log.success(' npx anchi-toolkit antigravity Cài đặt cho Antigravity (Gemini)');
2682
+ log.success(' npx anchi-toolkit init Cài đặt thông minh (chọn profile)');
2683
+ log.success(' npx anchi-toolkit update Kiểm tra cập nhật');
2684
+ log.success(' npx anchi-toolkit uninstall Gỡ cài đặt');
2685
+ log.success(' npx anchi-toolkit doctor Kiểm tra setup health');
2686
+ log.success(' npx anchi-toolkit memory Quản lý project context');
2687
+ log.success(' npx anchi-toolkit clean Dọn dẹp context/logs');
2688
+ console.log('');
2689
+ console.log('Flags:');
2690
+ log.success(' -y, --force Bỏ qua tất cả prompts (auto-overwrite)');
2691
+ console.log('');
2692
+ console.log('Examples:');
2693
+ log.gray(' npx anchi-toolkit install -y # Non-interactive install');
2694
+ log.gray(' npx anchi-toolkit antigravity -y # Non-interactive Antigravity install');
2695
+ console.log('');
2696
+ console.log('Documentation:');
2697
+ console.log(' https://github.com/ANCHI-STE/anchi-webkit-dev');
2698
+ console.log('');
2699
+ }
2700
+
2701
+ main().catch((err) => {
2702
+ log.error(`❌ Error: ${err.message}`);
2703
+ rl.close();
2704
+ process.exit(1);
2705
+ });
2706
+
2707
+ module.exports = __webpack_exports__;
2708
+ /******/ })()
2709
+ ;