@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,195 +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, afterEach } from 'vitest';
|
|
5
|
-
import { writeFileSync, unlinkSync, existsSync } from 'fs';
|
|
6
|
-
import { resolve } from 'path';
|
|
7
|
-
import {
|
|
8
|
-
parseTranscript,
|
|
9
|
-
extractUserMessages,
|
|
10
|
-
extractAssistantMessages,
|
|
11
|
-
extractToolCalls,
|
|
12
|
-
extractFileOperations,
|
|
13
|
-
extractVerificationCommands,
|
|
14
|
-
extractDecisions,
|
|
15
|
-
extractFailedAttempts,
|
|
16
|
-
estimateTokens,
|
|
17
|
-
getLastAssistantMessage,
|
|
18
|
-
} from '../transcript-parser.ts';
|
|
19
|
-
|
|
20
|
-
// P7-002: Transcript Parser Tests
|
|
21
|
-
|
|
22
|
-
const TEST_JSONL = resolve(__dirname, '../test-transcript.jsonl');
|
|
23
|
-
|
|
24
|
-
function writeTestTranscript(entries: Record<string, unknown>[]): void {
|
|
25
|
-
const content = entries.map(e => JSON.stringify(e)).join('\n');
|
|
26
|
-
writeFileSync(TEST_JSONL, content, 'utf-8');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function cleanup(): void {
|
|
30
|
-
if (existsSync(TEST_JSONL)) unlinkSync(TEST_JSONL);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe('Transcript Parser', () => {
|
|
34
|
-
afterEach(cleanup);
|
|
35
|
-
|
|
36
|
-
describe('parseTranscript', () => {
|
|
37
|
-
it('parses JSONL entries', async () => {
|
|
38
|
-
writeTestTranscript([
|
|
39
|
-
{ type: 'user', sessionId: 'sess-1', message: { role: 'user', content: [{ type: 'text', text: 'Hello' }] } },
|
|
40
|
-
{ type: 'assistant', sessionId: 'sess-1', message: { role: 'assistant', content: [{ type: 'text', text: 'Hi there' }] } },
|
|
41
|
-
]);
|
|
42
|
-
|
|
43
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
44
|
-
expect(entries.length).toBe(2);
|
|
45
|
-
expect(entries[0].type).toBe('user');
|
|
46
|
-
expect(entries[1].type).toBe('assistant');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('handles malformed lines gracefully', async () => {
|
|
50
|
-
writeFileSync(TEST_JSONL, '{"type":"user","message":{"role":"user","content":[{"type":"text","text":"valid"}]}}\n{invalid json\n', 'utf-8');
|
|
51
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
52
|
-
expect(entries.length).toBe(1);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('handles file-history-snapshot entries', async () => {
|
|
56
|
-
writeTestTranscript([
|
|
57
|
-
{ type: 'file-history-snapshot', snapshot: {} },
|
|
58
|
-
{ type: 'user', message: { role: 'user', content: [{ type: 'text', text: 'Hello' }] } },
|
|
59
|
-
]);
|
|
60
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
61
|
-
expect(entries.length).toBe(2);
|
|
62
|
-
expect(entries[0].type).toBe('file-history-snapshot');
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
describe('extractUserMessages', () => {
|
|
67
|
-
it('extracts user messages, skipping meta', async () => {
|
|
68
|
-
writeTestTranscript([
|
|
69
|
-
{ type: 'user', isMeta: true, message: { role: 'user', content: [{ type: 'text', text: 'meta msg' }] } },
|
|
70
|
-
{ type: 'user', message: { role: 'user', content: [{ type: 'text', text: 'real message' }] } },
|
|
71
|
-
]);
|
|
72
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
73
|
-
const messages = extractUserMessages(entries);
|
|
74
|
-
expect(messages.length).toBe(1);
|
|
75
|
-
expect(messages[0].text).toBe('real message');
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
describe('extractToolCalls', () => {
|
|
80
|
-
it('extracts tool_use and tool_result', async () => {
|
|
81
|
-
writeTestTranscript([
|
|
82
|
-
{
|
|
83
|
-
type: 'assistant',
|
|
84
|
-
message: {
|
|
85
|
-
role: 'assistant',
|
|
86
|
-
content: [
|
|
87
|
-
{ type: 'tool_use', id: 'tool-1', name: 'Bash', input: { command: 'npm test' } },
|
|
88
|
-
],
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
type: 'user',
|
|
93
|
-
message: {
|
|
94
|
-
role: 'user',
|
|
95
|
-
content: [
|
|
96
|
-
{ type: 'tool_result', tool_use_id: 'tool-1', content: 'All tests passed', is_error: false },
|
|
97
|
-
],
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
]);
|
|
101
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
102
|
-
const toolCalls = extractToolCalls(entries);
|
|
103
|
-
expect(toolCalls.length).toBe(1);
|
|
104
|
-
expect(toolCalls[0].toolName).toBe('Bash');
|
|
105
|
-
expect(toolCalls[0].result).toBe('All tests passed');
|
|
106
|
-
expect(toolCalls[0].isError).toBe(false);
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
describe('extractFileOperations', () => {
|
|
111
|
-
it('extracts file operations from tool calls', () => {
|
|
112
|
-
const ops = extractFileOperations([
|
|
113
|
-
{ toolName: 'Read', toolUseId: '1', input: { file_path: '/path/file.ts' } },
|
|
114
|
-
{ toolName: 'Write', toolUseId: '2', input: { file_path: '/path/new.ts' } },
|
|
115
|
-
{ toolName: 'Edit', toolUseId: '3', input: { file_path: '/path/edit.ts' } },
|
|
116
|
-
{ toolName: 'Glob', toolUseId: '4', input: { pattern: '**/*.ts' } },
|
|
117
|
-
]);
|
|
118
|
-
expect(ops.length).toBe(4);
|
|
119
|
-
expect(ops[0].type).toBe('read');
|
|
120
|
-
expect(ops[1].type).toBe('write');
|
|
121
|
-
expect(ops[2].type).toBe('edit');
|
|
122
|
-
expect(ops[3].type).toBe('glob');
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
describe('extractVerificationCommands', () => {
|
|
127
|
-
it('detects verification commands', () => {
|
|
128
|
-
const verifications = extractVerificationCommands([
|
|
129
|
-
{ toolName: 'Bash', toolUseId: '1', input: { command: 'npm run build' }, result: 'Build succeeded' },
|
|
130
|
-
{ toolName: 'Bash', toolUseId: '2', input: { command: 'npm test' }, result: 'All passed', isError: false },
|
|
131
|
-
{ toolName: 'Bash', toolUseId: '3', input: { command: './scripts/pattern-scanner.sh' }, result: 'PASS' },
|
|
132
|
-
]);
|
|
133
|
-
expect(verifications.length).toBe(3);
|
|
134
|
-
expect(verifications[0].vrType).toBe('VR-BUILD');
|
|
135
|
-
expect(verifications[0].passed).toBe(true);
|
|
136
|
-
expect(verifications[1].vrType).toBe('VR-TEST');
|
|
137
|
-
expect(verifications[2].vrType).toBe('VR-PATTERN');
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe('extractDecisions', () => {
|
|
142
|
-
it('extracts decision-like text', async () => {
|
|
143
|
-
writeTestTranscript([
|
|
144
|
-
{
|
|
145
|
-
type: 'assistant',
|
|
146
|
-
message: {
|
|
147
|
-
role: 'assistant',
|
|
148
|
-
content: [{ type: 'text', text: 'I decided to use esbuild instead of tsc for better performance.' }],
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
]);
|
|
152
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
153
|
-
const decisions = extractDecisions(entries);
|
|
154
|
-
expect(decisions.length).toBeGreaterThan(0);
|
|
155
|
-
expect(decisions[0].text).toContain('decided');
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
describe('extractFailedAttempts', () => {
|
|
160
|
-
it('extracts failure-like text', async () => {
|
|
161
|
-
writeTestTranscript([
|
|
162
|
-
{
|
|
163
|
-
type: 'assistant',
|
|
164
|
-
message: {
|
|
165
|
-
role: 'assistant',
|
|
166
|
-
content: [{ type: 'text', text: 'The regex approach failed because it cannot handle nested braces properly.' }],
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
]);
|
|
170
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
171
|
-
const failures = extractFailedAttempts(entries);
|
|
172
|
-
expect(failures.length).toBeGreaterThan(0);
|
|
173
|
-
expect(failures[0].text).toContain('failed');
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
describe('estimateTokens', () => {
|
|
178
|
-
it('approximates tokens as chars/4', () => {
|
|
179
|
-
expect(estimateTokens('hello')).toBe(2); // 5/4 = 1.25 -> ceil = 2
|
|
180
|
-
expect(estimateTokens('a'.repeat(100))).toBe(25);
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
describe('getLastAssistantMessage', () => {
|
|
185
|
-
it('returns last assistant text', async () => {
|
|
186
|
-
writeTestTranscript([
|
|
187
|
-
{ type: 'assistant', message: { role: 'assistant', content: [{ type: 'text', text: 'First response' }] } },
|
|
188
|
-
{ type: 'assistant', message: { role: 'assistant', content: [{ type: 'text', text: 'Final response' }] } },
|
|
189
|
-
]);
|
|
190
|
-
const entries = await parseTranscript(TEST_JSONL);
|
|
191
|
-
const last = getLastAssistantMessage(entries);
|
|
192
|
-
expect(last).toBe('Final response');
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
});
|
|
@@ -1,25 +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 } from 'vitest';
|
|
5
|
-
import { extractProcedures } from '../trpc-index.ts';
|
|
6
|
-
|
|
7
|
-
describe('extractProcedures', () => {
|
|
8
|
-
// This test requires actual router files to exist.
|
|
9
|
-
// We test the function's behavior with a known router.
|
|
10
|
-
it('extracts procedures from the orders router if it exists', () => {
|
|
11
|
-
const procs = extractProcedures('src/server/api/routers/orders.ts');
|
|
12
|
-
// If the file exists, we should get some procedures
|
|
13
|
-
if (procs.length > 0) {
|
|
14
|
-
expect(procs[0]).toHaveProperty('name');
|
|
15
|
-
expect(procs[0]).toHaveProperty('type');
|
|
16
|
-
expect(procs[0]).toHaveProperty('isProtected');
|
|
17
|
-
expect(['query', 'mutation']).toContain(procs[0].type);
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('returns empty array for non-existent file', () => {
|
|
22
|
-
const procs = extractProcedures('src/server/api/routers/nonexistent-router-xyzzy.ts');
|
|
23
|
-
expect(procs).toEqual([]);
|
|
24
|
-
});
|
|
25
|
-
});
|