@massu/core 0.1.1 → 0.1.2
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 +2 -2
- package/dist/hooks/cost-tracker.js +23 -35
- package/dist/hooks/post-edit-context.js +2 -2
- package/dist/hooks/post-tool-use.js +43 -58
- package/dist/hooks/pre-compact.js +23 -38
- package/dist/hooks/pre-delete-check.js +18 -31
- package/dist/hooks/quality-event.js +23 -35
- package/dist/hooks/session-end.js +62 -78
- package/dist/hooks/session-start.js +33 -42
- package/dist/hooks/user-prompt.js +23 -38
- package/package.json +8 -14
- package/src/adr-generator.ts +9 -2
- package/src/analytics.ts +9 -3
- package/src/audit-trail.ts +10 -3
- package/src/cloud-sync.ts +14 -18
- package/src/commands/init.ts +1 -5
- package/src/cost-tracker.ts +11 -6
- package/src/dependency-scorer.ts +9 -2
- package/src/docs-tools.ts +13 -10
- package/src/hooks/post-edit-context.ts +3 -3
- package/src/hooks/session-end.ts +3 -3
- package/src/hooks/session-start.ts +2 -2
- package/src/memory-db.ts +1351 -23
- package/src/memory-tools.ts +14 -15
- package/src/observability-tools.ts +13 -2
- package/src/prompt-analyzer.ts +9 -2
- package/src/regression-detector.ts +9 -3
- package/src/security-scorer.ts +9 -2
- package/src/sentinel-db.ts +43 -88
- package/src/sentinel-tools.ts +8 -11
- package/src/server.ts +1 -2
- package/src/team-knowledge.ts +9 -2
- package/src/tools.ts +771 -35
- package/src/validate-features-runner.ts +0 -1
- package/src/validation-engine.ts +9 -2
- package/dist/cli.js +0 -7890
- package/dist/server.js +0 -7008
- package/src/__tests__/adr-generator.test.ts +0 -260
- package/src/__tests__/analytics.test.ts +0 -282
- package/src/__tests__/audit-trail.test.ts +0 -382
- package/src/__tests__/backfill-sessions.test.ts +0 -690
- package/src/__tests__/cli.test.ts +0 -290
- package/src/__tests__/cloud-sync.test.ts +0 -261
- package/src/__tests__/config-sections.test.ts +0 -359
- package/src/__tests__/config.test.ts +0 -732
- package/src/__tests__/cost-tracker.test.ts +0 -348
- package/src/__tests__/db.test.ts +0 -177
- package/src/__tests__/dependency-scorer.test.ts +0 -325
- package/src/__tests__/docs-integration.test.ts +0 -178
- package/src/__tests__/docs-tools.test.ts +0 -199
- package/src/__tests__/domains.test.ts +0 -236
- package/src/__tests__/hooks.test.ts +0 -221
- package/src/__tests__/import-resolver.test.ts +0 -95
- package/src/__tests__/integration/path-traversal.test.ts +0 -134
- package/src/__tests__/integration/pricing-consistency.test.ts +0 -88
- package/src/__tests__/integration/tool-registration.test.ts +0 -146
- package/src/__tests__/memory-db.test.ts +0 -404
- package/src/__tests__/memory-enhancements.test.ts +0 -316
- package/src/__tests__/memory-tools.test.ts +0 -199
- package/src/__tests__/middleware-tree.test.ts +0 -177
- package/src/__tests__/observability-tools.test.ts +0 -595
- package/src/__tests__/observability.test.ts +0 -437
- package/src/__tests__/observation-extractor.test.ts +0 -167
- package/src/__tests__/page-deps.test.ts +0 -60
- package/src/__tests__/prompt-analyzer.test.ts +0 -298
- package/src/__tests__/regression-detector.test.ts +0 -295
- package/src/__tests__/rules.test.ts +0 -87
- package/src/__tests__/schema-mapper.test.ts +0 -29
- package/src/__tests__/security-scorer.test.ts +0 -238
- package/src/__tests__/security-utils.test.ts +0 -175
- package/src/__tests__/sentinel-db.test.ts +0 -491
- package/src/__tests__/sentinel-scanner.test.ts +0 -750
- package/src/__tests__/sentinel-tools.test.ts +0 -324
- package/src/__tests__/sentinel-types.test.ts +0 -750
- package/src/__tests__/server.test.ts +0 -452
- package/src/__tests__/session-archiver.test.ts +0 -524
- package/src/__tests__/session-state-generator.test.ts +0 -900
- package/src/__tests__/team-knowledge.test.ts +0 -327
- package/src/__tests__/tools.test.ts +0 -340
- package/src/__tests__/transcript-parser.test.ts +0 -195
- package/src/__tests__/trpc-index.test.ts +0 -25
- package/src/__tests__/validate-features-runner.test.ts +0 -517
- package/src/__tests__/validation-engine.test.ts +0 -300
- package/src/core-tools.ts +0 -685
- package/src/memory-queries.ts +0 -804
- package/src/memory-schema.ts +0 -546
- package/src/tool-helpers.ts +0 -41
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2026 Massu. All rights reserved.
|
|
2
|
-
// Licensed under BSL 1.1 - see LICENSE file for details.
|
|
3
|
-
|
|
4
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
5
|
-
import Database from 'better-sqlite3';
|
|
6
|
-
import {
|
|
7
|
-
getAuditToolDefinitions,
|
|
8
|
-
isAuditTool,
|
|
9
|
-
logAuditEntry,
|
|
10
|
-
queryAuditLog,
|
|
11
|
-
getFileChain,
|
|
12
|
-
backfillAuditLog,
|
|
13
|
-
handleAuditToolCall,
|
|
14
|
-
type AuditEntry,
|
|
15
|
-
} from '../audit-trail.ts';
|
|
16
|
-
|
|
17
|
-
function createTestDb(): Database.Database {
|
|
18
|
-
const db = new Database(':memory:');
|
|
19
|
-
db.pragma('journal_mode = WAL');
|
|
20
|
-
|
|
21
|
-
db.exec(`
|
|
22
|
-
CREATE TABLE sessions (
|
|
23
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
24
|
-
session_id TEXT UNIQUE NOT NULL,
|
|
25
|
-
started_at TEXT NOT NULL,
|
|
26
|
-
started_at_epoch INTEGER NOT NULL
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
CREATE TABLE observations (
|
|
30
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
31
|
-
session_id TEXT NOT NULL,
|
|
32
|
-
type TEXT NOT NULL,
|
|
33
|
-
detail TEXT,
|
|
34
|
-
files_involved TEXT,
|
|
35
|
-
created_at TEXT NOT NULL
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
CREATE TABLE audit_log (
|
|
39
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
40
|
-
session_id TEXT NOT NULL,
|
|
41
|
-
timestamp TEXT DEFAULT (datetime('now')),
|
|
42
|
-
event_type TEXT NOT NULL CHECK(event_type IN ('code_change', 'rule_enforced', 'approval', 'review', 'commit', 'compaction')),
|
|
43
|
-
actor TEXT NOT NULL DEFAULT 'ai' CHECK(actor IN ('ai', 'human', 'hook', 'agent')),
|
|
44
|
-
model_id TEXT,
|
|
45
|
-
file_path TEXT,
|
|
46
|
-
change_type TEXT CHECK(change_type IN ('create', 'edit', 'delete')),
|
|
47
|
-
rules_in_effect TEXT,
|
|
48
|
-
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
49
|
-
evidence TEXT,
|
|
50
|
-
metadata TEXT
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
CREATE INDEX idx_al_file ON audit_log(file_path);
|
|
54
|
-
CREATE INDEX idx_al_timestamp ON audit_log(timestamp DESC);
|
|
55
|
-
`);
|
|
56
|
-
|
|
57
|
-
return db;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
describe('audit-trail', () => {
|
|
61
|
-
let db: Database.Database;
|
|
62
|
-
|
|
63
|
-
beforeEach(() => {
|
|
64
|
-
db = createTestDb();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
afterEach(() => {
|
|
68
|
-
db.close();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
describe('getAuditToolDefinitions', () => {
|
|
72
|
-
it('should return tool definitions for audit tools', () => {
|
|
73
|
-
const defs = getAuditToolDefinitions();
|
|
74
|
-
expect(defs.length).toBe(3);
|
|
75
|
-
|
|
76
|
-
const names = defs.map(d => d.name);
|
|
77
|
-
expect(names.some(n => n.includes('audit_log'))).toBe(true);
|
|
78
|
-
expect(names.some(n => n.includes('audit_report'))).toBe(true);
|
|
79
|
-
expect(names.some(n => n.includes('audit_chain'))).toBe(true);
|
|
80
|
-
|
|
81
|
-
for (const def of defs) {
|
|
82
|
-
expect(def.name).toBeTruthy();
|
|
83
|
-
expect(def.description).toBeTruthy();
|
|
84
|
-
expect(def.inputSchema).toBeTruthy();
|
|
85
|
-
expect(def.inputSchema.type).toBe('object');
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
describe('isAuditTool', () => {
|
|
91
|
-
it('should return true for audit tools', () => {
|
|
92
|
-
expect(isAuditTool('massu_audit_log')).toBe(true);
|
|
93
|
-
expect(isAuditTool('massu_audit_report')).toBe(true);
|
|
94
|
-
expect(isAuditTool('massu_audit_chain')).toBe(true);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should return false for non-audit tools', () => {
|
|
98
|
-
expect(isAuditTool('massu_cost_session')).toBe(false);
|
|
99
|
-
expect(isAuditTool('massu_quality_score')).toBe(false);
|
|
100
|
-
expect(isAuditTool('random_tool')).toBe(false);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should handle base names without prefix', () => {
|
|
104
|
-
expect(isAuditTool('audit_log')).toBe(true);
|
|
105
|
-
expect(isAuditTool('audit_report')).toBe(true);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
describe('logAuditEntry', () => {
|
|
110
|
-
it('should log an audit entry', () => {
|
|
111
|
-
const sessionId = 'test-session-1';
|
|
112
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
113
|
-
sessionId,
|
|
114
|
-
new Date().toISOString(),
|
|
115
|
-
Math.floor(Date.now() / 1000)
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
const entry: AuditEntry = {
|
|
119
|
-
eventType: 'code_change',
|
|
120
|
-
actor: 'ai',
|
|
121
|
-
filePath: 'src/auth.ts',
|
|
122
|
-
changeType: 'edit',
|
|
123
|
-
evidence: 'Fixed authentication bug',
|
|
124
|
-
sessionId,
|
|
125
|
-
modelId: 'claude-sonnet-4-5',
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
logAuditEntry(db, entry);
|
|
129
|
-
|
|
130
|
-
const logs = db.prepare('SELECT * FROM audit_log WHERE session_id = ?').all(sessionId) as Array<Record<string, unknown>>;
|
|
131
|
-
expect(logs.length).toBe(1);
|
|
132
|
-
expect(logs[0].event_type).toBe('code_change');
|
|
133
|
-
expect(logs[0].actor).toBe('ai');
|
|
134
|
-
expect(logs[0].file_path).toBe('src/auth.ts');
|
|
135
|
-
expect(logs[0].change_type).toBe('edit');
|
|
136
|
-
expect(logs[0].evidence).toBe('Fixed authentication bug');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should handle optional fields', () => {
|
|
140
|
-
const sessionId = 'test-session-2';
|
|
141
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
142
|
-
sessionId,
|
|
143
|
-
new Date().toISOString(),
|
|
144
|
-
Math.floor(Date.now() / 1000)
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
const entry: AuditEntry = {
|
|
148
|
-
eventType: 'review',
|
|
149
|
-
actor: 'human',
|
|
150
|
-
sessionId,
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
logAuditEntry(db, entry);
|
|
154
|
-
|
|
155
|
-
const logs = db.prepare('SELECT * FROM audit_log WHERE session_id = ?').all(sessionId) as Array<Record<string, unknown>>;
|
|
156
|
-
expect(logs.length).toBe(1);
|
|
157
|
-
expect(logs[0].event_type).toBe('review');
|
|
158
|
-
expect(logs[0].file_path).toBeNull();
|
|
159
|
-
expect(logs[0].change_type).toBeNull();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('should store metadata as JSON', () => {
|
|
163
|
-
const sessionId = 'test-session-3';
|
|
164
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
165
|
-
sessionId,
|
|
166
|
-
new Date().toISOString(),
|
|
167
|
-
Math.floor(Date.now() / 1000)
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
const entry: AuditEntry = {
|
|
171
|
-
eventType: 'commit',
|
|
172
|
-
actor: 'hook',
|
|
173
|
-
sessionId,
|
|
174
|
-
metadata: { commitHash: 'abc123', branch: 'main' },
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
logAuditEntry(db, entry);
|
|
178
|
-
|
|
179
|
-
const logs = db.prepare('SELECT * FROM audit_log WHERE session_id = ?').all(sessionId) as Array<Record<string, unknown>>;
|
|
180
|
-
expect(logs.length).toBe(1);
|
|
181
|
-
const metadata = JSON.parse(logs[0].metadata as string);
|
|
182
|
-
expect(metadata.commitHash).toBe('abc123');
|
|
183
|
-
expect(metadata.branch).toBe('main');
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
describe('queryAuditLog', () => {
|
|
188
|
-
beforeEach(() => {
|
|
189
|
-
const sessionId = 'query-test-session';
|
|
190
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
191
|
-
sessionId,
|
|
192
|
-
new Date().toISOString(),
|
|
193
|
-
Math.floor(Date.now() / 1000)
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
const entries: AuditEntry[] = [
|
|
197
|
-
{ eventType: 'code_change', actor: 'ai', filePath: 'src/auth.ts', changeType: 'edit', sessionId },
|
|
198
|
-
{ eventType: 'review', actor: 'human', filePath: 'src/auth.ts', sessionId },
|
|
199
|
-
{ eventType: 'code_change', actor: 'ai', filePath: 'src/user.ts', changeType: 'create', sessionId },
|
|
200
|
-
{ eventType: 'commit', actor: 'hook', sessionId },
|
|
201
|
-
];
|
|
202
|
-
|
|
203
|
-
for (const entry of entries) {
|
|
204
|
-
logAuditEntry(db, entry);
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
it('should query all audit logs', () => {
|
|
209
|
-
const logs = queryAuditLog(db, {});
|
|
210
|
-
expect(logs.length).toBe(4);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('should filter by event type', () => {
|
|
214
|
-
const logs = queryAuditLog(db, { eventType: 'code_change' });
|
|
215
|
-
expect(logs.length).toBe(2);
|
|
216
|
-
for (const log of logs) {
|
|
217
|
-
expect(log.event_type).toBe('code_change');
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('should filter by actor', () => {
|
|
222
|
-
const logs = queryAuditLog(db, { actor: 'ai' });
|
|
223
|
-
expect(logs.length).toBe(2);
|
|
224
|
-
for (const log of logs) {
|
|
225
|
-
expect(log.actor).toBe('ai');
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
it('should filter by file path', () => {
|
|
230
|
-
const logs = queryAuditLog(db, { filePath: 'src/auth.ts' });
|
|
231
|
-
expect(logs.length).toBe(2);
|
|
232
|
-
for (const log of logs) {
|
|
233
|
-
expect(log.file_path).toBe('src/auth.ts');
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it('should limit results', () => {
|
|
238
|
-
const logs = queryAuditLog(db, { limit: 2 });
|
|
239
|
-
expect(logs.length).toBe(2);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should filter by change type', () => {
|
|
243
|
-
const logs = queryAuditLog(db, { changeType: 'edit' });
|
|
244
|
-
expect(logs.length).toBe(1);
|
|
245
|
-
expect(logs[0].change_type).toBe('edit');
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
describe('getFileChain', () => {
|
|
250
|
-
it('should return audit chain for a file', () => {
|
|
251
|
-
const sessionId = 'chain-test-session';
|
|
252
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
253
|
-
sessionId,
|
|
254
|
-
new Date().toISOString(),
|
|
255
|
-
Math.floor(Date.now() / 1000)
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
const filePath = 'src/auth.ts';
|
|
259
|
-
const entries: AuditEntry[] = [
|
|
260
|
-
{ eventType: 'code_change', actor: 'ai', filePath, changeType: 'create', sessionId },
|
|
261
|
-
{ eventType: 'review', actor: 'human', filePath, sessionId },
|
|
262
|
-
{ eventType: 'code_change', actor: 'ai', filePath, changeType: 'edit', sessionId },
|
|
263
|
-
];
|
|
264
|
-
|
|
265
|
-
for (const entry of entries) {
|
|
266
|
-
logAuditEntry(db, entry);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const chain = getFileChain(db, filePath);
|
|
270
|
-
expect(chain.length).toBe(3);
|
|
271
|
-
expect(chain[0].change_type).toBe('create');
|
|
272
|
-
expect(chain[1].event_type).toBe('review');
|
|
273
|
-
expect(chain[2].change_type).toBe('edit');
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
it('should return empty array for file with no history', () => {
|
|
277
|
-
const chain = getFileChain(db, 'nonexistent.ts');
|
|
278
|
-
expect(chain.length).toBe(0);
|
|
279
|
-
});
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
describe('backfillAuditLog', () => {
|
|
283
|
-
it('should backfill audit log from observations', () => {
|
|
284
|
-
const sessionId = 'backfill-session';
|
|
285
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
286
|
-
sessionId,
|
|
287
|
-
new Date().toISOString(),
|
|
288
|
-
Math.floor(Date.now() / 1000)
|
|
289
|
-
);
|
|
290
|
-
|
|
291
|
-
db.prepare('INSERT INTO observations (session_id, type, detail, files_involved, created_at) VALUES (?, ?, ?, ?, ?)').run(
|
|
292
|
-
sessionId,
|
|
293
|
-
'bugfix',
|
|
294
|
-
'Fixed critical bug',
|
|
295
|
-
JSON.stringify(['src/auth.ts']),
|
|
296
|
-
new Date().toISOString()
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
db.prepare('INSERT INTO observations (session_id, type, detail, files_involved, created_at) VALUES (?, ?, ?, ?, ?)').run(
|
|
300
|
-
sessionId,
|
|
301
|
-
'cr_violation',
|
|
302
|
-
'Rule violation detected',
|
|
303
|
-
JSON.stringify(['src/user.ts']),
|
|
304
|
-
new Date().toISOString()
|
|
305
|
-
);
|
|
306
|
-
|
|
307
|
-
const backfilled = backfillAuditLog(db);
|
|
308
|
-
expect(backfilled).toBe(2);
|
|
309
|
-
|
|
310
|
-
const logs = queryAuditLog(db, { sessionId });
|
|
311
|
-
expect(logs.length).toBe(2);
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
it('should not duplicate existing audit entries', () => {
|
|
315
|
-
const sessionId = 'duplicate-test';
|
|
316
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
317
|
-
sessionId,
|
|
318
|
-
new Date().toISOString(),
|
|
319
|
-
Math.floor(Date.now() / 1000)
|
|
320
|
-
);
|
|
321
|
-
|
|
322
|
-
const description = 'Fixed bug in auth';
|
|
323
|
-
db.prepare('INSERT INTO observations (session_id, type, detail, files_involved, created_at) VALUES (?, ?, ?, ?, ?)').run(
|
|
324
|
-
sessionId,
|
|
325
|
-
'bugfix',
|
|
326
|
-
description,
|
|
327
|
-
JSON.stringify(['src/auth.ts']),
|
|
328
|
-
new Date().toISOString()
|
|
329
|
-
);
|
|
330
|
-
|
|
331
|
-
backfillAuditLog(db);
|
|
332
|
-
const firstCount = backfillAuditLog(db);
|
|
333
|
-
|
|
334
|
-
expect(firstCount).toBe(0); // No new entries on second backfill
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
describe('handleAuditToolCall', () => {
|
|
339
|
-
it('should handle audit_chain tool call', () => {
|
|
340
|
-
const sessionId = 'handler-session';
|
|
341
|
-
db.prepare('INSERT INTO sessions (session_id, started_at, started_at_epoch) VALUES (?, ?, ?)').run(
|
|
342
|
-
sessionId,
|
|
343
|
-
new Date().toISOString(),
|
|
344
|
-
Math.floor(Date.now() / 1000)
|
|
345
|
-
);
|
|
346
|
-
|
|
347
|
-
const filePath = 'src/test.ts';
|
|
348
|
-
logAuditEntry(db, {
|
|
349
|
-
eventType: 'code_change',
|
|
350
|
-
actor: 'ai',
|
|
351
|
-
filePath,
|
|
352
|
-
changeType: 'create',
|
|
353
|
-
sessionId,
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
const result = handleAuditToolCall('massu_audit_chain', { file: filePath }, db);
|
|
357
|
-
|
|
358
|
-
expect(result.content).toBeDefined();
|
|
359
|
-
expect(result.content.length).toBeGreaterThan(0);
|
|
360
|
-
expect(result.content[0].type).toBe('text');
|
|
361
|
-
const text = result.content[0].text;
|
|
362
|
-
expect(text).toContain('Audit Chain');
|
|
363
|
-
expect(text).toContain(filePath);
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
it('should return error for missing file parameter', () => {
|
|
367
|
-
const result = handleAuditToolCall('massu_audit_chain', {}, db);
|
|
368
|
-
|
|
369
|
-
expect(result.content).toBeDefined();
|
|
370
|
-
expect(result.content[0].type).toBe('text');
|
|
371
|
-
expect(result.content[0].text).toContain('Usage');
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
it('should handle unknown tool name', () => {
|
|
375
|
-
const result = handleAuditToolCall('massu_unknown_audit_tool', {}, db);
|
|
376
|
-
|
|
377
|
-
expect(result.content).toBeDefined();
|
|
378
|
-
expect(result.content[0].type).toBe('text');
|
|
379
|
-
expect(result.content[0].text).toContain('Unknown audit tool');
|
|
380
|
-
});
|
|
381
|
-
});
|
|
382
|
-
});
|