@vera-ai/cli 2.0.0 → 2.1.0
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 +2 -2
- package/bin/vera.js +82 -27
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Code search for AI agents. Vera indexes your codebase using tree-sitter parsing and hybrid search (BM25 + vector similarity + optional cross-encoder reranking), then returns ranked code snippets as Markdown codeblocks by default, or JSON with `--json`.
|
|
4
4
|
|
|
5
|
-
This package downloads and wraps the native Vera binary for your platform. It downloads the exact package version, checks the release archive size and SHA-256, and stores a completed binary cache. Later runs use that cache without network access. Older caches are downloaded and verified once before they can be reused offline. On Linux without glibc (such as Alpine or NixOS), the wrapper selects the musl binary. Other native targets use their platform system libraries; optional ONNX backends have additional runtime requirements. Set `VERA_TARGET` to override target detection (e.g., `VERA_TARGET=x86_64-unknown-linux-musl
|
|
5
|
+
This package downloads and wraps the native Vera binary for your platform. It downloads the exact package version, checks the release archive size and SHA-256, and stores a completed binary cache. Later runs use that cache without network access. Older caches are downloaded and verified once before they can be reused offline. On Linux without glibc (such as Alpine or NixOS), the wrapper selects the musl binary. Other native targets use their platform system libraries; optional ONNX backends have additional runtime requirements. Set `VERA_TARGET` to override target detection (e.g., `VERA_TARGET=x86_64-unknown-linux-musl npx -y @vera-ai/cli install`).
|
|
6
6
|
|
|
7
7
|
The default local embedding model, `minishlab/potion-code-16M-v2`, runs on CPU and works offline after its first download. API mode is also available; Qwen/OpenRouter is recommended among API presets (paid usage). The [benchmark report](https://github.com/VeraTools/Vera/blob/master/docs/benchmarks.md) separates the full 1,251-task suite from smaller screening subsets, and the [agent benchmark](https://github.com/VeraTools/Vera/blob/master/docs/benchmarks-history.md#agent-level-benchmark) records context measurements and their sample limits.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
|
|
12
|
+
npx -y @vera-ai/cli install
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Quick Start
|
package/bin/vera.js
CHANGED
|
@@ -84,7 +84,19 @@ function manifestUrl(version) {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function defaultVeraHome() {
|
|
87
|
-
|
|
87
|
+
if (process.env.VERA_HOME && process.env.VERA_HOME.trim()) return path.resolve(process.env.VERA_HOME);
|
|
88
|
+
const home = os.homedir();
|
|
89
|
+
const legacy = path.join(home, ".vera");
|
|
90
|
+
try {
|
|
91
|
+
if (fs.readdirSync(legacy).some((name) => !name.startsWith(".") && name !== "update-check.json")) return legacy;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (error.code !== "ENOENT") throw error;
|
|
94
|
+
}
|
|
95
|
+
const data = process.platform === "win32" ? process.env.APPDATA : process.platform === "darwin"
|
|
96
|
+
? path.join(home, "Library", "Application Support")
|
|
97
|
+
: process.env.XDG_DATA_HOME && path.isAbsolute(process.env.XDG_DATA_HOME)
|
|
98
|
+
? process.env.XDG_DATA_HOME : path.join(home, ".local", "share");
|
|
99
|
+
return data ? path.join(data, "vera") : legacy;
|
|
88
100
|
}
|
|
89
101
|
|
|
90
102
|
function installMetadataPath() {
|
|
@@ -367,21 +379,66 @@ async function extractArchive(archivePath, destination, target) {
|
|
|
367
379
|
}
|
|
368
380
|
}
|
|
369
381
|
|
|
382
|
+
function shimContents(binaryPath, platform) {
|
|
383
|
+
if (platform === "win32") {
|
|
384
|
+
return `@echo off\r\nsetlocal DisableDelayedExpansion\r\n"${binaryPath.replace(/%/g, "%%")}" %*\r\n`;
|
|
385
|
+
}
|
|
386
|
+
return `#!/bin/sh\nexec '${binaryPath.replace(/'/g, "'\"'\"'")}' "$@"\n`;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function shimTarget(text) {
|
|
390
|
+
if (text.startsWith("#!/bin/sh\nexec ") && text.endsWith(' "$@"\n')) {
|
|
391
|
+
const word = text.slice(15, -6);
|
|
392
|
+
if (word.startsWith("'") && word.endsWith("'")) {
|
|
393
|
+
const parts = word.slice(1, -1).split("'\"'\"'");
|
|
394
|
+
if (parts.every((part) => !part.includes("'"))) return parts.join("'") || null;
|
|
395
|
+
} else if (word.startsWith('"') && word.endsWith('"')) {
|
|
396
|
+
const target = word.slice(1, -1);
|
|
397
|
+
return target && !/[$`\\"]/.test(target) ? target : null;
|
|
398
|
+
} else if (/^[A-Za-z0-9@%+=:,./_-]+$/.test(word)) return word;
|
|
399
|
+
}
|
|
400
|
+
for (const setlocal of [true, false]) {
|
|
401
|
+
const head = '@echo off\r\n' + (setlocal ? 'setlocal DisableDelayedExpansion\r\n' : '') + '"';
|
|
402
|
+
if (text.startsWith(head) && text.endsWith('" %*\r\n')) {
|
|
403
|
+
const target = text.slice(head.length, -6);
|
|
404
|
+
// cmd expands a lone `%`; only the escaped form may carry a literal one.
|
|
405
|
+
if (target.includes('"') || (setlocal ? target.replace(/%%/g, "") : target).includes("%")) return null;
|
|
406
|
+
return (setlocal ? target.replace(/%%/g, "%") : target) || null;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
|
|
370
412
|
async function createShim(binaryPath) {
|
|
371
413
|
const binDir = pickUserBinDir();
|
|
372
414
|
await fsp.mkdir(binDir, { recursive: true });
|
|
373
415
|
const shimPath = path.join(binDir, shimName());
|
|
374
416
|
if (path.join(await fsp.realpath(binDir), shimName()) === await fsp.realpath(binaryPath)) return shimPath;
|
|
417
|
+
const contents = shimContents(binaryPath, process.platform);
|
|
418
|
+
try {
|
|
419
|
+
const stat = await fsp.lstat(shimPath);
|
|
420
|
+
const current = stat.isFile() ? await fsp.readFile(shimPath, "utf8").catch(() => "") : "";
|
|
421
|
+
const target = shimTarget(current);
|
|
422
|
+
const normalized = target && path.isAbsolute(target) ? path.resolve(target) : null;
|
|
423
|
+
// Releases live at <home>/bin/<version>/<target>/<binary>. The legacy home
|
|
424
|
+
// counts too: an older uninstall could leave its shim behind.
|
|
425
|
+
const owned = normalized && [defaultVeraHome(), path.join(os.homedir(), ".vera")].some((home) => {
|
|
426
|
+
const relative = path.relative(path.resolve(home, "bin"), normalized);
|
|
427
|
+
const parts = relative.split(path.sep);
|
|
428
|
+
return !path.isAbsolute(relative) && parts.length === 3 && parts[0] !== ".." && parts[2] === binaryName();
|
|
429
|
+
});
|
|
430
|
+
if (!owned) {
|
|
431
|
+
console.error(`Left ${shimPath} in place because Vera did not create it. Run ${binaryPath} directly, or remove that file and install again.`);
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
if (current === contents) return shimPath;
|
|
435
|
+
} catch (error) {
|
|
436
|
+
if (error.code !== "ENOENT") throw error;
|
|
437
|
+
}
|
|
375
438
|
const staging = await fsp.mkdtemp(path.join(binDir, ".vera-shim-"));
|
|
376
439
|
const stagedShim = path.join(staging, shimName());
|
|
377
440
|
try {
|
|
378
|
-
|
|
379
|
-
const contents = `@echo off\r\nsetlocal DisableDelayedExpansion\r\n"${binaryPath.replace(/%/g, "%%")}" %*\r\n`;
|
|
380
|
-
await fsp.writeFile(stagedShim, contents, "utf8");
|
|
381
|
-
} else {
|
|
382
|
-
const quoted = "'" + binaryPath.replace(/'/g, "'\"'\"'") + "'";
|
|
383
|
-
await fsp.writeFile(stagedShim, `#!/bin/sh\nexec ${quoted} "$@"\n`, { mode: 0o755 });
|
|
384
|
-
}
|
|
441
|
+
await fsp.writeFile(stagedShim, contents, { mode: 0o755 });
|
|
385
442
|
await fsp.rename(stagedShim, shimPath);
|
|
386
443
|
} finally {
|
|
387
444
|
await fsp.rm(staging, { recursive: true, force: true });
|
|
@@ -426,20 +483,23 @@ async function cachedBinary(target) {
|
|
|
426
483
|
return null;
|
|
427
484
|
}
|
|
428
485
|
|
|
429
|
-
async function finishInstall(binaryPath, version, target,
|
|
430
|
-
const
|
|
431
|
-
if (
|
|
432
|
-
|
|
486
|
+
async function finishInstall(binaryPath, version, target, install, downloaded = false) {
|
|
487
|
+
const writeLauncher = install || !fs.lstatSync(path.join(pickUserBinDir(), shimName()), { throwIfNoEntry: false });
|
|
488
|
+
if (writeLauncher) {
|
|
489
|
+
const shimPath = await createShim(binaryPath);
|
|
490
|
+
if (downloaded && shimPath && !isOnPath(path.dirname(shimPath))) {
|
|
491
|
+
console.error(`Added Vera to ${path.dirname(shimPath)}. Add that directory to PATH to run \`vera\` directly.`);
|
|
492
|
+
}
|
|
433
493
|
}
|
|
434
|
-
await writeInstallMetadata({ installMethod: currentInstallMethod(), version, binaryPath, target });
|
|
494
|
+
if (writeLauncher || downloaded) await writeInstallMetadata({ installMethod: currentInstallMethod(), version, binaryPath, target });
|
|
435
495
|
return { binaryPath, version };
|
|
436
496
|
}
|
|
437
497
|
|
|
438
|
-
async function ensureBinaryInstalled() {
|
|
498
|
+
async function ensureBinaryInstalled(install = false) {
|
|
439
499
|
const target = resolveTarget(process.platform, process.arch);
|
|
440
500
|
if (!/^[A-Za-z0-9_-]+$/.test(target)) throw new Error("invalid release target");
|
|
441
501
|
const cached = await cachedBinary(target);
|
|
442
|
-
if (cached) return finishInstall(cached.binaryPath, cached.version, target);
|
|
502
|
+
if (cached) return finishInstall(cached.binaryPath, cached.version, target, install);
|
|
443
503
|
const manifest = await loadManifest();
|
|
444
504
|
const asset = manifest.assets && manifest.assets[target];
|
|
445
505
|
if (!asset) throw new Error(`no release asset for target ${target}`);
|
|
@@ -470,7 +530,7 @@ async function ensureBinaryInstalled() {
|
|
|
470
530
|
} finally {
|
|
471
531
|
await fsp.rm(tempRoot, { recursive: true, force: true });
|
|
472
532
|
}
|
|
473
|
-
return finishInstall(binaryPath, version, target, true);
|
|
533
|
+
return finishInstall(binaryPath, version, target, install, true);
|
|
474
534
|
}
|
|
475
535
|
|
|
476
536
|
async function runBinary(binaryPath, args) {
|
|
@@ -494,19 +554,14 @@ async function runBinary(binaryPath, args) {
|
|
|
494
554
|
async function main() {
|
|
495
555
|
const { command, rest } = parseArgs(process.argv.slice(2));
|
|
496
556
|
|
|
497
|
-
|
|
498
|
-
await writeInstallMetadata({
|
|
499
|
-
installMethod: "npm",
|
|
500
|
-
version: packageVersion,
|
|
501
|
-
binaryPath: null,
|
|
502
|
-
});
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
const { binaryPath, version } = await ensureBinaryInstalled();
|
|
557
|
+
const { binaryPath, version } = await ensureBinaryInstalled(command === "install");
|
|
507
558
|
|
|
508
559
|
if (command === "install") {
|
|
509
560
|
console.error(`Vera ${version} installed.`);
|
|
561
|
+
if (rest.length === 0 && (!process.stdin.isTTY || !process.stderr.isTTY)) {
|
|
562
|
+
console.error("Run `vera agent install` in a terminal or `vera agent install --client all --scope global` to install agent skills.");
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
510
565
|
await runBinary(binaryPath, ["agent", "install", ...rest]);
|
|
511
566
|
return;
|
|
512
567
|
}
|
|
@@ -526,4 +581,4 @@ if (require.main === module) {
|
|
|
526
581
|
});
|
|
527
582
|
}
|
|
528
583
|
|
|
529
|
-
module.exports = { detectMusl, fetchText, downloadFile, extractArchive, ensureBinaryInstalled, createShim, runBinary };
|
|
584
|
+
module.exports = { defaultVeraHome, shimContents, shimTarget, detectMusl, fetchText, downloadFile, extractArchive, ensureBinaryInstalled, createShim, runBinary };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vera-ai/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Bootstrap installer and wrapper for the Vera CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/VeraTools/Vera#readme",
|
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/VeraTools/Vera/issues"
|
|
14
14
|
},
|
|
15
|
-
"bin":
|
|
16
|
-
|
|
17
|
-
"postinstall": "node ./bin/vera.js _record-install-method"
|
|
15
|
+
"bin": {
|
|
16
|
+
"vera-ai": "./bin/vera.js"
|
|
18
17
|
},
|
|
19
18
|
"files": [
|
|
20
19
|
"bin/vera.js",
|