chekk 0.5.4 → 0.5.5

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 CHANGED
@@ -4,7 +4,7 @@ import { execSync, spawn } from 'child_process';
4
4
  import { Command } from 'commander';
5
5
  import { run } from '../src/index.js';
6
6
 
7
- const LOCAL_VERSION = '0.5.4';
7
+ const LOCAL_VERSION = '0.5.5';
8
8
 
9
9
  // ── Auto-update check ──
10
10
  // If running from a cached npx install, check if there's a newer version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chekk",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "See how you prompt. Chekk analyzes your AI coding workflow, tells you what kind of engineer you are, and shows what your habits actually cost.",
5
5
  "bin": {
6
6
  "chekk": "./bin/chekk.js"
package/src/display.js CHANGED
@@ -173,7 +173,7 @@ export function displayHeader() {
173
173
  console.log();
174
174
  const lines = [
175
175
  '',
176
- ` ${bold.white('chekk')}${dim(' v0.5.4')}`,
176
+ ` ${bold.white('chekk')}${dim(' v0.5.5')}`,
177
177
  ` ${dim('prompt engineering capability profile')}`,
178
178
  '',
179
179
  ];
@@ -231,7 +231,7 @@ function displayProfileHeader(result, extra = {}) {
231
231
  console.log(` ${bold.white('PROMPT ENGINEERING CAPABILITY PROFILE')}`);
232
232
  console.log();
233
233
  if (sessionStats) {
234
- console.log(` ${dim(`Generated ${dateStr} | chekk v0.5.4`)}`);
234
+ console.log(` ${dim(`Generated ${dateStr} | chekk v0.5.5`)}`);
235
235
  console.log(` ${dim(`Analysis: ${sessionStats.totalSessions} sessions \u00B7 ${sessionStats.tools.length} tool${sessionStats.tools.length > 1 ? 's' : ''} \u00B7 ${numberFormat(sessionStats.totalExchanges)} exchanges`)}`);
236
236
  if (sessionStats.dateRangeShort) {
237
237
  console.log(` ${dim(`Period: ${sessionStats.dateRangeShort}`)}`);
package/src/index.js CHANGED
@@ -2,6 +2,7 @@ import chalk from 'chalk';
2
2
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
3
  import { join } from 'path';
4
4
  import { homedir } from 'os';
5
+ import { spawn as spawnProcess } from 'child_process';
5
6
  import { detectTools } from './detect.js';
6
7
  import { parseAllProjects } from './parsers/claude-code.js';
7
8
  import { parseAllWorkspaces } from './parsers/cursor.js';
@@ -204,15 +205,13 @@ export async function run(options = {}) {
204
205
  }
205
206
 
206
207
  // ── Step 5: Display results ──
207
- // Track line count so we can scroll back to top when done
208
- let lineCount = 0;
208
+ // Capture output to a buffer so we can page it from the top
209
+ const outputChunks = [];
209
210
  const origWrite = process.stdout.write.bind(process.stdout);
210
- process.stdout.write = function(chunk, ...args) {
211
- if (typeof chunk === 'string') {
212
- lineCount += (chunk.match(/\n/g) || []).length;
213
- }
214
- return origWrite(chunk, ...args);
215
- };
211
+ const origLog = console.log.bind(console);
212
+ const capture = (chunk) => { outputChunks.push(typeof chunk === 'string' ? chunk : String(chunk)); };
213
+ process.stdout.write = function(chunk, ...args) { capture(chunk); return true; };
214
+ console.log = function(...args) { capture(args.join(' ') + '\n'); };
216
215
 
217
216
  const extra = { scoreDelta, perToolScores, insights, sessionStats, tokenEfficiency };
218
217
  if (options.offline) {
@@ -221,10 +220,38 @@ export async function run(options = {}) {
221
220
  displayFull(result, metrics, prose, extra);
222
221
  }
223
222
 
224
- // ── Step 6: Verbose prompt (interactive) ──
223
+ // Include verbose in the paged output
225
224
  if (options.verbose) {
226
225
  displayVerbose(metrics, allSessions, tokenEfficiency);
226
+ }
227
+
228
+ // Restore stdout
229
+ process.stdout.write = origWrite;
230
+ console.log = origLog;
231
+
232
+ const fullOutput = outputChunks.join('');
233
+
234
+ // ── Page output through less (or fallback to direct print) ──
235
+ if (process.stdout.isTTY && !options.json) {
236
+ await new Promise((resolve) => {
237
+ const pager = spawnProcess('less', ['-R', '--quit-if-one-screen'], {
238
+ stdio: ['pipe', process.stdout, process.stderr],
239
+ });
240
+ pager.stdin.write(fullOutput);
241
+ pager.stdin.end();
242
+ pager.on('error', () => {
243
+ // less not available — just print directly
244
+ process.stdout.write(fullOutput);
245
+ resolve();
246
+ });
247
+ pager.on('exit', () => resolve());
248
+ });
227
249
  } else {
250
+ process.stdout.write(fullOutput);
251
+ }
252
+
253
+ // ── Step 6: Verbose prompt (interactive, if not already shown) ──
254
+ if (!options.verbose) {
228
255
  try {
229
256
  const wantsVerbose = await askVerbose();
230
257
  if (wantsVerbose) {
@@ -261,13 +288,6 @@ export async function run(options = {}) {
261
288
  console.log();
262
289
  }
263
290
  }
264
-
265
- // ── Scroll to top of output ──
266
- // Restore original write and scroll terminal back so profile starts at top
267
- process.stdout.write = origWrite;
268
- if (lineCount > 0 && process.stdout.isTTY) {
269
- process.stdout.write(`\x1b[${lineCount}A`);
270
- }
271
291
  }
272
292
 
273
293
  function formatDateRange(start, end) {