midas-mcp 2.9.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/ai.d.ts +2 -0
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +28 -45
- package/dist/ai.js.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +37 -87
- package/dist/analyzer.js.map +1 -1
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +109 -15
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +8 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +76 -7
- package/dist/context.js.map +1 -1
- package/dist/providers.d.ts +46 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +287 -0
- package/dist/providers.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +9 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/config.d.ts +73 -0
- package/dist/tools/config.d.ts.map +1 -0
- package/dist/tools/config.js +94 -0
- package/dist/tools/config.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +293 -210
- package/dist/tui.js.map +1 -1
- package/package.json +17 -5
- package/dist/tests/analyze.test.d.ts +0 -2
- package/dist/tests/analyze.test.d.ts.map +0 -1
- package/dist/tests/analyze.test.js +0 -120
- package/dist/tests/analyze.test.js.map +0 -1
- package/dist/tests/context.test.d.ts +0 -2
- package/dist/tests/context.test.d.ts.map +0 -1
- package/dist/tests/context.test.js +0 -213
- package/dist/tests/context.test.js.map +0 -1
- package/dist/tests/edge-cases.test.d.ts +0 -2
- package/dist/tests/edge-cases.test.d.ts.map +0 -1
- package/dist/tests/edge-cases.test.js +0 -234
- package/dist/tests/edge-cases.test.js.map +0 -1
- package/dist/tests/journal.test.d.ts +0 -2
- package/dist/tests/journal.test.d.ts.map +0 -1
- package/dist/tests/journal.test.js +0 -184
- package/dist/tests/journal.test.js.map +0 -1
- package/dist/tests/metrics.test.d.ts +0 -2
- package/dist/tests/metrics.test.d.ts.map +0 -1
- package/dist/tests/metrics.test.js +0 -178
- package/dist/tests/metrics.test.js.map +0 -1
- package/dist/tests/phase.test.d.ts +0 -2
- package/dist/tests/phase.test.d.ts.map +0 -1
- package/dist/tests/phase.test.js +0 -110
- package/dist/tests/phase.test.js.map +0 -1
- package/dist/tests/prompts.test.d.ts +0 -2
- package/dist/tests/prompts.test.d.ts.map +0 -1
- package/dist/tests/prompts.test.js +0 -157
- package/dist/tests/prompts.test.js.map +0 -1
- package/dist/tests/search.test.d.ts +0 -2
- package/dist/tests/search.test.d.ts.map +0 -1
- package/dist/tests/search.test.js +0 -228
- package/dist/tests/search.test.js.map +0 -1
- package/dist/tests/security.test.d.ts +0 -2
- package/dist/tests/security.test.d.ts.map +0 -1
- package/dist/tests/security.test.js +0 -105
- package/dist/tests/security.test.js.map +0 -1
- package/dist/tests/server.test.d.ts +0 -2
- package/dist/tests/server.test.d.ts.map +0 -1
- package/dist/tests/server.test.js +0 -93
- package/dist/tests/server.test.js.map +0 -1
- package/dist/tests/techstack.test.d.ts +0 -2
- package/dist/tests/techstack.test.d.ts.map +0 -1
- package/dist/tests/techstack.test.js +0 -187
- package/dist/tests/techstack.test.js.map +0 -1
- package/dist/tests/tools.test.d.ts +0 -2
- package/dist/tests/tools.test.d.ts.map +0 -1
- package/dist/tests/tools.test.js +0 -137
- package/dist/tests/tools.test.js.map +0 -1
- package/dist/tests/tracker.test.d.ts +0 -2
- package/dist/tests/tracker.test.d.ts.map +0 -1
- package/dist/tests/tracker.test.js +0 -197
- package/dist/tests/tracker.test.js.map +0 -1
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { mkdirSync, rmSync, writeFileSync, existsSync } from 'fs';
|
|
4
|
-
import { join } from 'path';
|
|
5
|
-
import { tmpdir } from 'os';
|
|
6
|
-
import { loadState, saveState, setPhase, getDefaultState } from '../state/phase.js';
|
|
7
|
-
import { startProject, getPhase, setPhaseManually } from '../tools/phase.js';
|
|
8
|
-
import { audit } from '../tools/audit.js';
|
|
9
|
-
import { checkDocs } from '../tools/docs.js';
|
|
10
|
-
import { loadTracker } from '../tracker.js';
|
|
11
|
-
import { loadMetrics } from '../metrics.js';
|
|
12
|
-
import { saveToJournal, getJournalEntries } from '../tools/journal.js';
|
|
13
|
-
describe('Edge Cases and Error Handling', () => {
|
|
14
|
-
const testDir = join(tmpdir(), 'midas-edge-test-' + Date.now());
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
mkdirSync(testDir, { recursive: true });
|
|
17
|
-
});
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
rmSync(testDir, { recursive: true, force: true });
|
|
20
|
-
});
|
|
21
|
-
describe('Corrupted State Files', () => {
|
|
22
|
-
it('handles corrupted state.json gracefully', () => {
|
|
23
|
-
mkdirSync(join(testDir, '.midas'), { recursive: true });
|
|
24
|
-
writeFileSync(join(testDir, '.midas', 'state.json'), 'not valid json{{{');
|
|
25
|
-
// Should return default state instead of crashing
|
|
26
|
-
const state = loadState(testDir);
|
|
27
|
-
assert.deepStrictEqual(state.current, { phase: 'IDLE' });
|
|
28
|
-
});
|
|
29
|
-
it('handles corrupted tracker.json gracefully', () => {
|
|
30
|
-
mkdirSync(join(testDir, '.midas'), { recursive: true });
|
|
31
|
-
writeFileSync(join(testDir, '.midas', 'tracker.json'), '{ broken');
|
|
32
|
-
const tracker = loadTracker(testDir);
|
|
33
|
-
assert.deepStrictEqual(tracker.inferredPhase, { phase: 'IDLE' });
|
|
34
|
-
});
|
|
35
|
-
it('handles corrupted metrics.json gracefully', () => {
|
|
36
|
-
mkdirSync(join(testDir, '.midas'), { recursive: true });
|
|
37
|
-
writeFileSync(join(testDir, '.midas', 'metrics.json'), '[[invalid]]');
|
|
38
|
-
const metrics = loadMetrics(testDir);
|
|
39
|
-
assert.strictEqual(metrics.totalSessions, 0);
|
|
40
|
-
});
|
|
41
|
-
it('handles empty state file', () => {
|
|
42
|
-
mkdirSync(join(testDir, '.midas'), { recursive: true });
|
|
43
|
-
writeFileSync(join(testDir, '.midas', 'state.json'), '');
|
|
44
|
-
const state = loadState(testDir);
|
|
45
|
-
assert.deepStrictEqual(state.current, { phase: 'IDLE' });
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
describe('Missing Directories', () => {
|
|
49
|
-
it('creates .midas directory on save', () => {
|
|
50
|
-
const state = getDefaultState();
|
|
51
|
-
saveState(testDir, state);
|
|
52
|
-
assert.strictEqual(existsSync(join(testDir, '.midas')), true);
|
|
53
|
-
});
|
|
54
|
-
it('creates nested directory for journal', () => {
|
|
55
|
-
saveToJournal({
|
|
56
|
-
projectPath: testDir,
|
|
57
|
-
title: 'Test',
|
|
58
|
-
conversation: 'Content',
|
|
59
|
-
});
|
|
60
|
-
assert.strictEqual(existsSync(join(testDir, '.midas', 'journal')), true);
|
|
61
|
-
});
|
|
62
|
-
it('handles non-existent docs directory', () => {
|
|
63
|
-
const result = checkDocs({ projectPath: testDir });
|
|
64
|
-
assert.strictEqual(result.brainlift.exists, false);
|
|
65
|
-
assert.strictEqual(result.prd.exists, false);
|
|
66
|
-
assert.strictEqual(result.gameplan.exists, false);
|
|
67
|
-
assert.strictEqual(result.ready, false);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
describe('Empty and Minimal Content', () => {
|
|
71
|
-
it('handles project with no files', () => {
|
|
72
|
-
const result = audit({ projectPath: testDir });
|
|
73
|
-
assert.strictEqual(result.overall < 30, true);
|
|
74
|
-
});
|
|
75
|
-
it('handles empty package.json', () => {
|
|
76
|
-
writeFileSync(join(testDir, 'package.json'), '{}');
|
|
77
|
-
const result = audit({ projectPath: testDir });
|
|
78
|
-
// Should not crash
|
|
79
|
-
assert.strictEqual(typeof result.overall, 'number');
|
|
80
|
-
});
|
|
81
|
-
it('handles empty docs files', () => {
|
|
82
|
-
mkdirSync(join(testDir, 'docs'), { recursive: true });
|
|
83
|
-
writeFileSync(join(testDir, 'docs', 'brainlift.md'), '');
|
|
84
|
-
const result = checkDocs({ projectPath: testDir });
|
|
85
|
-
assert.strictEqual(result.brainlift.exists, true);
|
|
86
|
-
assert.strictEqual(result.brainlift.complete, false);
|
|
87
|
-
});
|
|
88
|
-
it('handles journal with no entries', () => {
|
|
89
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
90
|
-
assert.deepStrictEqual(entries, []);
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
describe('Invalid Input Handling', () => {
|
|
94
|
-
it('setPhaseManually handles invalid phase', () => {
|
|
95
|
-
const result = setPhaseManually({
|
|
96
|
-
projectPath: testDir,
|
|
97
|
-
phase: 'INVALID_PHASE' // Type cast to simulate bad input
|
|
98
|
-
});
|
|
99
|
-
// Should handle gracefully - will set to provided value
|
|
100
|
-
assert.strictEqual(result.success, true);
|
|
101
|
-
});
|
|
102
|
-
it('startProject with empty name still works', () => {
|
|
103
|
-
const result = startProject({
|
|
104
|
-
projectName: '',
|
|
105
|
-
projectPath: testDir
|
|
106
|
-
});
|
|
107
|
-
assert.strictEqual(result.success, true);
|
|
108
|
-
});
|
|
109
|
-
it('audit with malformed package.json dependencies', () => {
|
|
110
|
-
writeFileSync(join(testDir, 'package.json'), JSON.stringify({
|
|
111
|
-
dependencies: 'not an object',
|
|
112
|
-
}));
|
|
113
|
-
const result = audit({ projectPath: testDir });
|
|
114
|
-
// Should not crash
|
|
115
|
-
assert.strictEqual(typeof result.level, 'string');
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
describe('Concurrent Access Patterns', () => {
|
|
119
|
-
it('handles rapid consecutive saves', () => {
|
|
120
|
-
const state = getDefaultState();
|
|
121
|
-
// Rapid saves should not corrupt state
|
|
122
|
-
for (let i = 0; i < 10; i++) {
|
|
123
|
-
state.current = { phase: 'EAGLE_SIGHT', step: 'IDEA' };
|
|
124
|
-
saveState(testDir, state);
|
|
125
|
-
}
|
|
126
|
-
const loaded = loadState(testDir);
|
|
127
|
-
assert.strictEqual(loaded.current.phase, 'EAGLE_SIGHT');
|
|
128
|
-
});
|
|
129
|
-
it('handles rapid phase changes', () => {
|
|
130
|
-
setPhase(testDir, { phase: 'EAGLE_SIGHT', step: 'IDEA' });
|
|
131
|
-
setPhase(testDir, { phase: 'EAGLE_SIGHT', step: 'RESEARCH' });
|
|
132
|
-
setPhase(testDir, { phase: 'EAGLE_SIGHT', step: 'BRAINLIFT' });
|
|
133
|
-
const state = loadState(testDir);
|
|
134
|
-
assert.strictEqual(state.current.step, 'BRAINLIFT');
|
|
135
|
-
assert.strictEqual(state.history.length, 3);
|
|
136
|
-
});
|
|
137
|
-
it('handles multiple journal entries quickly', () => {
|
|
138
|
-
for (let i = 0; i < 5; i++) {
|
|
139
|
-
saveToJournal({
|
|
140
|
-
projectPath: testDir,
|
|
141
|
-
title: `Entry ${i}`,
|
|
142
|
-
conversation: `Content ${i}`,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
146
|
-
assert.strictEqual(entries.length, 5);
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
describe('Special Characters in Content', () => {
|
|
150
|
-
it('handles special characters in project name', () => {
|
|
151
|
-
const result = startProject({
|
|
152
|
-
projectName: 'my-project_v2.0 (beta)',
|
|
153
|
-
projectPath: testDir,
|
|
154
|
-
});
|
|
155
|
-
assert.strictEqual(result.success, true);
|
|
156
|
-
});
|
|
157
|
-
it('handles markdown in journal entries', () => {
|
|
158
|
-
const mdContent = '# Header\n```typescript\nconst x = 1;\n```\n- List item';
|
|
159
|
-
saveToJournal({
|
|
160
|
-
projectPath: testDir,
|
|
161
|
-
title: 'Markdown Test',
|
|
162
|
-
conversation: mdContent,
|
|
163
|
-
});
|
|
164
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
165
|
-
assert.strictEqual(entries[0].conversation.includes('```typescript'), true);
|
|
166
|
-
});
|
|
167
|
-
it('handles unicode in journal entries', () => {
|
|
168
|
-
saveToJournal({
|
|
169
|
-
projectPath: testDir,
|
|
170
|
-
title: 'Unicode Test',
|
|
171
|
-
conversation: 'Tested with emojis and symbols',
|
|
172
|
-
});
|
|
173
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
174
|
-
assert.strictEqual(entries.length, 1);
|
|
175
|
-
});
|
|
176
|
-
it('handles newlines in conversation content', () => {
|
|
177
|
-
const multiline = 'Line 1\nLine 2\n\nLine 4';
|
|
178
|
-
saveToJournal({
|
|
179
|
-
projectPath: testDir,
|
|
180
|
-
title: 'Multiline',
|
|
181
|
-
conversation: multiline,
|
|
182
|
-
});
|
|
183
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
184
|
-
assert.strictEqual(entries[0].conversation.includes('\n'), true);
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
describe('Path Edge Cases', () => {
|
|
188
|
-
it('handles path with spaces', () => {
|
|
189
|
-
const spacePath = join(testDir, 'path with spaces');
|
|
190
|
-
mkdirSync(spacePath, { recursive: true });
|
|
191
|
-
const state = getDefaultState();
|
|
192
|
-
saveState(spacePath, state);
|
|
193
|
-
const loaded = loadState(spacePath);
|
|
194
|
-
assert.deepStrictEqual(loaded.current, { phase: 'IDLE' });
|
|
195
|
-
});
|
|
196
|
-
it('uses cwd when projectPath not provided', () => {
|
|
197
|
-
const result = getPhase({});
|
|
198
|
-
// Should not crash - uses process.cwd()
|
|
199
|
-
assert.strictEqual(typeof result.current.phase, 'string');
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
describe('Boundary Conditions', () => {
|
|
203
|
-
it('handles very long journal entry', () => {
|
|
204
|
-
const longContent = 'A'.repeat(100000);
|
|
205
|
-
const result = saveToJournal({
|
|
206
|
-
projectPath: testDir,
|
|
207
|
-
title: 'Long Entry',
|
|
208
|
-
conversation: longContent,
|
|
209
|
-
});
|
|
210
|
-
assert.strictEqual(result.success, true);
|
|
211
|
-
});
|
|
212
|
-
it('handles many tags with security limit', () => {
|
|
213
|
-
// Security: Tags are limited to 20 max (LIMITS.MAX_TAGS)
|
|
214
|
-
const manyTags = Array.from({ length: 50 }, (_, i) => `tag${i}`);
|
|
215
|
-
const result = saveToJournal({
|
|
216
|
-
projectPath: testDir,
|
|
217
|
-
title: 'Many Tags',
|
|
218
|
-
conversation: 'Content',
|
|
219
|
-
tags: manyTags,
|
|
220
|
-
});
|
|
221
|
-
// Only first 20 tags should be stored (security limit)
|
|
222
|
-
assert.strictEqual(result.entry.tags?.length, 20);
|
|
223
|
-
});
|
|
224
|
-
it('handles deep history', () => {
|
|
225
|
-
// Create many phase transitions
|
|
226
|
-
for (let i = 0; i < 100; i++) {
|
|
227
|
-
setPhase(testDir, { phase: 'EAGLE_SIGHT', step: 'IDEA' });
|
|
228
|
-
}
|
|
229
|
-
const state = loadState(testDir);
|
|
230
|
-
assert.strictEqual(state.history.length, 100);
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
//# sourceMappingURL=edge-cases.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"edge-cases.test.js","sourceRoot":"","sources":["../../src/tests/edge-cases.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"journal.test.d.ts","sourceRoot":"","sources":["../../src/tests/journal.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { mkdirSync, rmSync, existsSync } from 'fs';
|
|
4
|
-
import { join } from 'path';
|
|
5
|
-
import { tmpdir } from 'os';
|
|
6
|
-
import { saveToJournal, getJournalEntries, searchJournal } from '../tools/journal.js';
|
|
7
|
-
describe('Journal Tools', () => {
|
|
8
|
-
const testDir = join(tmpdir(), 'midas-journal-test-' + Date.now());
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
mkdirSync(testDir, { recursive: true });
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
rmSync(testDir, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
describe('saveToJournal', () => {
|
|
16
|
-
it('creates journal directory if not exists', () => {
|
|
17
|
-
saveToJournal({
|
|
18
|
-
projectPath: testDir,
|
|
19
|
-
title: 'Test Entry',
|
|
20
|
-
conversation: 'User: Hello\nAI: Hi there!',
|
|
21
|
-
});
|
|
22
|
-
assert.strictEqual(existsSync(join(testDir, '.midas', 'journal')), true);
|
|
23
|
-
});
|
|
24
|
-
it('creates markdown file with correct structure', () => {
|
|
25
|
-
const result = saveToJournal({
|
|
26
|
-
projectPath: testDir,
|
|
27
|
-
title: 'Auth Implementation',
|
|
28
|
-
conversation: 'Implemented OAuth2 flow',
|
|
29
|
-
});
|
|
30
|
-
assert.strictEqual(result.success, true);
|
|
31
|
-
assert.strictEqual(result.path.endsWith('.md'), true);
|
|
32
|
-
assert.strictEqual(existsSync(result.path), true);
|
|
33
|
-
});
|
|
34
|
-
it('includes title in entry', () => {
|
|
35
|
-
const result = saveToJournal({
|
|
36
|
-
projectPath: testDir,
|
|
37
|
-
title: 'Database Migration',
|
|
38
|
-
conversation: 'Added user table',
|
|
39
|
-
});
|
|
40
|
-
assert.strictEqual(result.entry.title, 'Database Migration');
|
|
41
|
-
});
|
|
42
|
-
it('includes tags when provided', () => {
|
|
43
|
-
const result = saveToJournal({
|
|
44
|
-
projectPath: testDir,
|
|
45
|
-
title: 'Bug Fix',
|
|
46
|
-
conversation: 'Fixed null pointer',
|
|
47
|
-
tags: ['bugfix', 'auth'],
|
|
48
|
-
});
|
|
49
|
-
assert.deepStrictEqual(result.entry.tags, ['bugfix', 'auth']);
|
|
50
|
-
});
|
|
51
|
-
it('generates unique ID for each entry', () => {
|
|
52
|
-
const r1 = saveToJournal({
|
|
53
|
-
projectPath: testDir,
|
|
54
|
-
title: 'Entry 1',
|
|
55
|
-
conversation: 'Content 1',
|
|
56
|
-
});
|
|
57
|
-
const r2 = saveToJournal({
|
|
58
|
-
projectPath: testDir,
|
|
59
|
-
title: 'Entry 2',
|
|
60
|
-
conversation: 'Content 2',
|
|
61
|
-
});
|
|
62
|
-
assert.notStrictEqual(r1.entry.id, r2.entry.id);
|
|
63
|
-
});
|
|
64
|
-
it('stores full conversation content', () => {
|
|
65
|
-
const conversation = 'User: How do I implement auth?\nAI: Here is how...';
|
|
66
|
-
const result = saveToJournal({
|
|
67
|
-
projectPath: testDir,
|
|
68
|
-
title: 'Auth Discussion',
|
|
69
|
-
conversation,
|
|
70
|
-
});
|
|
71
|
-
assert.strictEqual(result.entry.conversation, conversation);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
describe('getJournalEntries', () => {
|
|
75
|
-
it('returns empty array for new project', () => {
|
|
76
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
77
|
-
assert.deepStrictEqual(entries, []);
|
|
78
|
-
});
|
|
79
|
-
it('returns saved entries', () => {
|
|
80
|
-
saveToJournal({
|
|
81
|
-
projectPath: testDir,
|
|
82
|
-
title: 'Entry 1',
|
|
83
|
-
conversation: 'Content 1',
|
|
84
|
-
});
|
|
85
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
86
|
-
assert.strictEqual(entries.length, 1);
|
|
87
|
-
assert.strictEqual(entries[0].title, 'Entry 1');
|
|
88
|
-
});
|
|
89
|
-
it('returns entries in reverse chronological order', async () => {
|
|
90
|
-
// Add small delays to ensure distinct timestamps
|
|
91
|
-
saveToJournal({ projectPath: testDir, title: 'First', conversation: 'A' });
|
|
92
|
-
await new Promise(r => setTimeout(r, 5));
|
|
93
|
-
saveToJournal({ projectPath: testDir, title: 'Second', conversation: 'B' });
|
|
94
|
-
await new Promise(r => setTimeout(r, 5));
|
|
95
|
-
saveToJournal({ projectPath: testDir, title: 'Third', conversation: 'C' });
|
|
96
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
97
|
-
// Most recent should be first
|
|
98
|
-
assert.strictEqual(entries[0].title, 'Third');
|
|
99
|
-
assert.strictEqual(entries[2].title, 'First');
|
|
100
|
-
});
|
|
101
|
-
it('respects limit parameter', () => {
|
|
102
|
-
for (let i = 0; i < 5; i++) {
|
|
103
|
-
saveToJournal({
|
|
104
|
-
projectPath: testDir,
|
|
105
|
-
title: `Entry ${i}`,
|
|
106
|
-
conversation: `Content ${i}`,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
const entries = getJournalEntries({ projectPath: testDir, limit: 2 });
|
|
110
|
-
assert.strictEqual(entries.length, 2);
|
|
111
|
-
});
|
|
112
|
-
it('parses tags from saved files', () => {
|
|
113
|
-
saveToJournal({
|
|
114
|
-
projectPath: testDir,
|
|
115
|
-
title: 'Tagged Entry',
|
|
116
|
-
conversation: 'Content',
|
|
117
|
-
tags: ['auth', 'frontend'],
|
|
118
|
-
});
|
|
119
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
120
|
-
assert.deepStrictEqual(entries[0].tags, ['auth', 'frontend']);
|
|
121
|
-
});
|
|
122
|
-
it('extracts conversation content correctly', () => {
|
|
123
|
-
const conversation = 'This is the full\nmultiline\nconversation';
|
|
124
|
-
saveToJournal({
|
|
125
|
-
projectPath: testDir,
|
|
126
|
-
title: 'Test',
|
|
127
|
-
conversation,
|
|
128
|
-
});
|
|
129
|
-
const entries = getJournalEntries({ projectPath: testDir });
|
|
130
|
-
assert.strictEqual(entries[0].conversation, conversation);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
describe('searchJournal', () => {
|
|
134
|
-
beforeEach(() => {
|
|
135
|
-
saveToJournal({
|
|
136
|
-
projectPath: testDir,
|
|
137
|
-
title: 'Authentication Flow',
|
|
138
|
-
conversation: 'Implemented OAuth2 with JWT tokens',
|
|
139
|
-
tags: ['auth', 'security'],
|
|
140
|
-
});
|
|
141
|
-
saveToJournal({
|
|
142
|
-
projectPath: testDir,
|
|
143
|
-
title: 'Database Schema',
|
|
144
|
-
conversation: 'Created user and session tables',
|
|
145
|
-
tags: ['database'],
|
|
146
|
-
});
|
|
147
|
-
saveToJournal({
|
|
148
|
-
projectPath: testDir,
|
|
149
|
-
title: 'API Endpoints',
|
|
150
|
-
conversation: 'REST API for user management',
|
|
151
|
-
tags: ['api', 'backend'],
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
it('searches by title', () => {
|
|
155
|
-
const results = searchJournal({ projectPath: testDir, query: 'Authentication' });
|
|
156
|
-
assert.strictEqual(results.length, 1);
|
|
157
|
-
assert.strictEqual(results[0].title, 'Authentication Flow');
|
|
158
|
-
});
|
|
159
|
-
it('searches by conversation content', () => {
|
|
160
|
-
const results = searchJournal({ projectPath: testDir, query: 'JWT' });
|
|
161
|
-
assert.strictEqual(results.length, 1);
|
|
162
|
-
assert.strictEqual(results[0].title, 'Authentication Flow');
|
|
163
|
-
});
|
|
164
|
-
it('searches by tags', () => {
|
|
165
|
-
const results = searchJournal({ projectPath: testDir, query: 'database' });
|
|
166
|
-
assert.strictEqual(results.length, 1);
|
|
167
|
-
assert.strictEqual(results[0].title, 'Database Schema');
|
|
168
|
-
});
|
|
169
|
-
it('is case insensitive', () => {
|
|
170
|
-
const results = searchJournal({ projectPath: testDir, query: 'oauth2' });
|
|
171
|
-
assert.strictEqual(results.length, 1);
|
|
172
|
-
});
|
|
173
|
-
it('returns multiple matches', () => {
|
|
174
|
-
const results = searchJournal({ projectPath: testDir, query: 'user' });
|
|
175
|
-
// Should match 'Database Schema' (user tables) and 'API Endpoints' (user management)
|
|
176
|
-
assert.strictEqual(results.length, 2);
|
|
177
|
-
});
|
|
178
|
-
it('returns empty array for no matches', () => {
|
|
179
|
-
const results = searchJournal({ projectPath: testDir, query: 'nonexistent' });
|
|
180
|
-
assert.deepStrictEqual(results, []);
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
//# sourceMappingURL=journal.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"journal.test.js","sourceRoot":"","sources":["../../src/tests/journal.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.test.d.ts","sourceRoot":"","sources":["../../src/tests/metrics.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { mkdirSync, rmSync, existsSync, writeFileSync as fsWriteFileSync } from 'fs';
|
|
4
|
-
import { join } from 'path';
|
|
5
|
-
import { tmpdir } from 'os';
|
|
6
|
-
import { loadMetrics, saveMetrics, startSession, endSession, recordToolCall, recordPromptCopied, recordPhaseChange, getMetricsSummary, } from '../metrics.js';
|
|
7
|
-
describe('Metrics Module', () => {
|
|
8
|
-
const testDir = join(tmpdir(), 'midas-metrics-test-' + Date.now());
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
mkdirSync(testDir, { recursive: true });
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
rmSync(testDir, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
describe('loadMetrics', () => {
|
|
16
|
-
it('returns default metrics for new project', () => {
|
|
17
|
-
const metrics = loadMetrics(testDir);
|
|
18
|
-
assert.strictEqual(metrics.totalSessions, 0);
|
|
19
|
-
assert.strictEqual(metrics.totalToolCalls, 0);
|
|
20
|
-
assert.strictEqual(metrics.sessions.length, 0);
|
|
21
|
-
assert.strictEqual(metrics.currentStreak, 0);
|
|
22
|
-
});
|
|
23
|
-
it('loads saved metrics', () => {
|
|
24
|
-
const saved = {
|
|
25
|
-
totalSessions: 5,
|
|
26
|
-
totalToolCalls: 42,
|
|
27
|
-
totalTornadoCycles: 3,
|
|
28
|
-
totalJournalsSaved: 2,
|
|
29
|
-
phaseHistory: [],
|
|
30
|
-
sessions: [],
|
|
31
|
-
averageSessionMinutes: 15,
|
|
32
|
-
currentStreak: 3,
|
|
33
|
-
lastSessionDate: '2026-01-12',
|
|
34
|
-
};
|
|
35
|
-
mkdirSync(join(testDir, '.midas'), { recursive: true });
|
|
36
|
-
fsWriteFileSync(join(testDir, '.midas', 'metrics.json'), JSON.stringify(saved));
|
|
37
|
-
const metrics = loadMetrics(testDir);
|
|
38
|
-
assert.strictEqual(metrics.totalSessions, 5);
|
|
39
|
-
assert.strictEqual(metrics.currentStreak, 3);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
describe('saveMetrics', () => {
|
|
43
|
-
it('creates .midas directory', () => {
|
|
44
|
-
saveMetrics(testDir, loadMetrics(testDir));
|
|
45
|
-
assert.strictEqual(existsSync(join(testDir, '.midas')), true);
|
|
46
|
-
});
|
|
47
|
-
it('persists metrics', () => {
|
|
48
|
-
const metrics = loadMetrics(testDir);
|
|
49
|
-
metrics.totalToolCalls = 10;
|
|
50
|
-
saveMetrics(testDir, metrics);
|
|
51
|
-
const loaded = loadMetrics(testDir);
|
|
52
|
-
assert.strictEqual(loaded.totalToolCalls, 10);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
describe('startSession', () => {
|
|
56
|
-
it('returns unique session ID', () => {
|
|
57
|
-
const id1 = startSession(testDir, { phase: 'IDLE' });
|
|
58
|
-
const id2 = startSession(testDir, { phase: 'IDLE' });
|
|
59
|
-
assert.notStrictEqual(id1, id2);
|
|
60
|
-
});
|
|
61
|
-
it('increments total sessions', () => {
|
|
62
|
-
startSession(testDir, { phase: 'IDLE' });
|
|
63
|
-
startSession(testDir, { phase: 'IDLE' });
|
|
64
|
-
const metrics = loadMetrics(testDir);
|
|
65
|
-
assert.strictEqual(metrics.totalSessions, 2);
|
|
66
|
-
});
|
|
67
|
-
it('records start phase', () => {
|
|
68
|
-
startSession(testDir, { phase: 'BUILD', step: 'IMPLEMENT' });
|
|
69
|
-
const metrics = loadMetrics(testDir);
|
|
70
|
-
assert.strictEqual(metrics.sessions[0].startPhase.phase, 'BUILD');
|
|
71
|
-
});
|
|
72
|
-
it('starts streak at 1 for first session', () => {
|
|
73
|
-
startSession(testDir, { phase: 'IDLE' });
|
|
74
|
-
const metrics = loadMetrics(testDir);
|
|
75
|
-
assert.strictEqual(metrics.currentStreak, 1);
|
|
76
|
-
});
|
|
77
|
-
it('updates last session date', () => {
|
|
78
|
-
startSession(testDir, { phase: 'IDLE' });
|
|
79
|
-
const metrics = loadMetrics(testDir);
|
|
80
|
-
const today = new Date().toISOString().slice(0, 10);
|
|
81
|
-
assert.strictEqual(metrics.lastSessionDate, today);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('endSession', () => {
|
|
85
|
-
it('records end time', () => {
|
|
86
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
87
|
-
endSession(testDir, sessionId, { phase: 'BUILD', step: 'IMPLEMENT' });
|
|
88
|
-
const metrics = loadMetrics(testDir);
|
|
89
|
-
assert.strictEqual(typeof metrics.sessions[0].endTime, 'string');
|
|
90
|
-
});
|
|
91
|
-
it('records end phase', () => {
|
|
92
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
93
|
-
endSession(testDir, sessionId, { phase: 'BUILD', step: 'TEST' });
|
|
94
|
-
const metrics = loadMetrics(testDir);
|
|
95
|
-
assert.strictEqual(metrics.sessions[0].endPhase?.phase, 'BUILD');
|
|
96
|
-
});
|
|
97
|
-
it('calculates average session time', () => {
|
|
98
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
99
|
-
// End immediately
|
|
100
|
-
endSession(testDir, sessionId, { phase: 'IDLE' });
|
|
101
|
-
const metrics = loadMetrics(testDir);
|
|
102
|
-
assert.strictEqual(typeof metrics.averageSessionMinutes, 'number');
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
describe('recordToolCall', () => {
|
|
106
|
-
it('increments session tool calls', () => {
|
|
107
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
108
|
-
recordToolCall(testDir, sessionId, 'midas_audit');
|
|
109
|
-
recordToolCall(testDir, sessionId, 'midas_check_docs');
|
|
110
|
-
const metrics = loadMetrics(testDir);
|
|
111
|
-
assert.strictEqual(metrics.sessions[0].toolCalls, 2);
|
|
112
|
-
});
|
|
113
|
-
it('increments total tool calls', () => {
|
|
114
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
115
|
-
recordToolCall(testDir, sessionId, 'midas_audit');
|
|
116
|
-
const metrics = loadMetrics(testDir);
|
|
117
|
-
assert.strictEqual(metrics.totalToolCalls, 1);
|
|
118
|
-
});
|
|
119
|
-
it('tracks tornado cycles specifically', () => {
|
|
120
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
121
|
-
recordToolCall(testDir, sessionId, 'midas_tornado');
|
|
122
|
-
recordToolCall(testDir, sessionId, 'midas_tornado');
|
|
123
|
-
const metrics = loadMetrics(testDir);
|
|
124
|
-
assert.strictEqual(metrics.sessions[0].tornadoCycles, 2);
|
|
125
|
-
assert.strictEqual(metrics.totalTornadoCycles, 2);
|
|
126
|
-
});
|
|
127
|
-
it('tracks journal saves specifically', () => {
|
|
128
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
129
|
-
recordToolCall(testDir, sessionId, 'midas_journal_save');
|
|
130
|
-
const metrics = loadMetrics(testDir);
|
|
131
|
-
assert.strictEqual(metrics.sessions[0].journalsSaved, 1);
|
|
132
|
-
assert.strictEqual(metrics.totalJournalsSaved, 1);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
describe('recordPromptCopied', () => {
|
|
136
|
-
it('increments prompt copy count', () => {
|
|
137
|
-
const sessionId = startSession(testDir, { phase: 'IDLE' });
|
|
138
|
-
recordPromptCopied(testDir, sessionId);
|
|
139
|
-
recordPromptCopied(testDir, sessionId);
|
|
140
|
-
const metrics = loadMetrics(testDir);
|
|
141
|
-
assert.strictEqual(metrics.sessions[0].promptsCopied, 2);
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
describe('recordPhaseChange', () => {
|
|
145
|
-
it('adds phase to history', () => {
|
|
146
|
-
recordPhaseChange(testDir, { phase: 'EAGLE_SIGHT', step: 'IDEA' });
|
|
147
|
-
const metrics = loadMetrics(testDir);
|
|
148
|
-
assert.strictEqual(metrics.phaseHistory.length, 1);
|
|
149
|
-
assert.strictEqual(metrics.phaseHistory[0].phase, 'EAGLE_SIGHT:IDEA');
|
|
150
|
-
});
|
|
151
|
-
it('records entry time', () => {
|
|
152
|
-
recordPhaseChange(testDir, { phase: 'BUILD', step: 'RULES' });
|
|
153
|
-
const metrics = loadMetrics(testDir);
|
|
154
|
-
assert.strictEqual(typeof metrics.phaseHistory[0].enteredAt, 'string');
|
|
155
|
-
});
|
|
156
|
-
it('calculates duration when changing phases', () => {
|
|
157
|
-
recordPhaseChange(testDir, { phase: 'BUILD', step: 'RULES' });
|
|
158
|
-
recordPhaseChange(testDir, { phase: 'BUILD', step: 'INDEX' });
|
|
159
|
-
const metrics = loadMetrics(testDir);
|
|
160
|
-
assert.strictEqual(typeof metrics.phaseHistory[0].duration, 'number');
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
describe('getMetricsSummary', () => {
|
|
164
|
-
it('returns message for no sessions', () => {
|
|
165
|
-
const summary = getMetricsSummary(testDir);
|
|
166
|
-
assert.strictEqual(summary, 'No sessions yet');
|
|
167
|
-
});
|
|
168
|
-
it('returns formatted summary', () => {
|
|
169
|
-
startSession(testDir, { phase: 'IDLE' });
|
|
170
|
-
const sessionId = startSession(testDir, { phase: 'BUILD', step: 'IMPLEMENT' });
|
|
171
|
-
recordToolCall(testDir, sessionId, 'midas_audit');
|
|
172
|
-
const summary = getMetricsSummary(testDir);
|
|
173
|
-
assert.strictEqual(summary.includes('Sessions:'), true);
|
|
174
|
-
assert.strictEqual(summary.includes('Tool calls:'), true);
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
//# sourceMappingURL=metrics.test.js.map
|