@su-record/vibe 0.1.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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +448 -0
  3. package/agents/backend-python-expert.md +453 -0
  4. package/agents/database-postgres-expert.md +538 -0
  5. package/agents/frontend-flutter-expert.md +487 -0
  6. package/agents/frontend-react-expert.md +424 -0
  7. package/agents/quality-reviewer.md +542 -0
  8. package/agents/specification-agent.md +505 -0
  9. package/bin/sutory +332 -0
  10. package/bin/vibe +338 -0
  11. package/mcp/dist/__tests__/complexity.test.js +126 -0
  12. package/mcp/dist/__tests__/memory.test.js +120 -0
  13. package/mcp/dist/__tests__/python-dart-complexity.test.js +146 -0
  14. package/mcp/dist/index.js +230 -0
  15. package/mcp/dist/lib/ContextCompressor.js +305 -0
  16. package/mcp/dist/lib/MemoryManager.js +334 -0
  17. package/mcp/dist/lib/ProjectCache.js +126 -0
  18. package/mcp/dist/lib/PythonParser.js +241 -0
  19. package/mcp/dist/tools/browser/browserPool.js +76 -0
  20. package/mcp/dist/tools/browser/browserUtils.js +135 -0
  21. package/mcp/dist/tools/browser/inspectNetworkRequests.js +140 -0
  22. package/mcp/dist/tools/browser/monitorConsoleLogs.js +97 -0
  23. package/mcp/dist/tools/convention/analyzeComplexity.js +248 -0
  24. package/mcp/dist/tools/convention/applyQualityRules.js +102 -0
  25. package/mcp/dist/tools/convention/checkCouplingCohesion.js +233 -0
  26. package/mcp/dist/tools/convention/complexityMetrics.js +133 -0
  27. package/mcp/dist/tools/convention/dartComplexity.js +117 -0
  28. package/mcp/dist/tools/convention/getCodingGuide.js +64 -0
  29. package/mcp/dist/tools/convention/languageDetector.js +50 -0
  30. package/mcp/dist/tools/convention/pythonComplexity.js +109 -0
  31. package/mcp/dist/tools/convention/suggestImprovements.js +257 -0
  32. package/mcp/dist/tools/convention/validateCodeQuality.js +177 -0
  33. package/mcp/dist/tools/memory/autoSaveContext.js +79 -0
  34. package/mcp/dist/tools/memory/database.js +123 -0
  35. package/mcp/dist/tools/memory/deleteMemory.js +39 -0
  36. package/mcp/dist/tools/memory/listMemories.js +38 -0
  37. package/mcp/dist/tools/memory/memoryConfig.js +27 -0
  38. package/mcp/dist/tools/memory/memorySQLite.js +138 -0
  39. package/mcp/dist/tools/memory/memoryUtils.js +34 -0
  40. package/mcp/dist/tools/memory/migrate.js +113 -0
  41. package/mcp/dist/tools/memory/prioritizeMemory.js +109 -0
  42. package/mcp/dist/tools/memory/recallMemory.js +40 -0
  43. package/mcp/dist/tools/memory/restoreSessionContext.js +69 -0
  44. package/mcp/dist/tools/memory/saveMemory.js +34 -0
  45. package/mcp/dist/tools/memory/searchMemories.js +37 -0
  46. package/mcp/dist/tools/memory/startSession.js +100 -0
  47. package/mcp/dist/tools/memory/updateMemory.js +46 -0
  48. package/mcp/dist/tools/planning/analyzeRequirements.js +166 -0
  49. package/mcp/dist/tools/planning/createUserStories.js +119 -0
  50. package/mcp/dist/tools/planning/featureRoadmap.js +202 -0
  51. package/mcp/dist/tools/planning/generatePrd.js +156 -0
  52. package/mcp/dist/tools/prompt/analyzePrompt.js +145 -0
  53. package/mcp/dist/tools/prompt/enhancePrompt.js +105 -0
  54. package/mcp/dist/tools/semantic/findReferences.js +195 -0
  55. package/mcp/dist/tools/semantic/findSymbol.js +200 -0
  56. package/mcp/dist/tools/thinking/analyzeProblem.js +50 -0
  57. package/mcp/dist/tools/thinking/breakDownProblem.js +140 -0
  58. package/mcp/dist/tools/thinking/createThinkingChain.js +39 -0
  59. package/mcp/dist/tools/thinking/formatAsPlan.js +73 -0
  60. package/mcp/dist/tools/thinking/stepByStepAnalysis.js +58 -0
  61. package/mcp/dist/tools/thinking/thinkAloudProcess.js +75 -0
  62. package/mcp/dist/tools/time/getCurrentTime.js +61 -0
  63. package/mcp/dist/tools/ui/previewUiAscii.js +232 -0
  64. package/mcp/dist/types/tool.js +2 -0
  65. package/mcp/package.json +53 -0
  66. package/package.json +49 -0
  67. package/scripts/install-mcp.js +48 -0
  68. package/scripts/install.sh +70 -0
  69. package/skills/core/communication-guide.md +104 -0
  70. package/skills/core/development-philosophy.md +53 -0
  71. package/skills/core/quick-start.md +121 -0
  72. package/skills/languages/dart-flutter.md +509 -0
  73. package/skills/languages/python-fastapi.md +386 -0
  74. package/skills/languages/typescript-nextjs.md +441 -0
  75. package/skills/languages/typescript-react-native.md +446 -0
  76. package/skills/languages/typescript-react.md +525 -0
  77. package/skills/quality/checklist.md +276 -0
  78. package/skills/quality/testing-strategy.md +437 -0
  79. package/skills/standards/anti-patterns.md +369 -0
  80. package/skills/standards/code-structure.md +291 -0
  81. package/skills/standards/complexity-metrics.md +312 -0
  82. package/skills/standards/naming-conventions.md +198 -0
  83. package/skills/tools/mcp-hi-ai-guide.md +665 -0
  84. package/skills/tools/mcp-workflow.md +51 -0
  85. package/templates/constitution-template.md +193 -0
  86. package/templates/plan-template.md +237 -0
  87. package/templates/spec-template.md +142 -0
  88. package/templates/tasks-template.md +132 -0
