junecoder 1.0.9 → 1.0.11
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/package.json +1 -1
- package/tui.mjs +25 -6
package/package.json
CHANGED
package/tui.mjs
CHANGED
|
@@ -229,6 +229,7 @@ export async function startTUI(agent, opts = {}) {
|
|
|
229
229
|
if (state.question) { borderColor = C.tool; title = " " + sliceByWidth(state.question.text, W - 6) + " "; }
|
|
230
230
|
else if (state.permission) { borderColor = C.warn; title = state.permission.name === "continue" ? " Continue? (y/n) " : " Allow " + state.permission.name + "? (y/n/a) "; }
|
|
231
231
|
else if (state.processing) title = " Processing... ";
|
|
232
|
+
else if (setupMode) title = " API Key ";
|
|
232
233
|
else title = " Input ";
|
|
233
234
|
const topBorder = "\u256d\u2500" + title + "\u2500".repeat(Math.max(0, W - 3 - stringWidth(title))) + "\u256e";
|
|
234
235
|
out.push(`${borderColor}${topBorder}${ansi.reset}${ansi.clearLine}`);
|
|
@@ -331,12 +332,14 @@ export async function startTUI(agent, opts = {}) {
|
|
|
331
332
|
// ─── First-run setup: capture API key from input box ──────────────────────────
|
|
332
333
|
let setupMode = opts.needsSetup;
|
|
333
334
|
if (setupMode) {
|
|
335
|
+
pushLine("", C.dim);
|
|
336
|
+
pushLine("", C.dim);
|
|
334
337
|
pushLine("", C.dim);
|
|
335
338
|
pushLine("Welcome to JuneCoder!", ansi.bold + C.assistant);
|
|
336
339
|
pushLine("Before you start, you need a DeepSeek API key.", C.text);
|
|
337
340
|
pushLine("Get one at: https://platform.deepseek.com/api_keys", C.dim);
|
|
338
341
|
pushLine("", C.dim);
|
|
339
|
-
state.status = "Paste your DeepSeek API key and press Enter
|
|
342
|
+
state.status = "Paste your DeepSeek API key and press Enter";
|
|
340
343
|
}
|
|
341
344
|
|
|
342
345
|
async function submit() {
|
|
@@ -345,11 +348,26 @@ export async function startTUI(agent, opts = {}) {
|
|
|
345
348
|
|
|
346
349
|
// ─── Setup mode: first input is the API key ──────────────────────────────
|
|
347
350
|
if (setupMode) {
|
|
348
|
-
setupMode = false;
|
|
349
351
|
state.input = []; state.cursor = 0;
|
|
350
352
|
const trimmed = text.trim();
|
|
351
353
|
|
|
354
|
+
// Allow slash commands to pass through during setup (e.g. /key cancel)
|
|
355
|
+
if (trimmed.startsWith("/")) {
|
|
356
|
+
setupMode = false;
|
|
357
|
+
await handleSlash(trimmed);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Empty input: exit on first-run, cancel on re-key
|
|
352
362
|
if (!trimmed) {
|
|
363
|
+
if (agent.provider.apiKey) {
|
|
364
|
+
// Already have a key — user is just changing their mind
|
|
365
|
+
setupMode = false;
|
|
366
|
+
pushLine("Key unchanged.", C.dim);
|
|
367
|
+
state.status = "Ready";
|
|
368
|
+
render();
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
353
371
|
pushLine("No API key provided. Exiting.", C.error);
|
|
354
372
|
render();
|
|
355
373
|
await new Promise(r => setTimeout(r, 1500));
|
|
@@ -360,8 +378,8 @@ export async function startTUI(agent, opts = {}) {
|
|
|
360
378
|
if (!trimmed.startsWith("sk-")) {
|
|
361
379
|
pushLine("Invalid key — DeepSeek API keys must start with 'sk-'. Try again:", C.error);
|
|
362
380
|
pushLine("", C.dim);
|
|
363
|
-
setupMode = true;
|
|
364
|
-
state.status = "Paste your DeepSeek API key and press Enter
|
|
381
|
+
setupMode = true;
|
|
382
|
+
state.status = "Paste your DeepSeek API key and press Enter";
|
|
365
383
|
render();
|
|
366
384
|
return;
|
|
367
385
|
}
|
|
@@ -374,6 +392,7 @@ export async function startTUI(agent, opts = {}) {
|
|
|
374
392
|
|
|
375
393
|
pushLine("API key saved to ~/.junecoder/.env", C.tool);
|
|
376
394
|
pushLine("", C.dim);
|
|
395
|
+
setupMode = false;
|
|
377
396
|
state.status = "Ready";
|
|
378
397
|
render();
|
|
379
398
|
return;
|
|
@@ -425,9 +444,9 @@ export async function startTUI(agent, opts = {}) {
|
|
|
425
444
|
case "model": pushLine(" Model: " + agent.provider.model + " | Provider: " + (agent.provider.type || "?"), C.dim); break;
|
|
426
445
|
case "key": {
|
|
427
446
|
pushLine(" Current key: " + (agent.provider.apiKey ? agent.provider.apiKey.slice(0, 8) + "..." : "(none)"), C.dim);
|
|
428
|
-
pushLine("
|
|
447
|
+
pushLine(" Paste a new key, /cmd to cancel, or Enter to keep current.", C.tool);
|
|
429
448
|
setupMode = true;
|
|
430
|
-
state.status = "Paste your DeepSeek API key and press Enter
|
|
449
|
+
state.status = "Paste your DeepSeek API key and press Enter";
|
|
431
450
|
break;
|
|
432
451
|
}
|
|
433
452
|
case "session": { const slots = listSlots(agent.cwd); pushLine("Sessions:", C.tool); if (slots.length === 0) pushLine(" (none)", C.dim); else for (const s of slots) pushLine(" " + s.label, C.dim); break; }
|