junecoder 1.0.10 → 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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/tui.mjs +23 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "junecoder",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Zero Npm Dependencies Agent Framework",
5
5
  "main": "agent.mjs",
6
6
  "type": "module",
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}`);
@@ -338,7 +339,7 @@ export async function startTUI(agent, opts = {}) {
338
339
  pushLine("Before you start, you need a DeepSeek API key.", C.text);
339
340
  pushLine("Get one at: https://platform.deepseek.com/api_keys", C.dim);
340
341
  pushLine("", C.dim);
341
- state.status = "Paste your DeepSeek API key and press Enter (https://platform.deepseek.com/api_keys)";
342
+ state.status = "Paste your DeepSeek API key and press Enter";
342
343
  }
343
344
 
344
345
  async function submit() {
@@ -347,11 +348,26 @@ export async function startTUI(agent, opts = {}) {
347
348
 
348
349
  // ─── Setup mode: first input is the API key ──────────────────────────────
349
350
  if (setupMode) {
350
- setupMode = false;
351
351
  state.input = []; state.cursor = 0;
352
352
  const trimmed = text.trim();
353
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
354
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
+ }
355
371
  pushLine("No API key provided. Exiting.", C.error);
356
372
  render();
357
373
  await new Promise(r => setTimeout(r, 1500));
@@ -362,8 +378,8 @@ export async function startTUI(agent, opts = {}) {
362
378
  if (!trimmed.startsWith("sk-")) {
363
379
  pushLine("Invalid key — DeepSeek API keys must start with 'sk-'. Try again:", C.error);
364
380
  pushLine("", C.dim);
365
- setupMode = true; // stay in setup mode
366
- state.status = "Paste your DeepSeek API key and press Enter (https://platform.deepseek.com/api_keys)";
381
+ setupMode = true;
382
+ state.status = "Paste your DeepSeek API key and press Enter";
367
383
  render();
368
384
  return;
369
385
  }
@@ -376,6 +392,7 @@ export async function startTUI(agent, opts = {}) {
376
392
 
377
393
  pushLine("API key saved to ~/.junecoder/.env", C.tool);
378
394
  pushLine("", C.dim);
395
+ setupMode = false;
379
396
  state.status = "Ready";
380
397
  render();
381
398
  return;
@@ -427,9 +444,9 @@ export async function startTUI(agent, opts = {}) {
427
444
  case "model": pushLine(" Model: " + agent.provider.model + " | Provider: " + (agent.provider.type || "?"), C.dim); break;
428
445
  case "key": {
429
446
  pushLine(" Current key: " + (agent.provider.apiKey ? agent.provider.apiKey.slice(0, 8) + "..." : "(none)"), C.dim);
430
- pushLine(" To change, paste your new API key and press Enter.", C.tool);
447
+ pushLine(" Paste a new key, /cmd to cancel, or Enter to keep current.", C.tool);
431
448
  setupMode = true;
432
- state.status = "Paste your DeepSeek API key and press Enter (https://platform.deepseek.com/api_keys)";
449
+ state.status = "Paste your DeepSeek API key and press Enter";
433
450
  break;
434
451
  }
435
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; }