sweet-search 2.5.8 → 2.5.9

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.
@@ -123,7 +123,6 @@ export function isVerboseMode() {
123
123
  const BAR_WIDTH = 30;
124
124
  const LABEL_COL = 17; // pad "Label:" to this width so every bar's [ ] aligns
125
125
  const SUB_BLOCKS = ['', '▏', '▎', '▍', '▌', '▋', '▊', '▉']; // eighth-block partial fills
126
- const CLEAR_EOL = '\x1b[K';
127
126
  const liveBars = new Map(); // label -> { current, total }; insertion order = display order
128
127
  let regionLines = 0; // bar lines currently pinned at the bottom (TTY)
129
128
  let lastLoggedPercent = {};
@@ -141,11 +140,20 @@ function renderBar(current, total, label) {
141
140
  return `${colors.cyan}${head}[${bar}${empty}] ${pct}% (${current}/${total})${colors.reset}`;
142
141
  }
143
142
 
144
- function drawRegion() {
145
- let out = regionLines > 0 ? `\x1b[${regionLines}A\r` : '\r';
146
- for (const [label, b] of liveBars) out += renderBar(b.current, b.total, label) + CLEAR_EOL + '\n';
147
- process.stdout.write(out);
148
- regionLines = liveBars.size;
143
+ // (Re)draw the live region in place (the `log-update` pattern). Invariant: the
144
+ // cursor enters and leaves at the END of the last bar line — NO trailing newline
145
+ // so a redraw never pushes a stale copy of a bar into scrollback. Each redraw
146
+ // moves up to the first region line and erases to end-of-screen (\x1b[J) before
147
+ // rewriting. `aboveLine`, if given, scrolls one permanent line above the bars.
148
+ function regionEscape(aboveLine) {
149
+ const bars = [...liveBars].map(([l, b]) => renderBar(b.current, b.total, l));
150
+ let out = '';
151
+ if (regionLines > 1) out += `\x1b[${regionLines - 1}A`; // up to the first region line
152
+ out += '\r\x1b[J'; // col 0, erase region + everything below
153
+ if (aboveLine != null) out += aboveLine + '\n'; // permanent line above the bars
154
+ out += bars.join('\n'); // bars — no trailing newline
155
+ regionLines = bars.length;
156
+ return out;
149
157
  }
150
158
 
151
159
  export function log(message, color = 'reset') {
@@ -153,17 +161,13 @@ export function log(message, color = 'reset') {
153
161
  const line = `${colors[color]}${message}${colors.reset}`;
154
162
  if (regionLines > 0 && process.stdout.isTTY) {
155
163
  if (liveBars.size > 1) {
156
- // Parallel bars are live: defer the line. Printing it now would scroll the
157
- // region and freeze a duplicate bar-pair into scrollback (e.g. the "✓ Late
158
- // interaction index built" line when LI finishes before Embedding). Flushed
159
- // once every bar in the region completes.
164
+ // Parallel bars live: defer the line so it can't disturb the region. Any
165
+ // mid-region print scrolls a stale bar-pair into scrollback. Flushed once
166
+ // every bar in the region finishes.
160
167
  deferredLogs.push(line);
161
168
  return;
162
169
  }
163
- // Single bar: print the line above it, then redraw the bar below.
164
- let out = `\x1b[${regionLines}A\r${line}${CLEAR_EOL}\n`;
165
- for (const [label, b] of liveBars) out += renderBar(b.current, b.total, label) + CLEAR_EOL + '\n';
166
- process.stdout.write(out);
170
+ process.stdout.write(regionEscape(line)); // single bar: line above, bar redrawn below
167
171
  } else {
168
172
  console.log(line);
169
173
  }
@@ -181,18 +185,18 @@ export function logProgress(current, total, label) {
181
185
  }
182
186
  return;
183
187
  }
184
- // Interactive TTY: update this bar in the live region and redraw.
188
+ // Interactive TTY: update this bar in the live region and redraw in place.
185
189
  liveBars.set(label, { current, total });
186
- drawRegion();
190
+ process.stdout.write(regionEscape());
187
191
  // Once every live bar is complete, commit the region (leave it on screen).
188
192
  let allDone = true;
189
193
  for (const b of liveBars.values()) if (b.current < b.total) { allDone = false; break; }
190
194
  if (allDone) {
195
+ process.stdout.write('\n'); // move below the finished bars (cursor was at their end)
191
196
  for (const k of liveBars.keys()) lastLoggedPercent[k] = 0;
192
197
  liveBars.clear();
193
198
  regionLines = 0;
194
- // Flush any lines deferred while the parallel bars were running — now below
195
- // the finished bars, in arrival order.
199
+ // Flush lines deferred while parallel bars ran — now below the finished bars.
196
200
  if (deferredLogs.length) {
197
201
  for (const l of deferredLogs) console.log(l);
198
202
  deferredLogs = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sweet-search",
3
- "version": "2.5.8",
3
+ "version": "2.5.9",
4
4
  "description": "Sweet Search - SOTA Hybrid Code Search Engine with WASM CatBoost Query Router, Semantic/Lexical/Structural Search, and Multilingual Support",
5
5
  "type": "module",
6
6
  "main": "core/search/sweet-search.js",
@@ -163,12 +163,12 @@
163
163
  },
164
164
  "optionalDependencies": {
165
165
  "usearch": "^2.21.4",
166
- "@sweet-search/native-darwin-arm64": "2.5.8",
167
- "@sweet-search/native-darwin-x64": "2.5.8",
168
- "@sweet-search/native-linux-arm64-gnu": "2.5.8",
169
- "@sweet-search/native-linux-arm64-gnu-cuda": "2.5.8",
170
- "@sweet-search/native-linux-x64-gnu": "2.5.8",
171
- "@sweet-search/native-linux-x64-gnu-cuda": "2.5.8"
166
+ "@sweet-search/native-darwin-arm64": "2.5.9",
167
+ "@sweet-search/native-darwin-x64": "2.5.9",
168
+ "@sweet-search/native-linux-arm64-gnu": "2.5.9",
169
+ "@sweet-search/native-linux-arm64-gnu-cuda": "2.5.9",
170
+ "@sweet-search/native-linux-x64-gnu": "2.5.9",
171
+ "@sweet-search/native-linux-x64-gnu-cuda": "2.5.9"
172
172
  },
173
173
  "engines": {
174
174
  "node": ">=18.0.0"
@@ -29,9 +29,13 @@ function run() {
29
29
  }
30
30
 
31
31
  const c = (n, s) => `\x1b[${n}m${s}\x1b[0m`;
32
+ // SWEET SEARCH half-block wordmark (kept in sync with core/search/cli-decoration.js).
33
+ const L1 = '█▀▀ █ █ █ █▀▀ █▀▀ ▀█▀ █▀▀ █▀▀ ▄▀▄ █▀▄ █▀▀ █▄█';
34
+ const L2 = '▄▄█ ▀▄█▄▀ ██▄ ██▄ █ ▄▄█ ██▄ █▀█ ██▄ █▄▄ █▀█';
32
35
  const msg = [
33
36
  '',
34
- ` ${c('1;38;5;213', 'sweet-search')} installed ${c('2', '— SOTA hybrid code search')}`,
37
+ ` ${c('1;38;5;213', L1)}`,
38
+ ` ${c('1;38;5;213', L2)}`,
35
39
  '',
36
40
  ` ${c('1', 'Get started:')}`,
37
41
  ` ${c('36', 'sweet-search init')} set up the current project`,