vigthoria-cli 1.13.11 → 1.13.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.
@@ -74,41 +74,93 @@ export function getInferenceRouterBaseUrls(selfHostedUrl) {
74
74
  return [...new Set(urls)];
75
75
  }
76
76
  let inferenceHealthCache = null;
77
- export async function isFastInferenceRouterAvailable(selfHostedUrl, timeoutMs = 400) {
78
- if (process.env.VIGTHORIA_AGENT_LLM_ROUTER === '0') {
79
- return false;
80
- }
81
- const now = Date.now();
82
- if (inferenceHealthCache && now - inferenceHealthCache.checkedAt < 60_000) {
83
- return inferenceHealthCache.ok;
84
- }
85
- for (const base of getInferenceRouterBaseUrls(selfHostedUrl)) {
77
+ function modelIdsFromPayload(payload) {
78
+ if (!payload || typeof payload !== 'object')
79
+ return [];
80
+ const body = payload;
81
+ const values = [
82
+ body.available_models,
83
+ body.loaded_models,
84
+ body.models,
85
+ body.data,
86
+ ].filter(Array.isArray).flat();
87
+ return values.map((entry) => {
88
+ if (typeof entry === 'string')
89
+ return entry;
90
+ if (entry && typeof entry === 'object') {
91
+ const model = entry;
92
+ return String(model.id || model.model || model.name || '');
93
+ }
94
+ return '';
95
+ }).filter(Boolean);
96
+ }
97
+ function includesBalancedRouterModel(modelIds) {
98
+ const allowed = new Set(INFERENCE_MODEL_IDS);
99
+ return modelIds.some((id) => allowed.has(String(id).trim().toLowerCase().replace(/:latest$/, '')));
100
+ }
101
+ async function probeBalancedRouterBase(base, timeoutMs) {
102
+ const fetchJson = async (path) => {
86
103
  const controller = new AbortController();
87
104
  const timer = setTimeout(() => controller.abort(), timeoutMs);
88
105
  try {
89
- const response = await fetch(`${base}/health`, { signal: controller.signal });
90
- clearTimeout(timer);
91
- if (response.ok) {
92
- inferenceHealthCache = { ok: true, checkedAt: now };
93
- return true;
94
- }
106
+ const response = await fetch(`${base}${path}`, { signal: controller.signal });
107
+ const payload = await response.json().catch(() => null);
108
+ return { ok: response.ok, payload };
95
109
  }
96
110
  catch {
111
+ return { ok: false, payload: null };
112
+ }
113
+ finally {
97
114
  clearTimeout(timer);
98
115
  }
116
+ };
117
+ const health = await fetchJson('/health');
118
+ if (!health.ok)
119
+ return false;
120
+ const advertisedByHealth = modelIdsFromPayload(health.payload);
121
+ if (advertisedByHealth.length > 0) {
122
+ return includesBalancedRouterModel(advertisedByHealth);
123
+ }
124
+ // Older inference nodes only expose capabilities on /v1/models.
125
+ const catalog = await fetchJson('/v1/models');
126
+ return catalog.ok && includesBalancedRouterModel(modelIdsFromPayload(catalog.payload));
127
+ }
128
+ async function compatibleInferenceRouterBases(selfHostedUrl, timeoutMs) {
129
+ const bases = getInferenceRouterBaseUrls(selfHostedUrl);
130
+ const key = bases.join('|');
131
+ const now = Date.now();
132
+ if (inferenceHealthCache
133
+ && inferenceHealthCache.key === key
134
+ && now - inferenceHealthCache.checkedAt < 60_000) {
135
+ return inferenceHealthCache.compatibleBases;
136
+ }
137
+ const compatibleBases = [];
138
+ for (const base of bases) {
139
+ if (await probeBalancedRouterBase(base, timeoutMs)) {
140
+ compatibleBases.push(base);
141
+ }
142
+ }
143
+ inferenceHealthCache = { key, compatibleBases, checkedAt: now };
144
+ return compatibleBases;
145
+ }
146
+ export async function isFastInferenceRouterAvailable(selfHostedUrl, timeoutMs = 400) {
147
+ if (process.env.VIGTHORIA_AGENT_LLM_ROUTER === '0') {
148
+ return false;
99
149
  }
100
- inferenceHealthCache = { ok: false, checkedAt: now };
101
- return false;
150
+ return (await compatibleInferenceRouterBases(selfHostedUrl, timeoutMs)).length > 0;
102
151
  }
103
152
  export async function routeWithBalanced4b(prompt, selfHostedUrl, options = {}) {
104
153
  const timeoutMs = options.timeoutMs ?? Number.parseInt(process.env.VIGTHORIA_AGENT_ROUTER_TIMEOUT_MS || '8000', 10);
105
- const bases = getInferenceRouterBaseUrls(selfHostedUrl);
154
+ const bases = await compatibleInferenceRouterBases(selfHostedUrl, Math.min(timeoutMs, 1500));
106
155
  let lastError = 'Inference router unreachable';
156
+ if (bases.length === 0) {
157
+ return { ok: false, error: 'No compatible Balanced 4B inference endpoint is available' };
158
+ }
107
159
  for (const base of bases) {
108
- const controller = new AbortController();
109
- const timer = setTimeout(() => controller.abort(), timeoutMs);
110
160
  const started = Date.now();
111
161
  for (const model of INFERENCE_MODEL_IDS) {
162
+ const controller = new AbortController();
163
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
112
164
  try {
113
165
  const response = await fetch(`${base}/v1/chat/completions`, {
114
166
  method: 'POST',
@@ -125,7 +177,6 @@ export async function routeWithBalanced4b(prompt, selfHostedUrl, options = {}) {
125
177
  }),
126
178
  signal: controller.signal,
127
179
  });
128
- clearTimeout(timer);
129
180
  const payload = await response.json().catch(() => null);
130
181
  if (!response.ok) {
131
182
  lastError = `HTTP ${response.status} from ${base}`;
@@ -149,8 +200,10 @@ export async function routeWithBalanced4b(prompt, selfHostedUrl, options = {}) {
149
200
  catch (err) {
150
201
  lastError = err instanceof Error ? err.message : String(err);
151
202
  }
203
+ finally {
204
+ clearTimeout(timer);
205
+ }
152
206
  }
153
- clearTimeout(timer);
154
207
  }
155
208
  return { ok: false, error: lastError };
156
209
  }
package/install.ps1 CHANGED
@@ -5,7 +5,7 @@
5
5
  $ErrorActionPreference = "Stop"
6
6
 
7
7
  # Configuration
8
- $CLI_VERSION = "1.13.9"
8
+ $CLI_VERSION = "1.13.12"
9
9
  $INSTALL_DIR = "$env:USERPROFILE\.vigthoria"
10
10
  $NPM_PACKAGE = "vigthoria-cli"
11
11
  $GIT_PACKAGE_URL = "git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
@@ -35,40 +35,40 @@ Resolve-ReleaseManifest
35
35
 
36
36
  function Write-Banner {
37
37
  Write-Host ""
38
- Write-Host " ╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
39
- Write-Host " " -ForegroundColor Cyan
40
- Write-Host " VIGTHORIA CLI INSTALLER v$CLI_VERSION " -ForegroundColor Cyan
41
- Write-Host " AI-Powered Terminal Coding Assistant " -ForegroundColor Cyan
42
- Write-Host " " -ForegroundColor Cyan
43
- Write-Host " ╚═══════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
38
+ Write-Host " +-----------------------------------------------------------+" -ForegroundColor Cyan
39
+ Write-Host " | |" -ForegroundColor Cyan
40
+ Write-Host " | VIGTHORIA CLI INSTALLER v$CLI_VERSION |" -ForegroundColor Cyan
41
+ Write-Host " | AI-Powered Terminal Coding Assistant |" -ForegroundColor Cyan
42
+ Write-Host " | |" -ForegroundColor Cyan
43
+ Write-Host " +-----------------------------------------------------------+" -ForegroundColor Cyan
44
44
  Write-Host ""
45
45
  }
46
46
 
47
47
  function Test-NetworkConnectivity {
48
- Write-Host "🔍 Checking network connectivity..." -ForegroundColor Yellow
48
+ Write-Host "[CHECK] Checking network connectivity..." -ForegroundColor Yellow
49
49
 
50
50
  try {
51
51
  $response = Invoke-WebRequest -Uri $HOSTED_TARBALL_URL -Method Head -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
52
- Write-Host " hosted CLI package is reachable" -ForegroundColor Green
52
+ Write-Host "[OK] Hosted CLI package is reachable" -ForegroundColor Green
53
53
  return $true
54
54
  }
55
55
  catch {
56
- Write-Host " Hosted package unavailable, checking npm registry..." -ForegroundColor Yellow
56
+ Write-Host "[WARN] Hosted package unavailable, checking npm registry..." -ForegroundColor Yellow
57
57
  }
58
58
 
59
59
  try {
60
60
  $response = Invoke-WebRequest -Uri "https://registry.npmjs.org/vigthoria-cli" -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
61
- Write-Host " npm registry is reachable" -ForegroundColor Green
61
+ Write-Host "[OK] npm registry is reachable" -ForegroundColor Green
62
62
  return $true
63
63
  }
64
64
  catch {
65
- Write-Host " Cannot reach hosted package or npm registry" -ForegroundColor Red
65
+ Write-Host "[ERROR] Cannot reach hosted package or npm registry" -ForegroundColor Red
66
66
  return $false
67
67
  }
68
68
  }
69
69
 
70
70
  function Test-Prerequisites {
71
- Write-Host "🔍 Checking prerequisites..." -ForegroundColor Yellow
71
+ Write-Host "[CHECK] Checking prerequisites..." -ForegroundColor Yellow
72
72
 
73
73
  # Check Node.js
74
74
  try {
@@ -77,16 +77,16 @@ function Test-Prerequisites {
77
77
  $versionText = $nodeVersion.TrimStart('v')
78
78
  $parsedVersion = [version]$versionText
79
79
  if ($parsedVersion -ge [version]"20.19.0") {
80
- Write-Host " Node.js $nodeVersion" -ForegroundColor Green
80
+ Write-Host "[OK] Node.js $nodeVersion" -ForegroundColor Green
81
81
  } else {
82
- Write-Host " Node.js 20.19+ required (found $nodeVersion)" -ForegroundColor Red
82
+ Write-Host "[ERROR] Node.js 20.19+ required (found $nodeVersion)" -ForegroundColor Red
83
83
  Write-Host " Download from: https://nodejs.org/" -ForegroundColor Yellow
84
84
  return $false
85
85
  }
86
86
  }
87
87
  }
88
88
  catch {
89
- Write-Host " Node.js is not installed" -ForegroundColor Red
89
+ Write-Host "[ERROR] Node.js is not installed" -ForegroundColor Red
90
90
  Write-Host ""
91
91
  Write-Host "Please install Node.js first:" -ForegroundColor Yellow
92
92
  Write-Host " Option 1: winget install OpenJS.NodeJS" -ForegroundColor White
@@ -99,11 +99,11 @@ function Test-Prerequisites {
99
99
  try {
100
100
  $npmVersion = npm -v 2>$null
101
101
  if ($npmVersion) {
102
- Write-Host " npm v$npmVersion" -ForegroundColor Green
102
+ Write-Host "[OK] npm v$npmVersion" -ForegroundColor Green
103
103
  }
104
104
  }
105
105
  catch {
106
- Write-Host " npm is not installed" -ForegroundColor Red
106
+ Write-Host "[ERROR] npm is not installed" -ForegroundColor Red
107
107
  return $false
108
108
  }
109
109
 
@@ -112,40 +112,40 @@ function Test-Prerequisites {
112
112
 
113
113
  function Install-VigthoriaCLI-NPM {
114
114
  Write-Host ""
115
- Write-Host "📦 Installing Vigthoria CLI..." -ForegroundColor Cyan
115
+ Write-Host "[INSTALL] Installing Vigthoria CLI..." -ForegroundColor Cyan
116
116
 
117
117
  try {
118
118
  npm install -g $HOSTED_TARBALL_URL
119
- Write-Host " Vigthoria CLI installed successfully!" -ForegroundColor Green
119
+ Write-Host "[OK] Vigthoria CLI installed successfully!" -ForegroundColor Green
120
120
  return $true
121
121
  }
122
122
  catch {
123
- Write-Host " Hosted package install failed, trying npm registry..." -ForegroundColor Yellow
123
+ Write-Host "[WARN] Hosted package install failed, trying npm registry..." -ForegroundColor Yellow
124
124
  }
125
125
 
126
126
  try {
127
127
  npm install -g vigthoria-cli
128
- Write-Host " Vigthoria CLI installed successfully!" -ForegroundColor Green
128
+ Write-Host "[OK] Vigthoria CLI installed successfully!" -ForegroundColor Green
129
129
  return $true
130
130
  }
131
131
  catch {
132
- Write-Host " npm registry install failed, trying git package..." -ForegroundColor Yellow
132
+ Write-Host "[WARN] npm registry install failed, trying git package..." -ForegroundColor Yellow
133
133
  }
134
134
 
135
135
  try {
136
136
  npm install -g $GIT_PACKAGE_URL
137
- Write-Host " Vigthoria CLI installed successfully from git package!" -ForegroundColor Green
137
+ Write-Host "[OK] Vigthoria CLI installed successfully from git package!" -ForegroundColor Green
138
138
  return $true
139
139
  }
140
140
  catch {
141
- Write-Host " install failed (hosted package + npm registry + git package): $_" -ForegroundColor Red
141
+ Write-Host "[ERROR] Install failed (hosted package + npm registry + git package): $_" -ForegroundColor Red
142
142
  return $false
143
143
  }
144
144
  }
145
145
 
146
146
  function Install-VigthoriaCLI-Direct {
147
147
  Write-Host ""
148
- Write-Host "📦 Installing Vigthoria CLI (Direct Download)..." -ForegroundColor Cyan
148
+ Write-Host "[INSTALL] Installing Vigthoria CLI (Direct Download)..." -ForegroundColor Cyan
149
149
 
150
150
  # Create install directory
151
151
  if (-not (Test-Path $INSTALL_DIR)) {
@@ -198,18 +198,18 @@ node "$packagePath\dist\index.js" %*
198
198
  # Cleanup
199
199
  Remove-Item $tarballPath -Force
200
200
 
201
- Write-Host " Vigthoria CLI installed successfully!" -ForegroundColor Green
201
+ Write-Host "[OK] Vigthoria CLI installed successfully!" -ForegroundColor Green
202
202
  return $true
203
203
  }
204
204
  catch {
205
- Write-Host " Direct install failed: $_" -ForegroundColor Red
205
+ Write-Host "[ERROR] Direct install failed: $_" -ForegroundColor Red
206
206
  return $false
207
207
  }
208
208
  }
209
209
 
210
210
  function Install-VigthoriaCLI-GitHub {
211
211
  Write-Host ""
212
- Write-Host "📦 Installing Vigthoria CLI (from Vigthoria Market)..." -ForegroundColor Cyan
212
+ Write-Host "[INSTALL] Installing Vigthoria CLI (from Vigthoria Market)..." -ForegroundColor Cyan
213
213
 
214
214
  # Create install directory
215
215
  if (-not (Test-Path $INSTALL_DIR)) {
@@ -222,7 +222,7 @@ function Install-VigthoriaCLI-GitHub {
222
222
  # Check if git is available
223
223
  $gitVersion = git --version 2>$null
224
224
  if (-not $gitVersion) {
225
- Write-Host " Git is not installed" -ForegroundColor Red
225
+ Write-Host "[ERROR] Git is not installed" -ForegroundColor Red
226
226
  return $false
227
227
  }
228
228
 
@@ -244,20 +244,20 @@ function Install-VigthoriaCLI-GitHub {
244
244
  npm link
245
245
  Pop-Location
246
246
 
247
- Write-Host " Vigthoria CLI installed successfully!" -ForegroundColor Green
247
+ Write-Host "[OK] Vigthoria CLI installed successfully!" -ForegroundColor Green
248
248
  return $true
249
249
  }
250
250
  catch {
251
- Write-Host " GitHub install failed: $_" -ForegroundColor Red
251
+ Write-Host "[ERROR] Git install failed: $_" -ForegroundColor Red
252
252
  return $false
253
253
  }
254
254
  }
255
255
 
256
256
  function Show-NetworkTroubleshooting {
257
257
  Write-Host ""
258
- Write-Host "═══════════════════════════════════════════════════════════════" -ForegroundColor Yellow
258
+ Write-Host "===============================================================" -ForegroundColor Yellow
259
259
  Write-Host " NETWORK TROUBLESHOOTING" -ForegroundColor Yellow
260
- Write-Host "═══════════════════════════════════════════════════════════════" -ForegroundColor Yellow
260
+ Write-Host "===============================================================" -ForegroundColor Yellow
261
261
  Write-Host ""
262
262
  Write-Host "The hosted package and npm registry could not be reached. Try these solutions:" -ForegroundColor White
263
263
  Write-Host ""
@@ -284,9 +284,9 @@ function Show-NetworkTroubleshooting {
284
284
 
285
285
  function Show-Success {
286
286
  Write-Host ""
287
- Write-Host "═══════════════════════════════════════════════════════════════" -ForegroundColor Green
287
+ Write-Host "===============================================================" -ForegroundColor Green
288
288
  Write-Host " INSTALLATION COMPLETE!" -ForegroundColor Green
289
- Write-Host "═══════════════════════════════════════════════════════════════" -ForegroundColor Green
289
+ Write-Host "===============================================================" -ForegroundColor Green
290
290
  Write-Host ""
291
291
  Write-Host " Get started:" -ForegroundColor White
292
292
  Write-Host " 1. Open a new terminal" -ForegroundColor Gray
package/install.sh CHANGED
@@ -26,12 +26,13 @@ else
26
26
  fi
27
27
 
28
28
  # Configuration
29
- CLI_VERSION="1.13.9"
29
+ CLI_VERSION="1.13.12"
30
30
  INSTALL_DIR="$HOME/.vigthoria"
31
31
  REPO_URL="https://market.vigthoria.io/vigthoria/vigthoria-cli"
32
32
  GIT_PACKAGE_URL="git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
33
33
  MANIFEST_URL="${VIGTHORIA_UPDATE_MANIFEST_URL:-https://extension.vigthoria.io/downloads/manifest.json}"
34
34
  HOSTED_TARBALL_URL="https://extension.vigthoria.io/downloads/vigthoria-cli-${CLI_VERSION}.tgz"
35
+ HOSTED_TARBALL_SHA256=""
35
36
 
36
37
  resolve_release_manifest() {
37
38
  if ! command -v curl >/dev/null 2>&1 || ! command -v python3 >/dev/null 2>&1; then
@@ -52,24 +53,34 @@ try:
52
53
  stable = (data.get('channels') or {}).get('stable') or {}
53
54
  version = str(stable.get('version') or '').strip()
54
55
  url = str(stable.get('url') or '').strip()
56
+ sha256 = str(stable.get('sha256') or '').strip().lower()
55
57
  if version:
56
58
  print(version)
57
59
  if url:
58
60
  print(url)
61
+ if sha256:
62
+ print(sha256)
59
63
  except Exception:
60
64
  pass
61
65
  " 2>/dev/null || true)"
62
66
 
63
67
  if [[ -n "$resolved" ]]; then
64
- mapfile -t _manifest_lines <<< "$resolved"
65
- if [[ -n "${_manifest_lines[0]:-}" ]]; then
66
- CLI_VERSION="${_manifest_lines[0]}"
68
+ # macOS ships Bash 3.2, which does not provide mapfile/readarray.
69
+ # Parse the two-line response with POSIX sed instead.
70
+ manifest_version="$(printf '%s\n' "$resolved" | sed -n '1p')"
71
+ manifest_url="$(printf '%s\n' "$resolved" | sed -n '2p')"
72
+ manifest_sha256="$(printf '%s\n' "$resolved" | sed -n '3p')"
73
+ if [[ -n "$manifest_version" ]]; then
74
+ CLI_VERSION="$manifest_version"
67
75
  fi
68
- if [[ -n "${_manifest_lines[1]:-}" ]]; then
69
- HOSTED_TARBALL_URL="${_manifest_lines[1]}"
70
- elif [[ -n "${_manifest_lines[0]:-}" ]]; then
76
+ if [[ -n "$manifest_url" ]]; then
77
+ HOSTED_TARBALL_URL="$manifest_url"
78
+ elif [[ -n "$manifest_version" ]]; then
71
79
  HOSTED_TARBALL_URL="https://extension.vigthoria.io/downloads/vigthoria-cli-${CLI_VERSION}.tgz"
72
80
  fi
81
+ if [[ "$manifest_sha256" =~ ^[a-f0-9]{64}$ ]]; then
82
+ HOSTED_TARBALL_SHA256="$manifest_sha256"
83
+ fi
73
84
  fi
74
85
  }
75
86
 
@@ -177,10 +188,32 @@ install_cli() {
177
188
  # Create install directory
178
189
  mkdir -p "$INSTALL_DIR"
179
190
 
180
- # Option 1: Install the hosted release package.
181
- if curl -fsI "$HOSTED_TARBALL_URL" > /dev/null 2>&1; then
182
- echo "Installing hosted release package..."
183
- npm install -g --force "$HOSTED_TARBALL_URL"
191
+ # Option 1: Download and verify the exact hosted release package.
192
+ if [[ -n "$HOSTED_TARBALL_SHA256" ]]; then
193
+ echo "Downloading checksum-verified hosted release package..."
194
+ RELEASE_TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/vigthoria-cli-install.XXXXXX")"
195
+ RELEASE_ARCHIVE="$RELEASE_TMP_DIR/vigthoria-cli-${CLI_VERSION}.tgz"
196
+ if ! curl -fsSL "$HOSTED_TARBALL_URL" -o "$RELEASE_ARCHIVE"; then
197
+ rm -rf "$RELEASE_TMP_DIR"
198
+ echo -e "${RED}✗ Failed to download verified release package${NC}"
199
+ exit 1
200
+ fi
201
+ if command -v shasum >/dev/null 2>&1; then
202
+ ACTUAL_SHA256="$(shasum -a 256 "$RELEASE_ARCHIVE" | awk '{print $1}')"
203
+ elif command -v sha256sum >/dev/null 2>&1; then
204
+ ACTUAL_SHA256="$(sha256sum "$RELEASE_ARCHIVE" | awk '{print $1}')"
205
+ else
206
+ rm -rf "$RELEASE_TMP_DIR"
207
+ echo -e "${RED}✗ SHA-256 verification tool is unavailable${NC}"
208
+ exit 1
209
+ fi
210
+ if [[ "$ACTUAL_SHA256" != "$HOSTED_TARBALL_SHA256" ]]; then
211
+ rm -rf "$RELEASE_TMP_DIR"
212
+ echo -e "${RED}✗ Release checksum verification failed${NC}"
213
+ exit 1
214
+ fi
215
+ npm install -g --force "$RELEASE_ARCHIVE"
216
+ rm -rf "$RELEASE_TMP_DIR"
184
217
  elif npm view vigthoria-cli version &> /dev/null; then
185
218
  echo "Installing from npm registry..."
186
219
  npm install -g --force vigthoria-cli
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vigthoria-cli",
3
- "version": "1.13.11",
3
+ "version": "1.13.12",
4
4
  "description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",