chekk 0.2.2 → 0.2.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/bin/chekk.js +1 -1
- package/package.json +1 -1
- package/src/display.js +88 -2
- package/src/metrics/ai-leverage.js +27 -3
- package/src/metrics/debug-cycles.js +24 -1
- package/src/metrics/decomposition.js +25 -0
- package/src/metrics/session-structure.js +20 -0
- package/src/upload.js +14 -0
package/bin/chekk.js
CHANGED
|
@@ -8,7 +8,7 @@ const program = new Command();
|
|
|
8
8
|
program
|
|
9
9
|
.name('chekk')
|
|
10
10
|
.description('The engineering capability score. See how you prompt.')
|
|
11
|
-
.version('0.2.
|
|
11
|
+
.version('0.2.3')
|
|
12
12
|
.option('--offline', 'Skip AI prose generation, show data-driven output')
|
|
13
13
|
.option('--verbose', 'Show detailed per-project and per-metric breakdowns')
|
|
14
14
|
.option('--json', 'Output raw metrics as JSON')
|
package/package.json
CHANGED
package/src/display.js
CHANGED
|
@@ -42,6 +42,28 @@ function pad(str, len) {
|
|
|
42
42
|
return str + ' '.repeat(Math.max(0, len - visible.length));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function snippet(prompt, maxLen = 70) {
|
|
46
|
+
if (!prompt) return null;
|
|
47
|
+
// Clean up whitespace / newlines
|
|
48
|
+
let clean = prompt.replace(/\s+/g, ' ').trim();
|
|
49
|
+
if (clean.length > maxLen) {
|
|
50
|
+
clean = clean.slice(0, maxLen - 1) + '\u2026';
|
|
51
|
+
}
|
|
52
|
+
return clean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function displaySnippet(prompt, maxLen = 70) {
|
|
56
|
+
const s = snippet(prompt, maxLen);
|
|
57
|
+
if (!s) return;
|
|
58
|
+
console.log(` ${dim('\u201C')}${dim.italic(s)}${dim('\u201D')}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function pickExample(examples, type) {
|
|
62
|
+
if (!examples || !examples.length) return null;
|
|
63
|
+
const match = examples.find(e => e.type === type);
|
|
64
|
+
return match ? match.prompt : null;
|
|
65
|
+
}
|
|
66
|
+
|
|
45
67
|
// ── Box drawing ──
|
|
46
68
|
|
|
47
69
|
function box(lines, width = 43) {
|
|
@@ -68,7 +90,7 @@ export function displayHeader() {
|
|
|
68
90
|
console.log();
|
|
69
91
|
const lines = [
|
|
70
92
|
'',
|
|
71
|
-
` ${bold.white('chekk')}${dim(' v0.2.
|
|
93
|
+
` ${bold.white('chekk')}${dim(' v0.2.3')}`,
|
|
72
94
|
` ${dim('the engineering capability score')}`,
|
|
73
95
|
'',
|
|
74
96
|
];
|
|
@@ -196,8 +218,10 @@ export function displayNarratives(metrics, prose) {
|
|
|
196
218
|
}
|
|
197
219
|
console.log();
|
|
198
220
|
}
|
|
221
|
+
// Show prompt evidence after AI prose
|
|
222
|
+
displayPromptEvidence(metrics);
|
|
199
223
|
} else {
|
|
200
|
-
// Fallback: data-driven bullet points
|
|
224
|
+
// Fallback: data-driven bullet points with inline snippets
|
|
201
225
|
displayDataNarratives(metrics);
|
|
202
226
|
}
|
|
203
227
|
}
|
|
@@ -207,6 +231,20 @@ function displayDataNarratives(metrics) {
|
|
|
207
231
|
const db = metrics.debugCycles.details;
|
|
208
232
|
const ai = metrics.aiLeverage.details;
|
|
209
233
|
const ss = metrics.sessionStructure.details;
|
|
234
|
+
const dEx = metrics.decomposition.examples || [];
|
|
235
|
+
const dbEx = metrics.debugCycles.examples || [];
|
|
236
|
+
const aiEx = metrics.aiLeverage.examples || [];
|
|
237
|
+
const ssEx = metrics.sessionStructure.examples || [];
|
|
238
|
+
|
|
239
|
+
// Track shown snippets to avoid duplicates
|
|
240
|
+
const shownSnippets = new Set();
|
|
241
|
+
function showUniqueSnippet(prompt) {
|
|
242
|
+
if (!prompt) return;
|
|
243
|
+
const s = snippet(prompt, 70);
|
|
244
|
+
if (shownSnippets.has(s)) return;
|
|
245
|
+
shownSnippets.add(s);
|
|
246
|
+
displaySnippet(prompt);
|
|
247
|
+
}
|
|
210
248
|
|
|
211
249
|
// Thinking
|
|
212
250
|
console.log(` ${bold('\uD83E\uDDE0 THINKING')}`);
|
|
@@ -214,6 +252,7 @@ function displayDataNarratives(metrics) {
|
|
|
214
252
|
console.log(` ${dim(exchPerSession > 20 ? `${exchPerSession} avg exchanges/session \u2014 marathon builder` : exchPerSession > 8 ? `${exchPerSession} avg exchanges/session \u2014 iterative` : `${exchPerSession} avg exchanges/session \u2014 concise`)}`);
|
|
215
253
|
console.log(` ${dim(d.avgPromptLength > 500 ? `${numberFormat(d.avgPromptLength)} char avg prompt \u2014 thinks out loud` : `${d.avgPromptLength} char avg prompt \u2014 concise communicator`)}`);
|
|
216
254
|
console.log(` ${dim(d.multiStepSessions > d.singleShotSessions * 2 ? 'Multi-step decomposition over single-shot' : 'Mix of multi-step and single-shot sessions')}`);
|
|
255
|
+
showUniqueSnippet(pickExample(dEx, 'decomposition'));
|
|
217
256
|
console.log();
|
|
218
257
|
|
|
219
258
|
// Debugging
|
|
@@ -222,6 +261,7 @@ function displayDataNarratives(metrics) {
|
|
|
222
261
|
console.log(` ${dim(turns <= 2 ? `${turns} turns to resolve \u2014 surgical` : turns <= 4 ? `${turns} turns to resolve \u2014 efficient` : `${turns} turns to resolve \u2014 iterative`)}`);
|
|
223
262
|
console.log(` ${dim(`${db.specificReportRatio}% specific error reports`)}`);
|
|
224
263
|
console.log(` ${dim(db.longLoops === 0 ? 'Zero extended debug loops detected' : `${db.longLoops} extended debug loops`)}`);
|
|
264
|
+
showUniqueSnippet(pickExample(dbEx, 'specific_report') || pickExample(dbEx, 'quick_fix'));
|
|
225
265
|
console.log();
|
|
226
266
|
|
|
227
267
|
// AI Leverage
|
|
@@ -230,6 +270,7 @@ function displayDataNarratives(metrics) {
|
|
|
230
270
|
const codingRatio = ai.toolDiversity.coding > ai.toolDiversity.research ? 'Coding-heavy' : 'Research-heavy';
|
|
231
271
|
console.log(` ${dim(`${codingRatio} over ${ai.toolDiversity.coding > ai.toolDiversity.research ? 'research' : 'coding'}-heavy`)}`);
|
|
232
272
|
console.log(` ${dim(`${ai.architecturalPrompts} architectural, ${ai.planningPrompts} planning, ${ai.exploratoryPrompts} exploratory`)}`);
|
|
273
|
+
showUniqueSnippet(pickExample(aiEx, 'architectural') || pickExample(aiEx, 'planning'));
|
|
233
274
|
console.log();
|
|
234
275
|
|
|
235
276
|
// Workflow
|
|
@@ -237,6 +278,51 @@ function displayDataNarratives(metrics) {
|
|
|
237
278
|
console.log(` ${dim(`${ss.contextSetRatio}% context-setting rate \u2014 ${ss.contextSetRatio > 50 ? 'deliberate' : ss.contextSetRatio > 25 ? 'moderate' : 'low'}`)}`);
|
|
238
279
|
console.log(` ${dim(`${ss.reviewEndRatio}% sessions end with review`)}`);
|
|
239
280
|
console.log(` ${dim(`${ss.refinementRatio}% refinement rate \u2014 ${ss.refinementRatio > 20 ? 'critical eye' : 'accepts readily'}`)}`);
|
|
281
|
+
showUniqueSnippet(pickExample(ssEx, 'context_setting') || pickExample(ssEx, 'refinement'));
|
|
282
|
+
console.log();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// ── Prompt evidence block (shown after AI prose) ──
|
|
286
|
+
|
|
287
|
+
function displayPromptEvidence(metrics) {
|
|
288
|
+
const allExamples = [
|
|
289
|
+
...(metrics.decomposition.examples || []),
|
|
290
|
+
...(metrics.debugCycles.examples || []),
|
|
291
|
+
...(metrics.aiLeverage.examples || []),
|
|
292
|
+
...(metrics.sessionStructure.examples || []),
|
|
293
|
+
];
|
|
294
|
+
|
|
295
|
+
if (allExamples.length === 0) return;
|
|
296
|
+
|
|
297
|
+
// Pick up to 3 best examples to show as evidence, deduplicated
|
|
298
|
+
const candidates = [];
|
|
299
|
+
const arch = pickExample(metrics.aiLeverage.examples, 'architectural');
|
|
300
|
+
const decomp = pickExample(metrics.decomposition.examples, 'decomposition');
|
|
301
|
+
const debug = pickExample(metrics.debugCycles.examples, 'specific_report');
|
|
302
|
+
const ctx = pickExample(metrics.sessionStructure.examples, 'context_setting');
|
|
303
|
+
|
|
304
|
+
if (arch) candidates.push({ label: 'Architecture', prompt: arch });
|
|
305
|
+
if (decomp) candidates.push({ label: 'Thinking', prompt: decomp });
|
|
306
|
+
if (debug) candidates.push({ label: 'Debugging', prompt: debug });
|
|
307
|
+
if (ctx) candidates.push({ label: 'Context', prompt: ctx });
|
|
308
|
+
|
|
309
|
+
// Deduplicate by snippet text
|
|
310
|
+
const picks = [];
|
|
311
|
+
const seen = new Set();
|
|
312
|
+
for (const c of candidates) {
|
|
313
|
+
const s = snippet(c.prompt, 65);
|
|
314
|
+
if (!seen.has(s)) {
|
|
315
|
+
seen.add(s);
|
|
316
|
+
picks.push(c);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (picks.length === 0) return;
|
|
321
|
+
|
|
322
|
+
console.log(dim(' YOUR PROMPTS\n'));
|
|
323
|
+
for (const pick of picks.slice(0, 3)) {
|
|
324
|
+
console.log(` ${dim(pick.label + ':')} ${dim('\u201C')}${dim.italic(snippet(pick.prompt, 65))}${dim('\u201D')}`);
|
|
325
|
+
}
|
|
240
326
|
console.log();
|
|
241
327
|
}
|
|
242
328
|
|
|
@@ -37,15 +37,32 @@ export function computeAILeverage(sessions) {
|
|
|
37
37
|
let complexPrompts = 0; // > 200 chars with multiple sentences
|
|
38
38
|
let trivialPrompts = 0; // < 50 chars, simple commands
|
|
39
39
|
|
|
40
|
+
// Capture representative examples
|
|
41
|
+
let bestArchPrompt = null; // best architectural prompt
|
|
42
|
+
let bestPlanPrompt = null; // best planning prompt
|
|
43
|
+
let bestExplorePrompt = null; // best exploratory prompt
|
|
44
|
+
let bestArchLen = 0;
|
|
45
|
+
let bestPlanLen = 0;
|
|
46
|
+
let bestExploreLen = 0;
|
|
47
|
+
|
|
40
48
|
for (const session of sessions) {
|
|
41
49
|
for (const exchange of session.exchanges) {
|
|
42
50
|
const prompt = exchange.userPrompt || '';
|
|
43
51
|
totalPrompts++;
|
|
44
52
|
|
|
45
53
|
// Categorize prompt type
|
|
46
|
-
if (architecturalPatterns.test(prompt))
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
if (architecturalPatterns.test(prompt)) {
|
|
55
|
+
architecturalPrompts++;
|
|
56
|
+
if (prompt.length > bestArchLen) { bestArchLen = prompt.length; bestArchPrompt = prompt; }
|
|
57
|
+
}
|
|
58
|
+
if (planningPatterns.test(prompt)) {
|
|
59
|
+
planningPrompts++;
|
|
60
|
+
if (prompt.length > bestPlanLen) { bestPlanLen = prompt.length; bestPlanPrompt = prompt; }
|
|
61
|
+
}
|
|
62
|
+
if (exploratoryPatterns.test(prompt)) {
|
|
63
|
+
exploratoryPrompts++;
|
|
64
|
+
if (prompt.length > bestExploreLen) { bestExploreLen = prompt.length; bestExplorePrompt = prompt; }
|
|
65
|
+
}
|
|
49
66
|
if (boilerplatePatterns.test(prompt)) boilerplatePrompts++;
|
|
50
67
|
if (testingPatterns.test(prompt)) testingPrompts++;
|
|
51
68
|
|
|
@@ -103,6 +120,12 @@ export function computeAILeverage(sessions) {
|
|
|
103
120
|
50 * 0 // baseline filler
|
|
104
121
|
);
|
|
105
122
|
|
|
123
|
+
// Build examples — pick the best one available
|
|
124
|
+
const examples = [];
|
|
125
|
+
if (bestArchPrompt) examples.push({ type: 'architectural', prompt: bestArchPrompt });
|
|
126
|
+
if (bestPlanPrompt) examples.push({ type: 'planning', prompt: bestPlanPrompt });
|
|
127
|
+
if (bestExplorePrompt) examples.push({ type: 'exploratory', prompt: bestExplorePrompt });
|
|
128
|
+
|
|
106
129
|
return {
|
|
107
130
|
score: Math.max(0, Math.min(100, score)),
|
|
108
131
|
details: {
|
|
@@ -120,5 +143,6 @@ export function computeAILeverage(sessions) {
|
|
|
120
143
|
coding: codingToolUses,
|
|
121
144
|
},
|
|
122
145
|
},
|
|
146
|
+
examples,
|
|
123
147
|
};
|
|
124
148
|
}
|
|
@@ -26,10 +26,16 @@ export function computeDebugCycles(sessions) {
|
|
|
26
26
|
let quickFixes = 0; // resolved in 1-2 turns
|
|
27
27
|
let longLoops = 0; // > 5 turns to resolve
|
|
28
28
|
|
|
29
|
+
// Capture representative examples
|
|
30
|
+
let bestSpecificReport = null; // best specific error report
|
|
31
|
+
let bestQuickFix = null; // prompt that led to quick resolution
|
|
32
|
+
let bestSpecificLen = 0;
|
|
33
|
+
|
|
29
34
|
for (const session of sessions) {
|
|
30
35
|
const { exchanges } = session;
|
|
31
36
|
let inDebugMode = false;
|
|
32
37
|
let debugTurnCount = 0;
|
|
38
|
+
let debugStartPrompt = null;
|
|
33
39
|
|
|
34
40
|
for (let i = 0; i < exchanges.length; i++) {
|
|
35
41
|
const prompt = exchanges[i].userPrompt || '';
|
|
@@ -39,6 +45,7 @@ export function computeDebugCycles(sessions) {
|
|
|
39
45
|
// Starting a new debug sequence
|
|
40
46
|
inDebugMode = true;
|
|
41
47
|
debugTurnCount = 1;
|
|
48
|
+
debugStartPrompt = prompt;
|
|
42
49
|
totalDebugSequences++;
|
|
43
50
|
} else {
|
|
44
51
|
debugTurnCount++;
|
|
@@ -50,21 +57,31 @@ export function computeDebugCycles(sessions) {
|
|
|
50
57
|
}
|
|
51
58
|
if (specificDebugPatterns.test(prompt) || prompt.length > 200) {
|
|
52
59
|
specificReports++;
|
|
60
|
+
// Track best specific report
|
|
61
|
+
if (prompt.length > bestSpecificLen) {
|
|
62
|
+
bestSpecificLen = prompt.length;
|
|
63
|
+
bestSpecificReport = prompt;
|
|
64
|
+
}
|
|
53
65
|
}
|
|
54
66
|
} else if (inDebugMode) {
|
|
55
67
|
// Check if this exchange resolves the debug
|
|
56
68
|
if (resolutionPatterns.test(prompt)) {
|
|
57
69
|
totalTurnsToResolve += debugTurnCount;
|
|
58
|
-
if (debugTurnCount <= 2)
|
|
70
|
+
if (debugTurnCount <= 2) {
|
|
71
|
+
quickFixes++;
|
|
72
|
+
if (!bestQuickFix) bestQuickFix = debugStartPrompt;
|
|
73
|
+
}
|
|
59
74
|
if (debugTurnCount > 5) longLoops++;
|
|
60
75
|
inDebugMode = false;
|
|
61
76
|
debugTurnCount = 0;
|
|
77
|
+
debugStartPrompt = null;
|
|
62
78
|
} else {
|
|
63
79
|
// Moved on without explicit resolution
|
|
64
80
|
totalTurnsToResolve += debugTurnCount;
|
|
65
81
|
unresolvedSequences++;
|
|
66
82
|
inDebugMode = false;
|
|
67
83
|
debugTurnCount = 0;
|
|
84
|
+
debugStartPrompt = null;
|
|
68
85
|
}
|
|
69
86
|
}
|
|
70
87
|
}
|
|
@@ -109,6 +126,11 @@ export function computeDebugCycles(sessions) {
|
|
|
109
126
|
(100 - longLoopPenalty) * 0.15
|
|
110
127
|
);
|
|
111
128
|
|
|
129
|
+
// Build examples array
|
|
130
|
+
const examples = [];
|
|
131
|
+
if (bestSpecificReport) examples.push({ type: 'specific_report', prompt: bestSpecificReport });
|
|
132
|
+
if (bestQuickFix) examples.push({ type: 'quick_fix', prompt: bestQuickFix });
|
|
133
|
+
|
|
112
134
|
return {
|
|
113
135
|
score: Math.max(0, Math.min(100, score)),
|
|
114
136
|
details: {
|
|
@@ -120,5 +142,6 @@ export function computeDebugCycles(sessions) {
|
|
|
120
142
|
vagueReports,
|
|
121
143
|
specificReports,
|
|
122
144
|
},
|
|
145
|
+
examples,
|
|
123
146
|
};
|
|
124
147
|
}
|
|
@@ -26,6 +26,11 @@ export function computeDecomposition(sessions) {
|
|
|
26
26
|
const followupPatterns = /^(now |next |then |also |and |ok |okay |great |good |perfect |after that|building on|following up|continuing)/i;
|
|
27
27
|
const refinementPatterns = /^(actually |wait |hmm |instead |change |modify |update |tweak |adjust |fix |but )/i;
|
|
28
28
|
|
|
29
|
+
// Capture representative prompt examples
|
|
30
|
+
// Keep top 3 candidates and pick the 2nd-longest to avoid overlap with other metrics
|
|
31
|
+
const decompCandidates = [];
|
|
32
|
+
let bestFollowupPrompt = null;
|
|
33
|
+
|
|
29
34
|
for (const session of sessions) {
|
|
30
35
|
const { exchanges } = session;
|
|
31
36
|
totalExchanges += exchanges.length;
|
|
@@ -45,10 +50,19 @@ export function computeDecomposition(sessions) {
|
|
|
45
50
|
if (len > 500) longPromptCount++;
|
|
46
51
|
if (len < 100) shortPromptCount++;
|
|
47
52
|
|
|
53
|
+
// Track decomposition examples (multi-sentence prompts showing task breakdown)
|
|
54
|
+
if (len > 150 && len < 2000) {
|
|
55
|
+
decompCandidates.push(prompt);
|
|
56
|
+
}
|
|
57
|
+
|
|
48
58
|
// Check for contextual followups (not the first prompt in a session)
|
|
49
59
|
if (i > 0) {
|
|
50
60
|
if (followupPatterns.test(prompt) || refinementPatterns.test(prompt)) {
|
|
51
61
|
contextualFollowups++;
|
|
62
|
+
// Capture best followup example
|
|
63
|
+
if (!bestFollowupPrompt || prompt.length > bestFollowupPrompt.length) {
|
|
64
|
+
bestFollowupPrompt = prompt;
|
|
65
|
+
}
|
|
52
66
|
}
|
|
53
67
|
}
|
|
54
68
|
}
|
|
@@ -83,6 +97,16 @@ export function computeDecomposition(sessions) {
|
|
|
83
97
|
depthScore * 0.2
|
|
84
98
|
);
|
|
85
99
|
|
|
100
|
+
// Build examples array — pick a mid-length prompt to avoid overlap with other metrics
|
|
101
|
+
const examples = [];
|
|
102
|
+
if (decompCandidates.length > 0) {
|
|
103
|
+
decompCandidates.sort((a, b) => b.length - a.length);
|
|
104
|
+
// Pick ~median length to avoid the longest (which will also match ai-leverage)
|
|
105
|
+
const pickIdx = Math.min(Math.floor(decompCandidates.length / 3), decompCandidates.length - 1);
|
|
106
|
+
examples.push({ type: 'decomposition', prompt: decompCandidates[pickIdx] });
|
|
107
|
+
}
|
|
108
|
+
if (bestFollowupPrompt) examples.push({ type: 'followup', prompt: bestFollowupPrompt });
|
|
109
|
+
|
|
86
110
|
return {
|
|
87
111
|
score: Math.max(0, Math.min(100, score)),
|
|
88
112
|
details: {
|
|
@@ -94,5 +118,6 @@ export function computeDecomposition(sessions) {
|
|
|
94
118
|
longPromptRatio: promptCount > 0 ? Math.round(longPromptCount / promptCount * 100) : 0,
|
|
95
119
|
contextualFollowupRatio: promptCount > 0 ? Math.round(followupRatio * 100) : 0,
|
|
96
120
|
},
|
|
121
|
+
examples,
|
|
97
122
|
};
|
|
98
123
|
}
|
|
@@ -34,6 +34,11 @@ export function computeSessionStructure(sessions) {
|
|
|
34
34
|
// First prompt length distribution (longer first prompts = more context setting)
|
|
35
35
|
let firstPromptTotalLength = 0;
|
|
36
36
|
|
|
37
|
+
// Capture representative examples
|
|
38
|
+
let bestContextPrompt = null; // best context-setting opener
|
|
39
|
+
let bestRefinementPrompt = null; // best refinement/critical feedback
|
|
40
|
+
let bestContextLen = 0;
|
|
41
|
+
|
|
37
42
|
for (const session of sessions) {
|
|
38
43
|
const { exchanges, durationMinutes } = session;
|
|
39
44
|
if (exchanges.length === 0) continue;
|
|
@@ -46,6 +51,11 @@ export function computeSessionStructure(sessions) {
|
|
|
46
51
|
|
|
47
52
|
if (contextSettingPatterns.test(firstPrompt) || firstPrompt.length > 200) {
|
|
48
53
|
contextSetSessions++;
|
|
54
|
+
// Track best context-setting prompt
|
|
55
|
+
if (firstPrompt.length > bestContextLen) {
|
|
56
|
+
bestContextLen = firstPrompt.length;
|
|
57
|
+
bestContextPrompt = firstPrompt;
|
|
58
|
+
}
|
|
49
59
|
}
|
|
50
60
|
|
|
51
61
|
if (planningStartPatterns.test(firstPrompt)) {
|
|
@@ -66,6 +76,10 @@ export function computeSessionStructure(sessions) {
|
|
|
66
76
|
const prompt = exchanges[i].userPrompt || '';
|
|
67
77
|
if (refinementPatterns.test(prompt)) {
|
|
68
78
|
refinementCount++;
|
|
79
|
+
// Track best refinement example
|
|
80
|
+
if (!bestRefinementPrompt || prompt.length > bestRefinementPrompt.length) {
|
|
81
|
+
bestRefinementPrompt = prompt;
|
|
82
|
+
}
|
|
69
83
|
}
|
|
70
84
|
}
|
|
71
85
|
|
|
@@ -115,6 +129,11 @@ export function computeSessionStructure(sessions) {
|
|
|
115
129
|
firstPromptScore * 0.15
|
|
116
130
|
);
|
|
117
131
|
|
|
132
|
+
// Build examples array
|
|
133
|
+
const examples = [];
|
|
134
|
+
if (bestContextPrompt) examples.push({ type: 'context_setting', prompt: bestContextPrompt });
|
|
135
|
+
if (bestRefinementPrompt) examples.push({ type: 'refinement', prompt: bestRefinementPrompt });
|
|
136
|
+
|
|
118
137
|
return {
|
|
119
138
|
score: Math.max(0, Math.min(100, score)),
|
|
120
139
|
details: {
|
|
@@ -130,5 +149,6 @@ export function computeSessionStructure(sessions) {
|
|
|
130
149
|
focused: focusedSessions,
|
|
131
150
|
},
|
|
132
151
|
},
|
|
152
|
+
examples,
|
|
133
153
|
};
|
|
134
154
|
}
|
package/src/upload.js
CHANGED
|
@@ -5,24 +5,38 @@ const API_BASE = 'https://chekk-production.up.railway.app/api/v1';
|
|
|
5
5
|
/**
|
|
6
6
|
* Call the Chekk API to generate personalized prose from metrics.
|
|
7
7
|
*/
|
|
8
|
+
function truncateExamples(examples, maxLen = 120) {
|
|
9
|
+
if (!examples || !examples.length) return [];
|
|
10
|
+
return examples.map(e => ({
|
|
11
|
+
type: e.type,
|
|
12
|
+
prompt: e.prompt && e.prompt.length > maxLen
|
|
13
|
+
? e.prompt.replace(/\s+/g, ' ').trim().slice(0, maxLen) + '...'
|
|
14
|
+
: (e.prompt || '').replace(/\s+/g, ' ').trim(),
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
|
|
8
18
|
export async function generateProse(metrics, result, sessionStats) {
|
|
9
19
|
const payload = {
|
|
10
20
|
metrics: {
|
|
11
21
|
decomposition: {
|
|
12
22
|
score: metrics.decomposition.score,
|
|
13
23
|
details: metrics.decomposition.details,
|
|
24
|
+
examples: truncateExamples(metrics.decomposition.examples),
|
|
14
25
|
},
|
|
15
26
|
debugCycles: {
|
|
16
27
|
score: metrics.debugCycles.score,
|
|
17
28
|
details: metrics.debugCycles.details,
|
|
29
|
+
examples: truncateExamples(metrics.debugCycles.examples),
|
|
18
30
|
},
|
|
19
31
|
aiLeverage: {
|
|
20
32
|
score: metrics.aiLeverage.score,
|
|
21
33
|
details: metrics.aiLeverage.details,
|
|
34
|
+
examples: truncateExamples(metrics.aiLeverage.examples),
|
|
22
35
|
},
|
|
23
36
|
sessionStructure: {
|
|
24
37
|
score: metrics.sessionStructure.score,
|
|
25
38
|
details: metrics.sessionStructure.details,
|
|
39
|
+
examples: truncateExamples(metrics.sessionStructure.examples),
|
|
26
40
|
},
|
|
27
41
|
},
|
|
28
42
|
result: {
|