sweet-search 2.5.5 → 2.5.7
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/README.md +321 -109
- package/assets/banner/banner-frames.webp +0 -0
- package/assets/banner/banner-manifest.json +10 -0
- package/core/banner/render-banner.js +209 -0
- package/core/banner/sixel.js +126 -0
- package/core/embedding/embedding-local-model.js +1 -0
- package/core/graph/relationship-resolver.js +5 -1
- package/core/indexing/index-codebase-v21.js +7 -6
- package/core/indexing/indexer-ann.js +4 -4
- package/core/indexing/indexer-build.js +1 -1
- package/core/indexing/indexer-utils.js +64 -17
- package/core/infrastructure/onnx-session-utils.js +1 -0
- package/core/infrastructure/simd-distance.js +11 -6
- package/core/ranking/late-interaction-model.js +1 -0
- package/package.json +16 -10
- package/scripts/init.js +28 -6
- package/scripts/postinstall-banner.js +34 -0
package/scripts/init.js
CHANGED
|
@@ -252,9 +252,26 @@ export function detectProjectRoot(cwd = process.cwd()) {
|
|
|
252
252
|
export function ensureDataDir(projectRoot) {
|
|
253
253
|
const dataDir = join(projectRoot, DATA_DIR_NAME);
|
|
254
254
|
mkdirSync(dataDir, { recursive: true });
|
|
255
|
+
maybeIgnoreDataDir(projectRoot);
|
|
255
256
|
return dataDir;
|
|
256
257
|
}
|
|
257
258
|
|
|
259
|
+
// Add `.sweet-search/` to the project's .gitignore so the local index isn't
|
|
260
|
+
// committed — but ONLY if a .gitignore already exists. We never create one for
|
|
261
|
+
// a project that doesn't already use it.
|
|
262
|
+
function maybeIgnoreDataDir(projectRoot) {
|
|
263
|
+
try {
|
|
264
|
+
const gitignorePath = join(projectRoot, '.gitignore');
|
|
265
|
+
if (!existsSync(gitignorePath)) return;
|
|
266
|
+
const content = readFileSync(gitignorePath, 'utf8');
|
|
267
|
+
const already = content.split(/\r?\n/).map((l) => l.trim().replace(/^\//, '').replace(/\/$/, ''))
|
|
268
|
+
.some((l) => l === DATA_DIR_NAME);
|
|
269
|
+
if (already) return;
|
|
270
|
+
const sep = content.length === 0 || content.endsWith('\n') ? '' : '\n';
|
|
271
|
+
writeFileSync(gitignorePath, `${content}${sep}\n# Sweet Search local index\n${DATA_DIR_NAME}/\n`);
|
|
272
|
+
} catch { /* best-effort — never block init on .gitignore */ }
|
|
273
|
+
}
|
|
274
|
+
|
|
258
275
|
// ---------------------------------------------------------------------------
|
|
259
276
|
// Init config read/write
|
|
260
277
|
// ---------------------------------------------------------------------------
|
|
@@ -1450,6 +1467,12 @@ export async function runInit(args) {
|
|
|
1450
1467
|
return;
|
|
1451
1468
|
}
|
|
1452
1469
|
|
|
1470
|
+
// 0. Animated banner (best-effort; only on an interactive TTY, never in CI/pipes).
|
|
1471
|
+
if (process.stdout.isTTY && !process.env.CI && !process.env.NO_BANNER && !process.env.SWEET_SEARCH_NO_BANNER) {
|
|
1472
|
+
// query:false — init is interactive (readline); avoid any stdin contention with the terminal capability probe.
|
|
1473
|
+
try { const { showBanner } = await import('../core/banner/render-banner.js'); await showBanner({ query: false }); } catch { /* non-fatal */ }
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1453
1476
|
// 1. Node.js version check
|
|
1454
1477
|
checkNodeVersion();
|
|
1455
1478
|
|
|
@@ -1570,11 +1593,10 @@ export async function runInit(args) {
|
|
|
1570
1593
|
const skippedOptIns = getSkippedOptInModels(profile);
|
|
1571
1594
|
let modelResults = new Map();
|
|
1572
1595
|
|
|
1573
|
-
//
|
|
1574
|
-
//
|
|
1575
|
-
//
|
|
1576
|
-
|
|
1577
|
-
if (skippedOptIns.length > 0) {
|
|
1596
|
+
// Opt-in models (e.g. cross-encoder rerankers, disabled by default since
|
|
1597
|
+
// commit 43a61eb) are skipped silently — they're optional features, not
|
|
1598
|
+
// missing models. Set DEBUG=1 to see which were skipped and how to enable.
|
|
1599
|
+
if (process.env.DEBUG && skippedOptIns.length > 0) {
|
|
1578
1600
|
for (const skipped of skippedOptIns) {
|
|
1579
1601
|
process.stderr.write(
|
|
1580
1602
|
`[init] Skipping opt-in model "${skipped.key}" — ` +
|
|
@@ -2016,7 +2038,7 @@ function runCoremlCascadeBuild(options = {}) {
|
|
|
2016
2038
|
` The CoreML cascade build path currently requires a local clone\n` +
|
|
2017
2039
|
` of the sweet-search repository — it is not yet shipped via npm.\n` +
|
|
2018
2040
|
` To build the cascade:\n` +
|
|
2019
|
-
` git clone https://github.com/
|
|
2041
|
+
` git clone https://github.com/mrsladoje/sweet-search\n` +
|
|
2020
2042
|
` cd sweet-search\n` +
|
|
2021
2043
|
` node scripts/build-coreml-cascade.js\n` +
|
|
2022
2044
|
` Then point your install at the managed cache (init detects it).`,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* postinstall — print a short "what next" message after install.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately plain text: during `npm install` npm writes its own progress
|
|
6
|
+
* spinner to the terminal CONCURRENTLY with this script, which would interrupt
|
|
7
|
+
* any graphics/animation escape sequence mid-stream and leak its payload as
|
|
8
|
+
* garbage text. So the rich animated banner is reserved for `sweet-search init`
|
|
9
|
+
* and `sweet-search index` (where we own the TTY); install just prints a clean,
|
|
10
|
+
* escape-light pointer. Best-effort; always exits 0 so it can't fail an install.
|
|
11
|
+
*/
|
|
12
|
+
import process from 'node:process';
|
|
13
|
+
|
|
14
|
+
function run() {
|
|
15
|
+
const env = process.env;
|
|
16
|
+
if (env.NO_BANNER || env.SWEET_SEARCH_NO_BANNER) return;
|
|
17
|
+
try {
|
|
18
|
+
const c = (n, s) => (process.stdout.isTTY ? `\x1b[${n}m${s}\x1b[0m` : s);
|
|
19
|
+
const lines = [
|
|
20
|
+
'',
|
|
21
|
+
` ${c('1;38;5;213', 'sweet-search')} installed ${c('2', '— SOTA hybrid code search')}`,
|
|
22
|
+
'',
|
|
23
|
+
` ${c('1', 'Get started:')}`,
|
|
24
|
+
` ${c('36', 'sweet-search init')} set up the current project`,
|
|
25
|
+
` ${c('36', 'sweet-search index')} build the search index`,
|
|
26
|
+
` ${c('36', 'sweet-search "query"')} search your code`,
|
|
27
|
+
` ${c('2', '(installed locally? prefix with')} ${c('2;36', 'npx')}${c('2', ', e.g. `npx sweet-search init`)')}`,
|
|
28
|
+
'',
|
|
29
|
+
];
|
|
30
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
31
|
+
} catch { /* never break an install */ }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
run();
|