idlebench 1.0.0 → 1.0.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAmIA,wBAAsB,mBAAmB,kBAgNxC"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AA8IA,wBAAsB,mBAAmB,kBAgMxC"}
@@ -9,23 +9,25 @@ import { getNetworkInfo } from '../lib/network.js';
9
9
  import { runBenchmark } from '../lib/benchmark.js';
10
10
  import { calculateGpuScore, calculateRuntimeScore, calculateNetworkScore, calculateInferenceScore, calculateStabilityScore, calculateFinalScore, getGrade, } from '../lib/scoring.js';
11
11
  import { buildReport, saveReportLocally } from '../lib/report.js';
12
- const CLI_VERSION = '1.0.0';
13
- const DEFAULT_API_URL = 'https://idlebench.com';
12
+ import { createRequire } from 'module';
13
+ const require = createRequire(import.meta.url);
14
+ const { version: CLI_VERSION } = require('../../package.json');
15
+ const DEFAULT_API_URL = 'https://idlebench.vercel.app';
14
16
  function line() {
15
17
  console.log(chalk.dim(' ─────────────────────────────────────────'));
16
18
  }
17
19
  function header() {
18
20
  console.log();
19
- console.log(chalk.bold.white(' IdleBench'));
21
+ console.log(chalk.bold.white(' IdleBench') + chalk.dim(` v${CLI_VERSION}`));
20
22
  console.log(chalk.dim(' The verification layer for idle compute.'));
21
23
  console.log();
22
- console.log(chalk.bgYellow.black(' SECURITY NOTICE ') + chalk.yellow(' IdleBench never asks for private keys or seed phrases.'));
24
+ console.log(chalk.bgYellow.black(' SECURITY ') + chalk.yellow(' IdleBench never asks for private keys or seed phrases.'));
23
25
  console.log();
24
26
  line();
25
27
  console.log();
26
28
  }
27
29
  function checkRow(label, value, ok) {
28
- const icon = ok === true ? chalk.green('✓') : ok === false ? chalk.red('✗') : chalk.yellow('—');
30
+ const icon = ok === true ? chalk.green('✓') : ok === false ? chalk.red('✗') : chalk.dim('—');
29
31
  console.log(` ${icon} ${chalk.dim(label.padEnd(26))} ${chalk.white(value)}`);
30
32
  }
