gitnexus 1.2.2 → 1.2.3
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/dist/cli/wiki.js +79 -46
- package/package.json +1 -1
package/dist/cli/wiki.js
CHANGED
|
@@ -108,65 +108,83 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
108
108
|
await saveCLIConfig({ ...existing, ...updates });
|
|
109
109
|
console.log(' Config saved to ~/.gitnexus/config.json\n');
|
|
110
110
|
}
|
|
111
|
+
const savedConfig = await loadCLIConfig();
|
|
112
|
+
const hasSavedConfig = !!(savedConfig.apiKey && savedConfig.baseUrl);
|
|
113
|
+
const hasCLIOverrides = !!(options?.apiKey || options?.model || options?.baseUrl);
|
|
111
114
|
let llmConfig = await resolveLLMConfig({
|
|
112
115
|
model: options?.model,
|
|
113
116
|
baseUrl: options?.baseUrl,
|
|
114
117
|
apiKey: options?.apiKey,
|
|
115
118
|
});
|
|
116
|
-
if
|
|
119
|
+
// Run interactive setup if no saved config and no CLI flags provided
|
|
120
|
+
// (even if env vars exist — let user explicitly choose their provider)
|
|
121
|
+
if (!hasSavedConfig && !hasCLIOverrides) {
|
|
117
122
|
if (!process.stdin.isTTY) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
console.log(' No LLM configured. Let\'s set it up.\n');
|
|
125
|
-
console.log(' Supports OpenAI, OpenRouter, or any OpenAI-compatible API.\n');
|
|
126
|
-
// Provider selection
|
|
127
|
-
console.log(' [1] OpenAI (api.openai.com)');
|
|
128
|
-
console.log(' [2] OpenRouter (openrouter.ai)');
|
|
129
|
-
console.log(' [3] Custom endpoint\n');
|
|
130
|
-
const choice = await prompt(' Select provider (1/2/3): ');
|
|
131
|
-
let baseUrl;
|
|
132
|
-
let defaultModel;
|
|
133
|
-
if (choice === '2') {
|
|
134
|
-
baseUrl = 'https://openrouter.ai/api/v1';
|
|
135
|
-
defaultModel = 'openai/gpt-4o-mini';
|
|
136
|
-
}
|
|
137
|
-
else if (choice === '3') {
|
|
138
|
-
baseUrl = await prompt(' Base URL (e.g. http://localhost:11434/v1): ');
|
|
139
|
-
if (!baseUrl) {
|
|
140
|
-
console.log('\n No URL provided. Aborting.\n');
|
|
123
|
+
if (!llmConfig.apiKey) {
|
|
124
|
+
console.log(' Error: No LLM API key found.');
|
|
125
|
+
console.log(' Set OPENAI_API_KEY or GITNEXUS_API_KEY environment variable,');
|
|
126
|
+
console.log(' or pass --api-key <key>.\n');
|
|
141
127
|
process.exitCode = 1;
|
|
142
128
|
return;
|
|
143
129
|
}
|
|
144
|
-
|
|
130
|
+
// Non-interactive with env var — just use it
|
|
145
131
|
}
|
|
146
132
|
else {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
133
|
+
console.log(' No LLM configured. Let\'s set it up.\n');
|
|
134
|
+
console.log(' Supports OpenAI, OpenRouter, or any OpenAI-compatible API.\n');
|
|
135
|
+
// Provider selection
|
|
136
|
+
console.log(' [1] OpenAI (api.openai.com)');
|
|
137
|
+
console.log(' [2] OpenRouter (openrouter.ai)');
|
|
138
|
+
console.log(' [3] Custom endpoint\n');
|
|
139
|
+
const choice = await prompt(' Select provider (1/2/3): ');
|
|
140
|
+
let baseUrl;
|
|
141
|
+
let defaultModel;
|
|
142
|
+
if (choice === '2') {
|
|
143
|
+
baseUrl = 'https://openrouter.ai/api/v1';
|
|
144
|
+
defaultModel = 'openai/gpt-4o-mini';
|
|
145
|
+
}
|
|
146
|
+
else if (choice === '3') {
|
|
147
|
+
baseUrl = await prompt(' Base URL (e.g. http://localhost:11434/v1): ');
|
|
148
|
+
if (!baseUrl) {
|
|
149
|
+
console.log('\n No URL provided. Aborting.\n');
|
|
150
|
+
process.exitCode = 1;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
defaultModel = 'gpt-4o-mini';
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
baseUrl = 'https://api.openai.com/v1';
|
|
157
|
+
defaultModel = 'gpt-4o-mini';
|
|
158
|
+
}
|
|
159
|
+
// Model
|
|
160
|
+
const modelInput = await prompt(` Model (default: ${defaultModel}): `);
|
|
161
|
+
const model = modelInput || defaultModel;
|
|
162
|
+
// API key — pre-fill hint if env var exists
|
|
163
|
+
const envKey = process.env.GITNEXUS_API_KEY || process.env.OPENAI_API_KEY || '';
|
|
164
|
+
let key;
|
|
165
|
+
if (envKey) {
|
|
166
|
+
const masked = envKey.slice(0, 6) + '...' + envKey.slice(-4);
|
|
167
|
+
const useEnv = await prompt(` Use existing env key (${masked})? (Y/n): `);
|
|
168
|
+
if (!useEnv || useEnv.toLowerCase() === 'y' || useEnv.toLowerCase() === 'yes') {
|
|
169
|
+
key = envKey;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
key = await prompt(' API key: ', true);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
key = await prompt(' API key: ', true);
|
|
177
|
+
}
|
|
178
|
+
if (!key) {
|
|
179
|
+
console.log('\n No key provided. Aborting.\n');
|
|
180
|
+
process.exitCode = 1;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// Save
|
|
163
184
|
await saveCLIConfig({ apiKey: key, baseUrl, model });
|
|
164
|
-
console.log(' Config saved
|
|
165
|
-
|
|
166
|
-
else {
|
|
167
|
-
console.log(' Config will be used for this session only.\n');
|
|
185
|
+
console.log(' Config saved to ~/.gitnexus/config.json\n');
|
|
186
|
+
llmConfig = { ...llmConfig, apiKey: key, baseUrl, model };
|
|
168
187
|
}
|
|
169
|
-
llmConfig = { ...llmConfig, apiKey: key, baseUrl, model };
|
|
170
188
|
}
|
|
171
189
|
// ── Setup progress bar ──────────────────────────────────────────────
|
|
172
190
|
const bar = new cliProgress.SingleBar({
|
|
@@ -225,6 +243,21 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
225
243
|
}
|
|
226
244
|
else if (err.message?.includes('API key') || err.message?.includes('API error')) {
|
|
227
245
|
console.log(`\n LLM Error: ${err.message}\n`);
|
|
246
|
+
// Offer to reconfigure on auth-related failures
|
|
247
|
+
const isAuthError = err.message?.includes('401') || err.message?.includes('403')
|
|
248
|
+
|| err.message?.includes('502') || err.message?.includes('authenticate')
|
|
249
|
+
|| err.message?.includes('Unauthorized');
|
|
250
|
+
if (isAuthError && process.stdin.isTTY) {
|
|
251
|
+
const answer = await new Promise((resolve) => {
|
|
252
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
253
|
+
rl.question(' Reconfigure LLM settings? (Y/n): ', (ans) => { rl.close(); resolve(ans.trim().toLowerCase()); });
|
|
254
|
+
});
|
|
255
|
+
if (!answer || answer === 'y' || answer === 'yes') {
|
|
256
|
+
// Clear saved config so next run triggers interactive setup
|
|
257
|
+
await saveCLIConfig({});
|
|
258
|
+
console.log(' Config cleared. Run `gitnexus wiki` again to reconfigure.\n');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
228
261
|
}
|
|
229
262
|
else {
|
|
230
263
|
console.log(`\n Error: ${err.message}\n`);
|
package/package.json
CHANGED