opencode-azure-setup 1.0.5 → 1.0.7
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/index.js +81 -37
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
7
|
* npx opencode-azure-setup
|
|
8
|
+
* npx opencode-azure-setup -y # Non-interactive (use existing config)
|
|
8
9
|
* node install-azure.js
|
|
9
10
|
*/
|
|
10
11
|
|
|
@@ -14,6 +15,10 @@ import readline from 'readline';
|
|
|
14
15
|
import https from 'https';
|
|
15
16
|
import os from 'os';
|
|
16
17
|
|
|
18
|
+
// Parse args
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
const nonInteractive = args.includes('-y') || args.includes('--yes') || args.includes('--non-interactive');
|
|
21
|
+
|
|
17
22
|
// Colors
|
|
18
23
|
const colors = {
|
|
19
24
|
blue: '\x1b[34m',
|
|
@@ -67,15 +72,22 @@ function getExistingAzureSettings(config) {
|
|
|
67
72
|
};
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
// Only create readline interface if not in non-interactive mode
|
|
76
|
+
let rl = null;
|
|
77
|
+
function getRl() {
|
|
78
|
+
if (!rl) {
|
|
79
|
+
rl = readline.createInterface({
|
|
80
|
+
input: process.stdin,
|
|
81
|
+
output: process.stdout,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return rl;
|
|
85
|
+
}
|
|
74
86
|
|
|
75
87
|
function ask(question, defaultValue = '') {
|
|
76
88
|
return new Promise((resolve) => {
|
|
77
89
|
const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
78
|
-
|
|
90
|
+
getRl().question(prompt, (answer) => resolve(answer || defaultValue));
|
|
79
91
|
});
|
|
80
92
|
}
|
|
81
93
|
|
|
@@ -240,14 +252,29 @@ async function main() {
|
|
|
240
252
|
// If existing config found, show current values
|
|
241
253
|
if (existingAzure && existingAzure.baseUrl) {
|
|
242
254
|
console.log(colors.green + '✓ Existing configuration found' + colors.reset);
|
|
243
|
-
|
|
255
|
+
if (nonInteractive) {
|
|
256
|
+
console.log(colors.dim + ' Using existing values (non-interactive mode)' + colors.reset);
|
|
257
|
+
} else {
|
|
258
|
+
console.log(colors.dim + ' Press Enter to keep current values, or type new ones' + colors.reset);
|
|
259
|
+
}
|
|
244
260
|
console.log();
|
|
245
261
|
}
|
|
246
262
|
|
|
247
263
|
// Endpoint - accepts full URL or just the base
|
|
248
|
-
let baseUrl, deployment, apiVersion;
|
|
249
|
-
|
|
250
|
-
|
|
264
|
+
let baseUrl, deployment, apiVersion, apiKey;
|
|
265
|
+
|
|
266
|
+
// Non-interactive mode with existing config - skip all prompts
|
|
267
|
+
if (nonInteractive && existingAzure?.baseUrl && existingAzure?.apiKey) {
|
|
268
|
+
baseUrl = existingAzure.baseUrl;
|
|
269
|
+
deployment = existingAzure.deployment;
|
|
270
|
+
apiVersion = existingAzure.apiVersion;
|
|
271
|
+
apiKey = existingAzure.apiKey;
|
|
272
|
+
console.log(colors.dim + ` Endpoint: ${baseUrl}` + colors.reset);
|
|
273
|
+
console.log(colors.dim + ` Deployment: ${deployment}` + colors.reset);
|
|
274
|
+
} else if (nonInteractive && !existingAzure?.baseUrl) {
|
|
275
|
+
console.log(colors.red + 'No existing config found. Run without -y flag to configure.' + colors.reset);
|
|
276
|
+
process.exit(1);
|
|
277
|
+
} else if (existingAzure?.baseUrl) {
|
|
251
278
|
console.log('Azure OpenAI Endpoint');
|
|
252
279
|
const rawEndpoint = await ask('Endpoint', existingAzure.baseUrl);
|
|
253
280
|
|
|
@@ -263,6 +290,22 @@ async function main() {
|
|
|
263
290
|
deployment = parsed.deployment;
|
|
264
291
|
apiVersion = parsed.apiVersion;
|
|
265
292
|
}
|
|
293
|
+
|
|
294
|
+
// API Key
|
|
295
|
+
console.log();
|
|
296
|
+
apiKey = await askPassword('API Key', existingAzure?.apiKey || '');
|
|
297
|
+
if (!apiKey) {
|
|
298
|
+
console.log(colors.red + 'API Key is required' + colors.reset);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Deployment (only ask if not using existing)
|
|
303
|
+
if (existingAzure?.deployment && deployment === existingAzure.deployment) {
|
|
304
|
+
// Keep existing
|
|
305
|
+
} else {
|
|
306
|
+
console.log();
|
|
307
|
+
deployment = await ask('Deployment name', deployment);
|
|
308
|
+
}
|
|
266
309
|
} else {
|
|
267
310
|
console.log('Paste your Azure OpenAI endpoint');
|
|
268
311
|
console.log(colors.dim + 'Tip: You can paste the full URL from Azure Portal - we\'ll extract what we need' + colors.reset);
|
|
@@ -278,20 +321,15 @@ async function main() {
|
|
|
278
321
|
baseUrl = parsed.baseUrl;
|
|
279
322
|
deployment = parsed.deployment;
|
|
280
323
|
apiVersion = parsed.apiVersion;
|
|
281
|
-
}
|
|
282
324
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
325
|
+
// API Key
|
|
326
|
+
console.log();
|
|
327
|
+
apiKey = await askPassword('API Key');
|
|
328
|
+
if (!apiKey) {
|
|
329
|
+
console.log(colors.red + 'API Key is required' + colors.reset);
|
|
330
|
+
process.exit(1);
|
|
331
|
+
}
|
|
290
332
|
|
|
291
|
-
// Deployment (only ask if not using existing)
|
|
292
|
-
if (existingAzure?.deployment && deployment === existingAzure.deployment) {
|
|
293
|
-
// Keep existing
|
|
294
|
-
} else {
|
|
295
333
|
console.log();
|
|
296
334
|
deployment = await ask('Deployment name', deployment);
|
|
297
335
|
}
|
|
@@ -315,22 +353,27 @@ async function main() {
|
|
|
315
353
|
}
|
|
316
354
|
}
|
|
317
355
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
deployment = await ask('Deployment name', deployment);
|
|
322
|
-
apiVersion = await ask('API Version', apiVersion);
|
|
323
|
-
|
|
324
|
-
console.log();
|
|
325
|
-
console.log(colors.blue + 'Retrying...' + colors.reset);
|
|
326
|
-
result = await testConnection(baseUrl, apiKey, deployment, apiVersion);
|
|
327
|
-
|
|
328
|
-
if (result.ok) {
|
|
329
|
-
console.log(colors.green + '✓ Connection successful!' + colors.reset);
|
|
356
|
+
if (nonInteractive) {
|
|
357
|
+
// Non-interactive mode - just continue with existing config
|
|
358
|
+
console.log(colors.yellow + '⚠ Continuing anyway (non-interactive mode)' + colors.reset);
|
|
330
359
|
} else {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
360
|
+
// Offer to edit settings if connection failed
|
|
361
|
+
console.log();
|
|
362
|
+
console.log(colors.yellow + 'Let\'s try different settings:' + colors.reset);
|
|
363
|
+
deployment = await ask('Deployment name', deployment);
|
|
364
|
+
apiVersion = await ask('API Version', apiVersion);
|
|
365
|
+
|
|
366
|
+
console.log();
|
|
367
|
+
console.log(colors.blue + 'Retrying...' + colors.reset);
|
|
368
|
+
result = await testConnection(baseUrl, apiKey, deployment, apiVersion);
|
|
369
|
+
|
|
370
|
+
if (result.ok) {
|
|
371
|
+
console.log(colors.green + '✓ Connection successful!' + colors.reset);
|
|
372
|
+
} else {
|
|
373
|
+
console.log(colors.red + `✗ Still failing (${result.status || 'error'})` + colors.reset);
|
|
374
|
+
const cont = await ask('Save config anyway? (y/N)', 'N');
|
|
375
|
+
if (cont.toLowerCase() !== 'y') process.exit(1);
|
|
376
|
+
}
|
|
334
377
|
}
|
|
335
378
|
}
|
|
336
379
|
|
|
@@ -388,6 +431,7 @@ async function main() {
|
|
|
388
431
|
// Add to config
|
|
389
432
|
config.mcp = config.mcp || {};
|
|
390
433
|
config.mcp['mcp-marketplace'] = {
|
|
434
|
+
type: 'local',
|
|
391
435
|
command: 'node',
|
|
392
436
|
args: [mcpPath],
|
|
393
437
|
};
|
|
@@ -421,7 +465,7 @@ async function main() {
|
|
|
421
465
|
console.log(' ' + colors.blue + 'opencode' + colors.reset);
|
|
422
466
|
console.log();
|
|
423
467
|
|
|
424
|
-
rl.close();
|
|
468
|
+
if (rl) rl.close();
|
|
425
469
|
}
|
|
426
470
|
|
|
427
471
|
main().catch((err) => {
|