anchi-toolkit 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.ai-audit/README.md +53 -0
  2. package/.ai-memory/README.md +137 -0
  3. package/.ai-memory/context.json +26 -0
  4. package/.ai-memory/decisions.json +3 -0
  5. package/.antigravity/agent-skill-index.yaml +24 -0
  6. package/.antigravity/anchi-toolkit.config.yaml +12 -0
  7. package/.antigravity/docs/README.md +9 -0
  8. package/.antigravity/skills/_template.md +30 -0
  9. package/.antigravity/team.yaml +154 -0
  10. package/.antigravity/workflows/config.md +144 -0
  11. package/.antigravity/workflows/demo.md +50 -0
  12. package/.antigravity/workflows/help.md +11 -4
  13. package/.antigravity/workflows/skill-learn.md +48 -0
  14. package/.antigravity/workflows/start.md +38 -117
  15. package/.antigravity/workflows/status.md +8 -8
  16. package/.antigravity/workflows/undo.md +7 -7
  17. package/.cursor/agent-skill-index.yaml +39 -0
  18. package/.cursor/agents/graph-architect.md +30 -0
  19. package/.cursor/agents/trend-watcher.md +24 -0
  20. package/.cursor/commands/config.md +144 -0
  21. package/.cursor/commands/demo.md +50 -0
  22. package/.cursor/commands/do.md +127 -90
  23. package/.cursor/commands/help.md +23 -16
  24. package/.cursor/commands/skill-learn.md +48 -0
  25. package/.cursor/commands/start.md +38 -117
  26. package/.cursor/commands/status.md +19 -19
  27. package/.cursor/commands/undo.md +19 -19
  28. package/.cursor/orchestration.yaml +18 -0
  29. package/.cursor/skills/_template.md +30 -0
  30. package/ANTIGRAVITY.md +84 -0
  31. package/CURSOR.md +50 -157
  32. package/LICENSE +17 -14
  33. package/README.md +64 -89
  34. package/docs/ALL_COMMANDS.md +31 -73
  35. package/docs/CI_CD.md +44 -0
  36. package/docs/COMPARISON.md +65 -0
  37. package/docs/ROADMAP.md +45 -161
  38. package/docs/WORKFLOW.md +56 -317
  39. package/package.json +9 -2
  40. package/presets/ci-cd/ai-review.yml +49 -0
  41. package/scripts/install-hooks.ps1 +21 -7
  42. package/scripts/install-hooks.sh +18 -3
  43. package/src/cli.js +111 -59
  44. package/src/commands/clean.js +87 -0
  45. package/src/commands/doctor.js +88 -21
  46. package/src/commands/init.js +22 -2
  47. package/src/commands/uninstall.js +17 -2
  48. package/src/lib/configManager.js +20 -5
  49. package/src/lib/memoryManager.js +7 -4
  50. package/docs/CODEBASE.md +0 -178
  51. package/docs/COMMAND_MAPPING.md +0 -217
  52. package/docs/FAQ.md +0 -174
  53. package/docs/ONBOARDING.md +0 -111
  54. package/docs/ORCHESTRATION_RUNTIME.md +0 -173
  55. package/docs/WALKTHROUGH.md +0 -192
  56. /package/.cursor/{anchi-kit.config.yaml → anchi-toolkit.config.yaml} +0 -0
