prior-cli 1.3.10 → 1.3.12

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/prior.js CHANGED
@@ -608,7 +608,7 @@ async function startChat(opts = {}) {
608
608
  const chatHistory = [];
609
609
  let currentModel = opts.model || null;
610
610
  let _currentAbortController = null;
611
- let _pendingImageBase64 = null; // set by alt+v clipboard paste
611
+ let _pendingImages = []; // set by alt+v clipboard paste (supports multiple)
612
612
 
613
613
  // ── Live slash-command suggestions ──────────────────────────
614
614
  let clearSuggestions = () => {};
@@ -652,8 +652,12 @@ async function startChat(opts = {}) {
652
652
  let rows = 0;
653
653
 
654
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')}`);
655
+ if (_pendingImages.length > 0) {
656
+ const tags = _pendingImages.map((_, i) => c.brand(`[Image ${i + 1}]`)).join(' ');
657
+ const hint = _pendingImages.length > 0
658
+ ? c.dim(' · alt+v to add more · alt+v (empty clipboard) to remove last')
659
+ : '';
660
+ process.stdout.write(`\x1b[B\r\x1b[2K ${c.brand('◈')} ${tags}${hint}`);
657
661
  rows++;
658
662
  }
659
663
 
@@ -690,14 +694,17 @@ async function startChat(opts = {}) {
690
694
  return;
691
695
  }
692
696
 
693
- // Alt+V — grab image from Windows clipboard
697
+ // Alt+V — add image from clipboard, or remove last if clipboard is empty
694
698
  if (key.meta && key.name === 'v') {
695
699
  try {
696
700
  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 { '' }`;
697
701
  const b64 = execSync(`powershell -NoProfile -Command "${ps}"`, { timeout: 5000 }).toString().trim();
698
702
  if (b64) {
699
- _pendingImageBase64 = b64;
700
- renderSubRows(rl.line || ''); // immediate redraw with indicator
703
+ _pendingImages.push(b64);
704
+ renderSubRows(rl.line || '');
705
+ } else if (_pendingImages.length > 0) {
706
+ _pendingImages.pop();
707
+ renderSubRows(rl.line || '');
701
708
  } else {
702
709
  flashSubRow(c.muted('✗ No image found in clipboard'));
703
710
  }
@@ -980,11 +987,12 @@ Keep it under 350 words. Write prior.md now.`;
980
987
  console.log('');
981
988
 
982
989
  {
983
- const imageForThisMsg = _pendingImageBase64;
984
- _pendingImageBase64 = null;
990
+ const imagesForThisMsg = [..._pendingImages];
991
+ _pendingImages = [];
985
992
 
986
- if (imageForThisMsg) {
987
- console.log(c.brand('') + c.dim(' image attached'));
993
+ if (imagesForThisMsg.length > 0) {
994
+ const label = imagesForThisMsg.length === 1 ? '1 image' : `${imagesForThisMsg.length} images`;
995
+ console.log(c.brand(' ◈') + c.dim(` ${label} attached`));
988
996
  }
989
997
 
990
998
  let responseText = '';
@@ -1012,7 +1020,7 @@ Keep it under 350 words. Write prior.md now.`;
1012
1020
  model: currentModel,
1013
1021
  cwd: process.cwd(),
1014
1022
  projectContext,
1015
- imageBase64: imageForThisMsg,
1023
+ images: imagesForThisMsg,
1016
1024
  confirm,
1017
1025
  signal: _currentAbortController.signal,
1018
1026
  send: ev => {
package/lib/agent.js CHANGED
@@ -10,11 +10,11 @@ const MAX_ITER = 14;
10
10
 
11
11
  // ── Single inference call (server just runs Ollama + returns) ─
12
12
 
13
- async function infer(messages, model, token, { cwd, uncensored, projectContext, imageBase64 } = {}, signal) {
13
+ async function infer(messages, model, token, { cwd, uncensored, projectContext, images } = {}, signal) {
14
14
  const res = await fetch(`${CLI_BASE}/api/infer`, {
15
15
  method: 'POST',
16
16
  headers: { 'Content-Type': 'application/json' },
17
- body: JSON.stringify({ messages, model, token, cwd, uncensored, projectContext, imageBase64 }),
17
+ body: JSON.stringify({ messages, model, token, cwd, uncensored, projectContext, images }),
18
18
  timeout: 120000,
19
19
  signal,
20
20
  });
@@ -200,13 +200,13 @@ function stripToolTags(text) {
200
200
 
201
201
  const CONFIRM_TOOLS = new Set(['run_command', 'file_delete', 'file_write']);
202
202
 
203
- async function runAgent({ messages, model, uncensored, cwd, projectContext, imageBase64, send, confirm, signal }) {
203
+ async function runAgent({ messages, model, uncensored, cwd, projectContext, images, send, confirm, signal }) {
204
204
  const token = getToken();
205
205
  const history = [...messages];
206
206
 
207
207
  let totalPromptTokens = 0;
208
208
  let totalCompletionTokens = 0;
209
- let pendingImage = imageBase64 || null; // only sent on first iteration
209
+ let pendingImages = (images && images.length) ? images : null; // only sent on first iteration
210
210
 
211
211
  for (let iter = 0; iter < MAX_ITER; iter++) {
212
212
 
@@ -219,10 +219,10 @@ async function runAgent({ messages, model, uncensored, cwd, projectContext, imag
219
219
  send({ type: 'thinking' });
220
220
 
221
221
  let result;
222
- const iterImage = pendingImage;
223
- pendingImage = null; // clear after first use
222
+ const iterImages = pendingImages;
223
+ pendingImages = null; // clear after first use
224
224
  try {
225
- result = await infer(history, model || 'qwen3.5:4b', token, { cwd, uncensored, projectContext, imageBase64: iterImage }, signal);
225
+ result = await infer(history, model || 'qwen3.5:4b', token, { cwd, uncensored, projectContext, images: iterImages }, signal);
226
226
  } catch (err) {
227
227
  await trackTokenUsage(token, totalPromptTokens, totalCompletionTokens);
228
228
  if (err.name === 'AbortError' || signal?.aborted) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prior-cli",
3
- "version": "1.3.10",
3
+ "version": "1.3.12",
4
4
  "description": "Prior Network AI — command-line interface",
5
5
  "bin": {
6
6
  "prior": "bin/prior.js"