cmp-memory-system 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +541 -0
- package/dist/analytics/index.d.ts +5 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +5 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/tracker.d.ts +107 -0
- package/dist/analytics/tracker.d.ts.map +1 -0
- package/dist/analytics/tracker.js +333 -0
- package/dist/analytics/tracker.js.map +1 -0
- package/dist/auto-improve/eslint-generator.d.ts +36 -0
- package/dist/auto-improve/eslint-generator.d.ts.map +1 -0
- package/dist/auto-improve/eslint-generator.js +280 -0
- package/dist/auto-improve/eslint-generator.js.map +1 -0
- package/dist/auto-improve/index.d.ts +6 -0
- package/dist/auto-improve/index.d.ts.map +1 -0
- package/dist/auto-improve/index.js +6 -0
- package/dist/auto-improve/index.js.map +1 -0
- package/dist/auto-improve/pattern-detector.d.ts +92 -0
- package/dist/auto-improve/pattern-detector.d.ts.map +1 -0
- package/dist/auto-improve/pattern-detector.js +231 -0
- package/dist/auto-improve/pattern-detector.js.map +1 -0
- package/dist/cli/index.d.ts +16 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +636 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/dashboard/index.d.ts +6 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +6 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/server.d.ts +15 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +373 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/dashboard/ui.d.ts +9 -0
- package/dist/dashboard/ui.d.ts.map +1 -0
- package/dist/dashboard/ui.js +530 -0
- package/dist/dashboard/ui.js.map +1 -0
- package/dist/db/client.d.ts +66 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +159 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/drizzle-client.d.ts +302 -0
- package/dist/db/drizzle-client.d.ts.map +1 -0
- package/dist/db/drizzle-client.js +404 -0
- package/dist/db/drizzle-client.js.map +1 -0
- package/dist/db/index.d.ts +5 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +5 -0
- package/dist/db/index.js.map +1 -0
- package/dist/feedback/collector.d.ts +74 -0
- package/dist/feedback/collector.d.ts.map +1 -0
- package/dist/feedback/collector.js +231 -0
- package/dist/feedback/collector.js.map +1 -0
- package/dist/feedback/index.d.ts +5 -0
- package/dist/feedback/index.d.ts.map +1 -0
- package/dist/feedback/index.js +5 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/memory-checkpoint.d.ts +43 -0
- package/dist/hooks/memory-checkpoint.d.ts.map +1 -0
- package/dist/hooks/memory-checkpoint.js +257 -0
- package/dist/hooks/memory-checkpoint.js.map +1 -0
- package/dist/hooks/post-tool-use.d.ts +61 -0
- package/dist/hooks/post-tool-use.d.ts.map +1 -0
- package/dist/hooks/post-tool-use.js +262 -0
- package/dist/hooks/post-tool-use.js.map +1 -0
- package/dist/hooks/pre-tool-use.d.ts +34 -0
- package/dist/hooks/pre-tool-use.d.ts.map +1 -0
- package/dist/hooks/pre-tool-use.js +358 -0
- package/dist/hooks/pre-tool-use.js.map +1 -0
- package/dist/hooks/session-start.d.ts +38 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +274 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +42 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +599 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/registry/embeddings.d.ts +38 -0
- package/dist/registry/embeddings.d.ts.map +1 -0
- package/dist/registry/embeddings.js +110 -0
- package/dist/registry/embeddings.js.map +1 -0
- package/dist/registry/generator.d.ts +41 -0
- package/dist/registry/generator.d.ts.map +1 -0
- package/dist/registry/generator.js +323 -0
- package/dist/registry/generator.js.map +1 -0
- package/dist/registry/index.d.ts +6 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +6 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/services/IdeaCollector.d.ts +103 -0
- package/dist/services/IdeaCollector.d.ts.map +1 -0
- package/dist/services/IdeaCollector.js +371 -0
- package/dist/services/IdeaCollector.js.map +1 -0
- package/dist/services/TaskTracker.d.ts +89 -0
- package/dist/services/TaskTracker.d.ts.map +1 -0
- package/dist/services/TaskTracker.js +324 -0
- package/dist/services/TaskTracker.js.map +1 -0
- package/dist/services/WorkPlanManager.d.ts +107 -0
- package/dist/services/WorkPlanManager.d.ts.map +1 -0
- package/dist/services/WorkPlanManager.js +440 -0
- package/dist/services/WorkPlanManager.js.map +1 -0
- package/dist/services/auto-inject.d.ts +77 -0
- package/dist/services/auto-inject.d.ts.map +1 -0
- package/dist/services/auto-inject.js +289 -0
- package/dist/services/auto-inject.js.map +1 -0
- package/dist/services/auto-tag.d.ts +61 -0
- package/dist/services/auto-tag.d.ts.map +1 -0
- package/dist/services/auto-tag.js +203 -0
- package/dist/services/auto-tag.js.map +1 -0
- package/dist/services/cross-project-sync.d.ts +76 -0
- package/dist/services/cross-project-sync.d.ts.map +1 -0
- package/dist/services/cross-project-sync.js +235 -0
- package/dist/services/cross-project-sync.js.map +1 -0
- package/dist/services/index.d.ts +15 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +18 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/memory-consolidation.d.ts +77 -0
- package/dist/services/memory-consolidation.d.ts.map +1 -0
- package/dist/services/memory-consolidation.js +298 -0
- package/dist/services/memory-consolidation.js.map +1 -0
- package/dist/services/semantic-search.d.ts +93 -0
- package/dist/services/semantic-search.d.ts.map +1 -0
- package/dist/services/semantic-search.js +278 -0
- package/dist/services/semantic-search.js.map +1 -0
- package/dist/services/weekly-digest.d.ts +105 -0
- package/dist/services/weekly-digest.d.ts.map +1 -0
- package/dist/services/weekly-digest.js +292 -0
- package/dist/services/weekly-digest.js.map +1 -0
- package/dist/types/index.d.ts +274 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +84 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/config.d.ts +21 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +89 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/paths.d.ts +28 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +80 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +89 -0
- package/templates/memory-config.json +82 -0
- package/templates/memory-config.schema.json +212 -0
- package/templates/settings.json +58 -0
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CMP Memory System CLI
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* init - Initialize memory system in project
|
|
7
|
+
* generate - Generate embedding registry
|
|
8
|
+
* scan - Scan for patterns
|
|
9
|
+
* improve - Run auto-improvement
|
|
10
|
+
* status - Show memory system status
|
|
11
|
+
* tasks - View and manage tasks
|
|
12
|
+
* ideas - View captured ideas
|
|
13
|
+
* plan - Manage work plans
|
|
14
|
+
*/
|
|
15
|
+
// Load environment variables from project root
|
|
16
|
+
import { config as loadEnv } from 'dotenv';
|
|
17
|
+
import { resolve } from 'path';
|
|
18
|
+
// Try to load .env from current working directory (project root)
|
|
19
|
+
loadEnv({ path: resolve(process.cwd(), '.env') });
|
|
20
|
+
// Also try plugin's own .env as fallback
|
|
21
|
+
loadEnv({ path: resolve(import.meta.dirname, '../../.env') });
|
|
22
|
+
import { Command } from 'commander';
|
|
23
|
+
import chalk from 'chalk';
|
|
24
|
+
import fs from 'fs/promises';
|
|
25
|
+
import path from 'path';
|
|
26
|
+
import { loadConfig, saveConfig, getDefaultConfig } from '../utils/config.js';
|
|
27
|
+
import { getProjectRoot, getClaudeDir, getHooksDir, getKnowledgeDir } from '../utils/paths.js';
|
|
28
|
+
import { RegistryGenerator } from '../registry/generator.js';
|
|
29
|
+
import { PatternDetector } from '../auto-improve/pattern-detector.js';
|
|
30
|
+
import { ESLintGenerator } from '../auto-improve/eslint-generator.js';
|
|
31
|
+
const program = new Command();
|
|
32
|
+
program
|
|
33
|
+
.name('cmp-memory')
|
|
34
|
+
.description('CMP Memory System - Task tracking, ideas & workflow for Claude Code')
|
|
35
|
+
.version('1.0.0');
|
|
36
|
+
// =============================================================================
|
|
37
|
+
// INIT COMMAND
|
|
38
|
+
// =============================================================================
|
|
39
|
+
program
|
|
40
|
+
.command('init')
|
|
41
|
+
.description('Initialize memory system in current project')
|
|
42
|
+
.option('-s, --system <system>', 'System identifier (SWARMSCALE, PANEL, etc.)', 'SWARMSCALE')
|
|
43
|
+
.option('-n, --name <name>', 'Project name')
|
|
44
|
+
.option('-f, --force', 'Overwrite existing configuration')
|
|
45
|
+
.action(async (options) => {
|
|
46
|
+
console.log(chalk.blue('🧠 Initializing MetaNautical Memory System\n'));
|
|
47
|
+
const projectRoot = await getProjectRoot();
|
|
48
|
+
console.log(chalk.gray(`Project: ${projectRoot}`));
|
|
49
|
+
// Check for existing config
|
|
50
|
+
const configPath = path.join(projectRoot, '.claude/memory-config.json');
|
|
51
|
+
try {
|
|
52
|
+
await fs.access(configPath);
|
|
53
|
+
if (!options.force) {
|
|
54
|
+
console.log(chalk.yellow('\n⚠️ Configuration already exists. Use --force to overwrite.'));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// No existing config, proceed
|
|
60
|
+
}
|
|
61
|
+
// Create directories
|
|
62
|
+
const claudeDir = getClaudeDir(projectRoot);
|
|
63
|
+
const hooksDir = getHooksDir(projectRoot);
|
|
64
|
+
const knowledgeDir = getKnowledgeDir(projectRoot);
|
|
65
|
+
await fs.mkdir(claudeDir, { recursive: true });
|
|
66
|
+
await fs.mkdir(hooksDir, { recursive: true });
|
|
67
|
+
await fs.mkdir(knowledgeDir, { recursive: true });
|
|
68
|
+
console.log(chalk.green('✓ Created .claude directories'));
|
|
69
|
+
// Create config
|
|
70
|
+
const config = getDefaultConfig(options.system);
|
|
71
|
+
if (options.name) {
|
|
72
|
+
config.projectName = options.name;
|
|
73
|
+
}
|
|
74
|
+
await saveConfig(projectRoot, config);
|
|
75
|
+
console.log(chalk.green('✓ Created memory-config.json'));
|
|
76
|
+
// Create empty registry
|
|
77
|
+
const registryPath = path.join(knowledgeDir, 'registry.json');
|
|
78
|
+
await fs.writeFile(registryPath, JSON.stringify({
|
|
79
|
+
version: '1.0.0',
|
|
80
|
+
model: 'pending',
|
|
81
|
+
dimension: 0,
|
|
82
|
+
generatedAt: '',
|
|
83
|
+
sections: []
|
|
84
|
+
}, null, 2));
|
|
85
|
+
console.log(chalk.green('✓ Created empty registry.json'));
|
|
86
|
+
// Show next steps
|
|
87
|
+
console.log(chalk.blue('\n📋 Next steps:'));
|
|
88
|
+
console.log(' 1. Edit .claude/memory-config.json to configure domains');
|
|
89
|
+
console.log(' 2. Run: claude-memory generate');
|
|
90
|
+
console.log(' 3. Update .claude/settings.json with hooks');
|
|
91
|
+
console.log(chalk.green('\n✅ Initialization complete!'));
|
|
92
|
+
});
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// GENERATE COMMAND
|
|
95
|
+
// =============================================================================
|
|
96
|
+
program
|
|
97
|
+
.command('generate')
|
|
98
|
+
.description('Generate embedding registry from documentation')
|
|
99
|
+
.option('-i, --incremental', 'Only update changed files')
|
|
100
|
+
.option('--files <files>', 'Specific files to process (comma-separated)')
|
|
101
|
+
.action(async (options) => {
|
|
102
|
+
console.log(chalk.blue('📚 Generating Knowledge Registry\n'));
|
|
103
|
+
const generator = new RegistryGenerator();
|
|
104
|
+
if (options.files) {
|
|
105
|
+
const files = options.files.split(',').map((f) => f.trim());
|
|
106
|
+
console.log(`Processing ${files.length} specific files...`);
|
|
107
|
+
await generator.update(files);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
await generator.generate();
|
|
111
|
+
}
|
|
112
|
+
console.log(chalk.green('\n✅ Registry generation complete!'));
|
|
113
|
+
});
|
|
114
|
+
// =============================================================================
|
|
115
|
+
// SCAN COMMAND
|
|
116
|
+
// =============================================================================
|
|
117
|
+
program
|
|
118
|
+
.command('scan')
|
|
119
|
+
.description('Scan codebase for patterns')
|
|
120
|
+
.option('-d, --dir <directory>', 'Directory to scan', 'src')
|
|
121
|
+
.option('-t, --threshold <number>', 'Pattern threshold', '3')
|
|
122
|
+
.action(async (options) => {
|
|
123
|
+
console.log(chalk.blue('🔍 Scanning for Patterns\n'));
|
|
124
|
+
const projectRoot = await getProjectRoot();
|
|
125
|
+
const config = await loadConfig(projectRoot);
|
|
126
|
+
const detector = new PatternDetector(config);
|
|
127
|
+
// Find TypeScript files
|
|
128
|
+
const { glob } = await import('glob');
|
|
129
|
+
const files = await glob(`${options.dir}/**/*.{ts,tsx}`, {
|
|
130
|
+
cwd: projectRoot,
|
|
131
|
+
absolute: true,
|
|
132
|
+
ignore: ['**/node_modules/**', '**/*.d.ts', '**/*.test.ts'],
|
|
133
|
+
});
|
|
134
|
+
console.log(`Scanning ${files.length} files...`);
|
|
135
|
+
for (const file of files) {
|
|
136
|
+
const content = await fs.readFile(file, 'utf-8');
|
|
137
|
+
detector.scan(content, file);
|
|
138
|
+
}
|
|
139
|
+
const results = detector.getResults();
|
|
140
|
+
console.log(chalk.blue('\n📊 Results:'));
|
|
141
|
+
console.log(` Total patterns: ${results.total}`);
|
|
142
|
+
console.log(` Triggered (≥${options.threshold}): ${results.triggered.length}`);
|
|
143
|
+
if (results.patterns.length > 0) {
|
|
144
|
+
console.log(chalk.blue('\n📋 Detected Patterns:'));
|
|
145
|
+
for (const pattern of results.patterns) {
|
|
146
|
+
const icon = pattern.needsAutoImprove ? '🔴' : '⚪';
|
|
147
|
+
const severity = chalk.gray(`[${pattern.severity}]`);
|
|
148
|
+
console.log(` ${icon} ${pattern.patternId} ${severity}`);
|
|
149
|
+
console.log(` Count: ${pattern.count}, Files: ${pattern.files.length}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (results.triggered.length > 0) {
|
|
153
|
+
console.log(chalk.yellow('\n⚠️ Patterns ready for auto-improvement:'));
|
|
154
|
+
for (const pattern of results.triggered) {
|
|
155
|
+
console.log(` - ${pattern.patternId} (${pattern.count} occurrences)`);
|
|
156
|
+
}
|
|
157
|
+
console.log(chalk.gray('\n Run: claude-memory improve'));
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
// =============================================================================
|
|
161
|
+
// IMPROVE COMMAND
|
|
162
|
+
// =============================================================================
|
|
163
|
+
program
|
|
164
|
+
.command('improve')
|
|
165
|
+
.description('Run auto-improvement for triggered patterns')
|
|
166
|
+
.option('--dry-run', 'Show what would be done without making changes')
|
|
167
|
+
.option('-p, --pattern <pattern>', 'Specific pattern to improve')
|
|
168
|
+
.action(async (options) => {
|
|
169
|
+
console.log(chalk.blue('🔧 Running Auto-Improvement\n'));
|
|
170
|
+
const projectRoot = await getProjectRoot();
|
|
171
|
+
const config = await loadConfig(projectRoot);
|
|
172
|
+
// First scan for patterns
|
|
173
|
+
const detector = new PatternDetector(config);
|
|
174
|
+
const { glob } = await import('glob');
|
|
175
|
+
const files = await glob('src/**/*.{ts,tsx}', {
|
|
176
|
+
cwd: projectRoot,
|
|
177
|
+
absolute: true,
|
|
178
|
+
ignore: ['**/node_modules/**', '**/*.d.ts'],
|
|
179
|
+
});
|
|
180
|
+
for (const file of files) {
|
|
181
|
+
const content = await fs.readFile(file, 'utf-8');
|
|
182
|
+
detector.scan(content, file);
|
|
183
|
+
}
|
|
184
|
+
const results = detector.getResults();
|
|
185
|
+
// Filter patterns to improve
|
|
186
|
+
let patternsToImprove = results.triggered;
|
|
187
|
+
if (options.pattern) {
|
|
188
|
+
patternsToImprove = patternsToImprove.filter(p => p.patternId === options.pattern);
|
|
189
|
+
}
|
|
190
|
+
if (patternsToImprove.length === 0) {
|
|
191
|
+
console.log(chalk.green('✅ No patterns need improvement'));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
console.log(`Found ${patternsToImprove.length} patterns to improve:`);
|
|
195
|
+
for (const pattern of patternsToImprove) {
|
|
196
|
+
console.log(` - ${pattern.patternId}`);
|
|
197
|
+
}
|
|
198
|
+
if (options.dryRun) {
|
|
199
|
+
console.log(chalk.yellow('\n[DRY RUN] Would generate ESLint rules for above patterns'));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// Generate ESLint rules
|
|
203
|
+
const generator = new ESLintGenerator();
|
|
204
|
+
const improvementResults = await generator.generateAllRules(patternsToImprove);
|
|
205
|
+
console.log(chalk.blue('\n📋 Improvement Results:'));
|
|
206
|
+
for (const result of improvementResults) {
|
|
207
|
+
if (result.success) {
|
|
208
|
+
console.log(chalk.green(` ✓ ${result.action}: ${result.filePath}`));
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
console.log(chalk.red(` ✗ ${result.action}: ${result.error}`));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
const successCount = improvementResults.filter(r => r.success).length;
|
|
215
|
+
console.log(chalk.green(`\n✅ Completed: ${successCount}/${improvementResults.length} improvements`));
|
|
216
|
+
});
|
|
217
|
+
// =============================================================================
|
|
218
|
+
// STATUS COMMAND
|
|
219
|
+
// =============================================================================
|
|
220
|
+
program
|
|
221
|
+
.command('status')
|
|
222
|
+
.description('Show memory system status')
|
|
223
|
+
.action(async () => {
|
|
224
|
+
console.log(chalk.blue('📊 Memory System Status\n'));
|
|
225
|
+
const projectRoot = await getProjectRoot();
|
|
226
|
+
// Check config
|
|
227
|
+
let config;
|
|
228
|
+
try {
|
|
229
|
+
config = await loadConfig(projectRoot);
|
|
230
|
+
console.log(chalk.green('✓ Configuration found'));
|
|
231
|
+
console.log(` System: ${config.system}`);
|
|
232
|
+
console.log(` Project: ${config.projectName}`);
|
|
233
|
+
console.log(` Domains: ${config.domains.length}`);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
console.log(chalk.red('✗ No configuration found'));
|
|
237
|
+
console.log(chalk.gray(' Run: claude-memory init'));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// Check registry
|
|
241
|
+
const registryPath = path.join(projectRoot, '.claude/knowledge/registry.json');
|
|
242
|
+
try {
|
|
243
|
+
const registryContent = await fs.readFile(registryPath, 'utf-8');
|
|
244
|
+
const registry = JSON.parse(registryContent);
|
|
245
|
+
console.log(chalk.green('✓ Registry found'));
|
|
246
|
+
console.log(` Sections: ${registry.sections.length}`);
|
|
247
|
+
console.log(` Generated: ${registry.generatedAt || 'pending'}`);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
console.log(chalk.yellow('⚠ No registry found'));
|
|
251
|
+
console.log(chalk.gray(' Run: claude-memory generate'));
|
|
252
|
+
}
|
|
253
|
+
// Check hooks
|
|
254
|
+
const hooksDir = getHooksDir(projectRoot);
|
|
255
|
+
try {
|
|
256
|
+
const hooks = await fs.readdir(hooksDir);
|
|
257
|
+
const hookFiles = hooks.filter(h => h.endsWith('.ts') || h.endsWith('.md'));
|
|
258
|
+
console.log(chalk.green(`✓ Hooks directory (${hookFiles.length} files)`));
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
console.log(chalk.yellow('⚠ No hooks directory'));
|
|
262
|
+
}
|
|
263
|
+
// Check settings.json
|
|
264
|
+
const settingsPath = path.join(projectRoot, '.claude/settings.json');
|
|
265
|
+
try {
|
|
266
|
+
const settingsContent = await fs.readFile(settingsPath, 'utf-8');
|
|
267
|
+
const settings = JSON.parse(settingsContent);
|
|
268
|
+
const hasMemoryPlugin = settings.plugins?.['metanautical-memory'];
|
|
269
|
+
if (hasMemoryPlugin) {
|
|
270
|
+
console.log(chalk.green('✓ Memory plugin configured in settings.json'));
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
console.log(chalk.yellow('⚠ Memory plugin not in settings.json'));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
console.log(chalk.yellow('⚠ No settings.json found'));
|
|
278
|
+
}
|
|
279
|
+
// Features status
|
|
280
|
+
console.log(chalk.blue('\n🔧 Features:'));
|
|
281
|
+
console.log(` Guards: ${config.guards.enabled ? 'Enabled' : 'Disabled'} (${config.guards.rules.length} rules)`);
|
|
282
|
+
console.log(` Embedding: ${config.embedding.enabled ? 'Enabled' : 'Disabled'}`);
|
|
283
|
+
console.log(` Checkpoint: ${config.checkpoint.enabled ? 'Enabled' : 'Disabled'}`);
|
|
284
|
+
console.log(` Auto-improve: ${config.autoImprovement.enabled ? 'Enabled' : 'Disabled'} (threshold: ${config.autoImprovement.violationThreshold})`);
|
|
285
|
+
});
|
|
286
|
+
// =============================================================================
|
|
287
|
+
// DASHBOARD COMMAND
|
|
288
|
+
// =============================================================================
|
|
289
|
+
program
|
|
290
|
+
.command('dashboard')
|
|
291
|
+
.description('Start the memory dashboard web UI')
|
|
292
|
+
.option('-p, --port <port>', 'Port to run on', '3847')
|
|
293
|
+
.option('--no-open', 'Do not open browser automatically')
|
|
294
|
+
.action(async (options) => {
|
|
295
|
+
console.log(chalk.blue('🖥️ Starting Memory Dashboard\n'));
|
|
296
|
+
const { startDashboard } = await import('../dashboard/server.js');
|
|
297
|
+
await startDashboard({
|
|
298
|
+
port: parseInt(options.port, 10),
|
|
299
|
+
openBrowser: options.open !== false,
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
// =============================================================================
|
|
303
|
+
// MCP COMMAND
|
|
304
|
+
// =============================================================================
|
|
305
|
+
program
|
|
306
|
+
.command('mcp')
|
|
307
|
+
.description('Start the MCP server for Claude integration')
|
|
308
|
+
.action(async () => {
|
|
309
|
+
console.log(chalk.blue('🔌 Starting MCP Server\n'));
|
|
310
|
+
const { startMCPServer } = await import('../mcp/server.js');
|
|
311
|
+
await startMCPServer();
|
|
312
|
+
});
|
|
313
|
+
// =============================================================================
|
|
314
|
+
// ANALYTICS COMMAND
|
|
315
|
+
// =============================================================================
|
|
316
|
+
program
|
|
317
|
+
.command('analytics')
|
|
318
|
+
.description('Show analytics and system health')
|
|
319
|
+
.option('-p, --period <period>', 'Time period (day, week, month)', 'week')
|
|
320
|
+
.option('--json', 'Output as JSON')
|
|
321
|
+
.action(async (options) => {
|
|
322
|
+
console.log(chalk.blue('📈 Memory System Analytics\n'));
|
|
323
|
+
const projectRoot = await getProjectRoot();
|
|
324
|
+
const config = await loadConfig(projectRoot);
|
|
325
|
+
const { createAnalyticsTracker } = await import('../analytics/tracker.js');
|
|
326
|
+
const tracker = createAnalyticsTracker(config.system);
|
|
327
|
+
const report = await tracker.generateReport();
|
|
328
|
+
if (options.json) {
|
|
329
|
+
console.log(JSON.stringify(report, null, 2));
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
// System Health
|
|
333
|
+
const healthColor = {
|
|
334
|
+
healthy: chalk.green,
|
|
335
|
+
degraded: chalk.yellow,
|
|
336
|
+
critical: chalk.red,
|
|
337
|
+
}[report.health.status];
|
|
338
|
+
console.log(chalk.blue('🏥 System Health:'));
|
|
339
|
+
console.log(` Status: ${healthColor(report.health.status.toUpperCase())}`);
|
|
340
|
+
console.log(` Total Memories: ${report.health.metrics.totalMemories}`);
|
|
341
|
+
console.log(` Active Patterns: ${report.health.metrics.activePatterns}`);
|
|
342
|
+
console.log(` Triggered Patterns: ${report.health.metrics.triggeredPatterns}`);
|
|
343
|
+
console.log(` Recent Sessions (24h): ${report.health.metrics.recentSessions}`);
|
|
344
|
+
console.log(` Feedback Rate: ${(report.health.metrics.feedbackRate * 100).toFixed(1)}%`);
|
|
345
|
+
console.log(` Avg Memory Age: ${report.health.metrics.avgMemoryAge} days`);
|
|
346
|
+
if (report.health.issues.length > 0) {
|
|
347
|
+
console.log(chalk.yellow('\n⚠️ Issues:'));
|
|
348
|
+
for (const issue of report.health.issues) {
|
|
349
|
+
console.log(` - ${issue}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (report.health.recommendations.length > 0) {
|
|
353
|
+
console.log(chalk.blue('\n💡 Recommendations:'));
|
|
354
|
+
for (const rec of report.health.recommendations) {
|
|
355
|
+
console.log(` - ${rec}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// Usage Stats
|
|
359
|
+
console.log(chalk.blue(`\n📊 Usage (${report.usage.period}):`));
|
|
360
|
+
console.log(` Sessions: ${report.usage.sessions}`);
|
|
361
|
+
console.log(` Memories Created: ${report.usage.memoriesCreated}`);
|
|
362
|
+
console.log(` Memories Accessed: ${report.usage.memoriesAccessed}`);
|
|
363
|
+
console.log(` Searches: ${report.usage.searchesPerformed}`);
|
|
364
|
+
console.log(` Patterns Detected: ${report.usage.patternsDetected}`);
|
|
365
|
+
console.log(` Feedback Given: ${report.usage.feedbackGiven}`);
|
|
366
|
+
// Memory Insights
|
|
367
|
+
if (report.memoryInsights.mostAccessedMemories.length > 0) {
|
|
368
|
+
console.log(chalk.blue('\n🔝 Most Accessed Memories:'));
|
|
369
|
+
for (const m of report.memoryInsights.mostAccessedMemories.slice(0, 5)) {
|
|
370
|
+
console.log(` ${m.accessCount}x - ${m.title}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// Domain Distribution
|
|
374
|
+
const domains = Object.entries(report.memoryInsights.domainDistribution);
|
|
375
|
+
if (domains.length > 0) {
|
|
376
|
+
console.log(chalk.blue('\n📁 Domain Distribution:'));
|
|
377
|
+
for (const [domain, count] of domains.sort((a, b) => b[1] - a[1]).slice(0, 5)) {
|
|
378
|
+
console.log(` ${domain}: ${count}`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
// Pattern Insights
|
|
382
|
+
if (report.patternInsights.autoImprovementCandidates.length > 0) {
|
|
383
|
+
console.log(chalk.yellow('\n🔧 Auto-Improvement Candidates:'));
|
|
384
|
+
for (const p of report.patternInsights.autoImprovementCandidates) {
|
|
385
|
+
console.log(` ${p.patternId}: ${p.occurrences}x in ${p.files} files`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
console.log(chalk.gray(`\nGenerated at: ${report.generatedAt}`));
|
|
389
|
+
});
|
|
390
|
+
// =============================================================================
|
|
391
|
+
// FEEDBACK COMMAND
|
|
392
|
+
// =============================================================================
|
|
393
|
+
program
|
|
394
|
+
.command('feedback')
|
|
395
|
+
.description('View feedback statistics')
|
|
396
|
+
.action(async () => {
|
|
397
|
+
console.log(chalk.blue('💬 Feedback Statistics\n'));
|
|
398
|
+
const projectRoot = await getProjectRoot();
|
|
399
|
+
const config = await loadConfig(projectRoot);
|
|
400
|
+
const { createFeedbackCollector } = await import('../feedback/collector.js');
|
|
401
|
+
const collector = createFeedbackCollector(config.system);
|
|
402
|
+
const stats = await collector.getStats();
|
|
403
|
+
console.log(`Total Feedback: ${stats.totalFeedback}`);
|
|
404
|
+
console.log(`Helpful: ${stats.helpfulCount} (${(stats.helpfulRate * 100).toFixed(1)}%)`);
|
|
405
|
+
console.log(`Not Helpful: ${stats.notHelpfulCount}`);
|
|
406
|
+
if (stats.topHelpfulMemories.length > 0) {
|
|
407
|
+
console.log(chalk.green('\n👍 Top Helpful Memories:'));
|
|
408
|
+
for (const m of stats.topHelpfulMemories) {
|
|
409
|
+
console.log(` ${m.helpfulCount}x - ${m.title}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (stats.topUnhelpfulMemories.length > 0) {
|
|
413
|
+
console.log(chalk.yellow('\n👎 Needs Improvement:'));
|
|
414
|
+
for (const m of stats.topUnhelpfulMemories) {
|
|
415
|
+
console.log(` ${m.unhelpfulCount}x - ${m.title}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
// Get deprecation suggestions
|
|
419
|
+
const deprecations = await collector.getSuggestedDeprecations();
|
|
420
|
+
if (deprecations.length > 0) {
|
|
421
|
+
console.log(chalk.red(`\n🗑️ Suggested Deprecations: ${deprecations.length} memories`));
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
// =============================================================================
|
|
425
|
+
// TASKS COMMAND
|
|
426
|
+
// =============================================================================
|
|
427
|
+
program
|
|
428
|
+
.command('tasks')
|
|
429
|
+
.description('View and manage tasks')
|
|
430
|
+
.option('-a, --all', 'Show all tasks including completed')
|
|
431
|
+
.option('-l, --limit <number>', 'Limit number of tasks', '10')
|
|
432
|
+
.action(async (options) => {
|
|
433
|
+
console.log(chalk.blue('📋 Tasks\n'));
|
|
434
|
+
const projectRoot = await getProjectRoot();
|
|
435
|
+
const config = await loadConfig(projectRoot);
|
|
436
|
+
const { getTaskTracker } = await import('../services/TaskTracker.js');
|
|
437
|
+
const tracker = getTaskTracker(config.system);
|
|
438
|
+
// Get current task
|
|
439
|
+
const currentTask = await tracker.getCurrentTask();
|
|
440
|
+
if (currentTask) {
|
|
441
|
+
const content = currentTask.content;
|
|
442
|
+
console.log(chalk.green('▶ Current Task:'));
|
|
443
|
+
console.log(` ${content.title}`);
|
|
444
|
+
console.log(` Status: ${content.status}`);
|
|
445
|
+
if (content.filesModified?.length) {
|
|
446
|
+
console.log(` Files: ${content.filesModified.length} modified`);
|
|
447
|
+
}
|
|
448
|
+
console.log('');
|
|
449
|
+
}
|
|
450
|
+
// Get recent tasks
|
|
451
|
+
const tasks = await tracker.getRecentTasks(parseInt(options.limit, 10));
|
|
452
|
+
if (tasks.length > 0) {
|
|
453
|
+
console.log(chalk.blue('📜 Recent Tasks:'));
|
|
454
|
+
for (const task of tasks) {
|
|
455
|
+
const content = task.content;
|
|
456
|
+
const icon = content.status === 'completed' ? '✓' : content.status === 'in_progress' ? '→' : '○';
|
|
457
|
+
console.log(` ${icon} ${content.title} [${content.status}]`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
console.log(chalk.gray('No tasks found'));
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
// =============================================================================
|
|
465
|
+
// IDEAS COMMAND
|
|
466
|
+
// =============================================================================
|
|
467
|
+
program
|
|
468
|
+
.command('ideas')
|
|
469
|
+
.description('View captured ideas')
|
|
470
|
+
.option('-c, --category <category>', 'Filter by category')
|
|
471
|
+
.option('-p, --priority <priority>', 'Filter by priority')
|
|
472
|
+
.option('-l, --limit <number>', 'Limit number of ideas', '20')
|
|
473
|
+
.action(async (options) => {
|
|
474
|
+
console.log(chalk.blue('💡 Ideas\n'));
|
|
475
|
+
const projectRoot = await getProjectRoot();
|
|
476
|
+
const config = await loadConfig(projectRoot);
|
|
477
|
+
const { getIdeaCollector } = await import('../services/IdeaCollector.js');
|
|
478
|
+
const collector = getIdeaCollector(config.system);
|
|
479
|
+
const stats = await collector.getIdeaStats();
|
|
480
|
+
// Summary
|
|
481
|
+
console.log(`Total Ideas: ${stats.totalIdeas}`);
|
|
482
|
+
console.log(`By Category: ${Object.entries(stats.byCategory).map(([k, v]) => `${k}(${v})`).join(', ')}`);
|
|
483
|
+
console.log(`By Priority: ${Object.entries(stats.byPriority).map(([k, v]) => `${k}(${v})`).join(', ')}`);
|
|
484
|
+
console.log('');
|
|
485
|
+
// List ideas
|
|
486
|
+
const ideas = await collector.getAllIdeas({
|
|
487
|
+
category: options.category,
|
|
488
|
+
priority: options.priority,
|
|
489
|
+
limit: parseInt(options.limit, 10),
|
|
490
|
+
});
|
|
491
|
+
if (ideas.length > 0) {
|
|
492
|
+
console.log(chalk.blue('📝 Ideas:'));
|
|
493
|
+
for (const idea of ideas) {
|
|
494
|
+
const priorityIcon = idea.priority === 'high' ? '🔴' : idea.priority === 'medium' ? '🟡' : '🟢';
|
|
495
|
+
console.log(` ${priorityIcon} [${idea.category}] ${idea.title}`);
|
|
496
|
+
if (idea.relatedFiles?.length) {
|
|
497
|
+
console.log(chalk.gray(` Files: ${idea.relatedFiles.slice(0, 2).join(', ')}`));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
console.log(chalk.gray('No ideas found'));
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
// =============================================================================
|
|
506
|
+
// IMPROVEMENTS COMMAND
|
|
507
|
+
// =============================================================================
|
|
508
|
+
program
|
|
509
|
+
.command('improvements')
|
|
510
|
+
.description('View suggested improvements')
|
|
511
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
512
|
+
.option('-e, --effort <effort>', 'Filter by effort')
|
|
513
|
+
.option('-l, --limit <number>', 'Limit number', '20')
|
|
514
|
+
.action(async (options) => {
|
|
515
|
+
console.log(chalk.blue('🔧 Improvements\n'));
|
|
516
|
+
const projectRoot = await getProjectRoot();
|
|
517
|
+
const config = await loadConfig(projectRoot);
|
|
518
|
+
const { getIdeaCollector } = await import('../services/IdeaCollector.js');
|
|
519
|
+
const collector = getIdeaCollector(config.system);
|
|
520
|
+
const stats = await collector.getImprovementStats();
|
|
521
|
+
// Summary
|
|
522
|
+
console.log(`Total Improvements: ${stats.totalImprovements}`);
|
|
523
|
+
console.log(`By Type: ${Object.entries(stats.byType).map(([k, v]) => `${k}(${v})`).join(', ')}`);
|
|
524
|
+
console.log(`By Effort: ${Object.entries(stats.byEffort).map(([k, v]) => `${k}(${v})`).join(', ')}`);
|
|
525
|
+
console.log('');
|
|
526
|
+
// List improvements
|
|
527
|
+
const improvements = await collector.getAllImprovements({
|
|
528
|
+
type: options.type,
|
|
529
|
+
effort: options.effort,
|
|
530
|
+
limit: parseInt(options.limit, 10),
|
|
531
|
+
});
|
|
532
|
+
if (improvements.length > 0) {
|
|
533
|
+
console.log(chalk.blue('📋 Improvements:'));
|
|
534
|
+
for (const imp of improvements) {
|
|
535
|
+
const effortIcon = imp.effort === 'small' ? '🟢' : imp.effort === 'medium' ? '🟡' : '🔴';
|
|
536
|
+
console.log(` ${effortIcon} [${imp.type}] ${imp.title}`);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
console.log(chalk.gray('No improvements found'));
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
// =============================================================================
|
|
544
|
+
// PLAN COMMAND
|
|
545
|
+
// =============================================================================
|
|
546
|
+
program
|
|
547
|
+
.command('plan')
|
|
548
|
+
.description('Manage work plans')
|
|
549
|
+
.option('-s, --status', 'Show current plan status')
|
|
550
|
+
.option('-c, --complete', 'Complete current task')
|
|
551
|
+
.option('-n, --next', 'Move to next task')
|
|
552
|
+
.option('-h, --history', 'Show plan history')
|
|
553
|
+
.action(async (options) => {
|
|
554
|
+
const projectRoot = await getProjectRoot();
|
|
555
|
+
const config = await loadConfig(projectRoot);
|
|
556
|
+
const { getWorkPlanManager } = await import('../services/WorkPlanManager.js');
|
|
557
|
+
const manager = getWorkPlanManager(config.system);
|
|
558
|
+
if (options.complete) {
|
|
559
|
+
console.log(chalk.blue('Completing current task...'));
|
|
560
|
+
await manager.completeCurrentTask();
|
|
561
|
+
console.log(chalk.green('✓ Task completed'));
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
if (options.history) {
|
|
565
|
+
console.log(chalk.blue('📜 Plan History\n'));
|
|
566
|
+
const history = await manager.getPlanHistory();
|
|
567
|
+
for (const plan of history) {
|
|
568
|
+
const statusIcon = plan.status === 'completed' ? '✓' : plan.status === 'active' ? '→' : '○';
|
|
569
|
+
console.log(` ${statusIcon} ${plan.title} (${plan.progress}%)`);
|
|
570
|
+
}
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
// Default: show status
|
|
574
|
+
console.log(chalk.blue('📋 Work Plan Status\n'));
|
|
575
|
+
const summary = await manager.getPlanSummary();
|
|
576
|
+
if (!summary) {
|
|
577
|
+
console.log(chalk.yellow('No active work plan'));
|
|
578
|
+
console.log(chalk.gray('Create a plan by starting a new task session'));
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
console.log(chalk.green(`Plan: ${summary.title}`));
|
|
582
|
+
console.log(`Progress: ${summary.progress}%`);
|
|
583
|
+
console.log(`Tasks: ${summary.completedTasks}/${summary.totalTasks} completed`);
|
|
584
|
+
if (summary.currentTask) {
|
|
585
|
+
console.log(chalk.blue(`\nCurrent Task: ${summary.currentTask.title}`));
|
|
586
|
+
}
|
|
587
|
+
const tasks = await manager.getPlanTasks();
|
|
588
|
+
console.log(chalk.blue('\nAll Tasks:'));
|
|
589
|
+
for (const task of tasks) {
|
|
590
|
+
const icon = task.status === 'completed' ? '✓' : task.isCurrent ? '→' : '○';
|
|
591
|
+
console.log(` ${icon} ${task.title} [${task.status}]`);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
// =============================================================================
|
|
595
|
+
// CAPTURE COMMAND (quick idea/improvement capture)
|
|
596
|
+
// =============================================================================
|
|
597
|
+
program
|
|
598
|
+
.command('capture <text>')
|
|
599
|
+
.description('Quick capture an idea or improvement')
|
|
600
|
+
.option('-t, --task <taskId>', 'Associate with task')
|
|
601
|
+
.action(async (text, options) => {
|
|
602
|
+
const projectRoot = await getProjectRoot();
|
|
603
|
+
const config = await loadConfig(projectRoot);
|
|
604
|
+
const { getIdeaCollector } = await import('../services/IdeaCollector.js');
|
|
605
|
+
const collector = getIdeaCollector(config.system);
|
|
606
|
+
const result = await collector.quickCapture(text, {
|
|
607
|
+
taskId: options.task,
|
|
608
|
+
});
|
|
609
|
+
if (result.ideaId) {
|
|
610
|
+
console.log(chalk.green(`✓ Captured as idea: ${result.ideaId}`));
|
|
611
|
+
}
|
|
612
|
+
if (result.improvementId) {
|
|
613
|
+
console.log(chalk.green(`✓ Captured as improvement: ${result.improvementId}`));
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
// =============================================================================
|
|
617
|
+
// EXPORT COMMAND
|
|
618
|
+
// =============================================================================
|
|
619
|
+
program
|
|
620
|
+
.command('export')
|
|
621
|
+
.description('Export ideas and improvements as markdown')
|
|
622
|
+
.option('-o, --output <file>', 'Output file', 'IDEAS_AND_IMPROVEMENTS.md')
|
|
623
|
+
.action(async (options) => {
|
|
624
|
+
const projectRoot = await getProjectRoot();
|
|
625
|
+
const config = await loadConfig(projectRoot);
|
|
626
|
+
const { getIdeaCollector } = await import('../services/IdeaCollector.js');
|
|
627
|
+
const collector = getIdeaCollector(config.system);
|
|
628
|
+
const markdown = await collector.exportMarkdown();
|
|
629
|
+
await fs.writeFile(path.join(projectRoot, options.output), markdown);
|
|
630
|
+
console.log(chalk.green(`✓ Exported to ${options.output}`));
|
|
631
|
+
});
|
|
632
|
+
// =============================================================================
|
|
633
|
+
// MAIN
|
|
634
|
+
// =============================================================================
|
|
635
|
+
program.parse();
|
|
636
|
+
//# sourceMappingURL=index.js.map
|