yaver-cli
Advanced tools
+1
-1
| { | ||
| "name": "yaver-cli", | ||
| "version": "1.99.360", | ||
| "version": "1.99.367", | ||
| "mcpName": "io.github.yaver-io/yaver", | ||
@@ -5,0 +5,0 @@ "description": "Unified npm bootstrap for the Yaver agent, SDK injection, and local-first developer runtime", |
+61
-1
@@ -62,3 +62,11 @@ const fs = require('fs'); | ||
| if (process.platform !== 'win32') fs.chmodSync(binaryPath, 0o755); | ||
| return binaryPath; | ||
| if (cachedBinaryRuns(binaryPath)) return binaryPath; | ||
| // Present but unusable: re-download rather than hand back a brick. The | ||
| // old code returned it on existence alone, so one interrupted download | ||
| // wedged that version forever — every later run found the file, returned | ||
| // it, and failed identically with nothing to point at. | ||
| if (!quiet) { | ||
| console.error(`[yaver] cached agent ${asset.version} is present but will not run — re-downloading`); | ||
| } | ||
| try { fs.rmSync(installDir, { recursive: true, force: true }); } catch (_) {} | ||
| } | ||
@@ -85,2 +93,40 @@ return await downloadAndCacheAgent(asset, { quiet }); | ||
| /** A cached agent binary is only usable if it actually RUNS. | ||
| * | ||
| * `fs.existsSync` answers "is there a file here", which is a proxy for the | ||
| * thing we need: "can this machine exec it and get a version back". The two | ||
| * disagree in exactly the cases that matter — an interrupted download leaves a | ||
| * truncated file, a killed extract leaves a 0-byte one, an unsigned or | ||
| * quarantined binary on macOS exists and refuses to launch. Every one of those | ||
| * passes existsSync and then dies at spawn with a bare exit code and nothing | ||
| * said (observed 2026-07-25: a launchd agent flapping on status 78 because its | ||
| * version dir held no binary — the operator sees "the daemon won't start" and | ||
| * no reason anywhere). | ||
| * | ||
| * So probe the operation: run `--version` with a short timeout. Cheap (single | ||
| * exec, no network) and it turns a silent brick into a fall back onto the last | ||
| * binary that demonstrably works. */ | ||
| function cachedBinaryRuns(binaryPath) { | ||
| try { | ||
| const st = fs.statSync(binaryPath); | ||
| // A real agent is tens of MB; anything tiny is a truncated download, and | ||
| // exec'ing it would just be a slower way to learn that. | ||
| if (!st.isFile() || st.size < 1024 * 1024) return false; | ||
| } catch (_) { | ||
| return false; | ||
| } | ||
| try { | ||
| const res = spawnSync(binaryPath, ['--version'], { | ||
| timeout: 10_000, | ||
| encoding: 'utf8', | ||
| stdio: ['ignore', 'pipe', 'pipe'], | ||
| }); | ||
| if (res.error) return false; | ||
| if (res.status !== 0) return false; | ||
| return /\byaver\b/i.test(String(res.stdout || '') + String(res.stderr || '')); | ||
| } catch (_) { | ||
| return false; | ||
| } | ||
| } | ||
| /** Walk CACHE_ROOT and return the path + version of any cached | ||
@@ -107,2 +153,9 @@ * binary newer than `version` that matches this platform. Returns | ||
| } | ||
| // Verify before preferring it: a broken NEWER cache entry must not | ||
| // shadow a working older one. Skipping this is how "prefer newest" | ||
| // becomes "prefer whatever downloaded halfway". | ||
| if (!cachedBinaryRuns(p)) { | ||
| console.error(`[yaver] cached agent ${v} will not run (incomplete download?) — skipping it`); | ||
| continue; | ||
| } | ||
| return { path: p, version: v }; | ||
@@ -132,2 +185,9 @@ } | ||
| } | ||
| // This is the offline/rate-limited fallback — the LAST thing standing | ||
| // between the user and "yaver does nothing". Returning a file that | ||
| // cannot exec here produces a bare failure with no network to blame. | ||
| if (!cachedBinaryRuns(p)) { | ||
| console.error(`[yaver] cached agent ${v} will not run (incomplete download?) — trying an older one`); | ||
| continue; | ||
| } | ||
| return p; | ||
@@ -134,0 +194,0 @@ } |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 5 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 3 instances
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
12801292
0.02%4912
1.22%63
3.28%