gitarsenal-cli 1.9.32 → 1.9.34
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/.venv_status.json +1 -1
- package/bin/gitarsenal.js +163 -1
- package/package.json +1 -1
package/.venv_status.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"created":"2025-08-10T17:
|
|
1
|
+
{"created":"2025-08-10T17:58:47.793Z","packages":["modal","gitingest","requests","anthropic"],"uv_version":"uv 0.8.4 (Homebrew 2025-07-30)"}
|
package/bin/gitarsenal.js
CHANGED
|
@@ -104,6 +104,163 @@ function activateVirtualEnvironment() {
|
|
|
104
104
|
return true;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
// Lightweight preview of GPU/Torch/CUDA recommendations prior to GPU selection
|
|
108
|
+
async function previewRecommendations(repoUrl) {
|
|
109
|
+
const spinner = ora('Analyzing repository for GPU/Torch/CUDA recommendations...').start();
|
|
110
|
+
try {
|
|
111
|
+
const apiUrl = process.env.GITARSENAL_API_URL || 'https://www.gitarsenal.dev/api/gitingest-setup-commands';
|
|
112
|
+
const payload = {
|
|
113
|
+
repoUrl,
|
|
114
|
+
// Minimal GitIngest data to allow backend to run LLM analysis
|
|
115
|
+
gitingestData: {
|
|
116
|
+
system_info: {
|
|
117
|
+
platform: process.platform,
|
|
118
|
+
python_version: process.version,
|
|
119
|
+
detected_language: 'Unknown',
|
|
120
|
+
detected_technologies: [],
|
|
121
|
+
file_count: 0,
|
|
122
|
+
repo_stars: 0,
|
|
123
|
+
repo_forks: 0,
|
|
124
|
+
primary_package_manager: 'Unknown',
|
|
125
|
+
complexity_level: 'Unknown'
|
|
126
|
+
},
|
|
127
|
+
repository_analysis: {
|
|
128
|
+
summary: `Repository: ${repoUrl}`,
|
|
129
|
+
tree: '',
|
|
130
|
+
content_preview: ''
|
|
131
|
+
},
|
|
132
|
+
success: true
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Use global fetch (Node 18+) and follow redirects
|
|
137
|
+
const res = await fetch(apiUrl, {
|
|
138
|
+
method: 'POST',
|
|
139
|
+
headers: {
|
|
140
|
+
'Content-Type': 'application/json',
|
|
141
|
+
'User-Agent': 'GitArsenal-CLI/1.0'
|
|
142
|
+
},
|
|
143
|
+
body: JSON.stringify(payload),
|
|
144
|
+
redirect: 'follow'
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
spinner.stop();
|
|
148
|
+
|
|
149
|
+
if (!res.ok) {
|
|
150
|
+
const text = await res.text().catch(() => '');
|
|
151
|
+
console.log(chalk.yellow(`⚠️ Preview request failed (${res.status}).`));
|
|
152
|
+
if (text) console.log(chalk.gray(`Response: ${text.slice(0, 500)}`));
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const data = await res.json().catch(() => null);
|
|
157
|
+
if (!data) {
|
|
158
|
+
console.log(chalk.yellow('⚠️ Could not parse recommendations preview response.'));
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
printGpuTorchCudaSummary(data);
|
|
163
|
+
return data;
|
|
164
|
+
} catch (e) {
|
|
165
|
+
spinner.stop();
|
|
166
|
+
console.log(chalk.yellow(`⚠️ Preview failed: ${e.message}`));
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function httpPostJson(urlString, body) {
|
|
172
|
+
return new Promise((resolve) => {
|
|
173
|
+
try {
|
|
174
|
+
const urlObj = new URL(urlString);
|
|
175
|
+
const data = JSON.stringify(body);
|
|
176
|
+
const options = {
|
|
177
|
+
hostname: urlObj.hostname,
|
|
178
|
+
port: urlObj.port || (urlObj.protocol === 'https:' ? 443 : 80),
|
|
179
|
+
path: urlObj.pathname,
|
|
180
|
+
method: 'POST',
|
|
181
|
+
headers: {
|
|
182
|
+
'Content-Type': 'application/json',
|
|
183
|
+
'Content-Length': Buffer.byteLength(data),
|
|
184
|
+
'User-Agent': 'GitArsenal-CLI/1.0'
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const client = urlObj.protocol === 'https:' ? https : http;
|
|
188
|
+
const req = client.request(options, (res) => {
|
|
189
|
+
let responseData = '';
|
|
190
|
+
res.on('data', (chunk) => {
|
|
191
|
+
responseData += chunk;
|
|
192
|
+
});
|
|
193
|
+
res.on('end', () => {
|
|
194
|
+
try {
|
|
195
|
+
const parsed = JSON.parse(responseData);
|
|
196
|
+
resolve(parsed);
|
|
197
|
+
} catch (err) {
|
|
198
|
+
resolve(null);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
req.on('error', () => resolve(null));
|
|
203
|
+
req.write(data);
|
|
204
|
+
req.end();
|
|
205
|
+
} catch (e) {
|
|
206
|
+
resolve(null);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function printGpuTorchCudaSummary(result) {
|
|
212
|
+
try {
|
|
213
|
+
console.log(chalk.bold('\n📊 API RESULT SUMMARY (GPU/Torch/CUDA)'));
|
|
214
|
+
console.log('────────────────────────────────────────────────────────');
|
|
215
|
+
|
|
216
|
+
const cuda = result.cudaRecommendation;
|
|
217
|
+
if (cuda) {
|
|
218
|
+
console.log(chalk.bold('🎯 CUDA Recommendation'));
|
|
219
|
+
if (cuda.recommendedCudaVersion) console.log(` - CUDA: ${cuda.recommendedCudaVersion}`);
|
|
220
|
+
if (Array.isArray(cuda.compatibleTorchVersions) && cuda.compatibleTorchVersions.length)
|
|
221
|
+
console.log(` - Torch Compatibility: ${cuda.compatibleTorchVersions.join(', ')}`);
|
|
222
|
+
if (cuda.dockerImage) console.log(` - Docker Image: ${cuda.dockerImage}`);
|
|
223
|
+
if (Array.isArray(cuda.installCommands) && cuda.installCommands.length) {
|
|
224
|
+
console.log(' - Install Commands:');
|
|
225
|
+
cuda.installCommands.forEach((c) => console.log(` $ ${c}`));
|
|
226
|
+
}
|
|
227
|
+
if (cuda.notes) console.log(` - Notes: ${cuda.notes}`);
|
|
228
|
+
console.log();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const torch = result.torchRecommendation;
|
|
232
|
+
if (torch) {
|
|
233
|
+
console.log(chalk.bold('🔥 PyTorch Recommendation'));
|
|
234
|
+
if (torch.recommendedTorchVersion) console.log(` - Torch: ${torch.recommendedTorchVersion}`);
|
|
235
|
+
if (torch.cudaVariant) console.log(` - CUDA Variant: ${torch.cudaVariant}`);
|
|
236
|
+
if (torch.pipInstallCommand) {
|
|
237
|
+
console.log(' - Install:');
|
|
238
|
+
console.log(` $ ${torch.pipInstallCommand}`);
|
|
239
|
+
}
|
|
240
|
+
if (Array.isArray(torch.extraPackages) && torch.extraPackages.length)
|
|
241
|
+
console.log(` - Extra Packages: ${torch.extraPackages.join(', ')}`);
|
|
242
|
+
if (torch.notes) console.log(` - Notes: ${torch.notes}`);
|
|
243
|
+
console.log();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const gpu = result.gpuRecommendation;
|
|
247
|
+
if (gpu) {
|
|
248
|
+
console.log(chalk.bold('🖥️ GPU Recommendation'));
|
|
249
|
+
if (gpu.minimumVramGb !== undefined) console.log(` - Min VRAM: ${gpu.minimumVramGb} GB`);
|
|
250
|
+
if (gpu.recommendedVramGb !== undefined) console.log(` - Recommended VRAM: ${gpu.recommendedVramGb} GB`);
|
|
251
|
+
if (gpu.minComputeCapability) console.log(` - Min Compute Capability: ${gpu.minComputeCapability}`);
|
|
252
|
+
if (Array.isArray(gpu.recommendedModels) && gpu.recommendedModels.length)
|
|
253
|
+
console.log(` - Recommended Models: ${gpu.recommendedModels.join(', ')}`);
|
|
254
|
+
if (Array.isArray(gpu.budgetOptions) && gpu.budgetOptions.length)
|
|
255
|
+
console.log(` - Budget Options: ${gpu.budgetOptions.join(', ')}`);
|
|
256
|
+
if (Array.isArray(gpu.cloudInstances) && gpu.cloudInstances.length)
|
|
257
|
+
console.log(` - Cloud Instances: ${gpu.cloudInstances.join(', ')}`);
|
|
258
|
+
if (gpu.notes) console.log(` - Notes: ${gpu.notes}`);
|
|
259
|
+
console.log();
|
|
260
|
+
}
|
|
261
|
+
} catch {}
|
|
262
|
+
}
|
|
263
|
+
|
|
107
264
|
// Function to send user data to web application
|
|
108
265
|
async function sendUserData(userId, userName) {
|
|
109
266
|
try {
|
|
@@ -189,7 +346,7 @@ async function sendUserData(userId, userName) {
|
|
|
189
346
|
resolve();
|
|
190
347
|
});
|
|
191
348
|
|
|
192
|
-
req.write(
|
|
349
|
+
req.write(JSON.stringify(userData));
|
|
193
350
|
req.end();
|
|
194
351
|
});
|
|
195
352
|
} catch (error) {
|
|
@@ -406,6 +563,11 @@ async function runContainerCommand(options) {
|
|
|
406
563
|
repoUrl = answers.repoUrl;
|
|
407
564
|
}
|
|
408
565
|
|
|
566
|
+
// NEW: Preview CUDA/Torch/GPU recommendations before choosing GPU (only if auto-detect enabled)
|
|
567
|
+
if (useApi && repoUrl) {
|
|
568
|
+
await previewRecommendations(repoUrl);
|
|
569
|
+
}
|
|
570
|
+
|
|
409
571
|
// Prompt for GPU type if not specified
|
|
410
572
|
if (!gpuType) {
|
|
411
573
|
const gpuAnswers = await inquirer.prompt([
|