anchi-kit 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of anchi-kit might be problematic. Click here for more details.

Files changed (51) hide show
  1. package/.cursor/commands/entity.md +135 -0
  2. package/.cursor/commands/memory/add.md +65 -0
  3. package/.cursor/commands/memory/load.md +74 -0
  4. package/.cursor/commands/memory/save.md +68 -0
  5. package/.cursor/commands/memory.md +141 -0
  6. package/README.md +427 -127
  7. package/package.json +1 -1
  8. package/src/cli.js +6 -0
  9. package/src/commands/memory.js +158 -0
  10. package/src/lib/contextDatabase.js +362 -0
  11. package/src/lib/memoryManager.js +250 -0
  12. package/.antigravity/agent/code-reviewer.md +0 -141
  13. package/.antigravity/agent/debugger.md +0 -75
  14. package/.antigravity/agent/docs-manager.md +0 -120
  15. package/.antigravity/agent/git-manager.md +0 -60
  16. package/.antigravity/agent/planner-researcher.md +0 -101
  17. package/.antigravity/agent/planner.md +0 -88
  18. package/.antigravity/agent/project-manager.md +0 -113
  19. package/.antigravity/agent/researcher.md +0 -174
  20. package/.antigravity/agent/solution-brainstormer.md +0 -90
  21. package/.antigravity/agent/system-architecture.md +0 -193
  22. package/.antigravity/agent/tester.md +0 -96
  23. package/.antigravity/agent/ui-ux-designer.md +0 -233
  24. package/.antigravity/agent/ui-ux-developer.md +0 -98
  25. package/.antigravity/command/cook.md +0 -7
  26. package/.antigravity/command/debug.md +0 -10
  27. package/.antigravity/command/design/3d.md +0 -65
  28. package/.antigravity/command/design/fast.md +0 -18
  29. package/.antigravity/command/design/good.md +0 -21
  30. package/.antigravity/command/design/screenshot.md +0 -22
  31. package/.antigravity/command/design/video.md +0 -22
  32. package/.antigravity/command/docs/init.md +0 -11
  33. package/.antigravity/command/docs/summarize.md +0 -10
  34. package/.antigravity/command/docs/update.md +0 -18
  35. package/.antigravity/command/fix/ci.md +0 -8
  36. package/.antigravity/command/fix/fast.md +0 -11
  37. package/.antigravity/command/fix/hard.md +0 -15
  38. package/.antigravity/command/fix/logs.md +0 -16
  39. package/.antigravity/command/fix/test.md +0 -18
  40. package/.antigravity/command/fix/types.md +0 -10
  41. package/.antigravity/command/git/cm.md +0 -5
  42. package/.antigravity/command/git/cp.md +0 -4
  43. package/.antigravity/command/plan/ci.md +0 -12
  44. package/.antigravity/command/plan/two.md +0 -13
  45. package/.antigravity/command/plan.md +0 -10
  46. package/.antigravity/command/test.md +0 -7
  47. package/.antigravity/command/watzup.md +0 -8
  48. package/ANTIGRAVITY.md +0 -36
  49. package/GEMINI.md +0 -75
  50. package/scripts/prepare-release-assets.cjs +0 -97
  51. package/scripts/send-discord-release.cjs +0 -204