@@ -0,0 +1,123 @@
1
+ // SQLite database connection and schema management
2
+ import Database from 'better-sqlite3';
3
+ import path from 'path';
4
+ import { getMemoryDir } from './memoryConfig.js';
5
+ import { existsSync, mkdirSync } from 'fs';
6
+ class MemoryDatabase {
7
+ db = null;
8
+ dbPath;
9
+ constructor() {
10
+ const memoryDir = getMemoryDir();
11
+ // Ensure directory exists
12
+ if (!existsSync(memoryDir)) {
13
+ mkdirSync(memoryDir, { recursive: true });
14
+ }
15
+ this.dbPath = path.join(memoryDir, 'memories.db');
16
+ }
17
+ /**
18
+ * Get database connection (lazy initialization)
19
+ */
20
+ getConnection() {
21
+ if (!this.db) {
22
+ // Ensure directory exists before opening database
23
+ const memoryDir = getMemoryDir();
24
+ if (!existsSync(memoryDir)) {
25
+ mkdirSync(memoryDir, { recursive: true });
26
+ }
27
+ this.db = new Database(this.dbPath);
28
+ // Enable WAL mode for better concurrency
29
+ this.db.pragma('journal_mode = WAL');
30
+ // Initialize schema
31
+ this.initSchema();
32
+ }
33
+ return this.db;
34
+ }
35
+ /**
36
+ * Initialize database schema
37
+ */
38
+ initSchema() {
39
+ const db = this.db;
40
+ // Memories table
41
+ db.exec(`
42
+ CREATE TABLE IF NOT EXISTS memories (
43
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
44
+ key TEXT UNIQUE NOT NULL,
45
+ value TEXT NOT NULL,
46
+ category TEXT NOT NULL DEFAULT 'general',
47
+ timestamp TEXT NOT NULL,
48
+ lastAccessed TEXT NOT NULL
49
+ );
50
+
51
+ CREATE INDEX IF NOT EXISTS idx_memories_key ON memories(key);
52
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
53
+ CREATE INDEX IF NOT EXISTS idx_memories_lastAccessed ON memories(lastAccessed);
54
+ `);
55
+ // Sessions table
56
+ db.exec(`
57
+ CREATE TABLE IF NOT EXISTS sessions (
58
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
59
+ sessionId TEXT NOT NULL,
60
+ contextType TEXT NOT NULL,
61
+ summary TEXT NOT NULL,
62
+ urgency TEXT NOT NULL,
63
+ currentTask TEXT,
64
+ codeChanges TEXT,
65
+ decisions TEXT,
66
+ blockers TEXT,
67
+ nextSteps TEXT,
68
+ timestamp TEXT NOT NULL
69
+ );
70
+
71
+ CREATE INDEX IF NOT EXISTS idx_sessions_sessionId ON sessions(sessionId);
72
+ CREATE INDEX IF NOT EXISTS idx_sessions_timestamp ON sessions(timestamp);
73
+ CREATE INDEX IF NOT EXISTS idx_sessions_urgency ON sessions(urgency);
74
+ `);
75
+ // Guides table (for coding guides)
76
+ db.exec(`
77
+ CREATE TABLE IF NOT EXISTS guides (
78
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
79
+ name TEXT UNIQUE NOT NULL,
80
+ category TEXT NOT NULL,
81
+ content TEXT NOT NULL,
82
+ timestamp TEXT NOT NULL
83
+ );
84
+
85
+ CREATE INDEX IF NOT EXISTS idx_guides_name ON guides(name);
86
+ CREATE INDEX IF NOT EXISTS idx_guides_category ON guides(category);
87
+ `);
88
+ }
89
+ /**
90
+ * Close database connection
91
+ */
92
+ close() {
93
+ if (this.db) {
94
+ this.db.close();
95
+ this.db = null;
96
+ }
97
+ }
98
+ /**
99
+ * Run a checkpoint to merge WAL file
100
+ */
101
+ checkpoint() {
102
+ if (this.db) {
103
+ this.db.pragma('wal_checkpoint(TRUNCATE)');
104
+ }
105
+ }
106
+ }
107
+ // Singleton instance
108
+ export const memoryDB = new MemoryDatabase();
109
+ // Cleanup on process exit
110
+ process.on('exit', () => {
111
+ memoryDB.checkpoint();
112
+ memoryDB.close();
113
+ });
114
+ process.on('SIGINT', () => {
115
+ memoryDB.checkpoint();
116
+ memoryDB.close();
117
+ process.exit(0);
118
+ });
119
+ process.on('SIGTERM', () => {
120
+ memoryDB.checkpoint();
121
+ memoryDB.close();
122
+ process.exit(0);
123
+ });
@@ -0,0 +1,39 @@
1
+ // Memory management tool - completely independent
2
+ import { MemoryManager } from '../../lib/MemoryManager.js';
3
+ export const deleteMemoryDefinition = {
4
+ name: 'delete_memory',
5
+ description: '잊어|삭제해|지워|forget|delete|remove|erase - Delete specific memory',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ key: { type: 'string', description: 'Memory key to delete' }
10
+ },
11
+ required: ['key']
12
+ },
13
+ annotations: {
14
+ title: 'Delete Memory',
15
+ audience: ['user', 'assistant']
16
+ }
17
+ };
18
+ export async function deleteMemory(args) {
19
+ const { key: deleteKey } = args;
20
+ try {
21
+ const mm = MemoryManager.getInstance();
22
+ const deleted = mm.delete(deleteKey);
23
+ if (deleted) {
24
+ return {
25
+ content: [{ type: 'text', text: `✓ Deleted memory: "${deleteKey}"` }]
26
+ };
27
+ }
28
+ else {
29
+ return {
30
+ content: [{ type: 'text', text: `✗ Memory not found: "${deleteKey}"` }]
31
+ };
32
+ }
33
+ }
34
+ catch (error) {
35
+ return {
36
+ content: [{ type: 'text', text: `✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}` }]
37
+ };
38
+ }
39
+ }
@@ -0,0 +1,38 @@
1
+ // Memory management tool - completely independent
2
+ import { MemoryManager } from '../../lib/MemoryManager.js';
3
+ export const listMemoriesDefinition = {
4
+ name: 'list_memories',
5
+ description: '뭐 있었지|저장된 거|목록|what did I save|list memories|show saved - List saved memories',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ category: { type: 'string', description: 'Filter by category' },
10
+ limit: { type: 'number', description: 'Maximum number of results' }
11
+ },
12
+ required: []
13
+ },
14
+ annotations: {
15
+ title: 'List Memories',
16
+ audience: ['user', 'assistant']
17
+ }
18
+ };
19
+ export async function listMemories(args) {
20
+ const { category: listCategory, limit = 10 } = args;
21
+ try {
22
+ const mm = MemoryManager.getInstance();
23
+ const allMemories = mm.list(listCategory);
24
+ const limitedMemories = allMemories.slice(0, limit);
25
+ const memoryList = limitedMemories.map(m => `• ${m.key} (${m.category}): ${m.value.substring(0, 50)}${m.value.length > 50 ? '...' : ''}`).join('\n');
26
+ return {
27
+ content: [{
28
+ type: 'text',
29
+ text: `✓ Found ${allMemories.length} memories${listCategory ? ` in '${listCategory}'` : ''}:\n${memoryList || 'None'}`
30
+ }]
31
+ };
32
+ }
33
+ catch (error) {
34
+ return {
35
+ content: [{ type: 'text', text: `✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}` }]
36
+ };
37
+ }
38
+ }
@@ -0,0 +1,27 @@
1
+ // Memory configuration - centralized path management
2
+ import path from 'path';
3
+ /**
4
+ * Get memory directory path
5
+ * Respects HI_AI_MEMORY_DIR environment variable
6
+ */
7
+ export function getMemoryDir() {
8
+ return process.env.HI_AI_MEMORY_DIR || path.join(process.cwd(), 'memories');
9
+ }
10
+ /**
11
+ * Get memory file path
12
+ */
13
+ export function getMemoryFile() {
14
+ return path.join(getMemoryDir(), 'memories.json');
15
+ }
16
+ /**
17
+ * Get session context directory
18
+ */
19
+ export function getSessionDir() {
20
+ return path.join(getMemoryDir(), 'sessions');
21
+ }
22
+ /**
23
+ * Get guides directory
24
+ */
25
+ export function getGuidesDir() {
26
+ return process.env.HI_AI_GUIDES_DIR || path.join(process.cwd(), 'guides');
27
+ }
@@ -0,0 +1,138 @@
1
+ // SQLite-based memory operations
2
+ import { memoryDB } from './database.js';
3
+ /**
4
+ * Save or update memory
5
+ */
6
+ export function saveMemory(key, value, category = 'general') {
7
+ const db = memoryDB.getConnection();
8
+ const timestamp = new Date().toISOString();
9
+ const stmt = db.prepare(`
10
+ INSERT INTO memories (key, value, category, timestamp, lastAccessed)
11
+ VALUES (?, ?, ?, ?, ?)
12
+ ON CONFLICT(key) DO UPDATE SET
13
+ value = excluded.value,
14
+ category = excluded.category,
15
+ timestamp = excluded.timestamp,
16
+ lastAccessed = excluded.lastAccessed
17
+ `);
18
+ stmt.run(key, value, category, timestamp, timestamp);
19
+ }
20
+ /**
21
+ * Get memory by key
22
+ */
23
+ export function getMemory(key) {
24
+ const db = memoryDB.getConnection();
25
+ const stmt = db.prepare('SELECT * FROM memories WHERE key = ?');
26
+ const memory = stmt.get(key);
27
+ // Update last accessed time
28
+ if (memory) {
29
+ const updateStmt = db.prepare('UPDATE memories SET lastAccessed = ? WHERE key = ?');
30
+ updateStmt.run(new Date().toISOString(), key);
31
+ }
32
+ return memory;
33
+ }
34
+ /**
35
+ * List memories with optional filtering
36
+ */
37
+ export function listMemories(options) {
38
+ const db = memoryDB.getConnection();
39
+ const { category, limit = 10, offset = 0 } = options;
40
+ let whereClause = '';
41
+ const params = [];
42
+ if (category) {
43
+ whereClause = 'WHERE category = ?';
44
+ params.push(category);
45
+ }
46
+ // Get total count
47
+ const countStmt = db.prepare(`SELECT COUNT(*) as count FROM memories ${whereClause}`);
48
+ const { count } = countStmt.get(...params);
49
+ // Get paginated results
50
+ const stmt = db.prepare(`
51
+ SELECT * FROM memories ${whereClause}
52
+ ORDER BY lastAccessed DESC
53
+ LIMIT ? OFFSET ?
54
+ `);
55
+ const memories = stmt.all(...params, limit, offset);
56
+ return { memories, total: count };
57
+ }
58
+ /**
59
+ * Search memories by content
60
+ */
61
+ export function searchMemories(query, options) {
62
+ const db = memoryDB.getConnection();
63
+ const { category, limit = 20 } = options || {};
64
+ let whereClause = 'WHERE (key LIKE ? OR value LIKE ?)';
65
+ const params = [`%${query}%`, `%${query}%`];
66
+ if (category) {
67
+ whereClause += ' AND category = ?';
68
+ params.push(category);
69
+ }
70
+ const stmt = db.prepare(`
71
+ SELECT * FROM memories ${whereClause}
72
+ ORDER BY lastAccessed DESC
73
+ LIMIT ?
74
+ `);
75
+ return stmt.all(...params, limit);
76
+ }
77
+ /**
78
+ * Delete memory by key
79
+ */
80
+ export function deleteMemory(key) {
81
+ const db = memoryDB.getConnection();
82
+ const stmt = db.prepare('DELETE FROM memories WHERE key = ?');
83
+ const result = stmt.run(key);
84
+ return result.changes > 0;
85
+ }
86
+ /**
87
+ * Update memory
88
+ */
89
+ export function updateMemory(key, value, append = false) {
90
+ const db = memoryDB.getConnection();
91
+ if (append) {
92
+ const existing = getMemory(key);
93
+ if (existing) {
94
+ value = existing.value + '\n' + value;
95
+ }
96
+ }
97
+ const stmt = db.prepare(`
98
+ UPDATE memories
99
+ SET value = ?, lastAccessed = ?
100
+ WHERE key = ?
101
+ `);
102
+ const result = stmt.run(value, new Date().toISOString(), key);
103
+ return result.changes > 0;
104
+ }
105
+ /**
106
+ * Get memory statistics
107
+ */
108
+ export function getMemoryStats() {
109
+ const db = memoryDB.getConnection();
110
+ // Total count
111
+ const totalStmt = db.prepare('SELECT COUNT(*) as count FROM memories');
112
+ const { count: totalMemories } = totalStmt.get();
113
+ // By category
114
+ const categoryStmt = db.prepare(`
115
+ SELECT category, COUNT(*) as count
116
+ FROM memories
117
+ GROUP BY category
118
+ `);
119
+ const categoryResults = categoryStmt.all();
120
+ const byCategory = Object.fromEntries(categoryResults.map(r => [r.category, r.count]));
121
+ // Recently accessed
122
+ const recentStmt = db.prepare(`
123
+ SELECT * FROM memories
124
+ ORDER BY lastAccessed DESC
125
+ LIMIT 10
126
+ `);
127
+ const recentlyAccessed = recentStmt.all();
128
+ return { totalMemories, byCategory, recentlyAccessed };
129
+ }
130
+ /**
131
+ * Clear all memories (use with caution!)
132
+ */
133
+ export function clearAllMemories() {
134
+ const db = memoryDB.getConnection();
135
+ const stmt = db.prepare('DELETE FROM memories');
136
+ const result = stmt.run();
137
+ return result.changes;
138
+ }
@@ -0,0 +1,34 @@
1
+ // Shared memory utilities
2
+ import { promises as fs } from 'fs';
3
+ import { getMemoryDir, getMemoryFile } from './memoryConfig.js';
4
+ /**
5
+ * Ensure memory directory exists
6
+ */
7
+ export async function ensureMemoryDir() {
8
+ try {
9
+ await fs.access(getMemoryDir());
10
+ }
11
+ catch {
12
+ await fs.mkdir(getMemoryDir(), { recursive: true });
13
+ }
14
+ }
15
+ /**
16
+ * Load all memories from file
17
+ */
18
+ export async function loadMemories() {
19
+ try {
20
+ await ensureMemoryDir();
21
+ const data = await fs.readFile(getMemoryFile(), 'utf-8');
22
+ return JSON.parse(data);
23
+ }
24
+ catch {
25
+ return [];
26
+ }
27
+ }
28
+ /**
29
+ * Save memories to file
30
+ */
31
+ export async function saveMemories(memories) {
32
+ await ensureMemoryDir();
33
+ await fs.writeFile(getMemoryFile(), JSON.stringify(memories, null, 2));
34
+ }
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ // Migration utility to convert JSON memories to SQLite
3
+ import { existsSync, readFileSync } from 'fs';
4
+ import path from 'path';
5
+ import { getMemoryDir } from './memoryConfig.js';
6
+ import { saveMemory } from './memorySQLite.js';
7
+ import { memoryDB } from './database.js';
8
+ /**
9
+ * Migrate from JSON to SQLite
10
+ */
11
+ export async function migrateFromJSON() {
12
+ const memoryDir = getMemoryDir();
13
+ const jsonPath = path.join(memoryDir, 'memories.json');
14
+ const result = {
15
+ success: false,
16
+ migrated: 0,
17
+ errors: []
18
+ };
19
+ // Check if JSON file exists
20
+ if (!existsSync(jsonPath)) {
21
+ result.errors.push('No legacy memories.json file found');
22
+ return result;
23
+ }
24
+ try {
25
+ // Read JSON file
26
+ const jsonData = readFileSync(jsonPath, 'utf-8');
27
+ const memories = JSON.parse(jsonData);
28
+ console.log(`Found ${memories.length} memories to migrate`);
29
+ // Migrate each memory
30
+ for (const memory of memories) {
31
+ try {
32
+ saveMemory(memory.key, memory.value, memory.category);
33
+ result.migrated++;
34
+ }
35
+ catch (error) {
36
+ result.errors.push(`Failed to migrate key "${memory.key}": ${error instanceof Error ? error.message : 'Unknown error'}`);
37
+ }
38
+ }
39
+ result.success = true;
40
+ console.log(`✅ Successfully migrated ${result.migrated} memories`);
41
+ if (result.errors.length > 0) {
42
+ console.warn(`⚠️ ${result.errors.length} errors occurred during migration:`);
43
+ result.errors.forEach(err => console.warn(` ${err}`));
44
+ }
45
+ }
46
+ catch (error) {
47
+ result.errors.push(`Failed to read JSON file: ${error instanceof Error ? error.message : 'Unknown error'}`);
48
+ }
49
+ return result;
50
+ }
51
+ /**
52
+ * Export SQLite database to JSON (for backup)
53
+ */
54
+ export async function exportToJSON(outputPath) {
55
+ const db = memoryDB.getConnection();
56
+ const stmt = db.prepare('SELECT * FROM memories');
57
+ const memories = stmt.all();
58
+ const exportPath = outputPath || path.join(getMemoryDir(), `backup-${Date.now()}.json`);
59
+ try {
60
+ const { writeFileSync } = await import('fs');
61
+ writeFileSync(exportPath, JSON.stringify(memories, null, 2));
62
+ return {
63
+ success: true,
64
+ exported: memories.length,
65
+ path: exportPath
66
+ };
67
+ }
68
+ catch (error) {
69
+ throw new Error(`Failed to export: ${error instanceof Error ? error.message : 'Unknown'}`);
70
+ }
71
+ }
72
+ // CLI interface
73
+ if (import.meta.url === `file://${process.argv[1]}`) {
74
+ const command = process.argv[2];
75
+ switch (command) {
76
+ case 'migrate':
77
+ console.log('🔄 Starting migration from JSON to SQLite...');
78
+ migrateFromJSON().then(result => {
79
+ if (result.success) {
80
+ console.log(`\n✅ Migration completed: ${result.migrated} memories migrated`);
81
+ process.exit(0);
82
+ }
83
+ else {
84
+ console.error('\n❌ Migration failed');
85
+ process.exit(1);
86
+ }
87
+ });
88
+ break;
89
+ case 'export':
90
+ console.log('📦 Exporting SQLite to JSON...');
91
+ exportToJSON().then(result => {
92
+ console.log(`\n✅ Export completed: ${result.exported} memories exported to ${result.path}`);
93
+ process.exit(0);
94
+ }).catch(error => {
95
+ console.error(`\n❌ Export failed: ${error.message}`);
96
+ process.exit(1);
97
+ });
98
+ break;
99
+ default:
100
+ console.log(`
101
+ Hi-AI Memory Migration Tool
102
+
103
+ Usage:
104
+ node dist/tools/memory/migrate.js migrate Migrate from JSON to SQLite
105
+ node dist/tools/memory/migrate.js export Export SQLite to JSON backup
106
+
107
+ Options:
108
+ migrate Convert memories.json to SQLite database
109
+ export Create JSON backup of SQLite database
110
+ `);
111
+ break;
112
+ }
113
+ }
@@ -0,0 +1,109 @@
1
+ // Memory management tool - completely independent
2
+ import { MemoryManager } from '../../lib/MemoryManager.js';
3
+ export const prioritizeMemoryDefinition = {
4
+ name: 'prioritize_memory',
5
+ description: '중요한 거|우선순위|prioritize|important|what matters|priority - Prioritize memories by importance',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ currentTask: { type: 'string', description: 'Current task description' },
10
+ criticalDecisions: { type: 'array', items: { type: 'string' }, description: 'List of critical decisions made' },
11
+ codeChanges: { type: 'array', items: { type: 'string' }, description: 'Important code changes' },
12
+ blockers: { type: 'array', items: { type: 'string' }, description: 'Current blockers or issues' },
13
+ nextSteps: { type: 'array', items: { type: 'string' }, description: 'Planned next steps' }
14
+ },
15
+ required: ['currentTask']
16
+ },
17
+ annotations: {
18
+ title: 'Prioritize Memory',
19
+ audience: ['user', 'assistant']
20
+ }
21
+ };
22
+ export async function prioritizeMemory(args) {
23
+ const { currentTask, criticalDecisions = [], codeChanges = [], blockers = [], nextSteps = [] } = args;
24
+ try {
25
+ const mm = MemoryManager.getInstance();
26
+ const allMemories = mm.list();
27
+ const prioritizedMemories = [];
28
+ for (const memory of allMemories) {
29
+ let priority = 0;
30
+ let reason = '';
31
+ // Analyze importance based on content
32
+ if (memory.value.includes('error') || memory.value.includes('Error')) {
33
+ priority = 0.9;
34
+ reason = 'error info';
35
+ }
36
+ else if (memory.value.includes('decision') || memory.value.includes('Decision')) {
37
+ priority = 0.8;
38
+ reason = 'decision';
39
+ }
40
+ else if (memory.value.includes('code') || memory.value.includes('function')) {
41
+ priority = 0.7;
42
+ reason = 'code-related';
43
+ }
44
+ else if (memory.category === 'context') {
45
+ priority = 0.6;
46
+ reason = 'context';
47
+ }
48
+ else if (memory.category === 'project') {
49
+ priority = 0.7;
50
+ reason = 'project';
51
+ }
52
+ else {
53
+ priority = 0.5;
54
+ reason = 'general';
55
+ }
56
+ // Boost priority for memories related to current task
57
+ if (memory.value.toLowerCase().includes(currentTask.toLowerCase())) {
58
+ priority += 0.2;
59
+ reason += ' +task';
60
+ }
61
+ // Boost priority for critical decisions
62
+ for (const decision of criticalDecisions) {
63
+ if (memory.value.toLowerCase().includes(decision.toLowerCase())) {
64
+ priority += 0.15;
65
+ reason += ' +critical';
66
+ break;
67
+ }
68
+ }
69
+ // Boost priority for code changes
70
+ for (const change of codeChanges) {
71
+ if (memory.value.toLowerCase().includes(change.toLowerCase())) {
72
+ priority += 0.1;
73
+ reason += ' +change';
74
+ break;
75
+ }
76
+ }
77
+ // Boost priority for blockers
78
+ for (const blocker of blockers) {
79
+ if (memory.value.toLowerCase().includes(blocker.toLowerCase())) {
80
+ priority += 0.25;
81
+ reason += ' +blocker';
82
+ break;
83
+ }
84
+ }
85
+ // Cap priority at 1.0
86
+ priority = Math.min(1.0, priority);
87
+ if (priority >= 0.6) {
88
+ prioritizedMemories.push({ memory, priority, reason });
89
+ // Update priority in database
90
+ mm.setPriority(memory.key, Math.floor(priority * 100));
91
+ }
92
+ }
93
+ const sortedMemories = prioritizedMemories
94
+ .sort((a, b) => b.priority - a.priority)
95
+ .slice(0, 20);
96
+ const resultList = sortedMemories.map(pm => `• [${(pm.priority * 100).toFixed(0)}%] ${pm.memory.key} (${pm.reason}): ${pm.memory.value.substring(0, 60)}${pm.memory.value.length > 60 ? '...' : ''}`).join('\n');
97
+ return {
98
+ content: [{
99
+ type: 'text',
100
+ text: `✓ Prioritized ${sortedMemories.length} memories for "${currentTask}":\n${resultList || 'None'}`
101
+ }]
102
+ };
103
+ }
104
+ catch (error) {
105
+ return {
106
+ content: [{ type: 'text', text: `✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}` }]
107
+ };
108
+ }
109
+ }
@@ -0,0 +1,40 @@
1
+ // Memory management tool - SQLite based (v1.3)
2
+ import { MemoryManager } from '../../lib/MemoryManager.js';
3
+ export const recallMemoryDefinition = {
4
+ name: 'recall_memory',
5
+ description: '떠올려|recall|기억나|remember what|what was|remind - Retrieve from memory',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ key: { type: 'string', description: 'Memory key to retrieve' },
10
+ category: { type: 'string', description: 'Memory category to search in' }
11
+ },
12
+ required: ['key']
13
+ },
14
+ annotations: {
15
+ title: 'Recall Memory',
16
+ audience: ['user', 'assistant']
17
+ }
18
+ };
19
+ export async function recallMemory(args) {
20
+ const { key: recallKey } = args;
21
+ try {
22
+ const memoryManager = MemoryManager.getInstance();
23
+ const memory = memoryManager.recall(recallKey);
24
+ if (memory) {
25
+ return {
26
+ content: [{ type: 'text', text: `${memory.key}: ${memory.value}\n[${memory.category}]` }]
27
+ };
28
+ }
29
+ else {
30
+ return {
31
+ content: [{ type: 'text', text: `✗ Not found: "${recallKey}"` }]
32
+ };
33
+ }
34
+ }
35
+ catch (error) {
36
+ return {
37
+ content: [{ type: 'text', text: `✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}` }]
38
+ };
39
+ }
40
+ }