chekk 0.3.0 → 0.4.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/bin/chekk.js +1 -1
- package/package.json +1 -1
- package/src/display.js +399 -238
- package/src/index.js +24 -3
- package/src/insights.js +503 -0
- package/src/scorer.js +55 -26
package/src/display.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { BENCHMARKS, DIM_RANGES } from './insights.js';
|
|
2
3
|
|
|
3
4
|
// ── Color palette ──
|
|
4
5
|
const gold = chalk.hex('#FFD700');
|
|
@@ -7,6 +8,8 @@ const blue = chalk.hex('#3B82F6');
|
|
|
7
8
|
const green = chalk.hex('#22C55E');
|
|
8
9
|
const cyan = chalk.hex('#06B6D4');
|
|
9
10
|
const orange = chalk.hex('#F97316');
|
|
11
|
+
const red = chalk.hex('#EF4444');
|
|
12
|
+
const yellow = chalk.hex('#EAB308');
|
|
10
13
|
const dim = chalk.dim;
|
|
11
14
|
const bold = chalk.bold;
|
|
12
15
|
const white = chalk.white;
|
|
@@ -22,9 +25,9 @@ function tierColor(tier) {
|
|
|
22
25
|
function scoreColor(score) {
|
|
23
26
|
if (score >= 85) return green;
|
|
24
27
|
if (score >= 70) return cyan;
|
|
25
|
-
if (score >= 55) return
|
|
28
|
+
if (score >= 55) return yellow;
|
|
26
29
|
if (score >= 40) return orange;
|
|
27
|
-
return
|
|
30
|
+
return red;
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
function progressBar(score, width = 18) {
|
|
@@ -45,23 +48,22 @@ function pad(str, len) {
|
|
|
45
48
|
|
|
46
49
|
// ── Qualitative tier labels for dimensions ──
|
|
47
50
|
function dimTierLabel(score) {
|
|
48
|
-
if (score >= 80) return '
|
|
49
|
-
if (score >= 65) return '
|
|
50
|
-
if (score >= 50) return '
|
|
51
|
-
if (score >= 35) return '
|
|
52
|
-
return '
|
|
51
|
+
if (score >= 80) return 'EXCEPTIONAL';
|
|
52
|
+
if (score >= 65) return 'STRONG';
|
|
53
|
+
if (score >= 50) return 'SOLID';
|
|
54
|
+
if (score >= 35) return 'DEVELOPING';
|
|
55
|
+
return 'NEEDS WORK';
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
function dimTierColor(score) {
|
|
56
59
|
if (score >= 80) return green;
|
|
57
60
|
if (score >= 65) return cyan;
|
|
58
|
-
if (score >= 50) return
|
|
61
|
+
if (score >= 50) return yellow;
|
|
59
62
|
if (score >= 35) return orange;
|
|
60
|
-
return
|
|
63
|
+
return red;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
// ── Snippet helpers ──
|
|
64
|
-
// Longer snippets with context labels instead of truncated decorations
|
|
65
67
|
|
|
66
68
|
function cleanPrompt(prompt, maxLen = 120) {
|
|
67
69
|
if (!prompt) return null;
|
|
@@ -86,7 +88,7 @@ function pickExample(examples, type) {
|
|
|
86
88
|
|
|
87
89
|
// ── Box drawing ──
|
|
88
90
|
|
|
89
|
-
function box(lines, width =
|
|
91
|
+
function box(lines, width = 47) {
|
|
90
92
|
const out = [];
|
|
91
93
|
out.push(dim(' \u250C' + '\u2500'.repeat(width) + '\u2510'));
|
|
92
94
|
for (const line of lines) {
|
|
@@ -98,33 +100,44 @@ function box(lines, width = 43) {
|
|
|
98
100
|
return out;
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
function doubleRule(width =
|
|
103
|
+
function doubleRule(width = 53) {
|
|
102
104
|
return dim(' ' + '\u2550'.repeat(width));
|
|
103
105
|
}
|
|
104
106
|
|
|
107
|
+
function wrapText(text, maxWidth = 49) {
|
|
108
|
+
const words = text.split(' ');
|
|
109
|
+
const lines = [];
|
|
110
|
+
let current = '';
|
|
111
|
+
for (const word of words) {
|
|
112
|
+
if (current.length + word.length + 1 > maxWidth) {
|
|
113
|
+
lines.push(current);
|
|
114
|
+
current = word;
|
|
115
|
+
} else {
|
|
116
|
+
current = current ? current + ' ' + word : word;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (current) lines.push(current);
|
|
120
|
+
return lines;
|
|
121
|
+
}
|
|
122
|
+
|
|
105
123
|
// ══════════════════════════════════════════════
|
|
106
|
-
// HEADER
|
|
124
|
+
// HEADER — Scanning + progress
|
|
107
125
|
// ══════════════════════════════════════════════
|
|
108
126
|
|
|
109
127
|
export function displayHeader() {
|
|
110
128
|
console.log();
|
|
111
129
|
const lines = [
|
|
112
130
|
'',
|
|
113
|
-
` ${bold.white('chekk')}${dim(' v0.
|
|
114
|
-
` ${dim('
|
|
131
|
+
` ${bold.white('chekk')}${dim(' v0.4.0')}`,
|
|
132
|
+
` ${dim('engineering capability profile')}`,
|
|
115
133
|
'',
|
|
116
134
|
];
|
|
117
135
|
for (const l of box(lines, 45)) console.log(l);
|
|
118
136
|
console.log();
|
|
119
137
|
}
|
|
120
138
|
|
|
121
|
-
// ══════════════════════════════════════════════
|
|
122
|
-
// SCAN RESULTS
|
|
123
|
-
// ══════════════════════════════════════════════
|
|
124
|
-
|
|
125
139
|
export function displayScan(tools) {
|
|
126
140
|
console.log(dim(' Scanning local AI tools...\n'));
|
|
127
|
-
|
|
128
141
|
for (const tool of tools) {
|
|
129
142
|
const sessions = numberFormat(tool.sessions);
|
|
130
143
|
const projects = tool.projects.length;
|
|
@@ -136,10 +149,6 @@ export function displayScan(tools) {
|
|
|
136
149
|
console.log();
|
|
137
150
|
}
|
|
138
151
|
|
|
139
|
-
// ══════════════════════════════════════════════
|
|
140
|
-
// ANALYSIS PROGRESS BAR
|
|
141
|
-
// ══════════════════════════════════════════════
|
|
142
|
-
|
|
143
152
|
export function displayAnalysisStart(dateRange) {
|
|
144
153
|
console.log(` ${dim('Analyzing')} ${white(dateRange)}${dim('...\n')}`);
|
|
145
154
|
}
|
|
@@ -148,7 +157,6 @@ export async function displayProgressBar(durationMs = 2000) {
|
|
|
148
157
|
const width = 40;
|
|
149
158
|
const steps = 40;
|
|
150
159
|
const stepTime = durationMs / steps;
|
|
151
|
-
|
|
152
160
|
for (let i = 0; i <= steps; i++) {
|
|
153
161
|
const filled = i;
|
|
154
162
|
const empty = width - filled;
|
|
@@ -159,108 +167,199 @@ export async function displayProgressBar(durationMs = 2000) {
|
|
|
159
167
|
}
|
|
160
168
|
console.log();
|
|
161
169
|
console.log();
|
|
162
|
-
console.log(` ${green('\u2713')} ${dim('
|
|
170
|
+
console.log(` ${green('\u2713')} ${dim('Profile generated.')}`);
|
|
163
171
|
console.log();
|
|
164
172
|
}
|
|
165
173
|
|
|
166
174
|
// ══════════════════════════════════════════════
|
|
167
|
-
//
|
|
175
|
+
// PROFILE HEADER — Official document feel
|
|
168
176
|
// ══════════════════════════════════════════════
|
|
169
177
|
|
|
170
|
-
|
|
171
|
-
const {
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
const
|
|
178
|
+
function displayProfileHeader(result, extra = {}) {
|
|
179
|
+
const { sessionStats } = extra;
|
|
180
|
+
const now = new Date();
|
|
181
|
+
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
182
|
+
const dateStr = `${months[now.getMonth()]} ${now.getDate()}, ${now.getFullYear()}`;
|
|
175
183
|
|
|
176
|
-
// Big score block
|
|
177
184
|
console.log(doubleRule());
|
|
178
185
|
console.log();
|
|
179
|
-
console.log(
|
|
186
|
+
console.log(` ${bold.white('ENGINEERING CAPABILITY PROFILE')}`);
|
|
180
187
|
console.log();
|
|
188
|
+
if (sessionStats) {
|
|
189
|
+
console.log(` ${dim(`Generated ${dateStr} | chekk v0.4.0`)}`);
|
|
190
|
+
console.log(` ${dim(`Analysis: ${sessionStats.totalSessions} sessions \u00B7 ${sessionStats.tools.length} tool${sessionStats.tools.length > 1 ? 's' : ''} \u00B7 ${numberFormat(sessionStats.totalExchanges)} exchanges`)}`);
|
|
191
|
+
if (sessionStats.dateRangeShort) {
|
|
192
|
+
console.log(` ${dim(`Period: ${sessionStats.dateRangeShort}`)}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
console.log();
|
|
196
|
+
console.log(doubleRule());
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ══════════════════════════════════════════════
|
|
200
|
+
// SUMMARY BLOCK
|
|
201
|
+
// ══════════════════════════════════════════════
|
|
202
|
+
|
|
203
|
+
function displaySummary(result, extra = {}) {
|
|
204
|
+
const { overall, scores, archetype, tier, tierBadge, tierPercentile } = result;
|
|
205
|
+
const { scoreDelta, perToolScores, insights, sessionStats } = extra;
|
|
206
|
+
const tc = tierColor(tier);
|
|
207
|
+
|
|
208
|
+
// Find strongest and weakest
|
|
209
|
+
const dims = [
|
|
210
|
+
{ label: 'Thinking', score: scores.decomposition },
|
|
211
|
+
{ label: 'Debugging', score: scores.debugCycles },
|
|
212
|
+
{ label: 'AI Leverage', score: scores.aiLeverage },
|
|
213
|
+
{ label: 'Workflow', score: scores.sessionStructure },
|
|
214
|
+
];
|
|
215
|
+
dims.sort((a, b) => b.score - a.score);
|
|
216
|
+
const strongest = dims[0];
|
|
217
|
+
const weakest = dims[dims.length - 1];
|
|
218
|
+
|
|
219
|
+
console.log();
|
|
220
|
+
console.log(dim(' SUMMARY'));
|
|
221
|
+
|
|
222
|
+
const badge = tierBadge || '';
|
|
223
|
+
const toolsList = sessionStats ? sessionStats.tools.join(' \u00B7 ') : '';
|
|
224
|
+
const sessionCount = sessionStats ? `${sessionStats.totalSessions} across ${sessionStats.projectCount} projects` : '';
|
|
225
|
+
const period = sessionStats?.dateRangeShort || '';
|
|
181
226
|
|
|
182
|
-
//
|
|
227
|
+
// Delta string
|
|
183
228
|
let deltaStr = '';
|
|
184
229
|
if (scoreDelta !== null && scoreDelta !== undefined) {
|
|
185
|
-
if (scoreDelta > 0) deltaStr = ` ${green('\u2191 +' + scoreDelta
|
|
186
|
-
else if (scoreDelta < 0) deltaStr = ` ${orange('\u2193 ' + scoreDelta
|
|
187
|
-
else deltaStr = ` ${dim('\u2192 same as last scan')}`;
|
|
230
|
+
if (scoreDelta > 0) deltaStr = ` ${green('\u2191 +' + scoreDelta)}`;
|
|
231
|
+
else if (scoreDelta < 0) deltaStr = ` ${orange('\u2193 ' + scoreDelta)}`;
|
|
188
232
|
}
|
|
189
|
-
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
233
|
+
|
|
234
|
+
const summaryLines = [
|
|
235
|
+
'',
|
|
236
|
+
` ${dim('Score')} ${scoreColor(overall).bold(String(overall))}${deltaStr}`,
|
|
237
|
+
` ${dim('Tier')} ${tc(tier)} ${badge} ${dim('\u2014')} ${dim(tierPercentile)}`,
|
|
238
|
+
` ${dim('Archetype')} ${bold.white(archetype.name)}`,
|
|
239
|
+
];
|
|
240
|
+
if (toolsList) summaryLines.push(` ${dim('Tools')} ${dim(toolsList)}`);
|
|
241
|
+
if (sessionCount) summaryLines.push(` ${dim('Sessions')} ${dim(sessionCount)}`);
|
|
242
|
+
if (period) summaryLines.push(` ${dim('Period')} ${dim(period)}`);
|
|
243
|
+
summaryLines.push(` ${dim('Strongest')} ${dim(strongest.label + ' (' + dimTierLabel(strongest.score) + ')')}`);
|
|
244
|
+
summaryLines.push(` ${dim('Growth Area')} ${dim(weakest.label + ' (' + dimTierLabel(weakest.score) + ')')}`);
|
|
245
|
+
summaryLines.push('');
|
|
246
|
+
|
|
247
|
+
for (const l of box(summaryLines, 53)) console.log(l);
|
|
194
248
|
console.log();
|
|
195
|
-
|
|
249
|
+
}
|
|
196
250
|
|
|
197
|
-
|
|
198
|
-
|
|
251
|
+
// ══════════════════════════════════════════════
|
|
252
|
+
// ARCHETYPE DEFINITION
|
|
253
|
+
// ══════════════════════════════════════════════
|
|
254
|
+
|
|
255
|
+
function displayArchetype(result) {
|
|
256
|
+
const { archetype } = result;
|
|
257
|
+
console.log(` ${bold.white(archetype.name)}`);
|
|
258
|
+
console.log();
|
|
259
|
+
if (archetype.description) {
|
|
260
|
+
const lines = wrapText(archetype.description, 51);
|
|
261
|
+
for (const line of lines) {
|
|
262
|
+
console.log(` ${dim(line)}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (archetype.distribution) {
|
|
266
|
+
console.log();
|
|
267
|
+
console.log(` ${dim('Distribution: ' + archetype.distribution + ' of scored engineers')}`);
|
|
199
268
|
}
|
|
200
269
|
console.log();
|
|
270
|
+
}
|
|
201
271
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
272
|
+
// ══════════════════════════════════════════════
|
|
273
|
+
// DIMENSIONS — with ranges and qualitative labels
|
|
274
|
+
// ══════════════════════════════════════════════
|
|
275
|
+
|
|
276
|
+
function displayDimensions(result) {
|
|
277
|
+
const { scores } = result;
|
|
278
|
+
console.log(dim(' DIMENSIONS'));
|
|
206
279
|
console.log();
|
|
207
280
|
|
|
208
|
-
//
|
|
209
|
-
console.log(dim('
|
|
281
|
+
// Score weight transparency
|
|
282
|
+
console.log(` ${dim('Weights: Thinking 25% | Debugging 25% | AI Leverage 30% | Workflow 20%')}`);
|
|
283
|
+
console.log();
|
|
210
284
|
|
|
211
|
-
function dimLine(label, score) {
|
|
285
|
+
function dimLine(label, key, score) {
|
|
212
286
|
const labelStr = bold(label);
|
|
213
287
|
const labelVisible = label.length;
|
|
214
288
|
const labelPad = ' '.repeat(Math.max(0, 15 - labelVisible));
|
|
215
|
-
const scoreStr = String(score);
|
|
216
|
-
const scorePad = score < 10 ? ' ' : score < 100 ? ' ' : '';
|
|
217
289
|
const tierLabel = dimTierLabel(score);
|
|
218
|
-
const tierStr = dimTierColor(score)(tierLabel);
|
|
219
|
-
|
|
290
|
+
const tierStr = dimTierColor(score)(pad(tierLabel, 11));
|
|
291
|
+
const range = DIM_RANGES[key];
|
|
292
|
+
const rangeStr = dim(`range: ${range.min}-${range.max} | you: ${score}`);
|
|
293
|
+
return [
|
|
294
|
+
` ${labelStr}${labelPad}${progressBar(score)} ${tierStr}`,
|
|
295
|
+
` ${' '.repeat(15)}${rangeStr}`,
|
|
296
|
+
];
|
|
220
297
|
}
|
|
221
298
|
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
299
|
+
const allLines = [''];
|
|
300
|
+
allLines.push(...dimLine('Thinking', 'decomposition', scores.decomposition));
|
|
301
|
+
allLines.push('');
|
|
302
|
+
allLines.push(...dimLine('Debugging', 'debugCycles', scores.debugCycles));
|
|
303
|
+
allLines.push('');
|
|
304
|
+
allLines.push(...dimLine('AI Leverage', 'aiLeverage', scores.aiLeverage));
|
|
305
|
+
allLines.push('');
|
|
306
|
+
allLines.push(...dimLine('Workflow', 'sessionStructure', scores.sessionStructure));
|
|
307
|
+
allLines.push('');
|
|
308
|
+
|
|
309
|
+
for (const l of box(allLines, 53)) console.log(l);
|
|
310
|
+
console.log();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ══════════════════════════════════════════════
|
|
314
|
+
// CROSS-PLATFORM
|
|
315
|
+
// ══════════════════════════════════════════════
|
|
316
|
+
|
|
317
|
+
function displayCrossPlatform(perToolScores) {
|
|
318
|
+
if (!perToolScores || Object.keys(perToolScores).length <= 1) return;
|
|
319
|
+
|
|
320
|
+
console.log(dim(' CROSS-PLATFORM\n'));
|
|
321
|
+
const sorted = Object.entries(perToolScores).sort((a, b) => {
|
|
322
|
+
if (a[1].score === null) return 1;
|
|
323
|
+
if (b[1].score === null) return -1;
|
|
324
|
+
return b[1].score - a[1].score;
|
|
325
|
+
});
|
|
326
|
+
const maxSessions = Math.max(...sorted.map(([, v]) => v.sessions));
|
|
327
|
+
|
|
328
|
+
for (const [tool, data] of sorted) {
|
|
329
|
+
if (data.score !== null) {
|
|
330
|
+
const isPrimary = data.sessions === maxSessions;
|
|
331
|
+
const label = isPrimary ? 'primary tool' : data.sessions < 5 ? 'limited usage' : 'active';
|
|
332
|
+
console.log(` ${pad(bold(tool), 18)} ${bold(String(data.score))} ${progressBar(data.score)} ${dim(label)}`);
|
|
333
|
+
} else {
|
|
334
|
+
console.log(` ${pad(bold(tool), 18)} ${dim('--')} ${dim('\u2591'.repeat(18))} ${dim('limited data')}`);
|
|
257
335
|
}
|
|
336
|
+
}
|
|
337
|
+
console.log();
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// ══════════════════════════════════════════════
|
|
341
|
+
// PROJECT ANALYSIS
|
|
342
|
+
// ══════════════════════════════════════════════
|
|
343
|
+
|
|
344
|
+
function displayProjects(insights) {
|
|
345
|
+
const projects = insights?.projectComplexity;
|
|
346
|
+
if (!projects || projects.length === 0) return;
|
|
347
|
+
|
|
348
|
+
console.log(dim(' PROJECT ANALYSIS\n'));
|
|
349
|
+
for (const p of projects) {
|
|
350
|
+
const compColor = p.complexity === 'HIGH' ? green : p.complexity === 'MEDIUM' ? yellow : dim;
|
|
351
|
+
const signals = p.signals.length > 0 ? p.signals.join(' \u00B7 ') : '';
|
|
352
|
+
console.log(` ${pad(bold(p.name), 32)} Complexity: ${compColor(p.complexity)}`);
|
|
353
|
+
if (signals) {
|
|
354
|
+
console.log(` ${dim(signals)}`);
|
|
355
|
+
}
|
|
356
|
+
console.log(` ${dim(`${p.sessions} sessions \u00B7 ${numberFormat(p.exchanges)} exchanges \u00B7 ${p.daysActive} days active`)}`);
|
|
258
357
|
console.log();
|
|
259
358
|
}
|
|
260
359
|
}
|
|
261
360
|
|
|
262
361
|
// ══════════════════════════════════════════════
|
|
263
|
-
// DIMENSION NARRATIVES
|
|
362
|
+
// DIMENSION NARRATIVES — Clinical, benchmarked
|
|
264
363
|
// ══════════════════════════════════════════════
|
|
265
364
|
|
|
266
365
|
export function displayNarratives(metrics, prose) {
|
|
@@ -275,10 +374,10 @@ export function displayNarratives(metrics, prose) {
|
|
|
275
374
|
|
|
276
375
|
if (prose && prose.sections) {
|
|
277
376
|
const sectionSnippetMap = {
|
|
278
|
-
'thinking': { label: '
|
|
279
|
-
'debugging': { label: '
|
|
280
|
-
'ai leverage': { label: '
|
|
281
|
-
'workflow': { label: '
|
|
377
|
+
'thinking': { label: 'Evidence', prompt: pickExample(metrics.decomposition.examples, 'decomposition') },
|
|
378
|
+
'debugging': { label: 'Evidence', prompt: pickExample(metrics.debugCycles.examples, 'specific_report') || pickExample(metrics.debugCycles.examples, 'quick_fix') },
|
|
379
|
+
'ai leverage': { label: 'Evidence', prompt: pickExample(metrics.aiLeverage.examples, 'architectural') || pickExample(metrics.aiLeverage.examples, 'planning') },
|
|
380
|
+
'workflow': { label: 'Evidence', prompt: pickExample(metrics.sessionStructure.examples, 'context_setting') || pickExample(metrics.sessionStructure.examples, 'refinement') },
|
|
282
381
|
};
|
|
283
382
|
|
|
284
383
|
for (const section of prose.sections) {
|
|
@@ -293,21 +392,17 @@ export function displayNarratives(metrics, prose) {
|
|
|
293
392
|
console.log();
|
|
294
393
|
}
|
|
295
394
|
} else {
|
|
296
|
-
|
|
395
|
+
displayDataNarratives(metrics, shownSnippets);
|
|
297
396
|
}
|
|
298
397
|
}
|
|
299
398
|
|
|
300
|
-
function
|
|
399
|
+
function displayDataNarratives(metrics, shownSnippets) {
|
|
301
400
|
const d = metrics.decomposition.details;
|
|
302
401
|
const db = metrics.debugCycles.details;
|
|
303
402
|
const ai = metrics.aiLeverage.details;
|
|
304
403
|
const ss = metrics.sessionStructure.details;
|
|
305
|
-
const dEx = metrics.decomposition.examples || [];
|
|
306
|
-
const dbEx = metrics.debugCycles.examples || [];
|
|
307
|
-
const aiEx = metrics.aiLeverage.examples || [];
|
|
308
|
-
const ssEx = metrics.sessionStructure.examples || [];
|
|
309
404
|
|
|
310
|
-
function
|
|
405
|
+
function showSnippet(label, prompt) {
|
|
311
406
|
if (!prompt) return;
|
|
312
407
|
const s = cleanPrompt(prompt, 120);
|
|
313
408
|
if (shownSnippets.has(s)) return;
|
|
@@ -315,128 +410,180 @@ function displayDataNarrativesWithTracker(metrics, shownSnippets) {
|
|
|
315
410
|
displayLabeledSnippet(label, prompt);
|
|
316
411
|
}
|
|
317
412
|
|
|
318
|
-
// Thinking
|
|
413
|
+
// Thinking — clinical
|
|
319
414
|
console.log(` ${bold('\uD83E\uDDE0 THINKING')}`);
|
|
320
|
-
|
|
321
|
-
console.log(` ${dim(
|
|
322
|
-
console.log(` ${dim(
|
|
323
|
-
|
|
324
|
-
showLabeledSnippet('Best decomposition prompt', pickExample(dEx, 'decomposition'));
|
|
415
|
+
console.log(` ${dim(`Avg session depth: ${d.avgExchangesPerSession} exchanges (benchmark: ${BENCHMARKS.avgExchangesPerSession})`)}`);
|
|
416
|
+
console.log(` ${dim(`Avg prompt length: ${numberFormat(d.avgPromptLength)} chars (benchmark: ${BENCHMARKS.avgPromptLength})`)}`);
|
|
417
|
+
console.log(` ${dim(`Multi-step ratio: ${d.multiStepSessions}/${d.totalSessions} sessions (${Math.round(d.multiStepSessions / Math.max(1, d.totalSessions) * 100)}%)`)}`);
|
|
418
|
+
showSnippet('Evidence', pickExample(metrics.decomposition.examples, 'decomposition'));
|
|
325
419
|
console.log();
|
|
326
420
|
|
|
327
|
-
// Debugging
|
|
421
|
+
// Debugging — clinical
|
|
328
422
|
console.log(` ${bold('\u26A1 DEBUGGING')}`);
|
|
329
|
-
|
|
330
|
-
console.log(` ${dim(
|
|
331
|
-
console.log(` ${dim(
|
|
332
|
-
|
|
333
|
-
showLabeledSnippet('Best debug prompt', pickExample(dbEx, 'specific_report') || pickExample(dbEx, 'quick_fix'));
|
|
423
|
+
console.log(` ${dim(`Avg resolution: ${db.avgTurnsToResolve} turns (benchmark: ${BENCHMARKS.avgTurnsToResolve})`)}`);
|
|
424
|
+
console.log(` ${dim(`Specific reports: ${db.specificReportRatio}% (benchmark: ${BENCHMARKS.specificReportRatio}%)`)}`);
|
|
425
|
+
console.log(` ${dim(`Extended loops: ${db.longLoops} | Quick fixes: ${db.quickFixes}/${db.totalDebugSequences}`)}`);
|
|
426
|
+
showSnippet('Evidence', pickExample(metrics.debugCycles.examples, 'specific_report') || pickExample(metrics.debugCycles.examples, 'quick_fix'));
|
|
334
427
|
console.log();
|
|
335
428
|
|
|
336
|
-
// AI Leverage
|
|
429
|
+
// AI Leverage — clinical
|
|
337
430
|
console.log(` ${bold('\uD83D\uDD27 AI LEVERAGE')}`);
|
|
338
|
-
console.log(` ${dim(
|
|
339
|
-
|
|
340
|
-
console.log(` ${dim(
|
|
341
|
-
|
|
342
|
-
showLabeledSnippet('Best leverage prompt', pickExample(aiEx, 'architectural') || pickExample(aiEx, 'planning'));
|
|
431
|
+
console.log(` ${dim(`High-level ratio: ${ai.highLevelRatio}% (benchmark: ${BENCHMARKS.highLevelRatio}%)`)}`);
|
|
432
|
+
console.log(` ${dim(`Breakdown: ${ai.architecturalPrompts} architectural \u00B7 ${ai.planningPrompts} planning \u00B7 ${ai.exploratoryPrompts} exploratory`)}`);
|
|
433
|
+
console.log(` ${dim(`Boilerplate: ${ai.boilerplatePrompts} (${Math.round(ai.boilerplatePrompts / Math.max(1, ai.totalPrompts) * 100)}%) \u00B7 Testing: ${ai.testingPrompts}`)}`);
|
|
434
|
+
showSnippet('Evidence', pickExample(metrics.aiLeverage.examples, 'architectural') || pickExample(metrics.aiLeverage.examples, 'planning'));
|
|
343
435
|
console.log();
|
|
344
436
|
|
|
345
|
-
// Workflow
|
|
437
|
+
// Workflow — clinical
|
|
346
438
|
console.log(` ${bold('\uD83D\uDCD0 WORKFLOW')}`);
|
|
347
|
-
console.log(` ${dim(
|
|
348
|
-
console.log(` ${dim(
|
|
349
|
-
console.log(` ${dim(
|
|
350
|
-
|
|
439
|
+
console.log(` ${dim(`Context-setting: ${ss.contextSetRatio}% (benchmark: ${BENCHMARKS.contextSetRatio}%)`)}`);
|
|
440
|
+
console.log(` ${dim(`Review at end: ${ss.reviewEndRatio}% (benchmark: ${BENCHMARKS.reviewEndRatio}%)`)}`);
|
|
441
|
+
console.log(` ${dim(`Refinement rate: ${ss.refinementRatio}% (benchmark: ${BENCHMARKS.refinementRatio}%)`)}`);
|
|
442
|
+
showSnippet('Evidence', pickExample(metrics.sessionStructure.examples, 'context_setting') || pickExample(metrics.sessionStructure.examples, 'refinement'));
|
|
351
443
|
console.log();
|
|
352
444
|
}
|
|
353
445
|
|
|
354
|
-
|
|
355
446
|
// ══════════════════════════════════════════════
|
|
356
|
-
//
|
|
447
|
+
// SIGNATURES — What makes you distinctive
|
|
357
448
|
// ══════════════════════════════════════════════
|
|
358
449
|
|
|
359
|
-
function
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
{
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
// Only show coaching if the weakest is actually dragging things down
|
|
372
|
-
if (weakest.score >= 70) return;
|
|
373
|
-
|
|
374
|
-
const tips = {
|
|
375
|
-
decomposition: 'Break complex tasks into subtasks before prompting.\nEngineers who decompose problems score 15+ points higher.',
|
|
376
|
-
debugCycles: 'Include specific error messages and stack traces in debug prompts.\nPrecise reports resolve 2x faster than "it\'s broken, fix it."',
|
|
377
|
-
aiLeverage: 'Use AI for architecture and planning, not just code generation.\nAsk "what\'s the best approach" before "write the code."',
|
|
378
|
-
sessionStructure: 'Set context at the start of each session and review at the end.\nEngineers who do this score 12 points higher on average.',
|
|
379
|
-
};
|
|
380
|
-
|
|
381
|
-
console.log(` ${bold('\uD83D\uDCA1 TO LEVEL UP')}`);
|
|
382
|
-
console.log(` ${dim(`Your ${weakest.label} score (${weakest.score}) is your biggest opportunity.`)}`);
|
|
383
|
-
const tipLines = tips[weakest.key].split('\n');
|
|
384
|
-
for (const line of tipLines) {
|
|
385
|
-
console.log(` ${dim(line)}`);
|
|
450
|
+
function displaySignatures(insights) {
|
|
451
|
+
const sigs = insights?.signatures;
|
|
452
|
+
if (!sigs || sigs.length === 0) return;
|
|
453
|
+
|
|
454
|
+
console.log(dim(' YOUR SIGNATURES\n'));
|
|
455
|
+
for (const sig of sigs) {
|
|
456
|
+
console.log(` ${cyan('\u2726')} ${bold(sig.name)}`);
|
|
457
|
+
const lines = wrapText(sig.detail, 49);
|
|
458
|
+
for (const line of lines) {
|
|
459
|
+
console.log(` ${dim(line)}`);
|
|
460
|
+
}
|
|
461
|
+
console.log();
|
|
386
462
|
}
|
|
387
|
-
console.log();
|
|
388
463
|
}
|
|
389
464
|
|
|
390
|
-
|
|
391
465
|
// ══════════════════════════════════════════════
|
|
392
|
-
//
|
|
466
|
+
// WATCH POINTS — Areas to improve
|
|
393
467
|
// ══════════════════════════════════════════════
|
|
394
468
|
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const eggs = [];
|
|
469
|
+
function displayWatchPoints(insights) {
|
|
470
|
+
const wps = insights?.watchPoints;
|
|
471
|
+
if (!wps || wps.length === 0) return;
|
|
400
472
|
|
|
401
|
-
|
|
402
|
-
|
|
473
|
+
console.log(dim(' WATCH POINTS\n'));
|
|
474
|
+
for (const wp of wps) {
|
|
475
|
+
console.log(` ${orange('\u26A0')} ${bold(wp.name)}`);
|
|
476
|
+
const lines = wrapText(wp.detail, 49);
|
|
477
|
+
for (const line of lines) {
|
|
478
|
+
console.log(` ${dim(line)}`);
|
|
479
|
+
}
|
|
480
|
+
console.log();
|
|
403
481
|
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// ══════════════════════════════════════════════
|
|
485
|
+
// TRAJECTORY — Weekly evolution
|
|
486
|
+
// ══════════════════════════════════════════════
|
|
404
487
|
|
|
405
|
-
|
|
406
|
-
|
|
488
|
+
function displayTrajectory(insights) {
|
|
489
|
+
const traj = insights?.trajectory;
|
|
490
|
+
if (!traj) return;
|
|
491
|
+
|
|
492
|
+
console.log(dim(' YOUR TRAJECTORY\n'));
|
|
493
|
+
for (let i = 0; i < traj.weeks.length; i++) {
|
|
494
|
+
const w = traj.weeks[i];
|
|
495
|
+
const prev = i > 0 ? traj.weeks[i - 1] : null;
|
|
496
|
+
const arrow = prev ? (w.score > prev.score ? green(' \u2191') : w.score < prev.score ? orange(' \u2193') : dim(' \u2192')) : '';
|
|
497
|
+
const tierLabel = dimTierLabel(w.score);
|
|
498
|
+
console.log(` ${dim(pad(w.label, 16))} Score: ${scoreColor(w.score).bold(String(w.score))} ${dimTierColor(w.score)(tierLabel)}${arrow}`);
|
|
407
499
|
}
|
|
500
|
+
console.log();
|
|
501
|
+
const velColor = traj.velocityLabel === 'FAST' ? green : traj.velocityLabel === 'STEADY' ? cyan : traj.velocityLabel === 'STABLE' ? yellow : orange;
|
|
502
|
+
console.log(` ${dim('Learning velocity:')} ${velColor(traj.velocityLabel)} ${dim('\u2014 ' + traj.velocityDetail)}`);
|
|
503
|
+
console.log();
|
|
504
|
+
}
|
|
408
505
|
|
|
409
|
-
|
|
410
|
-
|
|
506
|
+
// ══════════════════════════════════════════════
|
|
507
|
+
// ASSESSMENT — Narrative paragraph
|
|
508
|
+
// ══════════════════════════════════════════════
|
|
509
|
+
|
|
510
|
+
function displayAssessment(insights) {
|
|
511
|
+
const assessment = insights?.assessment;
|
|
512
|
+
if (!assessment) return;
|
|
513
|
+
|
|
514
|
+
console.log(dim(' ASSESSMENT\n'));
|
|
515
|
+
const lines = wrapText(assessment, 51);
|
|
516
|
+
for (const line of lines) {
|
|
517
|
+
console.log(` ${dim(line)}`);
|
|
411
518
|
}
|
|
519
|
+
console.log();
|
|
520
|
+
}
|
|
412
521
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
522
|
+
// ══════════════════════════════════════════════
|
|
523
|
+
// CONFIDENCE INDICATOR
|
|
524
|
+
// ══════════════════════════════════════════════
|
|
525
|
+
|
|
526
|
+
function displayConfidence(insights, sessionStats) {
|
|
527
|
+
const conf = insights?.confidence;
|
|
528
|
+
if (!conf) return;
|
|
529
|
+
|
|
530
|
+
const barWidth = 18;
|
|
531
|
+
const filled = Math.round((conf.score / 100) * barWidth);
|
|
532
|
+
const empty = barWidth - filled;
|
|
533
|
+
const confColor = conf.level === 'HIGH' ? green : conf.level === 'MODERATE' ? yellow : orange;
|
|
534
|
+
const bar = confColor('\u2588'.repeat(filled)) + dim('\u2591'.repeat(empty));
|
|
535
|
+
|
|
536
|
+
console.log(` ${dim('Profile confidence:')} ${bar} ${confColor(conf.level)}`);
|
|
537
|
+
if (sessionStats) {
|
|
538
|
+
console.log(` ${dim(`Based on ${sessionStats.totalSessions} sessions across ${sessionStats.tools.length} tool${sessionStats.tools.length > 1 ? 's' : ''}.`)}`);
|
|
539
|
+
}
|
|
540
|
+
console.log();
|
|
541
|
+
if (conf.level !== 'HIGH') {
|
|
542
|
+
console.log(` ${dim('Confidence increases with more sessions and tool')}`);
|
|
543
|
+
console.log(` ${dim('diversity. Run again in 30 days for updated assessment.')}`);
|
|
417
544
|
console.log();
|
|
418
545
|
}
|
|
419
546
|
}
|
|
420
547
|
|
|
421
548
|
// ══════════════════════════════════════════════
|
|
422
|
-
//
|
|
549
|
+
// METHODOLOGY FOOTER
|
|
423
550
|
// ══════════════════════════════════════════════
|
|
424
551
|
|
|
425
|
-
|
|
552
|
+
function displayMethodology() {
|
|
553
|
+
console.log(doubleRule());
|
|
554
|
+
console.log();
|
|
555
|
+
console.log(` ${dim('METHODOLOGY')}`);
|
|
556
|
+
console.log(` ${dim('Scores derived from structural analysis of prompt')}`);
|
|
557
|
+
console.log(` ${dim('patterns, debug sequences, and session architecture')}`);
|
|
558
|
+
console.log(` ${dim('across detected AI coding tools. Tier placement based')}`);
|
|
559
|
+
console.log(` ${dim('on distribution of scored engineers. No prompt content')}`);
|
|
560
|
+
console.log(` ${dim('is stored or transmitted. Learn more: chekk.dev/methodology')}`);
|
|
561
|
+
console.log();
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// ══════════════════════════════════════════════
|
|
565
|
+
// NEXT STEPS — Credential issuance
|
|
566
|
+
// ══════════════════════════════════════════════
|
|
567
|
+
|
|
568
|
+
function displayNextSteps(result) {
|
|
426
569
|
const { overall, archetype, tier, tierBadge } = result;
|
|
427
570
|
const tc = tierColor(tier);
|
|
428
571
|
|
|
429
572
|
console.log(doubleRule());
|
|
430
573
|
console.log();
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
console.log(` ${dim('\u2192 Claim your profile
|
|
434
|
-
console.log(`
|
|
435
|
-
console.log(`
|
|
436
|
-
console.log(`
|
|
437
|
-
console.log(
|
|
574
|
+
console.log(` ${bold.white('NEXT STEPS')}`);
|
|
575
|
+
console.log();
|
|
576
|
+
console.log(` ${dim('\u2192 Claim your verified profile')}`);
|
|
577
|
+
console.log(` ${dim('Link your GitHub and LinkedIn to create your')}`);
|
|
578
|
+
console.log(` ${dim('portable engineering credential.')}`);
|
|
579
|
+
console.log(` ${cyan.underline('chekk.dev/claim')}`);
|
|
580
|
+
console.log();
|
|
581
|
+
console.log(` ${dim('\u2192 View industry benchmarks')}`);
|
|
582
|
+
console.log(` ${dim('See how you compare across scored engineers.')}`);
|
|
583
|
+
console.log(` ${cyan.underline('chekk.dev/benchmarks')}`);
|
|
438
584
|
console.log();
|
|
439
|
-
console.log(` ${dim('\u2192
|
|
585
|
+
console.log(` ${dim('\u2192 Export this report')}`);
|
|
586
|
+
console.log(` ${dim('npx chekk --json')}`);
|
|
440
587
|
console.log();
|
|
441
588
|
|
|
442
589
|
// Copy-paste share line
|
|
@@ -446,12 +593,12 @@ export function displayEnding(result) {
|
|
|
446
593
|
console.log(` ${dim('\u2191 Copy this to share')}`);
|
|
447
594
|
console.log();
|
|
448
595
|
console.log(doubleRule());
|
|
449
|
-
console.log(` ${dim('chekk.dev \u2014
|
|
596
|
+
console.log(` ${dim('chekk.dev \u2014 engineering capability profiles')}`);
|
|
450
597
|
console.log();
|
|
451
598
|
}
|
|
452
599
|
|
|
453
600
|
// ══════════════════════════════════════════════
|
|
454
|
-
// VERBOSE: DETAILED BREAKDOWN
|
|
601
|
+
// VERBOSE: DETAILED BREAKDOWN
|
|
455
602
|
// ══════════════════════════════════════════════
|
|
456
603
|
|
|
457
604
|
export function displayVerbose(metrics, sessions) {
|
|
@@ -475,72 +622,77 @@ export function displayVerbose(metrics, sessions) {
|
|
|
475
622
|
}
|
|
476
623
|
console.log();
|
|
477
624
|
|
|
478
|
-
// Decomposition
|
|
625
|
+
// Decomposition
|
|
479
626
|
const d = metrics.decomposition.details;
|
|
480
|
-
console.log(bold(' DECOMPOSITION
|
|
481
|
-
console.log(` ${dim(pad('
|
|
482
|
-
console.log(` ${dim(pad('
|
|
483
|
-
console.log(` ${dim(pad('
|
|
484
|
-
console.log(` ${dim(pad('
|
|
485
|
-
console.log(` ${dim(pad('
|
|
486
|
-
console.log(` ${dim(pad('longPromptRatio', 30))} ${dim(d.longPromptRatio + '%')}`);
|
|
487
|
-
console.log(` ${dim(pad('contextualFollowupRatio', 30))} ${dim(d.contextualFollowupRatio + '%')} ${dim(d.contextualFollowupRatio > 20 ? '\u2014 builds on previous context well' : '\u2014 could reference prior context more')}`);
|
|
627
|
+
console.log(bold(' DECOMPOSITION'));
|
|
628
|
+
console.log(` ${dim(pad('Avg session depth', 30))} ${dim(String(d.avgExchangesPerSession))} ${dim(`(benchmark: ${BENCHMARKS.avgExchangesPerSession})`)}`);
|
|
629
|
+
console.log(` ${dim(pad('Avg prompt length', 30))} ${dim(d.avgPromptLength + ' chars')} ${dim(`(benchmark: ${BENCHMARKS.avgPromptLength})`)}`);
|
|
630
|
+
console.log(` ${dim(pad('Multi-step sessions', 30))} ${dim(String(d.multiStepSessions) + '/' + d.totalSessions)} ${dim(d.multiStepSessions > d.totalSessions * 0.5 ? '\u2014 strong' : '\u2014 room to grow')}`);
|
|
631
|
+
console.log(` ${dim(pad('Single-shot sessions', 30))} ${dim(String(d.singleShotSessions))}`);
|
|
632
|
+
console.log(` ${dim(pad('Contextual followups', 30))} ${dim(d.contextualFollowupRatio + '%')} ${dim(d.contextualFollowupRatio > 20 ? '\u2014 builds on context well' : '\u2014 could reference prior work more')}`);
|
|
488
633
|
console.log();
|
|
489
634
|
|
|
490
|
-
// Debug
|
|
635
|
+
// Debug
|
|
491
636
|
const db = metrics.debugCycles.details;
|
|
492
|
-
console.log(bold(' DEBUG
|
|
493
|
-
console.log(` ${dim(pad('
|
|
494
|
-
console.log(` ${dim(pad('
|
|
495
|
-
console.log(` ${dim(pad('
|
|
496
|
-
console.log(` ${dim(pad('
|
|
497
|
-
console.log(` ${dim(pad('
|
|
498
|
-
console.log(` ${dim(pad('
|
|
637
|
+
console.log(bold(' DEBUG CYCLES'));
|
|
638
|
+
console.log(` ${dim(pad('Total sequences', 30))} ${dim(String(db.totalDebugSequences))}`);
|
|
639
|
+
console.log(` ${dim(pad('Avg turns to resolve', 30))} ${dim(String(db.avgTurnsToResolve))} ${dim(`(benchmark: ${BENCHMARKS.avgTurnsToResolve})`)}`);
|
|
640
|
+
console.log(` ${dim(pad('Quick fixes (\u22642 turns)', 30))} ${dim(String(db.quickFixes))}`);
|
|
641
|
+
console.log(` ${dim(pad('Extended loops (>5 turns)', 30))} ${dim(String(db.longLoops))} ${dim(db.longLoops === 0 ? '\u2014 zero spirals' : '')}`);
|
|
642
|
+
console.log(` ${dim(pad('Specific report ratio', 30))} ${dim(db.specificReportRatio + '%')} ${dim(`(benchmark: ${BENCHMARKS.specificReportRatio}%)`)}`);
|
|
643
|
+
console.log(` ${dim(pad('Vague reports', 30))} ${dim(String(db.vagueReports))} ${dim(db.vagueReports === 0 ? '\u2014 never vague' : '')}`);
|
|
499
644
|
console.log();
|
|
500
645
|
|
|
501
|
-
// AI Leverage
|
|
646
|
+
// AI Leverage
|
|
502
647
|
const ai = metrics.aiLeverage.details;
|
|
503
|
-
console.log(bold(' AI LEVERAGE
|
|
504
|
-
console.log(` ${dim(pad('
|
|
505
|
-
console.log(` ${dim(pad('
|
|
506
|
-
console.log(` ${dim(pad('
|
|
507
|
-
console.log(` ${dim(pad('
|
|
508
|
-
console.log(` ${dim(pad('
|
|
509
|
-
console.log(` ${dim(pad('
|
|
510
|
-
console.log(` ${dim(pad('
|
|
511
|
-
console.log(
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
// Session structure details
|
|
648
|
+
console.log(bold(' AI LEVERAGE'));
|
|
649
|
+
console.log(` ${dim(pad('Total prompts', 30))} ${dim(numberFormat(ai.totalPrompts))}`);
|
|
650
|
+
console.log(` ${dim(pad('Architectural', 30))} ${dim(String(ai.architecturalPrompts))} ${dim(`(${Math.round(ai.architecturalPrompts / Math.max(1, ai.totalPrompts) * 100)}%)`)}`);
|
|
651
|
+
console.log(` ${dim(pad('Planning', 30))} ${dim(String(ai.planningPrompts))} ${dim(`(${Math.round(ai.planningPrompts / Math.max(1, ai.totalPrompts) * 100)}%)`)}`);
|
|
652
|
+
console.log(` ${dim(pad('Exploratory', 30))} ${dim(String(ai.exploratoryPrompts))} ${dim(`(${Math.round(ai.exploratoryPrompts / Math.max(1, ai.totalPrompts) * 100)}%)`)}`);
|
|
653
|
+
console.log(` ${dim(pad('Boilerplate', 30))} ${dim(String(ai.boilerplatePrompts))} ${dim(`(${Math.round(ai.boilerplatePrompts / Math.max(1, ai.totalPrompts) * 100)}%)`)} ${dim(ai.boilerplatePrompts < ai.totalPrompts * 0.05 ? '\u2014 minimal' : '')}`);
|
|
654
|
+
console.log(` ${dim(pad('Testing', 30))} ${dim(String(ai.testingPrompts))}`);
|
|
655
|
+
console.log(` ${dim(pad('High-level ratio', 30))} ${dim(ai.highLevelRatio + '%')} ${dim(`(benchmark: ${BENCHMARKS.highLevelRatio}%)`)}`);
|
|
656
|
+
console.log();
|
|
657
|
+
|
|
658
|
+
// Session structure
|
|
516
659
|
const ss = metrics.sessionStructure.details;
|
|
517
|
-
console.log(bold(' SESSION STRUCTURE
|
|
518
|
-
console.log(` ${dim(pad('
|
|
519
|
-
console.log(` ${dim(pad('
|
|
520
|
-
console.log(` ${dim(pad('
|
|
521
|
-
console.log(` ${dim(pad('
|
|
522
|
-
console.log(` ${dim(pad('
|
|
660
|
+
console.log(bold(' SESSION STRUCTURE'));
|
|
661
|
+
console.log(` ${dim(pad('Context-setting', 30))} ${dim(ss.contextSetRatio + '%')} ${dim(`(benchmark: ${BENCHMARKS.contextSetRatio}%)`)}`);
|
|
662
|
+
console.log(` ${dim(pad('Plan before code', 30))} ${dim(ss.planBeforeCodeRatio + '%')}`);
|
|
663
|
+
console.log(` ${dim(pad('Review at end', 30))} ${dim(ss.reviewEndRatio + '%')} ${dim(`(benchmark: ${BENCHMARKS.reviewEndRatio}%)`)}`);
|
|
664
|
+
console.log(` ${dim(pad('Refinement rate', 30))} ${dim(ss.refinementRatio + '%')} ${dim(`(benchmark: ${BENCHMARKS.refinementRatio}%)`)}`);
|
|
665
|
+
console.log(` ${dim(pad('Avg first prompt', 30))} ${dim(ss.avgFirstPromptLength + ' chars')}`);
|
|
523
666
|
if (ss.durationDistribution) {
|
|
524
667
|
const dur = ss.durationDistribution;
|
|
525
|
-
console.log(` ${dim(pad('
|
|
526
|
-
console.log(` ${dim(pad('
|
|
527
|
-
console.log(` ${dim(pad('
|
|
528
|
-
console.log(` ${dim(pad('
|
|
668
|
+
console.log(` ${dim(pad('Focused sessions (10-45m)', 30))} ${dim(String(dur.focused))}`);
|
|
669
|
+
console.log(` ${dim(pad('Short (<5m)', 30))} ${dim(String(dur.short))}`);
|
|
670
|
+
console.log(` ${dim(pad('Medium (5-60m)', 30))} ${dim(String(dur.medium))}`);
|
|
671
|
+
console.log(` ${dim(pad('Long (>60m)', 30))} ${dim(String(dur.long))}`);
|
|
529
672
|
}
|
|
530
673
|
console.log();
|
|
531
674
|
}
|
|
532
675
|
|
|
533
676
|
// ══════════════════════════════════════════════
|
|
534
|
-
// OFFLINE DISPLAY
|
|
677
|
+
// OFFLINE DISPLAY
|
|
535
678
|
// ══════════════════════════════════════════════
|
|
536
679
|
|
|
537
680
|
export function displayOffline(result, metrics, extra = {}) {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
681
|
+
displayProfileHeader(result, extra);
|
|
682
|
+
displaySummary(result, extra);
|
|
683
|
+
displayArchetype(result);
|
|
684
|
+
displayDimensions(result);
|
|
685
|
+
displayCrossPlatform(extra.perToolScores);
|
|
686
|
+
displayDataNarratives(metrics, new Set());
|
|
687
|
+
displayProjects(extra.insights);
|
|
688
|
+
displaySignatures(extra.insights);
|
|
689
|
+
displayWatchPoints(extra.insights);
|
|
690
|
+
displayTrajectory(extra.insights);
|
|
691
|
+
displayAssessment(extra.insights);
|
|
692
|
+
displayConfidence(extra.insights, extra.sessionStats);
|
|
693
|
+
displayMethodology();
|
|
694
|
+
console.log(dim(' Run without --offline for AI-generated narrative insights\n'));
|
|
695
|
+
displayNextSteps(result);
|
|
544
696
|
}
|
|
545
697
|
|
|
546
698
|
// ══════════════════════════════════════════════
|
|
@@ -548,11 +700,20 @@ export function displayOffline(result, metrics, extra = {}) {
|
|
|
548
700
|
// ══════════════════════════════════════════════
|
|
549
701
|
|
|
550
702
|
export function displayFull(result, metrics, prose, extra = {}) {
|
|
551
|
-
|
|
703
|
+
displayProfileHeader(result, extra);
|
|
704
|
+
displaySummary(result, extra);
|
|
705
|
+
displayArchetype(result);
|
|
706
|
+
displayDimensions(result);
|
|
707
|
+
displayCrossPlatform(extra.perToolScores);
|
|
552
708
|
displayNarratives(metrics, prose);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
709
|
+
displayProjects(extra.insights);
|
|
710
|
+
displaySignatures(extra.insights);
|
|
711
|
+
displayWatchPoints(extra.insights);
|
|
712
|
+
displayTrajectory(extra.insights);
|
|
713
|
+
displayAssessment(extra.insights);
|
|
714
|
+
displayConfidence(extra.insights, extra.sessionStats);
|
|
715
|
+
displayMethodology();
|
|
716
|
+
displayNextSteps(result);
|
|
556
717
|
}
|
|
557
718
|
|
|
558
719
|
// ── Utility ──
|