@@ -0,0 +1,158 @@
1
+ // =============================================================================
2
+ // anchi-kit Memory CLI Command
3
+ // =============================================================================
4
+
5
+ const { loadMemory, saveMemory, clearMemory, getMemorySummary, addNote, addDecision } = require('../lib/memoryManager');
6
+
7
+ async function memory(action = 'show', arg = null) {
8
+ const targetDir = process.cwd();
9
+
10
+ console.log('');
11
+ console.log('🧠 anchi-kit Memory');
12
+ console.log('═══════════════════════════════════════════════════════════════');
13
+ console.log('');
14
+
15
+ switch (action) {
16
+ case 'show':
17
+ case undefined:
18
+ showMemory(targetDir);
19
+ break;
20
+
21
+ case 'save':
22
+ saveProjectMemory(targetDir, arg);
23
+ break;
24
+
25
+ case 'load':
26
+ loadProjectMemory(targetDir);
27
+ break;
28
+
29
+ case 'clear':
30
+ clearProjectMemory(targetDir);
31
+ break;
32
+
33
+ case 'add':
34
+ addToMemory(targetDir, arg);
35
+ break;
36
+
37
+ default:
38
+ console.log('Usage:');
39
+ console.log(' npx anchi-kit memory show Show current memory');
40
+ console.log(' npx anchi-kit memory save Save context');
41
+ console.log(' npx anchi-kit memory load Load context');
42
+ console.log(' npx anchi-kit memory clear Clear memory');
43
+ console.log(' npx anchi-kit memory add "note" Add a note');
44
+ break;
45
+ }
46
+
47
+ console.log('');
48
+ }
49
+
50
+ function showMemory(targetDir) {
51
+ const memory = loadMemory(targetDir);
52
+
53
+ console.log('📂 Project:');
54
+ if (memory.project.name) {
55
+ console.log(` Name: ${memory.project.name}`);
56
+ if (memory.project.description) {
57
+ console.log(` Description: ${memory.project.description}`);
58
+ }
59
+ if (memory.project.tech_stack.length > 0) {
60
+ console.log(` Tech: ${memory.project.tech_stack.join(', ')}`);
61
+ }
62
+ if (memory.project.architecture) {
63
+ console.log(` Architecture: ${memory.project.architecture}`);
64
+ }
65
+ } else {
66
+ console.log(' (No project info saved)');
67
+ }
68
+
69
+ console.log('');
70
+ console.log('📌 Last Session:');
71
+ if (memory.session.last_task) {
72
+ console.log(` Task: ${memory.session.last_task}`);
73
+ if (memory.session.current_phase) {
74
+ console.log(` Phase: ${memory.session.current_phase}`);
75
+ }
76
+ console.log(` Last accessed: ${memory.session.last_accessed || 'Never'}`);
77
+ } else {
78
+ console.log(' (No session info)');
79
+ }
80
+
81
+ console.log('');
82
+ console.log('🧠 Decisions:');
83
+ if (memory.decisions.length > 0) {
84
+ const recent = memory.decisions.slice(-5);
85
+ for (const d of recent) {
86
+ console.log(` • ${d.decision}`);
87
+ }
88
+ if (memory.decisions.length > 5) {
89
+ console.log(` ... and ${memory.decisions.length - 5} more`);
90
+ }
91
+ } else {
92
+ console.log(' (No decisions recorded)');
93
+ }
94
+
95
+ console.log('');
96
+ console.log('📝 Notes:');
97
+ if (memory.notes.length > 0) {
98
+ const recent = memory.notes.slice(-5);
99
+ for (const n of recent) {
100
+ console.log(` • ${n.note}`);
101
+ }
102
+ if (memory.notes.length > 5) {
103
+ console.log(` ... and ${memory.notes.length - 5} more`);
104
+ }
105
+ } else {
106
+ console.log(' (No notes)');
107
+ }
108
+ }
109
+
110
+ function saveProjectMemory(targetDir, note) {
111
+ const memory = loadMemory(targetDir);
112
+ if (note) {
113
+ memory.notes.push({
114
+ id: Date.now(),
115
+ note: note,
116
+ category: 'session',
117
+ timestamp: new Date().toISOString(),
118
+ });
119
+ }
120
+ const path = saveMemory(targetDir, memory);
121
+ console.log('✅ Memory saved!');
122
+ console.log(` Location: ${path}`);
123
+ console.log(` Stats:`);
124
+ console.log(` • Decisions: ${memory.decisions.length}`);
125
+ console.log(` • Notes: ${memory.notes.length}`);
126
+ console.log(` • Entities: ${Object.keys(memory.entities).length}`);
127
+ }
128
+
129
+ function loadProjectMemory(targetDir) {
130
+ const summary = getMemorySummary(targetDir);
131
+ console.log(summary);
132
+ console.log('');
133
+ console.log('✅ Context loaded! AI now remembers your project.');
134
+ }
135
+
136
+ function clearProjectMemory(targetDir) {
137
+ clearMemory(targetDir);
138
+ console.log('✅ Memory cleared!');
139
+ console.log(' All project context has been reset.');
140
+ }
141
+
142
+ function addToMemory(targetDir, content) {
143
+ if (!content) {
144
+ console.log('Usage: npx anchi-kit memory add "your note"');
145
+ return;
146
+ }
147
+
148
+ if (content.startsWith('decision:')) {
149
+ const parts = content.slice(9).split(' - ');
150
+ addDecision(targetDir, parts[0].trim(), parts[1] || '');
151
+ console.log('✅ Decision recorded!');
152
+ } else {
153
+ addNote(targetDir, content);
154
+ console.log('✅ Note added!');
155
+ }
156
+ }
157
+
158
+ module.exports = { memory };
@@ -0,0 +1,362 @@
1
+ // =============================================================================
2
+ // anchi-kit SQLite Context Database
3
+ // Phase 2: Persistent storage with relationships
4
+ // =============================================================================
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ const DB_DIR = '.cursor/context';
10
+ const DB_FILE = 'context.db';
11
+
12
+ // SQLite schema for context database
13
+ const SCHEMA = `
14
+ -- Project information
15
+ CREATE TABLE IF NOT EXISTS project (
16
+ id INTEGER PRIMARY KEY,
17
+ name TEXT,
18
+ description TEXT,
19
+ tech_stack TEXT,
20
+ architecture TEXT,
21
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
22
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
23
+ );
24
+
25
+ -- Session history
26
+ CREATE TABLE IF NOT EXISTS sessions (
27
+ id INTEGER PRIMARY KEY,
28
+ task TEXT,
29
+ phase TEXT,
30
+ files_opened TEXT,
31
+ started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
32
+ ended_at DATETIME
33
+ );
34
+
35
+ -- Decisions log
36
+ CREATE TABLE IF NOT EXISTS decisions (
37
+ id INTEGER PRIMARY KEY,
38
+ decision TEXT NOT NULL,
39
+ reason TEXT,
40
+ files_affected TEXT,
41
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
42
+ );
43
+
44
+ -- Notes
45
+ CREATE TABLE IF NOT EXISTS notes (
46
+ id INTEGER PRIMARY KEY,
47
+ note TEXT NOT NULL,
48
+ category TEXT DEFAULT 'general',
49
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
50
+ );
51
+
52
+ -- Entities (knowledge graph nodes)
53
+ CREATE TABLE IF NOT EXISTS entities (
54
+ id INTEGER PRIMARY KEY,
55
+ name TEXT UNIQUE NOT NULL,
56
+ type TEXT,
57
+ description TEXT,
58
+ metadata TEXT,
59
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
60
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
61
+ );
62
+
63
+ -- Entity relationships (knowledge graph edges)
64
+ CREATE TABLE IF NOT EXISTS relations (
65
+ id INTEGER PRIMARY KEY,
66
+ source_id INTEGER NOT NULL,
67
+ target_id INTEGER NOT NULL,
68
+ relation_type TEXT NOT NULL,
69
+ metadata TEXT,
70
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
71
+ FOREIGN KEY (source_id) REFERENCES entities(id),
72
+ FOREIGN KEY (target_id) REFERENCES entities(id)
73
+ );
74
+
75
+ -- File analysis cache
76
+ CREATE TABLE IF NOT EXISTS file_cache (
77
+ id INTEGER PRIMARY KEY,
78
+ file_path TEXT UNIQUE NOT NULL,
79
+ summary TEXT,
80
+ entities TEXT,
81
+ last_modified DATETIME,
82
+ analyzed_at DATETIME DEFAULT CURRENT_TIMESTAMP
83
+ );
84
+ `;
85
+
86
+ /**
87
+ * Get database path
88
+ */
89
+ function getDbPath(targetDir) {
90
+ return path.join(targetDir, DB_DIR, DB_FILE);
91
+ }
92
+
93
+ /**
94
+ * Get database directory
95
+ */
96
+ function getDbDir(targetDir) {
97
+ return path.join(targetDir, DB_DIR);
98
+ }
99
+
100
+ /**
101
+ * Check if better-sqlite3 is available
102
+ */
103
+ function hasSqlite() {
104
+ try {
105
+ require('better-sqlite3');
106
+ return true;
107
+ } catch {
108
+ return false;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Initialize database (creates if not exists)
114
+ * Note: Requires better-sqlite3 package
115
+ */
116
+ function initDatabase(targetDir) {
117
+ if (!hasSqlite()) {
118
+ console.log('SQLite not available. Using JSON fallback.');
119
+ return null;
120
+ }
121
+
122
+ const Database = require('better-sqlite3');
123
+ const dbDir = getDbDir(targetDir);
124
+ const dbPath = getDbPath(targetDir);
125
+
126
+ if (!fs.existsSync(dbDir)) {
127
+ fs.mkdirSync(dbDir, { recursive: true });
128
+ }
129
+
130
+ const db = new Database(dbPath);
131
+ db.exec(SCHEMA);
132
+
133
+ return db;
134
+ }
135
+
136
+ /**
137
+ * Get or create database instance
138
+ */
139
+ let _db = null;
140
+ function getDatabase(targetDir) {
141
+ if (!_db) {
142
+ _db = initDatabase(targetDir);
143
+ }
144
+ return _db;
145
+ }
146
+
147
+ /**
148
+ * Close database connection
149
+ */
150
+ function closeDatabase() {
151
+ if (_db) {
152
+ _db.close();
153
+ _db = null;
154
+ }
155
+ }
156
+
157
+ // =============================================================================
158
+ // CRUD Operations
159
+ // =============================================================================
160
+
161
+ /**
162
+ * Set project info
163
+ */
164
+ function setProject(targetDir, info) {
165
+ const db = getDatabase(targetDir);
166
+ if (!db) return null;
167
+
168
+ const stmt = db.prepare(`
169
+ INSERT OR REPLACE INTO project (id, name, description, tech_stack, architecture, updated_at)
170
+ VALUES (1, ?, ?, ?, ?, CURRENT_TIMESTAMP)
171
+ `);
172
+
173
+ stmt.run(
174
+ info.name,
175
+ info.description,
176
+ JSON.stringify(info.tech_stack || []),
177
+ info.architecture
178
+ );
179
+
180
+ return info;
181
+ }
182
+
183
+ /**
184
+ * Get project info
185
+ */
186
+ function getProject(targetDir) {
187
+ const db = getDatabase(targetDir);
188
+ if (!db) return null;
189
+
190
+ const row = db.prepare('SELECT * FROM project WHERE id = 1').get();
191
+ if (!row) return null;
192
+
193
+ return {
194
+ name: row.name,
195
+ description: row.description,
196
+ tech_stack: JSON.parse(row.tech_stack || '[]'),
197
+ architecture: row.architecture,
198
+ created_at: row.created_at,
199
+ updated_at: row.updated_at,
200
+ };
201
+ }
202
+
203
+ /**
204
+ * Add decision
205
+ */
206
+ function addDecisionDb(targetDir, decision, reason = '', filesAffected = []) {
207
+ const db = getDatabase(targetDir);
208
+ if (!db) return null;
209
+
210
+ const stmt = db.prepare(`
211
+ INSERT INTO decisions (decision, reason, files_affected)
212
+ VALUES (?, ?, ?)
213
+ `);
214
+
215
+ const result = stmt.run(decision, reason, JSON.stringify(filesAffected));
216
+ return result.lastInsertRowid;
217
+ }
218
+
219
+ /**
220
+ * Get recent decisions
221
+ */
222
+ function getDecisions(targetDir, limit = 10) {
223
+ const db = getDatabase(targetDir);
224
+ if (!db) return [];
225
+
226
+ return db.prepare(`
227
+ SELECT * FROM decisions ORDER BY created_at DESC LIMIT ?
228
+ `).all(limit);
229
+ }
230
+
231
+ /**
232
+ * Add note
233
+ */
234
+ function addNoteDb(targetDir, note, category = 'general') {
235
+ const db = getDatabase(targetDir);
236
+ if (!db) return null;
237
+
238
+ const stmt = db.prepare(`
239
+ INSERT INTO notes (note, category) VALUES (?, ?)
240
+ `);
241
+
242
+ const result = stmt.run(note, category);
243
+ return result.lastInsertRowid;
244
+ }
245
+
246
+ /**
247
+ * Get recent notes
248
+ */
249
+ function getNotes(targetDir, category = null, limit = 10) {
250
+ const db = getDatabase(targetDir);
251
+ if (!db) return [];
252
+
253
+ if (category) {
254
+ return db.prepare(`
255
+ SELECT * FROM notes WHERE category = ? ORDER BY created_at DESC LIMIT ?
256
+ `).all(category, limit);
257
+ }
258
+
259
+ return db.prepare(`
260
+ SELECT * FROM notes ORDER BY created_at DESC LIMIT ?
261
+ `).all(limit);
262
+ }
263
+
264
+ /**
265
+ * Upsert entity
266
+ */
267
+ function upsertEntityDb(targetDir, name, type, description = '', metadata = {}) {
268
+ const db = getDatabase(targetDir);
269
+ if (!db) return null;
270
+
271
+ const stmt = db.prepare(`
272
+ INSERT INTO entities (name, type, description, metadata, updated_at)
273
+ VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
274
+ ON CONFLICT(name) DO UPDATE SET
275
+ type = excluded.type,
276
+ description = excluded.description,
277
+ metadata = excluded.metadata,
278
+ updated_at = CURRENT_TIMESTAMP
279
+ `);
280
+
281
+ stmt.run(name, type, description, JSON.stringify(metadata));
282
+ return name;
283
+ }
284
+
285
+ /**
286
+ * Get entity
287
+ */
288
+ function getEntityDb(targetDir, name) {
289
+ const db = getDatabase(targetDir);
290
+ if (!db) return null;
291
+
292
+ const row = db.prepare('SELECT * FROM entities WHERE name = ?').get(name);
293
+ if (!row) return null;
294
+
295
+ return {
296
+ id: row.id,
297
+ name: row.name,
298
+ type: row.type,
299
+ description: row.description,
300
+ metadata: JSON.parse(row.metadata || '{}'),
301
+ };
302
+ }
303
+
304
+ /**
305
+ * Add relation between entities
306
+ */
307
+ function addRelation(targetDir, sourceName, targetName, relationType, metadata = {}) {
308
+ const db = getDatabase(targetDir);
309
+ if (!db) return null;
310
+
311
+ const source = db.prepare('SELECT id FROM entities WHERE name = ?').get(sourceName);
312
+ const target = db.prepare('SELECT id FROM entities WHERE name = ?').get(targetName);
313
+
314
+ if (!source || !target) return null;
315
+
316
+ const stmt = db.prepare(`
317
+ INSERT INTO relations (source_id, target_id, relation_type, metadata)
318
+ VALUES (?, ?, ?, ?)
319
+ `);
320
+
321
+ const result = stmt.run(source.id, target.id, relationType, JSON.stringify(metadata));
322
+ return result.lastInsertRowid;
323
+ }
324
+
325
+ /**
326
+ * Get relations for entity
327
+ */
328
+ function getRelations(targetDir, entityName) {
329
+ const db = getDatabase(targetDir);
330
+ if (!db) return [];
331
+
332
+ return db.prepare(`
333
+ SELECT
334
+ r.*,
335
+ s.name as source_name,
336
+ t.name as target_name
337
+ FROM relations r
338
+ JOIN entities s ON r.source_id = s.id
339
+ JOIN entities t ON r.target_id = t.id
340
+ WHERE s.name = ? OR t.name = ?
341
+ `).all(entityName, entityName);
342
+ }
343
+
344
+ module.exports = {
345
+ SCHEMA,
346
+ getDbPath,
347
+ initDatabase,
348
+ getDatabase,
349
+ closeDatabase,
350
+ hasSqlite,
351
+ // CRUD
352
+ setProject,
353
+ getProject,
354
+ addDecisionDb,
355
+ getDecisions,
356
+ addNoteDb,
357
+ getNotes,
358
+ upsertEntityDb,
359
+ getEntityDb,
360
+ addRelation,
361
+ getRelations,
362
+ };