prior-cli 1.3.9 → 1.3.10

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.
Files changed (2) hide show
  1. package/bin/prior.js +52 -43
  2. package/package.json +1 -1
package/bin/prior.js CHANGED
@@ -628,27 +628,56 @@ async function startChat(opts = {}) {
628
628
  { cmd: '/exit', desc: 'Exit' },
629
629
  ];
630
630
 
631
- let _suggCount = 0;
632
- let _suggTimer = null;
631
+ // Unified sub-row tracker — covers image indicator + slash suggestions
632
+ let _subRowCount = 0;
633
+ let _suggTimer = null;
633
634
 
634
- clearSuggestions = function () {
635
- if (_suggCount === 0) return;
635
+ // Clear all rows rendered below the input line
636
+ function clearAllSubRows() {
637
+ if (!_subRowCount) return;
636
638
  process.stdout.write('\x1b[s');
637
- for (let i = 0; i < _suggCount; i++) process.stdout.write('\x1b[B\r\x1b[2K');
639
+ for (let i = 0; i < _subRowCount; i++) process.stdout.write('\x1b[B\r\x1b[2K');
638
640
  process.stdout.write('\x1b[u');
639
- _suggCount = 0;
640
- };
641
+ _subRowCount = 0;
642
+ }
641
643
 
642
- function renderSuggestions(matches) {
643
- clearSuggestions();
644
- if (!matches.length) return;
645
- _suggCount = matches.length;
646
- process.stdout.write('\x1b[s'); // save cursor at end of typed input
647
- for (const { cmd, desc } of matches) {
648
- // \x1b[B = cursor down 1 (no scroll), \r = col 0, \x1b[2K = clear line
649
- process.stdout.write(`\x1b[B\r\x1b[2K${c.brand(' ' + cmd.padEnd(14))}${c.dim(desc)}`);
644
+ // Alias used by the loop's rl.question callback
645
+ clearSuggestions = clearAllSubRows;
646
+
647
+ // Redraw image indicator + slash suggestions — always called together so
648
+ // they share the same row-count and never stomp on each other.
649
+ function renderSubRows(line) {
650
+ clearAllSubRows();
651
+ process.stdout.write('\x1b[s');
652
+ let rows = 0;
653
+
654
+ // Image indicator — always first, persists across backspace/typing
655
+ if (_pendingImageBase64) {
656
+ process.stdout.write(`\x1b[B\r\x1b[2K ${c.brand('◈')} ${c.dim('[Image] attached · alt+v to replace · type your prompt and press enter')}`);
657
+ rows++;
658
+ }
659
+
660
+ // Slash-command suggestions
661
+ if ((line || '').startsWith('/')) {
662
+ const word = line.split(' ')[0];
663
+ const matches = SLASH_CMDS.filter(({ cmd }) => cmd.startsWith(word));
664
+ for (const { cmd, desc } of matches) {
665
+ process.stdout.write(`\x1b[B\r\x1b[2K${c.brand(' ' + cmd.padEnd(14))}${c.dim(desc)}`);
666
+ rows++;
667
+ }
650
668
  }
651
- process.stdout.write('\x1b[u'); // restore cursor to end of typed input
669
+
670
+ process.stdout.write('\x1b[u');
671
+ _subRowCount = rows;
672
+ }
673
+
674
+ // Show a one-off message below the input (cleared on next keypress)
675
+ function flashSubRow(msg) {
676
+ clearAllSubRows();
677
+ process.stdout.write('\x1b[s');
678
+ process.stdout.write(`\x1b[B\r\x1b[2K ${msg}`);
679
+ process.stdout.write('\x1b[u');
680
+ _subRowCount = 1;
652
681
  }
653
682
 
654
683
  process.stdin.on('keypress', (ch, key) => {
@@ -661,52 +690,32 @@ async function startChat(opts = {}) {
661
690
  return;
662
691
  }
663
692
 
664
- // Alt+V — paste image from clipboard
693
+ // Alt+V — grab image from Windows clipboard
665
694
  if (key.meta && key.name === 'v') {
666
695
  try {
667
696
  const ps = `Add-Type -AssemblyName System.Windows.Forms; $img = [System.Windows.Forms.Clipboard]::GetImage(); if ($img) { $ms = New-Object System.IO.MemoryStream; $img.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png); [Convert]::ToBase64String($ms.ToArray()) } else { '' }`;
668
697
  const b64 = execSync(`powershell -NoProfile -Command "${ps}"`, { timeout: 5000 }).toString().trim();
669
698
  if (b64) {
670
699
  _pendingImageBase64 = b64;
671
- // Print the indicator below the current input line
672
- process.stdout.write('\x1b[s');
673
- process.stdout.write(`\x1b[B\r\x1b[2K ${c.brand('◈')} ${c.dim('image from clipboard attached — type your prompt and press enter')}`);
674
- process.stdout.write('\x1b[u');
700
+ renderSubRows(rl.line || ''); // immediate redraw with indicator
675
701
  } else {
676
- process.stdout.write('\x1b[s');
677
- process.stdout.write(`\x1b[B\r\x1b[2K ${c.muted('✗ No image found in clipboard')}`);
678
- process.stdout.write('\x1b[u');
702
+ flashSubRow(c.muted('✗ No image found in clipboard'));
679
703
  }
680
704
  } catch {
681
- process.stdout.write('\x1b[s');
682
- process.stdout.write(`\x1b[B\r\x1b[2K ${c.muted('✗ Could not read clipboard')}`);
683
- process.stdout.write('\x1b[u');
705
+ flashSubRow(c.muted('✗ Could not read clipboard'));
684
706
  }
685
707
  return;
686
708
  }
687
709
 
688
710
  if (key.name === 'return' || key.name === 'enter' || (key.ctrl && key.name === 'c')) {
689
- // Clear suggestions and image indicator before readline moves cursor
690
- const clearRows = _suggCount + (_pendingImageBase64 ? 1 : 0);
691
- if (clearRows > 0) {
692
- process.stdout.write('\x1b[s');
693
- for (let i = 0; i < clearRows; i++) process.stdout.write('\x1b[B\r\x1b[2K');
694
- process.stdout.write('\x1b[u');
695
- _suggCount = 0;
696
- }
711
+ clearAllSubRows();
697
712
  return;
698
713
  }
699
714
 
715
+ // Redraw sub-rows on every keypress so backspace / typing never wipes them
700
716
  _suggTimer = setTimeout(() => {
701
717
  _suggTimer = null;
702
- const line = rl.line || '';
703
- if (!line.startsWith('/')) {
704
- clearSuggestions();
705
- return;
706
- }
707
- const word = line.split(' ')[0];
708
- const matches = SLASH_CMDS.filter(({ cmd }) => cmd.startsWith(word));
709
- renderSuggestions(matches);
718
+ renderSubRows(rl.line || '');
710
719
  }, 50);
711
720
  });
712
721
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prior-cli",
3
- "version": "1.3.9",
3
+ "version": "1.3.10",
4
4
  "description": "Prior Network AI — command-line interface",
5
5
  "bin": {
6
6
  "prior": "bin/prior.js"