midas-mcp 2.6.0 → 2.7.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/dist/search.js ADDED
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Semantic Search for Midas
3
+ *
4
+ * Simple keyword-based search with TF-IDF-like scoring.
5
+ * Can be upgraded to use embeddings when available.
6
+ */
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
8
+ import { join } from 'path';
9
+ import { sanitizePath } from './security.js';
10
+ import { getJournalEntries } from './tools/journal.js';
11
+ const MIDAS_DIR = '.midas';
12
+ const INDEX_FILE = 'search-index.json';
13
+ // ============================================================================
14
+ // KEYWORD EXTRACTION
15
+ // ============================================================================
16
+ const STOP_WORDS = new Set([
17
+ 'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of',
18
+ 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'been', 'be',
19
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should',
20
+ 'may', 'might', 'must', 'that', 'this', 'these', 'those', 'it', 'its',
21
+ 'i', 'you', 'he', 'she', 'we', 'they', 'them', 'their', 'my', 'your',
22
+ 'not', 'no', 'yes', 'if', 'then', 'else', 'when', 'while', 'so', 'than',
23
+ 'just', 'only', 'also', 'very', 'too', 'more', 'most', 'some', 'any',
24
+ 'all', 'each', 'every', 'both', 'few', 'many', 'much', 'other', 'such',
25
+ ]);
26
+ function extractKeywords(text) {
27
+ // Tokenize and normalize
28
+ const words = text.toLowerCase()
29
+ .replace(/[^a-z0-9_\-\.]+/g, ' ')
30
+ .split(/\s+/)
31
+ .filter(w => w.length > 2 && !STOP_WORDS.has(w));
32
+ // Count frequencies
33
+ const freq = {};
34
+ for (const word of words) {
35
+ freq[word] = (freq[word] || 0) + 1;
36
+ }
37
+ // Return top keywords by frequency
38
+ return Object.entries(freq)
39
+ .sort((a, b) => b[1] - a[1])
40
+ .slice(0, 20)
41
+ .map(([word]) => word);
42
+ }
43
+ // ============================================================================
44
+ // INDEX MANAGEMENT
45
+ // ============================================================================
46
+ function getIndexPath(projectPath) {
47
+ return join(projectPath, MIDAS_DIR, INDEX_FILE);
48
+ }
49
+ function loadIndex(projectPath) {
50
+ const path = getIndexPath(projectPath);
51
+ if (existsSync(path)) {
52
+ try {
53
+ return JSON.parse(readFileSync(path, 'utf-8'));
54
+ }
55
+ catch {
56
+ // Corrupted index
57
+ }
58
+ }
59
+ return { chunks: [], keywords: {}, lastUpdated: 0 };
60
+ }
61
+ function saveIndex(projectPath, index) {
62
+ const dir = join(projectPath, MIDAS_DIR);
63
+ if (!existsSync(dir)) {
64
+ mkdirSync(dir, { recursive: true });
65
+ }
66
+ index.lastUpdated = Date.now();
67
+ writeFileSync(getIndexPath(projectPath), JSON.stringify(index, null, 2));
68
+ }
69
+ // ============================================================================
70
+ // INDEXING
71
+ // ============================================================================
72
+ /**
73
+ * Index journal entries for search
74
+ */
75
+ export function indexJournalEntries(projectPath) {
76
+ const safePath = sanitizePath(projectPath);
77
+ const index = loadIndex(safePath);
78
+ const entries = getJournalEntries({ projectPath: safePath, limit: 100 });
79
+ // Remove old journal chunks
80
+ index.chunks = index.chunks.filter(c => c.type !== 'journal');
81
+ // Add new journal chunks
82
+ for (const entry of entries) {
83
+ const keywords = extractKeywords(entry.title + ' ' + entry.conversation);
84
+ index.chunks.push({
85
+ id: `journal-${entry.id}`,
86
+ type: 'journal',
87
+ source: entry.id,
88
+ content: entry.conversation.slice(0, 1000), // Limit content size
89
+ timestamp: new Date(entry.timestamp).getTime(),
90
+ keywords,
91
+ });
92
+ // Update keyword frequencies
93
+ for (const kw of keywords) {
94
+ index.keywords[kw] = (index.keywords[kw] || 0) + 1;
95
+ }
96
+ }
97
+ saveIndex(safePath, index);
98
+ return entries.length;
99
+ }
100
+ /**
101
+ * Index code files for search
102
+ */
103
+ export function indexCodeFiles(projectPath, maxFiles = 50) {
104
+ const safePath = sanitizePath(projectPath);
105
+ const index = loadIndex(safePath);
106
+ // Remove old code chunks
107
+ index.chunks = index.chunks.filter(c => c.type !== 'code');
108
+ const extensions = ['.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs', '.swift', '.md'];
109
+ const ignore = ['node_modules', '.git', 'dist', 'build', '.next', '__pycache__', '.midas'];
110
+ let indexed = 0;
111
+ function scanDir(dir, depth = 0) {
112
+ if (depth > 3 || indexed >= maxFiles)
113
+ return;
114
+ try {
115
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
116
+ if (indexed >= maxFiles)
117
+ break;
118
+ if (entry.name.startsWith('.') || ignore.includes(entry.name))
119
+ continue;
120
+ const path = join(dir, entry.name);
121
+ if (entry.isDirectory()) {
122
+ scanDir(path, depth + 1);
123
+ }
124
+ else if (extensions.some(ext => entry.name.endsWith(ext))) {
125
+ try {
126
+ const content = readFileSync(path, 'utf-8').slice(0, 2000);
127
+ const keywords = extractKeywords(content);
128
+ const relativePath = path.replace(safePath + '/', '');
129
+ index.chunks.push({
130
+ id: `code-${relativePath}`,
131
+ type: 'code',
132
+ source: relativePath,
133
+ content: content.slice(0, 500),
134
+ timestamp: Date.now(),
135
+ keywords,
136
+ });
137
+ for (const kw of keywords) {
138
+ index.keywords[kw] = (index.keywords[kw] || 0) + 1;
139
+ }
140
+ indexed++;
141
+ }
142
+ catch {
143
+ // Can't read file
144
+ }
145
+ }
146
+ }
147
+ }
148
+ catch {
149
+ // Can't read directory
150
+ }
151
+ }
152
+ scanDir(safePath);
153
+ saveIndex(safePath, index);
154
+ return indexed;
155
+ }
156
+ /**
157
+ * Add an error to the search index
158
+ */
159
+ export function indexError(projectPath, error, file) {
160
+ const safePath = sanitizePath(projectPath);
161
+ const index = loadIndex(safePath);
162
+ const keywords = extractKeywords(error + ' ' + (file || ''));
163
+ index.chunks.push({
164
+ id: `error-${Date.now()}`,
165
+ type: 'error',
166
+ source: file || 'unknown',
167
+ content: error.slice(0, 500),
168
+ timestamp: Date.now(),
169
+ keywords,
170
+ });
171
+ for (const kw of keywords) {
172
+ index.keywords[kw] = (index.keywords[kw] || 0) + 1;
173
+ }
174
+ // Keep only recent errors (last 20)
175
+ const errorChunks = index.chunks.filter(c => c.type === 'error');
176
+ if (errorChunks.length > 20) {
177
+ const toRemove = errorChunks
178
+ .sort((a, b) => a.timestamp - b.timestamp)
179
+ .slice(0, errorChunks.length - 20)
180
+ .map(c => c.id);
181
+ index.chunks = index.chunks.filter(c => !toRemove.includes(c.id));
182
+ }
183
+ saveIndex(safePath, index);
184
+ }
185
+ // ============================================================================
186
+ // SEARCH
187
+ // ============================================================================
188
+ /**
189
+ * Search for relevant chunks
190
+ */
191
+ export function search(projectPath, query, options = {}) {
192
+ const safePath = sanitizePath(projectPath);
193
+ const index = loadIndex(safePath);
194
+ const queryKeywords = extractKeywords(query);
195
+ if (queryKeywords.length === 0)
196
+ return [];
197
+ // Calculate TF-IDF-like scores
198
+ const totalDocs = index.chunks.length || 1;
199
+ const scored = [];
200
+ for (const chunk of index.chunks) {
201
+ // Filter by type
202
+ if (options.types && !options.types.includes(chunk.type))
203
+ continue;
204
+ // Calculate score
205
+ let score = 0;
206
+ for (const qk of queryKeywords) {
207
+ if (chunk.keywords.includes(qk)) {
208
+ // TF: keyword is present
209
+ const tf = 1;
210
+ // IDF: log(total docs / docs with this keyword)
211
+ const df = index.keywords[qk] || 1;
212
+ const idf = Math.log(totalDocs / df);
213
+ score += tf * idf;
214
+ }
215
+ }
216
+ if (score > 0) {
217
+ scored.push({ ...chunk, score });
218
+ }
219
+ }
220
+ // Sort by score (descending) and recency
221
+ scored.sort((a, b) => {
222
+ const scoreDiff = (b.score || 0) - (a.score || 0);
223
+ if (Math.abs(scoreDiff) > 0.5)
224
+ return scoreDiff;
225
+ return b.timestamp - a.timestamp;
226
+ });
227
+ return scored.slice(0, options.limit || 10);
228
+ }
229
+ /**
230
+ * Get search index stats
231
+ */
232
+ export function getSearchStats(projectPath) {
233
+ const index = loadIndex(projectPath);
234
+ const byType = {};
235
+ for (const chunk of index.chunks) {
236
+ byType[chunk.type] = (byType[chunk.type] || 0) + 1;
237
+ }
238
+ return {
239
+ totalChunks: index.chunks.length,
240
+ byType,
241
+ totalKeywords: Object.keys(index.keywords).length,
242
+ lastUpdated: index.lastUpdated,
243
+ };
244
+ }
245
+ /**
246
+ * Rebuild the entire search index
247
+ */
248
+ export function rebuildIndex(projectPath) {
249
+ const safePath = sanitizePath(projectPath);
250
+ // Clear existing index
251
+ const index = { chunks: [], keywords: {}, lastUpdated: Date.now() };
252
+ saveIndex(safePath, index);
253
+ // Re-index everything
254
+ const journal = indexJournalEntries(safePath);
255
+ const code = indexCodeFiles(safePath);
256
+ return { journal, code };
257
+ }
258
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tech Stack Detection and Project Rules Generation
3
+ */
4
+ export interface TechStack {
5
+ language: 'typescript' | 'javascript' | 'python' | 'go' | 'rust' | 'swift' | 'unknown';
6
+ framework?: string;
7
+ runtime?: string;
8
+ hasTests: boolean;
9
+ hasDocs: boolean;
10
+ hasCI: boolean;
11
+ dependencies: string[];
12
+ }
13
+ /**
14
+ * Detect tech stack from project files
15
+ */
16
+ export declare function detectTechStack(projectPath: string): TechStack;
17
+ /**
18
+ * Generate project-specific .cursorrules based on tech stack
19
+ */
20
+ export declare function generateCursorRules(projectPath: string, projectName: string): string;
21
+ /**
22
+ * Write .cursorrules to project
23
+ */
24
+ export declare function writeCursorRules(projectPath: string, projectName: string): {
25
+ success: boolean;
26
+ path: string;
27
+ };
28
+ //# sourceMappingURL=techstack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"techstack.d.ts","sourceRoot":"","sources":["../src/techstack.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACvF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CA+F9D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAgGpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAQ7G"}
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Tech Stack Detection and Project Rules Generation
3
+ */
4
+ import { existsSync, readFileSync, readdirSync, writeFileSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { sanitizePath } from './security.js';
7
+ /**
8
+ * Detect tech stack from project files
9
+ */
10
+ export function detectTechStack(projectPath) {
11
+ const safePath = sanitizePath(projectPath);
12
+ const stack = {
13
+ language: 'unknown',
14
+ hasTests: false,
15
+ hasDocs: false,
16
+ hasCI: false,
17
+ dependencies: [],
18
+ };
19
+ // Check for package.json (Node.js/JavaScript/TypeScript)
20
+ const pkgPath = join(safePath, 'package.json');
21
+ if (existsSync(pkgPath)) {
22
+ try {
23
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
24
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
25
+ stack.dependencies = Object.keys(allDeps).slice(0, 20);
26
+ // Detect TypeScript
27
+ if (allDeps.typescript || existsSync(join(safePath, 'tsconfig.json'))) {
28
+ stack.language = 'typescript';
29
+ }
30
+ else {
31
+ stack.language = 'javascript';
32
+ }
33
+ // Detect framework
34
+ if (allDeps.next)
35
+ stack.framework = 'Next.js';
36
+ else if (allDeps.react)
37
+ stack.framework = 'React';
38
+ else if (allDeps.vue)
39
+ stack.framework = 'Vue';
40
+ else if (allDeps.svelte)
41
+ stack.framework = 'Svelte';
42
+ else if (allDeps.express)
43
+ stack.framework = 'Express';
44
+ else if (allDeps.fastify)
45
+ stack.framework = 'Fastify';
46
+ else if (allDeps['@hono/node-server'] || allDeps.hono)
47
+ stack.framework = 'Hono';
48
+ // Detect runtime
49
+ if (allDeps.bun)
50
+ stack.runtime = 'Bun';
51
+ else
52
+ stack.runtime = 'Node.js';
53
+ // Check for tests
54
+ if (pkg.scripts?.test && pkg.scripts.test !== 'echo "Error: no test specified" && exit 1') {
55
+ stack.hasTests = true;
56
+ }
57
+ }
58
+ catch {
59
+ // Invalid package.json
60
+ }
61
+ }
62
+ // Check for Python
63
+ const reqPath = join(safePath, 'requirements.txt');
64
+ const pyprojectPath = join(safePath, 'pyproject.toml');
65
+ if (existsSync(reqPath) || existsSync(pyprojectPath)) {
66
+ stack.language = 'python';
67
+ if (existsSync(reqPath)) {
68
+ const reqs = readFileSync(reqPath, 'utf-8');
69
+ if (reqs.includes('fastapi'))
70
+ stack.framework = 'FastAPI';
71
+ else if (reqs.includes('django'))
72
+ stack.framework = 'Django';
73
+ else if (reqs.includes('flask'))
74
+ stack.framework = 'Flask';
75
+ }
76
+ }
77
+ // Check for Go
78
+ if (existsSync(join(safePath, 'go.mod'))) {
79
+ stack.language = 'go';
80
+ }
81
+ // Check for Rust
82
+ if (existsSync(join(safePath, 'Cargo.toml'))) {
83
+ stack.language = 'rust';
84
+ }
85
+ // Check for Swift
86
+ if (existsSync(join(safePath, 'Package.swift'))) {
87
+ stack.language = 'swift';
88
+ }
89
+ // Check for docs
90
+ stack.hasDocs = existsSync(join(safePath, 'docs')) || existsSync(join(safePath, 'README.md'));
91
+ // Check for CI
92
+ stack.hasCI = existsSync(join(safePath, '.github', 'workflows'));
93
+ // Check for tests (general)
94
+ if (!stack.hasTests) {
95
+ try {
96
+ const files = readdirSync(safePath, { withFileTypes: true });
97
+ stack.hasTests = files.some(f => f.name.includes('test') || f.name.includes('spec') || f.name === '__tests__');
98
+ }
99
+ catch {
100
+ // Can't read directory
101
+ }
102
+ }
103
+ return stack;
104
+ }
105
+ /**
106
+ * Generate project-specific .cursorrules based on tech stack
107
+ */
108
+ export function generateCursorRules(projectPath, projectName) {
109
+ const stack = detectTechStack(projectPath);
110
+ const lines = [
111
+ `# Project: ${projectName}`,
112
+ '',
113
+ '# Golden Code Methodology',
114
+ '- Follow the 4 phases: EAGLE_SIGHT -> BUILD -> SHIP -> GROW',
115
+ '- Use the 7-step BUILD cycle: RULES -> INDEX -> READ -> RESEARCH -> IMPLEMENT -> TEST -> DEBUG',
116
+ '- When stuck: Use Tornado (research + logs + tests)',
117
+ '',
118
+ ];
119
+ // Language-specific rules
120
+ if (stack.language === 'typescript') {
121
+ lines.push('# TypeScript Rules');
122
+ lines.push('- Use strict mode (strict: true in tsconfig)');
123
+ lines.push('- No `any` types - use `unknown` and narrow with type guards');
124
+ lines.push('- Explicit return types on exported functions');
125
+ lines.push('- Use `type` imports: `import type { X } from ...`');
126
+ lines.push('- Always use .js extension in ESM imports');
127
+ lines.push('');
128
+ }
129
+ else if (stack.language === 'javascript') {
130
+ lines.push('# JavaScript Rules');
131
+ lines.push('- Use ES modules (import/export)');
132
+ lines.push('- Prefer const over let, never use var');
133
+ lines.push('- Use async/await over raw promises');
134
+ lines.push('');
135
+ }
136
+ else if (stack.language === 'python') {
137
+ lines.push('# Python Rules');
138
+ lines.push('- Use type hints on all function signatures');
139
+ lines.push('- Follow PEP 8 style guide');
140
+ lines.push('- Use dataclasses or Pydantic for data structures');
141
+ lines.push('- Virtual environment required (venv or poetry)');
142
+ lines.push('');
143
+ }
144
+ else if (stack.language === 'go') {
145
+ lines.push('# Go Rules');
146
+ lines.push('- Follow effective Go patterns');
147
+ lines.push('- Handle all errors explicitly');
148
+ lines.push('- Use gofmt for formatting');
149
+ lines.push('- Prefer composition over inheritance');
150
+ lines.push('');
151
+ }
152
+ else if (stack.language === 'rust') {
153
+ lines.push('# Rust Rules');
154
+ lines.push('- Follow Rust API guidelines');
155
+ lines.push('- Handle all Results and Options');
156
+ lines.push('- Use clippy for linting');
157
+ lines.push('- Document public APIs');
158
+ lines.push('');
159
+ }
160
+ // Framework-specific rules
161
+ if (stack.framework) {
162
+ lines.push(`# ${stack.framework} Rules`);
163
+ if (stack.framework === 'Next.js') {
164
+ lines.push('- Use App Router (app/) over Pages Router');
165
+ lines.push('- Server Components by default, use "use client" sparingly');
166
+ lines.push('- Colocate components with their routes');
167
+ }
168
+ else if (stack.framework === 'React') {
169
+ lines.push('- Functional components with hooks');
170
+ lines.push('- Colocate state with components that need it');
171
+ lines.push('- Extract reusable logic to custom hooks');
172
+ }
173
+ else if (stack.framework === 'Express' || stack.framework === 'Fastify') {
174
+ lines.push('- Validate all request inputs');
175
+ lines.push('- Use middleware for cross-cutting concerns');
176
+ lines.push('- Centralized error handling');
177
+ }
178
+ lines.push('');
179
+ }
180
+ // Testing rules
181
+ lines.push('# Testing');
182
+ if (stack.hasTests) {
183
+ lines.push('- Run tests before committing: npm test');
184
+ lines.push('- Write tests for new features');
185
+ lines.push('- Test edge cases and error paths');
186
+ }
187
+ else {
188
+ lines.push('- Set up testing framework');
189
+ lines.push('- Write tests for all business logic');
190
+ }
191
+ lines.push('');
192
+ // Security rules
193
+ lines.push('# Security');
194
+ lines.push('- Never commit API keys or secrets');
195
+ lines.push('- Validate and sanitize all user input');
196
+ lines.push('- Use environment variables for configuration');
197
+ lines.push('');
198
+ // Midas integration
199
+ lines.push('# Midas Integration');
200
+ lines.push('- Call midas_analyze at session start');
201
+ lines.push('- Call midas_journal_save after significant changes');
202
+ lines.push('- Call midas_tornado when stuck on the same error');
203
+ return lines.join('\n');
204
+ }
205
+ /**
206
+ * Write .cursorrules to project
207
+ */
208
+ export function writeCursorRules(projectPath, projectName) {
209
+ const safePath = sanitizePath(projectPath);
210
+ const rules = generateCursorRules(safePath, projectName);
211
+ const rulesPath = join(safePath, '.cursorrules');
212
+ writeFileSync(rulesPath, rules);
213
+ return { success: true, path: rulesPath };
214
+ }
215
+ //# sourceMappingURL=techstack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"techstack.js","sourceRoot":"","sources":["../src/techstack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=context.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.test.d.ts","sourceRoot":"","sources":["../../src/tests/context.test.ts"],"names":[],"mappings":""}