@tekdi/coding-analytics 1.0.2 → 1.0.3
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/analysis/analysis-prompt.d.ts +97 -0
- package/dist/analysis/analysis-prompt.d.ts.map +1 -0
- package/dist/analysis/analysis-prompt.js +312 -0
- package/dist/analysis/analysis-prompt.js.map +1 -0
- package/dist/analysis/feedback-aggregator.d.ts +15 -0
- package/dist/analysis/feedback-aggregator.d.ts.map +1 -0
- package/dist/analysis/feedback-aggregator.js +142 -0
- package/dist/analysis/feedback-aggregator.js.map +1 -0
- package/dist/analysis/llm-provider.d.ts +9 -0
- package/dist/analysis/llm-provider.d.ts.map +1 -0
- package/dist/analysis/llm-provider.js +23 -0
- package/dist/analysis/llm-provider.js.map +1 -0
- package/dist/analysis/providers/claude-provider.d.ts +11 -0
- package/dist/analysis/providers/claude-provider.d.ts.map +1 -0
- package/dist/analysis/providers/claude-provider.js +74 -0
- package/dist/analysis/providers/claude-provider.js.map +1 -0
- package/dist/analysis/providers/gemini-provider.d.ts +11 -0
- package/dist/analysis/providers/gemini-provider.d.ts.map +1 -0
- package/dist/analysis/providers/gemini-provider.js +58 -0
- package/dist/analysis/providers/gemini-provider.js.map +1 -0
- package/dist/analysis/providers/openai-provider.d.ts +11 -0
- package/dist/analysis/providers/openai-provider.d.ts.map +1 -0
- package/dist/analysis/providers/openai-provider.js +66 -0
- package/dist/analysis/providers/openai-provider.js.map +1 -0
- package/dist/analysis/providers/parse-helper.d.ts +7 -0
- package/dist/analysis/providers/parse-helper.d.ts.map +1 -0
- package/dist/analysis/providers/parse-helper.js +27 -0
- package/dist/analysis/providers/parse-helper.js.map +1 -0
- package/dist/analysis/session-analyzer.d.ts +8 -0
- package/dist/analysis/session-analyzer.d.ts.map +1 -0
- package/dist/analysis/session-analyzer.js +115 -0
- package/dist/analysis/session-analyzer.js.map +1 -0
- package/dist/analysis/session-builder.d.ts +19 -0
- package/dist/analysis/session-builder.d.ts.map +1 -0
- package/dist/analysis/session-builder.js +174 -0
- package/dist/analysis/session-builder.js.map +1 -0
- package/dist/analysis/types.d.ts +94 -0
- package/dist/analysis/types.d.ts.map +1 -0
- package/dist/analysis/types.js +3 -0
- package/dist/analysis/types.js.map +1 -0
- package/dist/artifact-extractor.d.ts +55 -0
- package/dist/artifact-extractor.d.ts.map +1 -0
- package/dist/artifact-extractor.js +146 -0
- package/dist/artifact-extractor.js.map +1 -0
- package/dist/claude-hooks-receiver.d.ts +9 -0
- package/dist/claude-hooks-receiver.d.ts.map +1 -1
- package/dist/claude-hooks-receiver.js +174 -2
- package/dist/claude-hooks-receiver.js.map +1 -1
- package/dist/cli.js +242 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -0
- package/dist/config.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +16 -8
- package/dist/logger.js.map +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-provider.js","sourceRoot":"","sources":["../../analysis/llm-provider.ts"],"names":[],"mappings":";;AASA,8CAmBC;AAnBD,SAAgB,iBAAiB,CAAC,MAAc,EAAE,KAAK,GAAG,KAAK;IAC7D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;IAErC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;YAClE,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;YAClE,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAC;YAClE,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;QACD;YACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,yCAAyC,CAAC,CAAC;IACtG,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LLMProvider } from '../llm-provider';
|
|
2
|
+
import { SessionContext, SessionFeedback } from '../types';
|
|
3
|
+
import { Config } from '../../config';
|
|
4
|
+
export declare class ClaudeProvider implements LLMProvider {
|
|
5
|
+
readonly name = "claude";
|
|
6
|
+
debug: boolean;
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config: Config, debug?: boolean);
|
|
9
|
+
analyzeSession(session: SessionContext): Promise<SessionFeedback>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=claude-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-provider.d.ts","sourceRoot":"","sources":["../../../analysis/providers/claude-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,IAAI,YAAY;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ;IAKnC,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CAmExE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClaudeProvider = void 0;
|
|
4
|
+
const analysis_prompt_1 = require("../analysis-prompt");
|
|
5
|
+
class ClaudeProvider {
|
|
6
|
+
constructor(config, debug = false) {
|
|
7
|
+
this.name = 'claude';
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.debug = debug;
|
|
10
|
+
}
|
|
11
|
+
async analyzeSession(session) {
|
|
12
|
+
let Anthropic;
|
|
13
|
+
try {
|
|
14
|
+
Anthropic = require('@anthropic-ai/sdk');
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
throw new Error('Claude provider requires @anthropic-ai/sdk. Run: npm install @anthropic-ai/sdk');
|
|
18
|
+
}
|
|
19
|
+
const client = new Anthropic.default({ apiKey: this.config.analysis.apiKey });
|
|
20
|
+
const userMessage = (0, analysis_prompt_1.buildUserMessage)(session);
|
|
21
|
+
if (this.debug) {
|
|
22
|
+
console.error('\n── DEBUG: REQUEST ──────────────────────────────────────');
|
|
23
|
+
console.error(`Model: ${this.config.analysis.model || 'claude-sonnet-4-6'}`);
|
|
24
|
+
console.error(`Max tokens: ${this.config.analysis.maxOutputTokens}`);
|
|
25
|
+
console.error(`System prompt length: ${analysis_prompt_1.SYSTEM_PROMPT.length} chars`);
|
|
26
|
+
console.error(`User message length: ${userMessage.length} chars`);
|
|
27
|
+
console.error('\n── DEBUG: USER MESSAGE ─────────────────────────────────');
|
|
28
|
+
console.error(userMessage);
|
|
29
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
30
|
+
}
|
|
31
|
+
const response = await client.messages.create({
|
|
32
|
+
model: this.config.analysis.model || 'claude-sonnet-4-6',
|
|
33
|
+
max_tokens: this.config.analysis.maxOutputTokens,
|
|
34
|
+
system: analysis_prompt_1.SYSTEM_PROMPT,
|
|
35
|
+
messages: [{ role: 'user', content: userMessage }],
|
|
36
|
+
tools: [
|
|
37
|
+
{
|
|
38
|
+
name: 'session_feedback',
|
|
39
|
+
description: 'Return structured feedback for the session',
|
|
40
|
+
input_schema: analysis_prompt_1.FEEDBACK_SCHEMA,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
tool_choice: { type: 'tool', name: 'session_feedback' },
|
|
44
|
+
});
|
|
45
|
+
if (this.debug) {
|
|
46
|
+
console.error('\n── DEBUG: RESPONSE ─────────────────────────────────────');
|
|
47
|
+
console.error(`Stop reason: ${response.stop_reason}`);
|
|
48
|
+
console.error(`Input tokens: ${response.usage?.input_tokens}`);
|
|
49
|
+
console.error(`Output tokens: ${response.usage?.output_tokens}`);
|
|
50
|
+
console.error(`Content blocks: ${response.content.map((b) => b.type).join(', ')}`);
|
|
51
|
+
const toolUseBlock = response.content.find((b) => b.type === 'tool_use');
|
|
52
|
+
if (toolUseBlock) {
|
|
53
|
+
console.error('\n── DEBUG: RAW TOOL INPUT ───────────────────────────────');
|
|
54
|
+
console.error(JSON.stringify(toolUseBlock.input, null, 2));
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const textBlock = response.content.find((b) => b.type === 'text');
|
|
58
|
+
if (textBlock) {
|
|
59
|
+
console.error('\n── DEBUG: RAW TEXT RESPONSE (no tool_use block) ────────');
|
|
60
|
+
console.error(textBlock.text);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
64
|
+
}
|
|
65
|
+
const toolUse = response.content.find((b) => b.type === 'tool_use');
|
|
66
|
+
if (!toolUse) {
|
|
67
|
+
throw new Error(`Claude did not return a tool_use block (stop_reason: ${response.stop_reason}). ` +
|
|
68
|
+
`Run with --debug to see the full response.`);
|
|
69
|
+
}
|
|
70
|
+
return toolUse.input;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.ClaudeProvider = ClaudeProvider;
|
|
74
|
+
//# sourceMappingURL=claude-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-provider.js","sourceRoot":"","sources":["../../../analysis/providers/claude-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LLMProvider } from '../llm-provider';
|
|
2
|
+
import { SessionContext, SessionFeedback } from '../types';
|
|
3
|
+
import { Config } from '../../config';
|
|
4
|
+
export declare class GeminiProvider implements LLMProvider {
|
|
5
|
+
readonly name = "gemini";
|
|
6
|
+
debug: boolean;
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config: Config, debug?: boolean);
|
|
9
|
+
analyzeSession(session: SessionContext): Promise<SessionFeedback>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=gemini-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-provider.d.ts","sourceRoot":"","sources":["../../../analysis/providers/gemini-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAItC,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,IAAI,YAAY;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ;IAKnC,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CAoDxE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GeminiProvider = void 0;
|
|
4
|
+
const analysis_prompt_1 = require("../analysis-prompt");
|
|
5
|
+
const parse_helper_1 = require("./parse-helper");
|
|
6
|
+
class GeminiProvider {
|
|
7
|
+
constructor(config, debug = false) {
|
|
8
|
+
this.name = 'gemini';
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.debug = debug;
|
|
11
|
+
}
|
|
12
|
+
async analyzeSession(session) {
|
|
13
|
+
let GoogleGenerativeAI;
|
|
14
|
+
try {
|
|
15
|
+
({ GoogleGenerativeAI } = require('@google/generative-ai'));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
throw new Error('Gemini provider requires @google/generative-ai. Run: npm install @google/generative-ai');
|
|
19
|
+
}
|
|
20
|
+
const genAI = new GoogleGenerativeAI(this.config.analysis.apiKey);
|
|
21
|
+
const model = genAI.getGenerativeModel({
|
|
22
|
+
model: this.config.analysis.model || 'gemini-1.5-pro',
|
|
23
|
+
systemInstruction: analysis_prompt_1.SYSTEM_PROMPT,
|
|
24
|
+
generationConfig: {
|
|
25
|
+
responseMimeType: 'application/json',
|
|
26
|
+
maxOutputTokens: this.config.analysis.maxOutputTokens,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
const userMessage = (0, analysis_prompt_1.buildUserMessage)(session);
|
|
30
|
+
if (this.debug) {
|
|
31
|
+
console.error('\n── DEBUG: REQUEST ──────────────────────────────────────');
|
|
32
|
+
console.error(`Model: ${this.config.analysis.model || 'gemini-1.5-pro'}`);
|
|
33
|
+
console.error(`Max tokens: ${this.config.analysis.maxOutputTokens}`);
|
|
34
|
+
console.error(`System prompt length: ${analysis_prompt_1.SYSTEM_PROMPT.length} chars`);
|
|
35
|
+
console.error(`User message length: ${userMessage.length} chars`);
|
|
36
|
+
console.error('\n── DEBUG: USER MESSAGE ─────────────────────────────────');
|
|
37
|
+
console.error(userMessage);
|
|
38
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
39
|
+
}
|
|
40
|
+
const result = await model.generateContent(userMessage);
|
|
41
|
+
const text = result.response.text();
|
|
42
|
+
if (this.debug) {
|
|
43
|
+
console.error('\n── DEBUG: RESPONSE ─────────────────────────────────────');
|
|
44
|
+
console.error(`Finish reason: ${result.response.candidates?.[0]?.finishReason}`);
|
|
45
|
+
console.error(`Token count: ${result.response.usageMetadata?.candidatesTokenCount}`);
|
|
46
|
+
console.error('\n── DEBUG: RAW CONTENT ──────────────────────────────────');
|
|
47
|
+
console.error(text || '(empty — model returned nothing)');
|
|
48
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
49
|
+
}
|
|
50
|
+
if (!text) {
|
|
51
|
+
throw new Error(`Gemini returned empty response (finish reason: ${result.response.candidates?.[0]?.finishReason}). ` +
|
|
52
|
+
`Run with --debug to investigate.`);
|
|
53
|
+
}
|
|
54
|
+
return (0, parse_helper_1.parseOrThrow)(text, 'Gemini', this.config.analysis.maxOutputTokens);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.GeminiProvider = GeminiProvider;
|
|
58
|
+
//# sourceMappingURL=gemini-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-provider.js","sourceRoot":"","sources":["../../../analysis/providers/gemini-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LLMProvider } from '../llm-provider';
|
|
2
|
+
import { SessionContext, SessionFeedback } from '../types';
|
|
3
|
+
import { Config } from '../../config';
|
|
4
|
+
export declare class OpenAIProvider implements LLMProvider {
|
|
5
|
+
readonly name = "openai";
|
|
6
|
+
debug: boolean;
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config: Config, debug?: boolean);
|
|
9
|
+
analyzeSession(session: SessionContext): Promise<SessionFeedback>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=openai-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../../analysis/providers/openai-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,IAAI,YAAY;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,KAAK,UAAQ;IAKnC,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CA2DxE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenAIProvider = void 0;
|
|
4
|
+
const analysis_prompt_1 = require("../analysis-prompt");
|
|
5
|
+
const parse_helper_1 = require("./parse-helper");
|
|
6
|
+
class OpenAIProvider {
|
|
7
|
+
constructor(config, debug = false) {
|
|
8
|
+
this.name = 'openai';
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.debug = debug;
|
|
11
|
+
}
|
|
12
|
+
async analyzeSession(session) {
|
|
13
|
+
let OpenAI;
|
|
14
|
+
try {
|
|
15
|
+
OpenAI = require('openai');
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
throw new Error('OpenAI provider requires openai. Run: npm install openai');
|
|
19
|
+
}
|
|
20
|
+
const client = new OpenAI.default({ apiKey: this.config.analysis.apiKey });
|
|
21
|
+
const userMessage = (0, analysis_prompt_1.buildUserMessage)(session);
|
|
22
|
+
if (this.debug) {
|
|
23
|
+
console.error('\n── DEBUG: REQUEST ──────────────────────────────────────');
|
|
24
|
+
console.error(`Model: ${this.config.analysis.model || 'gpt-4o'}`);
|
|
25
|
+
console.error(`Max tokens: ${this.config.analysis.maxOutputTokens}`);
|
|
26
|
+
console.error(`System prompt length: ${analysis_prompt_1.SYSTEM_PROMPT.length} chars`);
|
|
27
|
+
console.error(`User message length: ${userMessage.length} chars`);
|
|
28
|
+
console.error('\n── DEBUG: USER MESSAGE ─────────────────────────────────');
|
|
29
|
+
console.error(userMessage);
|
|
30
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
31
|
+
}
|
|
32
|
+
const response = await client.chat.completions.create({
|
|
33
|
+
model: this.config.analysis.model || 'gpt-4o',
|
|
34
|
+
max_tokens: this.config.analysis.maxOutputTokens,
|
|
35
|
+
messages: [
|
|
36
|
+
{ role: 'system', content: analysis_prompt_1.SYSTEM_PROMPT },
|
|
37
|
+
{ role: 'user', content: userMessage },
|
|
38
|
+
],
|
|
39
|
+
response_format: {
|
|
40
|
+
type: 'json_schema',
|
|
41
|
+
json_schema: {
|
|
42
|
+
name: 'session_feedback',
|
|
43
|
+
strict: true,
|
|
44
|
+
schema: analysis_prompt_1.FEEDBACK_SCHEMA,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
if (this.debug) {
|
|
49
|
+
console.error('\n── DEBUG: RESPONSE ─────────────────────────────────────');
|
|
50
|
+
console.error(`Finish reason: ${response.choices[0]?.finish_reason}`);
|
|
51
|
+
console.error(`Prompt tokens: ${response.usage?.prompt_tokens}`);
|
|
52
|
+
console.error(`Output tokens: ${response.usage?.completion_tokens}`);
|
|
53
|
+
console.error('\n── DEBUG: RAW CONTENT ──────────────────────────────────');
|
|
54
|
+
console.error(response.choices[0]?.message?.content);
|
|
55
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
56
|
+
}
|
|
57
|
+
const content = response.choices[0]?.message?.content;
|
|
58
|
+
if (!content) {
|
|
59
|
+
throw new Error(`OpenAI returned empty response (finish_reason: ${response.choices[0]?.finish_reason}). ` +
|
|
60
|
+
`Run with --debug to see the full response.`);
|
|
61
|
+
}
|
|
62
|
+
return (0, parse_helper_1.parseOrThrow)(content, 'OpenAI', this.config.analysis.maxOutputTokens);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.OpenAIProvider = OpenAIProvider;
|
|
66
|
+
//# sourceMappingURL=openai-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.js","sourceRoot":"","sources":["../../../analysis/providers/openai-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse JSON from an LLM response, giving a clear error when the response is truncated.
|
|
3
|
+
* "Unterminated string" / "Unexpected end of JSON" errors mean the model hit its output
|
|
4
|
+
* token limit mid-response — the remedy is to raise maxOutputTokens.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseOrThrow(text: string, provider: string, maxOutputTokens: number): any;
|
|
7
|
+
//# sourceMappingURL=parse-helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-helper.d.ts","sourceRoot":"","sources":["../../../analysis/providers/parse-helper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,GAAG,CAqBzF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseOrThrow = parseOrThrow;
|
|
4
|
+
/**
|
|
5
|
+
* Parse JSON from an LLM response, giving a clear error when the response is truncated.
|
|
6
|
+
* "Unterminated string" / "Unexpected end of JSON" errors mean the model hit its output
|
|
7
|
+
* token limit mid-response — the remedy is to raise maxOutputTokens.
|
|
8
|
+
*/
|
|
9
|
+
function parseOrThrow(text, provider, maxOutputTokens) {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(text);
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
const truncated = err.message?.includes('Unterminated') ||
|
|
15
|
+
err.message?.includes('Unexpected end') ||
|
|
16
|
+
err.message?.includes('Unexpected token');
|
|
17
|
+
if (truncated) {
|
|
18
|
+
throw new Error(`${provider} response was truncated before the JSON could be completed.\n` +
|
|
19
|
+
` Response length: ${text.length} chars\n` +
|
|
20
|
+
` Current maxOutputTokens: ${maxOutputTokens}\n` +
|
|
21
|
+
` Fix: coding-analytics analyze configure --max-output-tokens ${Math.round(maxOutputTokens * 1.5)}\n` +
|
|
22
|
+
` Run with --debug to see the full raw response.`);
|
|
23
|
+
}
|
|
24
|
+
throw new Error(`${provider} returned invalid JSON: ${err.message}\nRun with --debug to see the raw response.`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=parse-helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-helper.js","sourceRoot":"","sources":["../../../analysis/providers/parse-helper.ts"],"names":[],"mappings":";;AAKA,oCAqBC;AA1BD;;;;GAIG;AACH,SAAgB,YAAY,CAAC,IAAY,EAAE,QAAgB,EAAE,eAAuB;IAClF,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,SAAS,GACb,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC;YACrC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,gBAAgB,CAAC;YACvC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QAE5C,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,GAAG,QAAQ,+DAA+D;gBAC1E,sBAAsB,IAAI,CAAC,MAAM,UAAU;gBAC3C,8BAA8B,eAAe,IAAI;gBACjD,iEAAiE,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,IAAI;gBACtG,kDAAkD,CACnD,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,2BAA2B,GAAG,CAAC,OAAO,6CAA6C,CAAC,CAAC;IAClH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SessionContext, SessionFeedback } from './types';
|
|
2
|
+
import { LLMProvider } from './llm-provider';
|
|
3
|
+
export declare class SessionAnalyzer {
|
|
4
|
+
private provider;
|
|
5
|
+
constructor(provider: LLMProvider);
|
|
6
|
+
analyze(session: SessionContext): Promise<SessionFeedback>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=session-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-analyzer.d.ts","sourceRoot":"","sources":["../../analysis/session-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAc;gBAElB,QAAQ,EAAE,WAAW;IAI3B,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CAwCjE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionAnalyzer = void 0;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
class SessionAnalyzer {
|
|
6
|
+
constructor(provider) {
|
|
7
|
+
this.provider = provider;
|
|
8
|
+
}
|
|
9
|
+
async analyze(session) {
|
|
10
|
+
logger_1.logger.debug('Analyzing session', {
|
|
11
|
+
sessionId: session.sessionId,
|
|
12
|
+
provider: this.provider.name,
|
|
13
|
+
turns: session.turns.length,
|
|
14
|
+
});
|
|
15
|
+
if (session.stats.totalPrompts === 0) {
|
|
16
|
+
throw new Error(`Session ${session.sessionId} has no prompts — nothing to analyze`);
|
|
17
|
+
}
|
|
18
|
+
const raw = await this.provider.analyzeSession(session);
|
|
19
|
+
if (this.provider.debug) {
|
|
20
|
+
console.error('\n── DEBUG: RAW KEYS BEFORE NORMALIZATION ────────────────');
|
|
21
|
+
console.error('Top-level keys:', Object.keys(raw ?? {}));
|
|
22
|
+
console.error('context_setup :', typeof raw?.context_setup, '→', JSON.stringify(raw?.context_setup)?.slice(0, 120));
|
|
23
|
+
console.error('patterns_to_improve:', Array.isArray(raw?.patterns_to_improve)
|
|
24
|
+
? `array[${raw.patterns_to_improve.length}]`
|
|
25
|
+
: typeof raw?.patterns_to_improve, '→', JSON.stringify(raw?.patterns_to_improve)?.slice(0, 120));
|
|
26
|
+
console.error('scores :', typeof raw?.scores, '→ keys:', Object.keys(raw?.scores ?? {}));
|
|
27
|
+
console.error('quick_win :', typeof raw?.quick_win, '→', JSON.stringify(raw?.quick_win)?.slice(0, 120));
|
|
28
|
+
console.error('overview :', typeof raw?.overview, '→', JSON.stringify(raw?.overview)?.slice(0, 120));
|
|
29
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
30
|
+
}
|
|
31
|
+
const feedback = normalize(raw, this.provider.debug);
|
|
32
|
+
if (this.provider.debug) {
|
|
33
|
+
console.error('\n── DEBUG: AFTER NORMALIZATION ──────────────────────────');
|
|
34
|
+
console.error('overview :', feedback.overview?.slice(0, 100) || '(empty)');
|
|
35
|
+
console.error('context_setup :', feedback.context_setup?.slice(0, 100) || '(empty)');
|
|
36
|
+
console.error('patterns_count :', feedback.patterns_to_improve.length);
|
|
37
|
+
console.error('scores.prompt_clarity:', feedback.scores.prompt_clarity);
|
|
38
|
+
console.error('quick_win.action:', feedback.quick_win.action?.slice(0, 100) || '(empty)');
|
|
39
|
+
console.error('────────────────────────────────────────────────────────\n');
|
|
40
|
+
}
|
|
41
|
+
return feedback;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.SessionAnalyzer = SessionAnalyzer;
|
|
45
|
+
/**
|
|
46
|
+
* Coerce whatever the LLM returned into the expected SessionFeedback shape.
|
|
47
|
+
* LLMs occasionally use alternate field names, return the old schema shape,
|
|
48
|
+
* or omit fields when token budget runs short.
|
|
49
|
+
*/
|
|
50
|
+
function normalize(raw, debug = false) {
|
|
51
|
+
// Resolve alternate top-level key names before delegating to field normalizers
|
|
52
|
+
const contextSetup = raw.context_setup ?? raw.contextSetup ?? raw.setup ?? raw.configuration;
|
|
53
|
+
const patterns = raw.patterns_to_improve ?? raw.patterns ?? raw.improvements ?? raw.issues;
|
|
54
|
+
const scores = raw.scores ?? raw.score ?? raw.dimensions;
|
|
55
|
+
const quickWin = raw.quick_win ?? raw.quickWin ?? raw.win ?? raw.recommendation ?? raw.next_step;
|
|
56
|
+
const overview = raw.overview ?? raw.summary ?? raw.description ?? raw.session_overview;
|
|
57
|
+
return {
|
|
58
|
+
overview: typeof overview === 'string' ? overview : '',
|
|
59
|
+
context_setup: normalizeContextSetup(contextSetup),
|
|
60
|
+
patterns_to_improve: normalizePatterns(patterns),
|
|
61
|
+
scores: normalizeScores(scores),
|
|
62
|
+
quick_win: normalizeQuickWin(quickWin),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function normalizeContextSetup(v) {
|
|
66
|
+
if (typeof v === 'string')
|
|
67
|
+
return v;
|
|
68
|
+
if (!v)
|
|
69
|
+
return '';
|
|
70
|
+
// Old schema returned { issues: [], suggestions: [], score: n }
|
|
71
|
+
const parts = [];
|
|
72
|
+
if (Array.isArray(v.issues))
|
|
73
|
+
parts.push(v.issues.join(' '));
|
|
74
|
+
if (Array.isArray(v.suggestions))
|
|
75
|
+
parts.push(v.suggestions.join(' '));
|
|
76
|
+
if (typeof v.description === 'string')
|
|
77
|
+
parts.push(v.description);
|
|
78
|
+
return parts.join('\n') || JSON.stringify(v);
|
|
79
|
+
}
|
|
80
|
+
function normalizePatterns(v) {
|
|
81
|
+
if (!Array.isArray(v))
|
|
82
|
+
return [];
|
|
83
|
+
return v.map((p) => ({
|
|
84
|
+
name: p.name ?? p.pattern ?? 'Unknown pattern',
|
|
85
|
+
prompt_references: Array.isArray(p.prompt_references) ? p.prompt_references : [],
|
|
86
|
+
explanation: p.explanation ?? p.description ?? '',
|
|
87
|
+
rewrite: p.rewrite ?? p.suggested ?? p.example ?? '',
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
function normalizeScores(v) {
|
|
91
|
+
if (!v)
|
|
92
|
+
v = {};
|
|
93
|
+
// Accept both snake_case and alternate key names the LLM sometimes uses
|
|
94
|
+
return {
|
|
95
|
+
prompt_clarity: v.prompt_clarity ?? v.clarity ?? 0,
|
|
96
|
+
prompt_clarity_reason: v.prompt_clarity_reason ?? v.clarity_reason ?? '',
|
|
97
|
+
context_provision: v.context_provision ?? v.context ?? 0,
|
|
98
|
+
context_provision_reason: v.context_provision_reason ?? v.context_reason ?? '',
|
|
99
|
+
session_efficiency: v.session_efficiency ?? v.efficiency ?? 0,
|
|
100
|
+
session_efficiency_reason: v.session_efficiency_reason ?? v.efficiency_reason ?? '',
|
|
101
|
+
setup_and_tooling: v.setup_and_tooling ?? v.setup ?? v.tooling ?? 0,
|
|
102
|
+
setup_and_tooling_reason: v.setup_and_tooling_reason ?? v.setup_reason ?? v.tooling_reason ?? '',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function normalizeQuickWin(v) {
|
|
106
|
+
if (!v)
|
|
107
|
+
return { action: '', spec_sections_needed: [] };
|
|
108
|
+
if (typeof v === 'string')
|
|
109
|
+
return { action: v, spec_sections_needed: [] };
|
|
110
|
+
return {
|
|
111
|
+
action: v.action ?? v.text ?? v.recommendation ?? '',
|
|
112
|
+
spec_sections_needed: Array.isArray(v.spec_sections_needed) ? v.spec_sections_needed : [],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=session-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-analyzer.js","sourceRoot":"","sources":["../../analysis/session-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SessionContext } from './types';
|
|
2
|
+
import { Config } from '../config';
|
|
3
|
+
export declare class SessionBuilder {
|
|
4
|
+
private config;
|
|
5
|
+
constructor(config: Config);
|
|
6
|
+
build(sessionId: string): Promise<SessionContext>;
|
|
7
|
+
listSessionIds(distinctId: string, afterIso: string): Promise<string[]>;
|
|
8
|
+
private getQueryBase;
|
|
9
|
+
private authHeader;
|
|
10
|
+
private fetchEvents;
|
|
11
|
+
private fetchEventsByUser;
|
|
12
|
+
private paginate;
|
|
13
|
+
private assemble;
|
|
14
|
+
private detectProvider;
|
|
15
|
+
private extractMetadata;
|
|
16
|
+
private buildTurns;
|
|
17
|
+
private computeStats;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=session-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-builder.d.ts","sourceRoot":"","sources":["../../analysis/session-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8C,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AASnC,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAQjD,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAW7E,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;YAOJ,WAAW;YAQX,iBAAiB;YAKjB,QAAQ;IAoBtB,OAAO,CAAC,QAAQ;IAsBhB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,UAAU;IAuClB,OAAO,CAAC,YAAY;CAsBrB"}
|