package/src/cli.js CHANGED
@@ -186,8 +186,8 @@ function getAllFiles(dir, files = []) {
186
186
  async function installAntigravity(isForce = false) {
187
187
  console.log('');
188
188
  log.info('╔═══════════════════════════════════════════════════════════╗');
189
- log.info('║ 🌌 anchi-toolkit for Antigravity (Gemini) ║');
190
- log.info('║ Complete Installation Package ║');
189
+ log.info('║ 🌌 anchi-toolkit for Antigravity (Gemini) ║');
190
+ log.info('║ All-in-One Installation ║');
191
191
  log.info('╚═══════════════════════════════════════════════════════════╝');
192
192
  console.log('');
193
193
 
@@ -198,19 +198,16 @@ async function installAntigravity(isForce = false) {
198
198
  log.gray(`📂 Target: ${targetPath}`);
199
199
  console.log('');
200
200
 
201
- // Show what will be installed
202
- log.warn('📦 Components to install:');
203
- console.log(' ├── .antigravity/workflows/ 18 commands');
204
- console.log(' ├── .antigravity/agents/ 19 agents');
205
- console.log(' ├── .antigravity/skills/ 35 skills');
206
- console.log(' ├── presets/ 3 presets');
207
- console.log(' ├── docs/ Documentation');
208
- console.log(' ├── GEMINI.md AI instructions');
209
- console.log(' └── ANTIGRAVITY.md Antigravity config');
201
+ // Show what will be installed - ALL into .antigravity/
202
+ log.warn('📦 Installing:');
203
+ console.log(' ├── .antigravity/ 19 commands, 19 agents, 35 skills');
204
+ console.log(' ├── .ai-audit/ Decision logging');
205
+ console.log(' ├── .ai-memory/ Context storage');
206
+ console.log(' └── presets/docs Architecture & docs');
210
207
  console.log('');
211
208
 
212
209
  if (!isForce) {
213
- const confirm = await ask('Tiếp tục cài đặt cho Antigravity? (Y/n): ');
210
+ const confirm = await ask('Tiếp tục cài đặt? (Y/n): ');
214
211
  if (confirm.toLowerCase() === 'n') {
215
212
  log.error('❌ Đã hủy.');
216
213
  rl.close();
@@ -224,77 +221,112 @@ async function installAntigravity(isForce = false) {
224
221
  log.warn('📋 Installing anchi-toolkit for Antigravity...');
225
222
  console.log('');
226
223
 
227
- // 1. Copy .antigravity folder (core)
228
- const agentSource = path.join(kitPath, '.antigravity');
229
- const agentDest = path.join(targetPath, '.antigravity');
224
+ const antigravityDest = path.join(targetPath, '.antigravity');
225
+
226
+ // Ensure .antigravity folder exists
227
+ if (!fs.existsSync(antigravityDest)) {
228
+ fs.mkdirSync(antigravityDest, { recursive: true });
229
+ }
230
230
 
231
+ // 1. Copy .antigravity folder (workflows, agents, skills)
232
+ const agentSource = path.join(kitPath, '.antigravity');
231
233
  if (fs.existsSync(agentSource)) {
232
- log.gray(` 📂 Source: ${agentSource}`);
233
- await copyWithConflictHandling(agentSource, agentDest, true, isForce);
234
- log.success(' ✅ .antigravity/workflows/ - 18 commands');
235
- log.success(' ✅ .antigravity/agents/ - 19 agents');
236
- log.success(' ✅ .antigravity/skills/ - 35 skills');
234
+ await copyWithConflictHandling(agentSource, antigravityDest, true, isForce);
235
+ log.success(' ✅ workflows/ - 18 commands');
236
+ log.success(' ✅ agents/ - 19 agents');
237
+ log.success(' ✅ skills/ - 35 skills');
237
238
  } else {
238
239
  log.error(` ❌ .antigravity folder not found at: ${agentSource}`);
239
240
  }
240
241
 
241
- // 2. Copy presets
242
+ // 2. Copy presets INTO .antigravity/presets/
242
243
  const presetsSource = path.join(kitPath, 'presets');
243
- const presetsDest = path.join(targetPath, 'presets');
244
+ const presetsDest = path.join(antigravityDest, 'presets');
244
245
  if (fs.existsSync(presetsSource)) {
245
246
  await copyWithConflictHandling(presetsSource, presetsDest, true, isForce);
246
247
  log.success(' ✅ presets/ - 3 architecture presets');
247
248
  }
248
249
 
249
- // 3. Copy docs
250
+ // 3. Copy docs INTO .antigravity/docs/
250
251
  const docsSource = path.join(kitPath, 'docs');
251
- const docsDest = path.join(targetPath, 'docs');
252
+ const docsDest = path.join(antigravityDest, 'docs');
252
253
  if (fs.existsSync(docsSource)) {
253
254
  await copyWithConflictHandling(docsSource, docsDest, true, isForce);
254
- log.success(' ✅ docs/ - Documentation templates');
255
- }
256
-
257
- // 4. Copy AI instruction files
258
- const geminiMdPath = path.join(kitPath, 'GEMINI.md');
259
- if (fs.existsSync(geminiMdPath)) {
260
- fs.copyFileSync(geminiMdPath, path.join(targetPath, 'GEMINI.md'));
261
- log.success(' ✅ GEMINI.md');
255
+ log.success(' ✅ docs/ - Documentation');
262
256
  }
263
257
 
264
- const antigravityMdPath = path.join(kitPath, 'ANTIGRAVITY.md');
265
- if (fs.existsSync(antigravityMdPath)) {
266
- fs.copyFileSync(antigravityMdPath, path.join(targetPath, 'ANTIGRAVITY.md'));
267
- log.success(' ✅ ANTIGRAVITY.md');
268
- }
269
-
270
- // 5. Copy config files to .antigravity/
258
+ // 4. Copy config files from .cursor to .antigravity
271
259
  const configFiles = [
272
260
  'orchestration.yaml',
273
261
  'failure-modes.yaml',
274
262
  'agent-skill-index.yaml',
275
- 'team.yaml'
263
+ 'team.yaml',
264
+ 'anchi-toolkit.config.yaml'
276
265
  ];
277
266
 
278
267
  for (const configFile of configFiles) {
279
- const configSource = path.join(kitPath, '.cursor', configFile);
280
- const configDest = path.join(targetPath, '.antigravity', configFile);
281
- if (fs.existsSync(configSource)) {
268
+ // First check if exists in .antigravity source
269
+ let configSource = path.join(kitPath, '.antigravity', configFile);
270
+ if (!fs.existsSync(configSource)) {
271
+ // Fallback to .cursor
272
+ configSource = path.join(kitPath, '.cursor', configFile);
273
+ }
274
+ const configDest = path.join(antigravityDest, configFile);
275
+ if (fs.existsSync(configSource) && !fs.existsSync(configDest)) {
282
276
  fs.copyFileSync(configSource, configDest);
283
277
  }
284
278
  }
285
- log.success(' ✅ Config files (orchestration, failure-modes, etc.)');
279
+ // 5. Create .ai-audit folder (for logging)
280
+ const auditSource = path.join(kitPath, '.ai-audit');
281
+ const auditDest = path.join(antigravityDest, '.ai-audit'); // Inside .antigravity
282
+ if (fs.existsSync(auditSource)) {
283
+ await copyWithConflictHandling(auditSource, auditDest, true, isForce);
284
+ log.success(' ✅ .ai-audit/ - Decision logs');
285
+ }
286
286
 
287
+ // 6. Create .ai-memory folder (for context)
288
+ const memorySource = path.join(kitPath, '.ai-memory');
289
+ const memoryDest = path.join(antigravityDest, '.ai-memory'); // Inside .antigravity
290
+ if (fs.existsSync(memorySource)) {
291
+ await copyWithConflictHandling(memorySource, memoryDest, true, isForce);
292
+ log.success(' ✅ .ai-memory/ - Context storage');
293
+ }
294
+
295
+ // 7. Create scripts folder (for setup)
296
+ const scriptsSource = path.join(kitPath, 'scripts');
297
+ const scriptsDest = path.join(antigravityDest, 'scripts');
298
+ if (fs.existsSync(scriptsSource)) {
299
+ await copyWithConflictHandling(scriptsSource, scriptsDest, true, isForce);
300
+ log.success(' ✅ scripts/ - Setup tools');
301
+ }
302
+
303
+ // 8. Copy ANTIGRAVITY.md to root (entry point doc)
304
+ const antigravityMdPath = path.join(kitPath, 'ANTIGRAVITY.md');
305
+ if (fs.existsSync(antigravityMdPath)) {
306
+ fs.copyFileSync(antigravityMdPath, path.join(targetPath, 'ANTIGRAVITY.md'));
307
+ log.success(' ✅ ANTIGRAVITY.md (root)');
308
+ }
309
+
310
+ // =====================================================================
311
+ // SUCCESS MESSAGE - Clear Next Steps
312
+ // =====================================================================
313
+ console.log('');
314
+ console.log('');
315
+ log.success('╔═══════════════════════════════════════════════════════════╗');
316
+ log.success('║ ✅ INSTALLATION COMPLETE! ║');
317
+ log.success('╚═══════════════════════════════════════════════════════════╝');
318
+ console.log('');
319
+ log.info('📂 Installed to: .antigravity/');
287
320
  console.log('');
288
- log.success('══════════════════════════════════════════════════════════════');
289
- log.success(' ✅ anchi-toolkit for Antigravity installed!');
290
- log.success('══════════════════════════════════════════════════════════════');
321
+ console.log('╭───────────────────────────────────────────────────────────╮');
322
+ console.log('│ │');
323
+ log.success('│ 🚀 START NOW: Open Antigravity Chat and type: │');
324
+ console.log('│ │');
325
+ log.warn('│ /start │');
326
+ console.log('│ │');
327
+ console.log('╰───────────────────────────────────────────────────────────╯');
291
328
  console.log('');
292
- console.log('📌 Next steps:');
293
- log.info(' Open Antigravity Chat → Use slash commands:');
294
- log.info(' /start - Initialize project');
295
- log.info(' /do - Universal command');
296
- log.info(' /commit - Git operations');
297
- log.info(' /help - Show all commands');
329
+ log.gray('Other commands: /do, /commit, /test, /help');
298
330
  console.log('');
299
331
 
300
332
  rl.close();
@@ -331,17 +363,26 @@ async function install(isForce = false) {
331
363
  console.log('');
332
364
 
333
365
  // Components to install (Cursor AI specific)
366
+ const cursorDest = path.join(targetPath, '.cursor');
367
+ if (!fs.existsSync(cursorDest)) fs.mkdirSync(cursorDest, { recursive: true });
368
+
334
369
  const components = [
335
- { source: '.cursor', isDir: true, desc: 'Cursor commands, agents, skills' },
336
- { source: 'presets', isDir: true, desc: 'Architecture presets' },
337
- { source: 'docs', isDir: true, desc: 'Documentation templates' },
338
- { source: '.cursorrules', isDir: false, desc: 'Cursor rules' },
339
- { source: 'CURSOR.md', isDir: false, desc: 'AI instructions' },
370
+ // Folders go INSIDE .cursor/
371
+ { source: '.cursor', dest: '.cursor', isDir: true, desc: 'Cursor commands, agents, skills' },
372
+ { source: 'presets', dest: '.cursor/presets', isDir: true, desc: 'Architecture presets' },
373
+ { source: 'docs', dest: '.cursor/docs', isDir: true, desc: 'Documentation templates' },
374
+ { source: 'scripts', dest: '.cursor/scripts', isDir: true, desc: 'Setup scripts' },
375
+ { source: '.ai-audit', dest: '.cursor/.ai-audit', isDir: true, desc: 'AI decision logs' },
376
+ { source: '.ai-memory', dest: '.cursor/.ai-memory', isDir: true, desc: 'Context storage' },
377
+
378
+ // Root files (Required for IDE)
379
+ { source: '.cursorrules', dest: '.cursorrules', isDir: false, desc: 'Cursor rules (Root)' },
380
+ { source: 'CURSOR.md', dest: 'CURSOR.md', isDir: false, desc: 'AI instructions (Root)' },
340
381
  ];
341
382
 
342
383
  for (const comp of components) {
343
384
  const sourcePath = path.join(kitPath, comp.source);
344
- const destPath = path.join(targetPath, comp.source);
385
+ const destPath = path.join(targetPath, comp.dest);
345
386
 
346
387
  if (fs.existsSync(sourcePath)) {
347
388
  log.info(` 📦 ${comp.desc}...`);
@@ -411,6 +452,16 @@ async function main() {
411
452
  await installAntigravity(isForce);
412
453
  break;
413
454
 
455
+ case 'clean':
456
+ const { clean } = require('./commands/clean');
457
+ await clean(process.cwd(), {
458
+ all: flags.includes('--all'),
459
+ memory: flags.includes('--memory'),
460
+ audit: flags.includes('--audit'),
461
+ force: isForce
462
+ });
463
+ break;
464
+
414
465
  default:
415
466
  showHelp();
416
467
  break;
@@ -429,6 +480,7 @@ function showHelp() {
429
480
  log.success(' npx anchi-toolkit uninstall Gỡ cài đặt');
430
481
  log.success(' npx anchi-toolkit doctor Kiểm tra setup health');
431
482
  log.success(' npx anchi-toolkit memory Quản lý project context');
483
+ log.success(' npx anchi-toolkit clean Dọn dẹp context/logs');
432
484
  console.log('');
433
485
  console.log('Flags:');
434
486
  log.success(' -y, --force Bỏ qua tất cả prompts (auto-overwrite)');
@@ -0,0 +1,87 @@
1
+ // =============================================================================
2
+ // anchi-toolkit Clean Command
3
+ // Reset project context and logs
4
+ // =============================================================================
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const readline = require('readline');
9
+ const { getConfigDir } = require('../lib/configManager');
10
+
11
+ const rl = readline.createInterface({
12
+ input: process.stdin,
13
+ output: process.stdout,
14
+ });
15
+
16
+ function ask(question) {
17
+ return new Promise((resolve) => {
18
+ rl.question(question, (answer) => {
19
+ resolve(answer);
20
+ });
21
+ });
22
+ }
23
+
24
+ async function clean(targetDir = process.cwd(), options = {}) {
25
+ console.log('');
26
+ console.log('🧹 anchi-toolkit Clean');
27
+ console.log('═══════════════════════════════════════════════════════════════');
28
+ console.log('');
29
+
30
+ const configDir = getConfigDir(targetDir);
31
+ const auditDir = path.join(configDir, '.ai-audit');
32
+ const memoryDir = path.join(configDir, '.ai-memory');
33
+
34
+ const cleanMemory = options.memory || options.all;
35
+ const cleanAudit = options.audit || options.all;
36
+ const isForce = options.force;
37
+
38
+ if (!cleanMemory && !cleanAudit) {
39
+ console.log('Usage:');
40
+ console.log(' npx anchi-toolkit clean --memory Clear AI context');
41
+ console.log(' npx anchi-toolkit clean --audit Clear logs');
42
+ console.log(' npx anchi-toolkit clean --all Clear everything');
43
+ rl.close();
44
+ return;
45
+ }
46
+
47
+ console.log('Checking targets:');
48
+ if (cleanMemory) console.log(` • Context Memory: ${memoryDir}`);
49
+ if (cleanAudit) console.log(` • Audit Logs: ${auditDir}`);
50
+ console.log('');
51
+
52
+ if (!isForce) {
53
+ const confirm = await ask('⚠️ Are you sure you want to delete these files? (Y/n): ');
54
+ if (confirm.toLowerCase() === 'n') {
55
+ console.log('❌ Cancelled.');
56
+ rl.close();
57
+ return;
58
+ }
59
+ }
60
+
61
+ if (cleanMemory) {
62
+ if (fs.existsSync(memoryDir)) {
63
+ // Keep the directory, just empty it or recreate it
64
+ fs.rmSync(memoryDir, { recursive: true, force: true });
65
+ fs.mkdirSync(memoryDir, { recursive: true });
66
+ console.log('✅ Memory cleared.');
67
+ } else {
68
+ console.log('⚪ Memory already clean.');
69
+ }
70
+ }
71
+
72
+ if (cleanAudit) {
73
+ if (fs.existsSync(auditDir)) {
74
+ fs.rmSync(auditDir, { recursive: true, force: true });
75
+ fs.mkdirSync(auditDir, { recursive: true });
76
+ console.log('✅ Audit logs cleared.');
77
+ } else {
78
+ console.log('⚪ Audit logs already clean.');
79
+ }
80
+ }
81
+
82
+ console.log('');
83
+ console.log('✨ Clean complete!');
84
+ rl.close();
85
+ }
86
+
87
+ module.exports = { clean };
@@ -14,28 +14,47 @@ async function doctor(targetDir = process.cwd()) {
14
14
 
15
15
  const checks = [];
16
16
 
17
- // Check .cursor folder
18
- const cursorDir = path.join(targetDir, '.cursor');
17
+ const { getConfigDir, CONFIG_FILENAME } = require('../lib/configManager');
18
+ const configDir = getConfigDir(targetDir);
19
+ const configDirName = path.basename(configDir);
20
+
21
+ // Check config folder
19
22
  checks.push({
20
- name: '.cursor folder',
21
- ok: fs.existsSync(cursorDir),
23
+ name: `${configDirName} folder`,
24
+ ok: fs.existsSync(configDir),
22
25
  fix: 'Run: npx anchi-toolkit init'
23
26
  });
24
27
 
25
28
  // Check commands
26
- const commandsDir = path.join(cursorDir, 'commands');
27
- const commandCount = fs.existsSync(commandsDir)
28
- ? fs.readdirSync(commandsDir, { recursive: true }).filter(f => f.endsWith('.md')).length
29
+ const commandsDir = path.join(configDir, (configDirName === '.antigravity' ? 'workflows' : 'commands'));
30
+ // Antigravity has workflows, Cursor has commands. Though user might want consistency?
31
+ // Wait, my ANTIGRAVITY.md says .antigravity/workflows.
32
+ // cli.js installs .antigravity/workflows.
33
+ // So if configDir is .antigravity, check workflows.
34
+ // If configDir is .cursor, check commands.
35
+ // Actually, cli.js installs 'workflows' into .antigravity.
36
+ // Let's check logic:
37
+ // If .antigravity install: src: .cursor/commands (*.md) -> target: .antigravity/workflows (*.md)
38
+ // If .cursor install: src: .cursor/commands -> target: .cursor/commands.
39
+
40
+ // I need to detect which folder to check based on configDirName.
41
+ let cmdFolderName = 'commands';
42
+ if (configDirName === '.antigravity') cmdFolderName = 'workflows';
43
+
44
+ const cmdDir = path.join(configDir, cmdFolderName);
45
+
46
+ const commandCount = fs.existsSync(cmdDir)
47
+ ? fs.readdirSync(cmdDir, { recursive: true }).filter(f => f.endsWith('.md')).length
29
48
  : 0;
30
49
  checks.push({
31
- name: 'Commands',
50
+ name: `Commands/Workflows (${cmdFolderName})`,
32
51
  ok: commandCount > 0,
33
52
  value: `${commandCount} files`,
34
53
  fix: 'Run: npx anchi-toolkit install'
35
54
  });
36
55
 
37
56
  // Check agents
38
- const agentsDir = path.join(cursorDir, 'agents');
57
+ const agentsDir = path.join(configDir, 'agents');
39
58
  const agentCount = fs.existsSync(agentsDir)
40
59
  ? fs.readdirSync(agentsDir).filter(f => f.endsWith('.md')).length
41
60
  : 0;
@@ -46,24 +65,46 @@ async function doctor(targetDir = process.cwd()) {
46
65
  fix: 'Run: npx anchi-toolkit install'
47
66
  });
48
67
 
49
- // Check .cursorrules
50
- const rulesFile = path.join(targetDir, '.cursorrules');
51
- checks.push({
52
- name: '.cursorrules',
53
- ok: fs.existsSync(rulesFile),
54
- fix: 'Run: /use-preset [name]'
55
- });
68
+ // Check .cursorrules (Only for Cursor?)
69
+ if (configDirName === '.cursor') {
70
+ const rulesFile = path.join(targetDir, '.cursorrules');
71
+ checks.push({
72
+ name: '.cursorrules',
73
+ ok: fs.existsSync(rulesFile),
74
+ fix: 'Run: /use-preset [name]'
75
+ });
76
+ }
56
77
 
57
78
  // Check config
58
- const configFile = path.join(cursorDir, 'anchi-toolkit.config.yaml');
79
+ const configFile = path.join(configDir, CONFIG_FILENAME);
80
+ let configValid = false;
81
+ if (fs.existsSync(configFile)) {
82
+ try {
83
+ const content = fs.readFileSync(configFile, 'utf-8');
84
+ // Basic YAML validation check
85
+ if (content.trim().length > 0) {
86
+ configValid = true;
87
+ // Try parsing if possible
88
+ try {
89
+ const { parseYaml } = require('../lib/configManager');
90
+ parseYaml(content);
91
+ } catch (e) {
92
+ configValid = false;
93
+ console.log(` ❌ Config syntax error: ${e.message}`);
94
+ }
95
+ }
96
+ } catch (e) {
97
+ configValid = false;
98
+ }
99
+ }
59
100
  checks.push({
60
- name: 'Config file',
61
- ok: fs.existsSync(configFile),
62
- fix: 'Run: npx anchi-toolkit init'
101
+ name: 'Config file syntax',
102
+ ok: configValid,
103
+ fix: 'Run: npx anchi-toolkit init (or fix YAML)'
63
104
  });
64
105
 
65
106
  // Check docs
66
- const docsDir = path.join(targetDir, 'docs');
107
+ const docsDir = path.join(configDir, 'docs');
67
108
  checks.push({
68
109
  name: 'Docs folder',
69
110
  ok: fs.existsSync(docsDir),
@@ -78,6 +119,32 @@ async function doctor(targetDir = process.cwd()) {
78
119
  fix: 'Run: npm init -y'
79
120
  });
80
121
 
122
+ // Check Write Permissions (.ai-memory)
123
+ const memoryDir = path.join(configDir, '.ai-memory');
124
+ let memoryWriteable = false;
125
+ if (!fs.existsSync(memoryDir)) {
126
+ // Create checks will fail later if not exists, but we can try to create
127
+ // Actually, install should create it.
128
+ // If missing, check ok=false
129
+ }
130
+
131
+ // We check if we can write to configDir (essential for logs/memory)
132
+ try {
133
+ if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, {recursive: true});
134
+ const testFile = path.join(configDir, '.perm-test');
135
+ fs.writeFileSync(testFile, 'test');
136
+ fs.unlinkSync(testFile);
137
+ memoryWriteable = true;
138
+ } catch (e) {
139
+ memoryWriteable = false;
140
+ }
141
+
142
+ checks.push({
143
+ name: 'Write Permissions',
144
+ ok: memoryWriteable,
145
+ fix: 'Check folder permissions'
146
+ });
147
+
81
148
  // Display results
82
149
  let allOk = true;
83
150
  for (const check of checks) {
@@ -286,7 +286,7 @@ async function init() {
286
286
  if (finalConfig.includePresets) {
287
287
  const presetsPath = path.join(kitPath, 'presets');
288
288
  if (fs.existsSync(presetsPath)) {
289
- copyDirRecursive(presetsPath, path.join(targetPath, 'presets'));
289
+ copyDirRecursive(presetsPath, path.join(targetPath, '.cursor/presets'));
290
290
  log.success(' ✅ Presets');
291
291
  }
292
292
  }
@@ -294,11 +294,31 @@ async function init() {
294
294
  if (finalConfig.includeDocs) {
295
295
  const docsPath = path.join(kitPath, 'docs');
296
296
  if (fs.existsSync(docsPath)) {
297
- copyDirRecursive(docsPath, path.join(targetPath, 'docs'));
297
+ copyDirRecursive(docsPath, path.join(targetPath, '.cursor/docs'));
298
298
  log.success(' ✅ Docs');
299
299
  }
300
300
  }
301
301
 
302
+ // Install AI folders (Implicit)
303
+ const auditPath = path.join(kitPath, '.ai-audit');
304
+ if (fs.existsSync(auditPath)) {
305
+ copyDirRecursive(auditPath, path.join(targetPath, '.cursor/.ai-audit'));
306
+ log.success(' ✅ .ai-audit');
307
+ }
308
+
309
+ const memoryPath = path.join(kitPath, '.ai-memory');
310
+ if (fs.existsSync(memoryPath)) {
311
+ copyDirRecursive(memoryPath, path.join(targetPath, '.cursor/.ai-memory'));
312
+ log.success(' ✅ .ai-memory');
313
+ }
314
+
315
+ // Install scripts
316
+ const scriptsPath = path.join(kitPath, 'scripts');
317
+ if (fs.existsSync(scriptsPath)) {
318
+ copyDirRecursive(scriptsPath, path.join(targetPath, '.cursor/scripts'));
319
+ log.success(' ✅ scripts');
320
+ }
321
+
302
322
  // Always include
303
323
  const cursorRulesPath = path.join(kitPath, '.cursorrules');
304
324
  if (fs.existsSync(cursorRulesPath)) {
@@ -59,18 +59,33 @@ async function uninstall() {
59
59
 
60
60
  const targetPath = process.cwd();
61
61
 
62
+ // Items to remove
62
63
  // Items to remove
63
64
  const itemsToRemove = [
65
+ // Cursor
64
66
  { path: '.cursor/commands', type: 'dir', desc: 'Commands' },
65
67
  { path: '.cursor/agents', type: 'dir', desc: 'Agents' },
66
68
  { path: '.cursor/skills', type: 'dir', desc: 'Skills' },
69
+ { path: '.cursor/presets', type: 'dir', desc: 'Presets' },
70
+ { path: '.cursor/docs', type: 'dir', desc: 'Docs' },
71
+ { path: '.cursor/.ai-audit', type: 'dir', desc: 'Audit Logs' },
72
+ { path: '.cursor/.ai-memory', type: 'dir', desc: 'Memory' },
67
73
  { path: '.cursor/MODEL_COSTS.md', type: 'file', desc: 'Model costs guide' },
68
- { path: 'presets', type: 'dir', desc: 'Presets' },
69
- { path: 'docs', type: 'dir', desc: 'Docs (templates)' },
74
+
75
+ // Antigravity
76
+ { path: '.antigravity', type: 'dir', desc: 'Antigravity Folder' },
77
+
78
+ // Root files
70
79
  { path: '.cursorrules', type: 'file', desc: 'Cursor rules' },
71
80
  { path: 'CURSOR.md', type: 'file', desc: 'Cursor instructions' },
72
81
  { path: 'GEMINI.md', type: 'file', desc: 'Gemini instructions' },
73
82
  { path: 'ANTIGRAVITY.md', type: 'file', desc: 'Antigravity instructions' },
83
+
84
+ // Legacy (Root) - Cleanup old installs
85
+ { path: 'presets', type: 'dir', desc: 'Presets (Legacy)' },
86
+ { path: 'docs', type: 'dir', desc: 'Docs (Legacy)' },
87
+ { path: '.ai-audit', type: 'dir', desc: 'Audit Logs (Legacy)' },
88
+ { path: '.ai-memory', type: 'dir', desc: 'Memory (Legacy)' },
74
89
  ];
75
90
 
76
91
  // Check what exists
@@ -128,11 +128,25 @@ function deepMerge(target, source) {
128
128
  return result;
129
129
  }
130
130
 
131
+ /**
132
+ * Get config directory (.antigravity or .cursor)
133
+ */
134
+ function getConfigDir(targetDir) {
135
+ // Check for Antigravity first
136
+ const antigravityDir = path.join(targetDir, '.antigravity');
137
+ if (fs.existsSync(antigravityDir)) {
138
+ return antigravityDir;
139
+ }
140
+ // Fallback to Cursor
141
+ return path.join(targetDir, '.cursor');
142
+ }
143
+
131
144
  /**
132
145
  * Load config from target directory
133
146
  */
134
147
  function loadConfig(targetDir) {
135
- const configPath = path.join(targetDir, '.cursor', CONFIG_FILENAME);
148
+ const configDir = getConfigDir(targetDir);
149
+ const configPath = path.join(configDir, CONFIG_FILENAME);
136
150
 
137
151
  if (!fs.existsSync(configPath)) {
138
152
  return DEFAULT_CONFIG;
@@ -152,11 +166,11 @@ function loadConfig(targetDir) {
152
166
  * Save config to target directory
153
167
  */
154
168
  function saveConfig(targetDir, config) {
155
- const cursorDir = path.join(targetDir, '.cursor');
156
- const configPath = path.join(cursorDir, CONFIG_FILENAME);
169
+ const configDir = getConfigDir(targetDir);
170
+ const configPath = path.join(configDir, CONFIG_FILENAME);
157
171
 
158
- if (!fs.existsSync(cursorDir)) {
159
- fs.mkdirSync(cursorDir, { recursive: true });
172
+ if (!fs.existsSync(configDir)) {
173
+ fs.mkdirSync(configDir, { recursive: true });
160
174
  }
161
175
 
162
176
  const header = `# anchi-toolkit Configuration
@@ -197,4 +211,5 @@ module.exports = {
197
211
  deepMerge,
198
212
  getConfigValue,
199
213
  setConfigValue,
214
+ getConfigDir,
200
215
  };
@@ -5,9 +5,10 @@
5
5
 
6
6
  const fs = require('fs');
7
7
  const path = require('path');
8
+ const { getConfigDir } = require('./configManager');
8
9
 
9
- const MEMORY_DIR = '.cursor/context';
10
- const MEMORY_FILE = 'memory.json';
10
+ const MEMORY_DIR_NAME = '.ai-memory';
11
+ const MEMORY_FILE = 'context.json'; // Changed from memory.json to context.json based on what I saw in ls
11
12
 
12
13
  // Default memory structure
13
14
  const DEFAULT_MEMORY = {
@@ -36,14 +37,16 @@ const DEFAULT_MEMORY = {
36
37
  * Get memory file path
37
38
  */
38
39
  function getMemoryPath(targetDir) {
39
- return path.join(targetDir, MEMORY_DIR, MEMORY_FILE);
40
+ const configDir = getConfigDir(targetDir);
41
+ return path.join(configDir, MEMORY_DIR_NAME, MEMORY_FILE);
40
42
  }
41
43
 
42
44
  /**
43
45
  * Ensure memory directory exists
44
46
  */
45
47
  function ensureMemoryDir(targetDir) {
46
- const memoryDir = path.join(targetDir, MEMORY_DIR);
48
+ const configDir = getConfigDir(targetDir);
49
+ const memoryDir = path.join(configDir, MEMORY_DIR_NAME);
47
50
  if (!fs.existsSync(memoryDir)) {
48
51
  fs.mkdirSync(memoryDir, { recursive: true });
49
52
  }