llm-checker 3.5.14 → 3.5.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-checker",
3
- "version": "3.5.14",
3
+ "version": "3.5.15",
4
4
  "description": "Intelligent CLI tool with AI-powered model selection that analyzes your hardware and recommends optimal LLM models for your system",
5
5
  "bin": {
6
6
  "llm-checker": "bin/cli.js",
@@ -4,6 +4,7 @@ const chalk = require('chalk');
4
4
  const { execFileSync } = require('child_process');
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
+ const readline = require('readline');
7
8
 
8
9
  // Adapted from /Users/pchmirenko/Downloads/ascii-motion-cli.tsx frame model.
9
10
  const THEME_DARK = {
@@ -41,6 +42,8 @@ const FRAMES_PER_SECOND = 14;
41
42
  // Security: do not auto-load executable-style banner sources from user-writable folders.
42
43
  // External banner loading is opt-in via LLM_CHECKER_BANNER_SOURCE and supports JSON only.
43
44
  const DEFAULT_BANNER_SOURCE = null;
45
+ // Canonical startup banner asset. Do not edit casually: treat as product identity.
46
+ // Any intentional change should update tests/banner-canonical.test.js in the same commit.
44
47
  const BUNDLED_TEXT_BANNER_SOURCE = path.join(__dirname, 'banner-profesional-v2.txt');
45
48
  const DEFAULT_TEXT_BANNER_SOURCES = [
46
49
  BUNDLED_TEXT_BANNER_SOURCE
@@ -79,7 +82,14 @@ function sleep(ms) {
79
82
  }
80
83
 
81
84
  function clearTerminal() {
82
- process.stdout.write('\x1b[2J\x1b[0f');
85
+ if (!process.stdout.isTTY) return;
86
+
87
+ try {
88
+ readline.cursorTo(process.stdout, 0, 0);
89
+ readline.clearScreenDown(process.stdout);
90
+ } catch {
91
+ process.stdout.write('\x1b[2J\x1b[H');
92
+ }
83
93
  }
84
94
 
85
95
  function parseDarkBackgroundValue(value) {
@@ -32,7 +32,14 @@ const REQUIRED_ARG_PROMPTS = {
32
32
  };
33
33
 
34
34
  function clearTerminal() {
35
- process.stdout.write('\x1b[2J\x1b[0f');
35
+ if (!process.stdout.isTTY) return;
36
+
37
+ try {
38
+ readline.cursorTo(process.stdout, 0, 0);
39
+ readline.clearScreenDown(process.stdout);
40
+ } catch {
41
+ process.stdout.write('\x1b[2J\x1b[H');
42
+ }
36
43
  }
37
44
 
38
45
  function truncateText(text, maxLength) {
@@ -311,6 +318,18 @@ function renderPanel(state, catalog, primaryCommands, options = {}) {
311
318
  );
312
319
  }
313
320
 
321
+ function shouldEnableBannerPulse({
322
+ isTTY = process.stdout.isTTY,
323
+ disableAnimation = process.env.LLM_CHECKER_DISABLE_ANIMATION,
324
+ forcePulse = process.env.LLM_CHECKER_FORCE_PANEL_PULSE,
325
+ platform = process.platform
326
+ } = {}) {
327
+ if (!isTTY) return false;
328
+ if (disableAnimation === '1') return false;
329
+ if (forcePulse === '1') return true;
330
+ return platform !== 'win32';
331
+ }
332
+
314
333
  async function collectCommandArgs(commandMeta) {
315
334
  const prompts = [];
316
335
  const requiredPrompts = REQUIRED_ARG_PROMPTS[commandMeta.name] || [];
@@ -421,9 +440,7 @@ async function launchInteractivePanel(options) {
421
440
  readline.emitKeypressEvents(process.stdin);
422
441
 
423
442
  return new Promise((resolve) => {
424
- const shouldPulseBanner =
425
- process.stdout.isTTY &&
426
- process.env.LLM_CHECKER_DISABLE_ANIMATION !== '1';
443
+ const shouldPulseBanner = shouldEnableBannerPulse();
427
444
  let pulseTimer = null;
428
445
 
429
446
  const stopBannerPulse = () => {
@@ -578,6 +595,7 @@ module.exports = {
578
595
  buildCommandCatalog,
579
596
  buildPrimaryCommands,
580
597
  getVisibleCommands,
581
- truncateText
598
+ truncateText,
599
+ shouldEnableBannerPulse
582
600
  }
583
601
  };