31
33
  function scoreBar(label, score, width = 20) {
@@ -34,6 +36,31 @@ function scoreBar(label, score, width = 20) {
34
36
  const color = score >= 85 ? chalk.green : score >= 70 ? chalk.yellow : chalk.red;
35
37
  console.log(` ${chalk.dim(label.padEnd(28))} ${color(bar)} ${chalk.bold(score)}`);
36
38
  }
39
+ async function safeJsonFetch(url, options) {
40
+ let rawText = '';
41
+ try {
42
+ const res = await fetch(url, options);
43
+ rawText = await res.text();
44
+ let json;
45
+ try {
46
+ json = JSON.parse(rawText);
47
+ }
48
+ catch {
49
+ throw new Error(`Server returned non-JSON (HTTP ${res.status}). ` +
50
+ (rawText.length > 0 ? rawText.slice(0, 120) : 'Empty response.'));
51
+ }
52
+ if (!res.ok) {
53
+ const msg = typeof json.error === 'string' ? json.error : `HTTP ${res.status}`;
54
+ throw new Error(msg);
55
+ }
56
+ return json;
57
+ }
58
+ catch (err) {
59
+ if (err instanceof Error)
60
+ throw err;
61
+ throw new Error(`Network error: ${String(err)}`);
62
+ }
63
+ }
37
64
  async function promptSetup() {
38
65
  console.log(chalk.dim(' Answer a few questions to configure your benchmark.\n'));
39
66
  const answers = await inquirer.prompt([
@@ -42,11 +69,11 @@ async function promptSetup() {
42
69
  name: 'providerWallet',
43
70
  message: 'Solana wallet address (public key):',
44
71
  validate: (input) => {
45
- if (!input.trim())
72
+ const t = input.trim();
73
+ if (!t)
46
74
  return 'Wallet address is required';
47
- if (input.trim().length < 32 || input.trim().length > 44) {
48
- return 'Wallet address must be 32-44 characters';
49
- }
75
+ if (t.length < 32 || t.length > 44)
76
+ return 'Solana wallet address must be 3244 characters';
50
77
  return true;
51
78
  },
52
79
  },
@@ -74,7 +101,7 @@ async function promptSetup() {
74
101
  {
75
102
  type: 'input',
76
103
  name: 'idleGatewayUrl',
77
- message: 'IDLE gateway URL (optional, press Enter to skip):',
104
+ message: 'IDLE endpoint URL (from earnidle.com, optional — press Enter to skip):',
78
105
  default: '',
79
106
  validate: (input) => {
80
107
  if (!input.trim())
@@ -84,22 +111,7 @@ async function promptSetup() {
84
111
  return true;
85
112
  }
86
113
  catch {
87
- return 'Enter a valid URL or leave blank';
88
- }
89
- },
90
- },
91
- {
92
- type: 'input',
93
- name: 'apiUrl',
94
- message: `IdleBench API URL:`,
95
- default: DEFAULT_API_URL,
96
- validate: (input) => {
97
- try {
98
- new URL(input.trim());
99
- return true;
100
- }
101
- catch {
102
- return 'Enter a valid URL';
114
+ return 'Enter a valid URL (e.g. https://gateway.earnidle.com/ep/...) or leave blank';
103
115
  }
104
116
  },
105
117
  },
@@ -109,7 +121,7 @@ async function promptSetup() {
109
121
  resourceName: answers.resourceName.trim(),
110
122
  resourceType: answers.resourceType,
111
123
  idleGatewayUrl: answers.idleGatewayUrl.trim() || null,
112
- apiUrl: answers.apiUrl.trim(),
124
+ apiUrl: process.env.IDLEBENCH_API_URL?.trim() ?? DEFAULT_API_URL,
113
125
  };
114
126
  }
115
127
  export async function runBenchmarkCommand() {
@@ -135,7 +147,7 @@ export async function runBenchmarkCommand() {
135
147
  }
136
148
  catch (err) {
137
149
  spinner.fail('Failed to read system info');
138
- throw err;
150
+ throw new Error(`System check failed: ${err instanceof Error ? err.message : err}`);
139
151
  }
140
152
  }
141
153
  console.log();
@@ -143,19 +155,25 @@ export async function runBenchmarkCommand() {
143
155
  let gpu;
144
156
  {
145
157
  const spinner = ora({ text: 'Detecting GPU', color: 'green' }).start();
146
- gpu = await getGpuInfo();
147
- spinner.succeed(chalk.dim('GPU detection'));
148
- if (gpu.name) {
149
- checkRow('GPU Model', gpu.name, true);
150
- if (gpu.vramGb)
151
- checkRow('VRAM', `${gpu.vramGb} GB`);
152
- checkRow('CUDA', gpu.cudaAvailable ? `${gpu.cudaVersion ?? 'Available'}` : 'Not available', gpu.cudaAvailable);
153
- if (gpu.driverVersion)
154
- checkRow('NVIDIA Driver', gpu.driverVersion, true);
158
+ try {
159
+ gpu = await getGpuInfo();
160
+ spinner.succeed(chalk.dim('GPU detection'));
161
+ if (gpu.name) {
162
+ checkRow('GPU Model', gpu.name, true);
163
+ if (gpu.vramGb)
164
+ checkRow('VRAM', `${gpu.vramGb} GB`);
165
+ checkRow('CUDA', gpu.cudaAvailable ? `${gpu.cudaVersion ?? 'Available'}` : 'Not available', gpu.cudaAvailable);
166
+ if (gpu.driverVersion)
167
+ checkRow('NVIDIA Driver', gpu.driverVersion, true);
168
+ }
169
+ else {
170
+ checkRow('GPU', 'Not detected', null);
171
+ console.log(chalk.dim(' → No GPU found. Running CPU-only checks.'));
172
+ }
155
173
  }
156
- else {
157
- checkRow('GPU', 'Not detected', null);
158
- console.log(chalk.dim(' No GPU detected running CPU-only checks'));
174
+ catch (err) {
175
+ spinner.warn('GPU detection failed — continuing');
176
+ gpu = { name: null, vendor: null, vramGb: null, cudaAvailable: false, cudaVersion: null, driverVersion: null, temperature: null, utilizationPercent: null, detectionMethod: 'failed' };
159
177
  }
160
178
  }
161
179
  console.log();
@@ -163,72 +181,62 @@ export async function runBenchmarkCommand() {
163
181
  let docker;
164
182
  {
165
183
  const spinner = ora({ text: 'Checking Docker', color: 'green' }).start();
166
- docker = await getDockerInfo();
167
- spinner.succeed(chalk.dim('Docker check'));
168
- checkRow('Docker', docker.available ? `v${docker.version}` : 'Not installed', docker.available);
169
- if (docker.available) {
170
- if (docker.gpuRuntime) {
171
- checkRow('Docker GPU Runtime', 'Available', true);
172
- }
173
- else {
174
- checkRow('Docker GPU Runtime', docker.gpuRuntimeError ?? 'Not available', false);
184
+ try {
185
+ docker = await getDockerInfo();
186
+ spinner.succeed(chalk.dim('Docker check'));
187
+ checkRow('Docker', docker.available ? `v${docker.version}` : 'Not installed', docker.available);
188
+ if (docker.available) {
189
+ checkRow('Docker GPU Runtime', docker.gpuRuntime ? 'Available' : (docker.gpuRuntimeError ?? 'Not available'), docker.gpuRuntime);
175
190
  }
176
191
  }
192
+ catch (err) {
193
+ spinner.warn('Docker check failed — continuing');
194
+ docker = { available: false, version: null, gpuRuntime: false, gpuRuntimeError: 'Check failed' };
195
+ }
177
196
  }
178
197
  console.log();
179
198
  // Benchmark
180
199
  let benchmarkResult;
181
200
  {
182
201
  const spinner = ora({ text: 'Running benchmark', color: 'green' }).start();
183
- benchmarkResult = await runBenchmark();
184
- spinner.succeed(chalk.dim('Benchmark complete'));
185
- checkRow('CPU hash workload', `${benchmarkResult.cpuHashMs}ms`);
186
- checkRow('Matrix calculation', `${benchmarkResult.matrixMs}ms`);
202
+ try {
203
+ benchmarkResult = await runBenchmark();
204
+ spinner.succeed(chalk.dim('Benchmark complete'));
205
+ checkRow('CPU hash workload', `${benchmarkResult.cpuHashMs}ms`);
206
+ checkRow('Matrix calculation', `${benchmarkResult.matrixMs}ms`);
207
+ }
208
+ catch (err) {
209
+ spinner.warn('Benchmark failed — using defaults');
210
+ benchmarkResult = { cpuHashMs: 500, matrixMs: 500, totalMs: 1000 };
211
+ }
187
212
  }
188
213
  console.log();
189
214
  // Network
190
215
  let network;
191
216
  {
192
217
  const spinner = ora({ text: 'Testing network', color: 'green' }).start();
193
- network = await getNetworkInfo(apiUrl);
194
- spinner.succeed(chalk.dim('Network check'));
195
- checkRow('Latency', network.latencyMs !== null ? `${network.latencyMs}ms` : 'Could not measure', network.latencyMs !== null);
196
- if (network.downloadMbps !== null) {
197
- checkRow('Download estimate', `${network.downloadMbps} Mbps`);
218
+ try {
219
+ network = await getNetworkInfo(apiUrl);
220
+ spinner.succeed(chalk.dim('Network check'));
221
+ checkRow('Latency', network.latencyMs !== null ? `${network.latencyMs}ms` : 'Could not measure', network.latencyMs !== null && network.latencyMs < 500);
222
+ if (network.downloadMbps !== null)
223
+ checkRow('Download estimate', `${network.downloadMbps} Mbps`);
224
+ }
225
+ catch (err) {
226
+ spinner.warn('Network check failed — continuing');
227
+ network = { latencyMs: null, downloadMbps: null, uploadMbps: null };
198
228
  }
199
229
  }
200
230
  console.log();
201
231
  line();
202
232
  console.log();
203
233
  // Calculate scores
204
- const gpuScore = calculateGpuScore({
205
- gpuName: gpu.name,
206
- vramGb: gpu.vramGb,
207
- cpuCores: system.cpuCores,
208
- ramGb: system.ramGb,
209
- cudaAvailable: gpu.cudaAvailable,
210
- dockerAvailable: docker.available,
211
- dockerGpuRuntime: docker.gpuRuntime,
212
- });
213
- const runtimeScore = calculateRuntimeScore({
214
- gpuName: gpu.name,
215
- vramGb: gpu.vramGb,
216
- cpuCores: system.cpuCores,
217
- ramGb: system.ramGb,
218
- cudaAvailable: gpu.cudaAvailable,
219
- dockerAvailable: docker.available,
220
- dockerGpuRuntime: docker.gpuRuntime,
221
- });
234
+ const gpuScore = calculateGpuScore({ gpuName: gpu.name, vramGb: gpu.vramGb, cpuCores: system.cpuCores, ramGb: system.ramGb, cudaAvailable: gpu.cudaAvailable, dockerAvailable: docker.available, dockerGpuRuntime: docker.gpuRuntime });
235
+ const runtimeScore = calculateRuntimeScore({ gpuName: gpu.name, vramGb: gpu.vramGb, cpuCores: system.cpuCores, ramGb: system.ramGb, cudaAvailable: gpu.cudaAvailable, dockerAvailable: docker.available, dockerGpuRuntime: docker.gpuRuntime });
222
236
  const networkScore = calculateNetworkScore(network.latencyMs);
223
237
  const inferenceScore = calculateInferenceScore(system.cpuCores, system.ramGb, benchmarkResult.totalMs, gpu.name);
224
238
  const stabilityScore = calculateStabilityScore(system.cpuCores, system.ramGb);
225
- const finalScore = calculateFinalScore({
226
- gpuScore,
227
- runtimeScore,
228
- networkScore,
229
- inferenceScore,
230
- stabilityScore,
231
- });
239
+ const finalScore = calculateFinalScore({ gpuScore, runtimeScore, networkScore, inferenceScore, stabilityScore });
232
240
  const grade = getGrade(finalScore);
233
241
  console.log(chalk.bold(' Score breakdown'));
234
242
  console.log();
@@ -243,7 +251,7 @@ export async function runBenchmarkCommand() {
243
251
  console.log();
244
252
  line();
245
253
  console.log();
246
- // Build report
254
+ // Build + save report
247
255
  const report = buildReport({
248
256
  reportVersion: '1.0.0',
249
257
  providerWallet,
@@ -258,27 +266,25 @@ export async function runBenchmarkCommand() {
258
266
  benchmarkMs: benchmarkResult.totalMs,
259
267
  cliVersion: CLI_VERSION,
260
268
  });
261
- // Save locally
262
- const localPath = saveReportLocally(report);
263
- console.log(chalk.dim(` Report saved locally: ${localPath}`));
269
+ let localPath;
270
+ try {
271
+ localPath = saveReportLocally(report);
272
+ console.log(chalk.dim(` Report saved locally: ${localPath}`));
273
+ }
274
+ catch {
275
+ localPath = 'unknown';
276
+ console.log(chalk.dim(' Could not save report locally.'));
277
+ }
264
278
  console.log();
265
279
  // Upload
266
280
  const uploadSpinner = ora({ text: `Uploading to ${apiUrl}`, color: 'green' }).start();
267
281
  try {
268
- const res = await fetch(`${apiUrl}/api/reports/upload`, {
282
+ const json = await safeJsonFetch(`${apiUrl}/api/reports/upload`, {
269
283
  method: 'POST',
270
284
  headers: { 'Content-Type': 'application/json' },
271
285
  body: JSON.stringify(report),
272
286
  signal: AbortSignal.timeout(30000),
273
287
  });
274
- const json = await res.json();
275
- if (!res.ok) {
276
- uploadSpinner.fail('Upload failed');
277
- console.error(chalk.red(` ✗ Server error: ${JSON.stringify(json)}`));
278
- console.log(chalk.dim(` Your report was saved locally: ${localPath}`));
279
- console.log(chalk.dim(` You can upload it later with: idlebench upload ${localPath}`));
280
- return;
281
- }
282
288
  uploadSpinner.succeed('Report uploaded');
283
289
  console.log();
284
290
  console.log(chalk.bold(' Benchmark complete.'));
@@ -288,15 +294,16 @@ export async function runBenchmarkCommand() {
288
294
  console.log(chalk.dim(' Public URL: '), chalk.cyan(String(json.publicUrl)));
289
295
  console.log(chalk.dim(' Local report: '), chalk.dim(localPath));
290
296
  console.log();
291
- console.log(chalk.dim(' Attach the badge to your IDLE listing or GitHub README:'));
292
- console.log(chalk.dim(` Badge URL: ${apiUrl}/api/badge/${json.resourceId}`));
297
+ console.log(chalk.dim(` Badge: ${apiUrl}/api/badge/${json.resourceId}`));
293
298
  console.log();
294
299
  }
295
300
  catch (err) {
296
- uploadSpinner.fail('Upload failed — network error');
301
+ uploadSpinner.fail('Upload failed');
302
+ console.error();
297
303
  console.error(chalk.red(` ✗ ${err instanceof Error ? err.message : err}`));
298
- console.log();
304
+ console.error();
299
305
  console.log(chalk.dim(` Your report was saved locally: ${localPath}`));
300
306
  console.log(chalk.dim(` Upload later with: idlebench upload ${localPath}`));
307
+ console.log();
301
308
  }
302
309
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAqCA,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,iBA2D7E"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAqCA,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,iBAoE7E"}
@@ -65,10 +65,20 @@ export async function runUpload(filePath, options) {
65
65
  body: rawJson,
66
66
  signal: AbortSignal.timeout(30000),
67
67
  });
68
- const json = await res.json();
68
+ const rawText = await res.text();
69
+ let json;
70
+ try {
71
+ json = JSON.parse(rawText);
72
+ }
73
+ catch {
74
+ spinner.fail('Upload failed');
75
+ console.error(chalk.red(` ✗ Server returned non-JSON (HTTP ${res.status}):`));
76
+ console.error(chalk.dim(` ${rawText.slice(0, 200)}`));
77
+ process.exit(1);
78
+ }
69
79
  if (!res.ok) {
70
80
  spinner.fail('Upload failed');
71
- console.error(chalk.red(` ✗ ${JSON.stringify(json)}`));
81
+ console.error(chalk.red(` ✗ ${typeof json.error === 'string' ? json.error : JSON.stringify(json)}`));
72
82
  process.exit(1);
73
83
  }
74
84
  spinner.succeed('Report uploaded');
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
3
  import chalk from 'chalk';
4
+ import { createRequire } from 'module';
4
5
  import { runBenchmarkCommand } from './commands/run.js';
5
6
  import { runDoctor } from './commands/doctor.js';
6
7
  import { runUpload } from './commands/upload.js';
7
- const VERSION = '1.0.0';
8
+ const require = createRequire(import.meta.url);
9
+ const { version: VERSION } = require('../package.json');
8
10
  const program = new Command();
9
11
  program
10
12
  .name('idlebench')
@@ -1 +1 @@
1
- {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/lib/docker.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,UAAU,EAAE,OAAO,CAAA;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAkDzD"}
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/lib/docker.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,UAAU,EAAE,OAAO,CAAA;IACnB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAeD,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAuCzD"}
@@ -1,48 +1,48 @@
1
1
  import { execa } from 'execa';
2
- export async function getDockerInfo() {
3
- // Check if docker is installed
4
- let version = null;
2
+ async function runCmd(cmd, args, timeoutMs = 8000) {
5
3
  try {
6
- const { stdout } = await execa('docker', ['--version'], { timeout: 6000 });
7
- const match = stdout.match(/Docker version ([\d.]+)/);
8
- version = match ? match[1] : stdout.trim().split('\n')[0];
4
+ const { stdout } = await execa(cmd, args, {
5
+ timeout: timeoutMs,
6
+ shell: true, // use system shell — resolves PATH on Windows
7
+ reject: true,
8
+ });
9
+ return stdout.trim();
9
10
  }
10
11
  catch {
11
- return { available: false, version: null, gpuRuntime: false, gpuRuntimeError: 'Docker not installed' };
12
+ return null;
12
13
  }
13
- // Check docker daemon is running
14
- try {
15
- await execa('docker', ['info'], { timeout: 8000 });
14
+ }
15
+ export async function getDockerInfo() {
16
+ // Check version
17
+ const versionOut = await runCmd('docker', ['--version']);
18
+ if (!versionOut) {
19
+ return { available: false, version: null, gpuRuntime: false, gpuRuntimeError: 'Docker not found in PATH' };
16
20
  }
17
- catch {
21
+ const match = versionOut.match(/Docker version ([\d.]+)/);
22
+ const version = match ? match[1] : versionOut.split('\n')[0];
23
+ // Check daemon is running
24
+ const infoOut = await runCmd('docker', ['info', '--format', '{{.ServerVersion}}'], 10000);
25
+ if (!infoOut) {
18
26
  return { available: false, version, gpuRuntime: false, gpuRuntimeError: 'Docker daemon not running' };
19
27
  }
20
- // Try GPU runtime
28
+ // Test GPU passthrough
21
29
  let gpuRuntime = false;
22
30
  let gpuRuntimeError = null;
23
31
  try {
24
- await execa('docker', [
25
- 'run', '--rm',
26
- '--gpus', 'all',
27
- 'nvidia/cuda:12.3.0-base-ubuntu22.04',
28
- 'nvidia-smi', '-L',
29
- ], { timeout: 60000 });
30
- gpuRuntime = true;
32
+ const { stdout } = await execa('docker', ['run', '--rm', '--gpus', 'all', 'nvidia/cuda:12.3.0-base-ubuntu22.04', 'nvidia-smi', '-L'], { timeout: 60000, shell: true });
33
+ gpuRuntime = stdout.length > 0;
31
34
  }
32
35
  catch (err) {
33
- gpuRuntimeError = err instanceof Error ? err.message : 'GPU runtime test failed';
34
- // Check if it's a known non-GPU error vs docker error
35
- if (gpuRuntimeError.includes('could not select device driver')) {
36
+ const msg = err instanceof Error ? err.message : String(err);
37
+ if (msg.includes('could not select device driver') || msg.includes('nvidia')) {
36
38
  gpuRuntimeError = 'NVIDIA container toolkit not installed';
37
39
  }
38
- else if (gpuRuntimeError.includes('Unable to find image')) {
40
+ else if (msg.includes('Unable to find image')) {
39
41
  gpuRuntimeError = 'Could not pull test image';
40
42
  }
43
+ else {
44
+ gpuRuntimeError = 'GPU runtime not available';
45
+ }
41
46
  }
42
- return {
43
- available: true,
44
- version,
45
- gpuRuntime,
46
- gpuRuntimeError,
47
- };
47
+ return { available: true, version, gpuRuntime, gpuRuntimeError };
48
48
  }
package/dist/lib/gpu.js CHANGED
@@ -5,7 +5,7 @@ async function tryNvidiaSmi() {
5
5
  const { stdout } = await execa('nvidia-smi', [
6
6
  '--query-gpu=name,memory.total,driver_version,utilization.gpu,temperature.gpu',
7
7
  '--format=csv,noheader,nounits',
8
- ], { timeout: 8000 });
8
+ ], { timeout: 8000, shell: true });
9
9
  const lines = stdout.trim().split('\n');
10
10
  if (lines.length === 0)
11
11
  return null;
@@ -15,7 +15,7 @@ async function tryNvidiaSmi() {
15
15
  let cudaVersion = null;
16
16
  let cudaAvailable = false;
17
17
  try {
18
- const { stdout: smiOut } = await execa('nvidia-smi', [], { timeout: 5000 });
18
+ const { stdout: smiOut } = await execa('nvidia-smi', [], { timeout: 5000, shell: true });
19
19
  const cudaMatch = smiOut.match(/CUDA Version:\s*([\d.]+)/);
20
20
  if (cudaMatch) {
21
21
  cudaVersion = cudaMatch[1];
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "idlebench",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Benchmark and verify idle compute before it earns. The CLI for IDLE compute providers.",
5
5
  "license": "MIT",
6
6
  "author": "IdleBench",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/idlebench/idlebench-cli"
10
- },
7
+ "homepage": "https://idlebench.com",
11
8
  "keywords": [
12
9
  "benchmark",
13
10
  "gpu",
@@ -24,7 +21,8 @@
24
21
  "files": [
25
22
  "dist",
26
23
  "README.md",
27
- "LICENSE"
24
+ "LICENSE",
25
+ "package.json"
28
26
  ],
29
27
  "scripts": {
30
28
  "build": "tsc",