@trydecember/cli 0.4.10 → 0.4.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 (3) hide show
  1. package/README.md +3 -3
  2. package/dist/december.js +1391 -394
  3. package/package.json +1 -1
package/dist/december.js CHANGED
@@ -65,7 +65,7 @@ var package_default;
65
65
  var init_package = __esm(() => {
66
66
  package_default = {
67
67
  name: "@trydecember/cli",
68
- version: "0.4.10",
68
+ version: "0.4.11",
69
69
  description: "a (so much) better coding agent for terminal and cloud.",
70
70
  homepage: "https://trydecember.com",
71
71
  repository: {
@@ -306,7 +306,7 @@ function getModelContextWindow(value) {
306
306
  if (lower.startsWith("ollama/")) {
307
307
  lower = lower.slice("ollama/".length);
308
308
  }
309
- if (lower.includes("december-auto"))
309
+ if (lower.includes("december-auto") || lower.includes("humans-r1"))
310
310
  return 1e6;
311
311
  if (lower.includes("gemini"))
312
312
  return 1e6;
@@ -477,7 +477,7 @@ function supportsModelThinking(model) {
477
477
  if (lower.includes("claude-3-7") || lower.includes("claude-3.7") || lower.includes("claude-4") || lower.includes("claude-opus-4") || lower.includes("claude-sonnet-4") || lower.includes("claude-haiku-4") || lower.includes("claude-5") || lower.includes("claude-fable-5") || lower.includes("sonnet-5") || lower.includes("opus-5")) {
478
478
  return true;
479
479
  }
480
- if (lower.includes("gemini-2.5") || lower.includes("gemini-3") || lower.includes("december-auto")) {
480
+ if (lower.includes("gemini-2.5") || lower.includes("gemini-3") || lower.includes("december-auto") || lower.includes("humans-r1")) {
481
481
  return true;
482
482
  }
483
483
  if (lower.includes("deepseek-reasoner") || lower.includes("deepseek-r1") || lower.includes("r1-1776") || lower.includes("deepseek-v4")) {
@@ -505,6 +505,7 @@ var MODEL_CONTEXT_WINDOWS;
505
505
  var init_models = __esm(() => {
506
506
  MODEL_CONTEXT_WINDOWS = {
507
507
  "december-auto": 1e6,
508
+ "humans-r1": 1e6,
508
509
  "gemini-3.8-flash": 1e6,
509
510
  "gemini-3.7-flash": 1e6,
510
511
  "gemini-3.6-flash": 1e6,
@@ -107105,20 +107106,22 @@ function resolveCodexModel(model) {
107105
107106
  if (name.startsWith("openai/")) {
107106
107107
  name = name.slice("openai/".length);
107107
107108
  }
107108
- if (CODEX_SUPPORTED_MODELS.includes(name)) {
107109
- return name;
107110
- }
107111
- if (name.includes("5.5"))
107112
- return "gpt-5.5";
107113
107109
  if (name.includes("5.6-sol") || name.includes("sol"))
107114
107110
  return "gpt-5.6-sol";
107115
107111
  if (name.includes("5.6-terra") || name.includes("terra"))
107116
107112
  return "gpt-5.6-terra";
107117
107113
  if (name.includes("5.6-luna") || name.includes("luna"))
107118
107114
  return "gpt-5.6-luna";
107115
+ if (name.includes("5.5"))
107116
+ return "gpt-5.5";
107119
107117
  if (name.includes("mini"))
107120
107118
  return "gpt-5.4-mini";
107121
- return "gpt-5.4";
107119
+ if (name.includes("5.4"))
107120
+ return "gpt-5.4";
107121
+ if (CODEX_SUPPORTED_MODELS.includes(name)) {
107122
+ return name;
107123
+ }
107124
+ return "gpt-5.6-sol";
107122
107125
  }
107123
107126
  function extractChatGPTAccountId(token) {
107124
107127
  try {
@@ -107326,12 +107329,12 @@ function codexResponsesProvider(token, options) {
107326
107329
  var CODEX_DEFAULT_ENDPOINT = "https://chatgpt.com/backend-api", CODEX_SUPPORTED_MODELS;
107327
107330
  var init_codex = __esm(() => {
107328
107331
  CODEX_SUPPORTED_MODELS = [
107329
- "gpt-5.4",
107330
- "gpt-5.4-mini",
107331
- "gpt-5.5",
107332
107332
  "gpt-5.6-sol",
107333
107333
  "gpt-5.6-terra",
107334
- "gpt-5.6-luna"
107334
+ "gpt-5.6-luna",
107335
+ "gpt-5.5",
107336
+ "gpt-5.4",
107337
+ "gpt-5.4-mini"
107335
107338
  ];
107336
107339
  });
107337
107340
 
@@ -108441,6 +108444,7 @@ __export(exports_models2, {
108441
108444
  fetchOllamaModels: () => fetchOllamaModels,
108442
108445
  getDefaultModelForProvider: () => getDefaultModelForProvider,
108443
108446
  getDefaultUrlForLocalProvider: () => getDefaultUrlForLocalProvider,
108447
+ getModelLabel: () => getModelLabel,
108444
108448
  getProviderModels: () => getProviderModels,
108445
108449
  isValidModelForProvider: () => isValidModelForProvider
108446
108450
  });
@@ -109230,7 +109234,7 @@ var LIVE_MODEL_CACHE_TTL_MS, liveModelCache, diskCacheLoaded = false, getCurated
109230
109234
  ];
109231
109235
  case "december":
109232
109236
  case "december_proxy":
109233
- return [{ label: "december-auto", value: "december-auto" }];
109237
+ return [{ label: "Humans R1", value: "december-auto" }];
109234
109238
  case "copilot":
109235
109239
  case "github_copilot":
109236
109240
  case "github":
@@ -109244,12 +109248,10 @@ var LIVE_MODEL_CACHE_TTL_MS, liveModelCache, diskCacheLoaded = false, getCurated
109244
109248
  case "codex":
109245
109249
  case "chatgpt":
109246
109250
  return [
109247
- { label: "GPT-5.4", value: "gpt-5.4" },
109248
- { label: "GPT-5.4 Mini", value: "gpt-5.4-mini" },
109249
- { label: "GPT-5.5", value: "gpt-5.5" },
109250
109251
  { label: "GPT-5.6 Sol", value: "gpt-5.6-sol" },
109251
109252
  { label: "GPT-5.6 Terra", value: "gpt-5.6-terra" },
109252
- { label: "GPT-5.6 Luna", value: "gpt-5.6-luna" }
109253
+ { label: "GPT-5.6 Luna", value: "gpt-5.6-luna" },
109254
+ { label: "GPT-5.5", value: "gpt-5.5" }
109253
109255
  ];
109254
109256
  case "antigravity":
109255
109257
  return getCuratedProviderModels("gemini");
@@ -113377,6 +113379,11 @@ async function loadConfig() {
113377
113379
  const workspaceConfig = JSON.parse(wData);
113378
113380
  config = deepMergeSettings(config, workspaceConfig);
113379
113381
  } catch {}
113382
+ if (!config || typeof config !== "object") {
113383
+ config = { providers: {} };
113384
+ } else if (!config.providers || typeof config.providers !== "object" || Array.isArray(config.providers)) {
113385
+ config.providers = {};
113386
+ }
113380
113387
  if (!config.activeProvider) {
113381
113388
  if (config.providers && Object.keys(config.providers).length > 0) {
113382
113389
  config.activeProvider = Object.keys(config.providers)[0];
@@ -114378,18 +114385,19 @@ function formatSubscriptionToast(bundle, activeModel) {
114378
114385
  const modelPart = activeModel ? ` • ${activeModel}` : "";
114379
114386
  return `Connected to ${subject}${accountPart}${modelPart}`;
114380
114387
  }
114388
+ function formatSubscriptionSuccessMessage(provider) {
114389
+ const providerName = formatSubscriptionDisplayName(provider);
114390
+ return `${providerName} connected successfully`;
114391
+ }
114381
114392
  function formatSubscriptionCard(bundle, _activeModel) {
114382
- const providerName = formatSubscriptionDisplayName(bundle.provider);
114383
114393
  const plan = formatSubscriptionPlan(bundle);
114384
114394
  const identity = formatSubscriptionIdentity(bundle);
114385
- const lines = [`Linked ${providerName} Subscription`, ` • Plan: ${plan}`];
114386
114395
  if (identity) {
114387
114396
  const isGithub = bundle.provider === "copilot" || bundle.provider === "github";
114388
114397
  const accountDisplay = isGithub && identity.startsWith("@") ? `[${identity}](https://github.com/${identity.slice(1)})` : identity;
114389
- lines.push(` • Account: ${accountDisplay}`);
114398
+ return `Plan: ${plan} (${accountDisplay})`;
114390
114399
  }
114391
- return lines.join(`
114392
- `);
114400
+ return `Plan: ${plan}`;
114393
114401
  }
114394
114402
 
114395
114403
  // src/auth/subscriptions/index.ts
@@ -114402,11 +114410,15 @@ var init_subscriptions = __esm(() => {
114402
114410
  });
114403
114411
 
114404
114412
  // src/auth/device.ts
114405
- async function loginViaDeviceCode(serverUrl = process.env.SERVER_URL || "https://api.trydecember.com", onCodeGenerated) {
114413
+ async function loginViaDeviceCode(serverUrl = process.env.SERVER_URL || "https://api.trydecember.com", onCodeGenerated, signal) {
114414
+ if (signal?.aborted) {
114415
+ throw new Error("Login cancelled");
114416
+ }
114406
114417
  try {
114407
114418
  const genRes = await fetch(`${serverUrl}/api/v1/auth/device/code`, {
114408
114419
  method: "POST",
114409
- headers: { "Content-Type": "application/json" }
114420
+ headers: { "Content-Type": "application/json" },
114421
+ signal
114410
114422
  });
114411
114423
  let genData = {};
114412
114424
  try {
@@ -114417,13 +114429,30 @@ async function loginViaDeviceCode(serverUrl = process.env.SERVER_URL || "https:/
114417
114429
  }
114418
114430
  const { deviceCode, userCode, verificationUri, expiresIn, interval } = genData.data;
114419
114431
  onCodeGenerated(userCode, verificationUri);
114420
- const fullUrl = verificationUri.includes("?") ? `${verificationUri}&code=${encodeURIComponent(userCode)}` : `${verificationUri}?code=${encodeURIComponent(userCode)}`;
114421
- openUrl(fullUrl).catch(() => {});
114422
114432
  const startTime = Date.now();
114423
114433
  const pollInterval = interval * 1000 || 5000;
114424
114434
  return await new Promise((resolve, reject) => {
114435
+ let timeoutId = null;
114436
+ const onAbort = () => {
114437
+ if (timeoutId)
114438
+ clearTimeout(timeoutId);
114439
+ reject(new Error("Login cancelled"));
114440
+ };
114441
+ if (signal) {
114442
+ if (signal.aborted) {
114443
+ onAbort();
114444
+ return;
114445
+ }
114446
+ signal.addEventListener("abort", onAbort, { once: true });
114447
+ }
114425
114448
  const poll = async () => {
114449
+ if (signal?.aborted) {
114450
+ onAbort();
114451
+ return;
114452
+ }
114426
114453
  if (Date.now() - startTime > expiresIn * 1000) {
114454
+ if (signal)
114455
+ signal.removeEventListener("abort", onAbort);
114427
114456
  reject(new Error("Device code expired"));
114428
114457
  return;
114429
114458
  }
@@ -114431,10 +114460,13 @@ async function loginViaDeviceCode(serverUrl = process.env.SERVER_URL || "https:/
114431
114460
  const tokenRes = await fetch(`${serverUrl}/api/v1/auth/device/token`, {
114432
114461
  method: "POST",
114433
114462
  headers: { "Content-Type": "application/json" },
114434
- body: JSON.stringify({ deviceCode })
114463
+ body: JSON.stringify({ deviceCode }),
114464
+ signal
114435
114465
  });
114436
114466
  const tokenData = await tokenRes.json();
114437
114467
  if (tokenRes.ok && tokenData.success) {
114468
+ if (signal)
114469
+ signal.removeEventListener("abort", onAbort);
114438
114470
  resolve({
114439
114471
  token: tokenData.data.token,
114440
114472
  email: tokenData.data.email
@@ -114442,17 +114474,30 @@ async function loginViaDeviceCode(serverUrl = process.env.SERVER_URL || "https:/
114442
114474
  return;
114443
114475
  }
114444
114476
  if (tokenData.message === "authorization_pending") {
114445
- setTimeout(poll, pollInterval);
114477
+ if (!signal?.aborted) {
114478
+ timeoutId = setTimeout(poll, pollInterval);
114479
+ }
114446
114480
  } else {
114481
+ if (signal)
114482
+ signal.removeEventListener("abort", onAbort);
114447
114483
  reject(new Error(tokenData.message || "Polling failed"));
114448
114484
  }
114449
114485
  } catch (err) {
114450
- setTimeout(poll, pollInterval);
114486
+ if (signal?.aborted || err?.name === "AbortError") {
114487
+ onAbort();
114488
+ return;
114489
+ }
114490
+ if (!signal?.aborted) {
114491
+ timeoutId = setTimeout(poll, pollInterval);
114492
+ }
114451
114493
  }
114452
114494
  };
114453
- setTimeout(poll, pollInterval);
114495
+ timeoutId = setTimeout(poll, pollInterval);
114454
114496
  });
114455
114497
  } catch (err) {
114498
+ if (signal?.aborted || err?.name === "AbortError" || err?.message?.includes("cancelled")) {
114499
+ throw new Error("Login cancelled");
114500
+ }
114456
114501
  const msg = err?.message || String(err);
114457
114502
  if (msg.includes("fetch failed") || msg.includes("ECONNREFUSED") || msg.includes("ENOTFOUND") || msg.includes("Failed to fetch") || msg.includes("connect")) {
114458
114503
  throw new Error("Unable to connect. Is the computer able to access the url?", {
@@ -114463,13 +114508,9 @@ async function loginViaDeviceCode(serverUrl = process.env.SERVER_URL || "https:/
114463
114508
  }
114464
114509
  }
114465
114510
  }
114466
- var init_device = __esm(() => {
114467
- init_open();
114468
- });
114469
114511
 
114470
114512
  // src/auth/index.ts
114471
114513
  var init_auth = __esm(() => {
114472
- init_device();
114473
114514
  init_subscriptions();
114474
114515
  });
114475
114516
 
@@ -115489,7 +115530,10 @@ async function handleLoginCommand(options) {
115489
115530
  const targetProvider = (options?.provider || "december").toLowerCase().trim();
115490
115531
  await Promise.resolve().then(() => init_config());
115491
115532
  if (targetProvider === "copilot" || targetProvider === "github" || targetProvider === "claude" || targetProvider === "codex" || targetProvider === "chatgpt" || targetProvider === "openai" || targetProvider === "gemini" || targetProvider === "google" || targetProvider === "antigravity") {
115492
- await Promise.resolve().then(() => init_subscriptions());
115533
+ const {
115534
+ formatSubscriptionPlan,
115535
+ formatSubscriptionIdentity
115536
+ } = await Promise.resolve().then(() => (init_subscriptions(), {}));
115493
115537
  const providerName = formatSubscriptionDisplayName(targetProvider);
115494
115538
  console.log(`
115495
115539
  Initiating subscription login for ${providerName}...`);
@@ -115510,37 +115554,86 @@ Waiting for authorization...`);
115510
115554
  await Promise.resolve().then(() => init_models5());
115511
115555
  fetchLiveProviderModels(bundle.provider, bundle.accessToken, bundle.endpoint).catch(() => {});
115512
115556
  const GREEN = "\x1B[38;2;110;231;183m";
115513
- const WHITE = "\x1B[38;2;244;244;245m";
115514
- const BRAND = "\x1B[38;2;137;180;248m";
115515
115557
  const RESET = "\x1B[0m";
115516
- const plan = formatSubscriptionPlan(bundle);
115517
- const identity = formatSubscriptionIdentity(bundle);
115518
115558
  console.log(`
115519
- ${GREEN}Linked ${providerName} Subscription${RESET}`);
115520
- console.log(` • Plan: ${WHITE}${plan}${RESET}`);
115521
- if (identity) {
115522
- console.log(` • Account: ${BRAND}${identity}${RESET}`);
115523
- }
115559
+ ${GREEN}${formatSubscriptionSuccessMessage(bundle.provider)}${RESET}`);
115560
+ console.log(formatSubscriptionCard(bundle));
115524
115561
  console.log();
115525
115562
  return;
115526
115563
  }
115564
+ const config = await loadConfig();
115565
+ if (config.decemberToken) {
115566
+ const userEmail = config.email || "December user";
115567
+ if (process.stdin.isTTY) {
115568
+ const readline = await import("node:readline/promises");
115569
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
115570
+ const answer = (await rl.question(`
115571
+ You are already logged in as ${userEmail}.
115572
+ Do you want to switch to a different account? (y/N): `)).trim().toLowerCase();
115573
+ rl.close();
115574
+ if (answer !== "y" && answer !== "yes") {
115575
+ console.log(`
115576
+ Already logged in as ${userEmail}. Keeping current session.
115577
+ `);
115578
+ return;
115579
+ }
115580
+ }
115581
+ }
115527
115582
  await Promise.resolve().then(() => init_auth());
115583
+ await Promise.resolve().then(() => init_open());
115528
115584
  console.log(`
115529
115585
  Generating device code for December login...`);
115530
- const { token, email } = await loginViaDeviceCode(undefined, (code, uri) => {
115531
- console.log(`
115532
- Please open ${uri} on any device and enter code: ${code}
115533
- Waiting for authorization...`);
115534
- });
115535
- const configToSave = await loadConfig();
115536
- configToSave.decemberToken = token;
115537
- if (email)
115538
- configToSave.email = email;
115539
- configToSave.authPriority = "december";
115540
- configToSave.activeModel = "december-auto";
115541
- await saveConfig(configToSave);
115542
- console.log(`\x1B[32mSuccessfully logged in via device code!\x1B[0m
115586
+ let keypressListener = null;
115587
+ const cleanupKeypress = () => {
115588
+ if (keypressListener && process.stdin.isTTY) {
115589
+ process.stdin.removeListener("data", keypressListener);
115590
+ keypressListener = null;
115591
+ try {
115592
+ process.stdin.setRawMode(false);
115593
+ process.stdin.pause();
115594
+ } catch {}
115595
+ }
115596
+ };
115597
+ try {
115598
+ const { token, email } = await loginViaDeviceCode(undefined, (code, uri) => {
115599
+ const fullUrl = uri.includes("?") ? `${uri}&code=${encodeURIComponent(code)}` : `${uri}?code=${encodeURIComponent(code)}`;
115600
+ console.log(`
115601
+ Confirm code: ${code}
115602
+ Open URL: ${fullUrl}
115603
+
115604
+ Press [o] to open in browser · Esc to cancel
115605
+ Waiting for approval...`);
115606
+ if (process.stdin.isTTY) {
115607
+ try {
115608
+ process.stdin.setRawMode(true);
115609
+ process.stdin.resume();
115610
+ keypressListener = (data) => {
115611
+ const char = data.toString();
115612
+ if (char === "o" || char === "O") {
115613
+ openUrl(fullUrl).catch(() => {});
115614
+ } else if (char === "\x03" || char === "\x1B") {
115615
+ cleanupKeypress();
115616
+ process.exit(0);
115617
+ }
115618
+ };
115619
+ process.stdin.on("data", keypressListener);
115620
+ } catch {}
115621
+ }
115622
+ });
115623
+ cleanupKeypress();
115624
+ const configToSave = await loadConfig();
115625
+ configToSave.decemberToken = token;
115626
+ if (email)
115627
+ configToSave.email = email;
115628
+ configToSave.authPriority = "december";
115629
+ configToSave.activeModel = "december-auto";
115630
+ await saveConfig(configToSave);
115631
+ console.log(`\x1B[32mSuccessfully logged in via device code!\x1B[0m
115543
115632
  `);
115633
+ } catch (err) {
115634
+ cleanupKeypress();
115635
+ throw err;
115636
+ }
115544
115637
  }
115545
115638
  async function handleUpdateCommand(options) {
115546
115639
  await Promise.resolve().then(() => init_updater());
@@ -168204,6 +168297,7 @@ async function runInnerLoop(agent, eventQueue, signal, options) {
168204
168297
  toolCalls
168205
168298
  });
168206
168299
  await executeToolCalls(agent, toolCalls, eventQueue, signal, options);
168300
+ eventQueue.push({ type: "AgentStatus", message: "Working..." });
168207
168301
  }
168208
168302
  await agent.saveContext();
168209
168303
  eventQueue.push({ type: "TurnEnd" });
@@ -169972,10 +170066,33 @@ function resolveWorkspaceRoot(targetDir = process.cwd()) {
169972
170066
  }
169973
170067
  return resolved;
169974
170068
  }
170069
+ function formatDisplayPath(targetPath) {
170070
+ const home = path26.resolve(os13.homedir());
170071
+ const resolved = path26.resolve(targetPath);
170072
+ if (resolved === home) {
170073
+ return "~";
170074
+ }
170075
+ if (resolved.startsWith(home + path26.sep)) {
170076
+ return "~" + resolved.slice(home.length);
170077
+ }
170078
+ return resolved;
170079
+ }
169975
170080
  function isWorkspaceTrusted(workspaceRoot, config) {
169976
- const canonicalRoot = path26.resolve(workspaceRoot);
170081
+ let canonicalRoot = path26.resolve(workspaceRoot);
170082
+ try {
170083
+ if (fs25.existsSync(canonicalRoot)) {
170084
+ canonicalRoot = fs25.realpathSync(canonicalRoot);
170085
+ }
170086
+ } catch {}
169977
170087
  const homeDir = path26.resolve(os13.homedir());
169978
- const trustedList = (config.trustedWorkspaces || []).map((p) => path26.resolve(p));
170088
+ const trustedList = (config.trustedWorkspaces || []).map((p) => {
170089
+ const resolved = path26.resolve(p);
170090
+ try {
170091
+ return fs25.existsSync(resolved) ? fs25.realpathSync(resolved) : resolved;
170092
+ } catch {
170093
+ return resolved;
170094
+ }
170095
+ });
169979
170096
  for (const trustedPath of trustedList) {
169980
170097
  if (canonicalRoot === trustedPath) {
169981
170098
  return true;
@@ -169991,8 +170108,20 @@ function isWorkspaceTrusted(workspaceRoot, config) {
169991
170108
  }
169992
170109
  async function addTrustedWorkspace(workspaceRoot) {
169993
170110
  const config = await loadConfig();
169994
- const canonical = path26.resolve(workspaceRoot);
169995
- const existing = (config.trustedWorkspaces || []).map((p) => path26.resolve(p));
170111
+ let canonical = path26.resolve(workspaceRoot);
170112
+ try {
170113
+ if (fs25.existsSync(canonical)) {
170114
+ canonical = fs25.realpathSync(canonical);
170115
+ }
170116
+ } catch {}
170117
+ const existing = (config.trustedWorkspaces || []).map((p) => {
170118
+ const resolved = path26.resolve(p);
170119
+ try {
170120
+ return fs25.existsSync(resolved) ? fs25.realpathSync(resolved) : resolved;
170121
+ } catch {
170122
+ return resolved;
170123
+ }
170124
+ });
169996
170125
  if (!existing.includes(canonical)) {
169997
170126
  config.trustedWorkspaces = [...existing, canonical];
169998
170127
  await saveConfig(config);
@@ -170004,20 +170133,22 @@ async function promptWorkspaceTrust(workspaceRoot) {
170004
170133
  }
170005
170134
  const homeDir = path26.resolve(os13.homedir());
170006
170135
  const isHomeOrRoot = workspaceRoot === homeDir || workspaceRoot === "/";
170007
- const BRAND = "\x1B[38;2;137;180;248m";
170008
- const TEXT = "\x1B[38;2;244;244;245m";
170009
- const MUTED = "\x1B[38;2;170;170;170m";
170010
- const GRAY = "\x1B[38;2;119;119;119m";
170011
- const YELLOW = "\x1B[38;2;253;214;99m";
170136
+ const displayPath = formatDisplayPath(workspaceRoot);
170137
+ const BRAND_BLUE = "\x1B[38;2;137;180;248m";
170138
+ const BLUE = BRAND_BLUE;
170139
+ const WHITE = "\x1B[38;2;244;244;245m";
170140
+ const GRAY = "\x1B[38;2;161;161;170m";
170141
+ const YELLOW = "\x1B[38;2;253;224;71m";
170012
170142
  const BOLD = "\x1B[1m";
170013
170143
  const RESET = "\x1B[0m";
170014
170144
  const options = isHomeOrRoot ? [
170015
- { label: "No, exit", value: false },
170016
- { label: "Yes, trust folder anyway", value: true }
170145
+ { label: "Cancel", value: false },
170146
+ { label: "Trust and continue anyway", value: true }
170017
170147
  ] : [
170018
- { label: "Yes, trust folder", value: true },
170019
- { label: "No, exit", value: false }
170148
+ { label: "Trust and continue", value: true },
170149
+ { label: "Cancel", value: false }
170020
170150
  ];
170151
+ console.clear();
170021
170152
  return new Promise((resolve) => {
170022
170153
  let selectedIndex = 0;
170023
170154
  let renderedLineCount = 0;
@@ -170038,7 +170169,7 @@ async function promptWorkspaceTrust(workspaceRoot) {
170038
170169
  const clearRenderedLines = () => {
170039
170170
  if (renderedLineCount > 0) {
170040
170171
  readline3.cursorTo(process.stdout, 0);
170041
- readline3.moveCursor(process.stdout, 0, -renderedLineCount);
170172
+ readline3.moveCursor(process.stdout, 0, -(renderedLineCount - 1));
170042
170173
  readline3.clearScreenDown(process.stdout);
170043
170174
  }
170044
170175
  };
@@ -170046,25 +170177,21 @@ async function promptWorkspaceTrust(workspaceRoot) {
170046
170177
  clearRenderedLines();
170047
170178
  const lines = [];
170048
170179
  lines.push("");
170049
- lines.push(` ${BOLD}${TEXT}Trust workspace?${RESET}`);
170050
- lines.push("");
170051
- lines.push(` ${GRAY}Directory${RESET} ${BOLD}${BRAND}${workspaceRoot}${RESET}`);
170180
+ lines.push(` ${BOLD}${WHITE}Trust workspace:${RESET} ${BRAND_BLUE}${displayPath}${RESET}`);
170052
170181
  if (isHomeOrRoot) {
170053
- lines.push(` ${YELLOW}Warning${RESET} ${YELLOW}Home or system root directory. Gives access to all personal files.${RESET}`);
170054
- } else {
170055
- lines.push(` ${GRAY}Permission${RESET} ${TEXT}Read, edit, and run commands${RESET}`);
170182
+ lines.push(` ${YELLOW}Warning: Home or root directory gives access to all personal files.${RESET}`);
170056
170183
  }
170057
170184
  lines.push("");
170058
170185
  for (let i = 0;i < options.length; i++) {
170059
170186
  const opt = options[i];
170060
170187
  if (i === selectedIndex) {
170061
- lines.push(` ${BRAND}❭${RESET} ${BOLD}${TEXT}${opt.label}${RESET}`);
170188
+ lines.push(` ${BLUE}❭${RESET} ${BOLD}${WHITE}${opt.label}${RESET}`);
170062
170189
  } else {
170063
- lines.push(` ${MUTED}${opt.label}${RESET}`);
170190
+ lines.push(` ${GRAY}${opt.label}${RESET}`);
170064
170191
  }
170065
170192
  }
170066
170193
  lines.push("");
170067
- lines.push(` ${BRAND}Enter${RESET} ${MUTED}confirm${RESET} ${MUTED}·${RESET} ${BRAND}Esc${RESET} ${MUTED}cancel${RESET} ${MUTED}·${RESET} ${BRAND}↑↓${RESET} ${MUTED}navigate${RESET}`);
170194
+ lines.push(` ${GRAY}Enter confirm · Esc cancel${RESET}`);
170068
170195
  lines.push("");
170069
170196
  renderedLineCount = lines.length;
170070
170197
  process.stdout.write(lines.join(`
@@ -170075,13 +170202,13 @@ async function promptWorkspaceTrust(workspaceRoot) {
170075
170202
  return;
170076
170203
  const lowerStr = (str || "").toLowerCase();
170077
170204
  const keyName = key?.name;
170078
- if (lowerStr === "y" || keyName === "y") {
170205
+ if (lowerStr === "t" || lowerStr === "y") {
170079
170206
  cleanup();
170080
170207
  clearRenderedLines();
170081
170208
  resolve(true);
170082
170209
  return;
170083
170210
  }
170084
- if (lowerStr === "n" || keyName === "n") {
170211
+ if (lowerStr === "c" || lowerStr === "n") {
170085
170212
  cleanup();
170086
170213
  clearRenderedLines();
170087
170214
  resolve(false);
@@ -170093,7 +170220,7 @@ async function promptWorkspaceTrust(workspaceRoot) {
170093
170220
  } else if (keyName === "down" || keyName === "j" || keyName === "tab") {
170094
170221
  selectedIndex = Math.min(options.length - 1, selectedIndex + 1);
170095
170222
  render();
170096
- } else if (keyName === "return" || keyName === "enter") {
170223
+ } else if (keyName === "return" || keyName === "enter" || keyName === "space") {
170097
170224
  cleanup();
170098
170225
  clearRenderedLines();
170099
170226
  resolve(options[selectedIndex].value);
@@ -216112,7 +216239,7 @@ function InlineDialog({ config, close }) {
216112
216239
  return /* @__PURE__ */ jsx_runtime2.jsxs(Box_default, {
216113
216240
  flexDirection: "column",
216114
216241
  width: panelWidth,
216115
- borderStyle: "round",
216242
+ borderStyle: "single",
216116
216243
  borderColor: THEME.colors.border,
216117
216244
  paddingX: 1,
216118
216245
  paddingY: 0,
@@ -216320,6 +216447,14 @@ var init_prompt_history = __esm(() => {
216320
216447
  import { spawnSync } from "child_process";
216321
216448
  import * as os19 from "os";
216322
216449
  function writeToClipboard(text) {
216450
+ if (!text)
216451
+ return;
216452
+ try {
216453
+ if (process.stdout?.isTTY) {
216454
+ const base64 = Buffer.from(text, "utf8").toString("base64");
216455
+ process.stdout.write(`\x1B]52;c;${base64}\x07`);
216456
+ }
216457
+ } catch {}
216323
216458
  const platform = os19.platform();
216324
216459
  try {
216325
216460
  const isWsl = platform === "linux" && (!!process.env.WSL_DISTRO_NAME || os19.release().toLowerCase().includes("microsoft"));
@@ -216335,9 +216470,7 @@ function writeToClipboard(text) {
216335
216470
  spawnSync("xsel", ["--clipboard", "--input"], { input: text });
216336
216471
  }
216337
216472
  }
216338
- } catch (err) {
216339
- console.error("Failed to copy to clipboard", err);
216340
- }
216473
+ } catch {}
216341
216474
  }
216342
216475
  var init_clipboard = () => {};
216343
216476
 
@@ -216678,6 +216811,12 @@ var init_commands2 = __esm(() => {
216678
216811
  value: "/tasks",
216679
216812
  action: (ctx) => {}
216680
216813
  },
216814
+ {
216815
+ name: "tui",
216816
+ description: "Switch TUI renderer mode (fullscreen / classic)",
216817
+ value: "/tui",
216818
+ action: (ctx) => {}
216819
+ },
216681
216820
  {
216682
216821
  name: "update",
216683
216822
  description: "Update to the latest version",
@@ -217006,10 +217145,9 @@ function ShortcutsMenu({ onClose }) {
217006
217145
  const itemsBelow = SHORTCUTS.length - windowEnd;
217007
217146
  return /* @__PURE__ */ jsx_runtime6.jsxs(Box_default, {
217008
217147
  flexDirection: "column",
217009
- paddingX: THEME.padding.paddingX,
217010
217148
  children: [
217011
217149
  itemsAbove > 0 && /* @__PURE__ */ jsx_runtime6.jsx(Box_default, {
217012
- paddingLeft: 1,
217150
+ paddingLeft: 2,
217013
217151
  children: /* @__PURE__ */ jsx_runtime6.jsxs(Text3, {
217014
217152
  color: THEME.colors.muted,
217015
217153
  children: [
@@ -217048,7 +217186,7 @@ function ShortcutsMenu({ onClose }) {
217048
217186
  }, cmd.key);
217049
217187
  }),
217050
217188
  itemsBelow > 0 && /* @__PURE__ */ jsx_runtime6.jsx(Box_default, {
217051
- paddingLeft: 1,
217189
+ paddingLeft: 2,
217052
217190
  children: /* @__PURE__ */ jsx_runtime6.jsxs(Text3, {
217053
217191
  color: THEME.colors.muted,
217054
217192
  children: [
@@ -217059,7 +217197,7 @@ function ShortcutsMenu({ onClose }) {
217059
217197
  })
217060
217198
  }),
217061
217199
  /* @__PURE__ */ jsx_runtime6.jsx(Box_default, {
217062
- paddingLeft: 1,
217200
+ paddingLeft: 2,
217063
217201
  paddingTop: 1,
217064
217202
  children: /* @__PURE__ */ jsx_runtime6.jsxs(Text3, {
217065
217203
  color: THEME.colors.muted,
@@ -217622,6 +217760,7 @@ var init_input_bar = __esm(async () => {
217622
217760
  disabled = false,
217623
217761
  placeholder = "Ask December to build features, fix bugs, or work on your code...",
217624
217762
  activeModel = "unknown",
217763
+ modelLabel,
217625
217764
  authMethod,
217626
217765
  isAuthenticated = true,
217627
217766
  hasBothAuth = false,
@@ -217645,7 +217784,8 @@ var init_input_bar = __esm(async () => {
217645
217784
  tasks,
217646
217785
  onScrollUp,
217647
217786
  onScrollDown,
217648
- onStartVoice
217787
+ onStartVoice,
217788
+ onExit
217649
217789
  }) {
217650
217790
  const [value, setValue] = import_react42.useState("");
217651
217791
  const [isVoiceActive, setIsVoiceActive] = import_react42.useState(false);
@@ -217946,7 +218086,13 @@ var init_input_bar = __esm(async () => {
217946
218086
  }
217947
218087
  if (command.action) {
217948
218088
  command.action({
217949
- exit: () => process.exit(0),
218089
+ exit: () => {
218090
+ if (onExit) {
218091
+ onExit();
218092
+ } else {
218093
+ process.exit(0);
218094
+ }
218095
+ },
217950
218096
  toast,
217951
218097
  dialog,
217952
218098
  agent,
@@ -217955,6 +218101,7 @@ var init_input_bar = __esm(async () => {
217955
218101
  });
217956
218102
  }
217957
218103
  }, [
218104
+ onExit,
217958
218105
  toast,
217959
218106
  dialog,
217960
218107
  agent,
@@ -218017,7 +218164,7 @@ var init_input_bar = __esm(async () => {
218017
218164
  ]);
218018
218165
  const paddingLeft = THEME.padding.paddingLeft ?? THEME.padding.paddingX;
218019
218166
  const paddingRight = THEME.padding.paddingRight ?? 4;
218020
- const sepWidth = Math.max(10, columns - paddingLeft - paddingRight - 2);
218167
+ const sepWidth = Math.max(10, columns - paddingLeft - paddingRight);
218021
218168
  const sep = "─".repeat(sepWidth);
218022
218169
  const isOverlayActive = Boolean(authUI || workflowUI) && !customInputMode;
218023
218170
  const activeModeTag = planWorkflowPhase === "grilling" || grillMode ? "[GRILL]" : planWorkflowPhase === "executing" ? "[EXEC]" : planWorkflowPhase === "reviewing" || planWorkflowPhase === "refining" || planRefineMode || planMode || interactivePlanGoalMode ? "[PLAN]" : null;
@@ -218047,13 +218194,11 @@ var init_input_bar = __esm(async () => {
218047
218194
  }),
218048
218195
  showFileMenu && matchingFiles.length > 0 && /* @__PURE__ */ jsx_runtime8.jsx(Box_default, {
218049
218196
  flexDirection: "column",
218050
- paddingLeft: 1,
218051
218197
  marginBottom: 0,
218052
218198
  children: matchingFiles.map((file, idx) => {
218053
218199
  const isSelected = idx === selectedFileIndex;
218054
218200
  return /* @__PURE__ */ jsx_runtime8.jsxs(Box_default, {
218055
218201
  flexDirection: "row",
218056
- gap: 1,
218057
218202
  children: [
218058
218203
  /* @__PURE__ */ jsx_runtime8.jsx(Text3, {
218059
218204
  color: isSelected ? THEME.colors.brand : THEME.colors.muted,
@@ -218217,7 +218362,7 @@ var init_input_bar = __esm(async () => {
218217
218362
  " "
218218
218363
  ]
218219
218364
  }) : null,
218220
- !isAuthenticated ? "Not connected (run /login)" : `${activeModel}${authMethod === "subscription" ? " (Subscription)" : authMethod === "december" ? " (December Cloud)" : authMethod === "byok" ? " (BYOK)" : ""}`
218365
+ !isAuthenticated ? "Not connected (run /login)" : modelLabel || activeModel
218221
218366
  ]
218222
218367
  }),
218223
218368
  totalTasksCount > 0 && /* @__PURE__ */ jsx_runtime8.jsxs(Text3, {
@@ -218275,10 +218420,12 @@ var init_scroll_viewport = __esm(async () => {
218275
218420
  onScrollStateChange,
218276
218421
  isGenerating = false,
218277
218422
  isActive = true,
218278
- showIndicator = true
218423
+ showIndicator = true,
218424
+ onCopy
218279
218425
  }, ref) {
218280
218426
  const viewportRef = import_react43.useRef(null);
218281
218427
  const contentRef = import_react43.useRef(null);
218428
+ const isDraggingRef = import_react43.useRef(false);
218282
218429
  const defaultHeight = explicitHeight ?? (typeof process !== "undefined" && process.stdout?.rows ? Math.max(1, process.stdout.rows - 6) : 24);
218283
218430
  const [viewportHeight, setViewportHeight] = import_react43.useState(defaultHeight);
218284
218431
  const [contentHeight, setContentHeight] = import_react43.useState(0);
@@ -218305,6 +218452,7 @@ var init_scroll_viewport = __esm(async () => {
218305
218452
  scrollTop
218306
218453
  };
218307
218454
  const lastContentMeasureTimeRef = import_react43.useRef(0);
218455
+ const throttleTimerRef = import_react43.useRef(null);
218308
218456
  const pendingX10MouseRef = import_react43.useRef(false);
218309
218457
  import_react43.useLayoutEffect(() => {
218310
218458
  let vHeight = explicitHeight ?? viewportHeight;
@@ -218321,18 +218469,40 @@ var init_scroll_viewport = __esm(async () => {
218321
218469
  if (contentRef.current) {
218322
218470
  const now = Date.now();
218323
218471
  const shouldThrottle = isGenerating && !isReadingMode;
218324
- if (!shouldThrottle || now - lastContentMeasureTimeRef.current >= 80) {
218472
+ const elapsed = now - lastContentMeasureTimeRef.current;
218473
+ if (!shouldThrottle || elapsed >= 80) {
218474
+ if (throttleTimerRef.current) {
218475
+ clearTimeout(throttleTimerRef.current);
218476
+ throttleTimerRef.current = null;
218477
+ }
218325
218478
  lastContentMeasureTimeRef.current = now;
218326
218479
  const cMeasured = measure_element_default(contentRef.current);
218327
218480
  if (cMeasured.height !== prevContentHeightRef.current) {
218328
218481
  prevContentHeightRef.current = cMeasured.height;
218329
218482
  setContentHeight(cMeasured.height);
218330
218483
  }
218484
+ } else if (!throttleTimerRef.current) {
218485
+ throttleTimerRef.current = setTimeout(() => {
218486
+ throttleTimerRef.current = null;
218487
+ if (contentRef.current) {
218488
+ lastContentMeasureTimeRef.current = Date.now();
218489
+ const cMeasured = measure_element_default(contentRef.current);
218490
+ if (cMeasured.height !== prevContentHeightRef.current) {
218491
+ prevContentHeightRef.current = cMeasured.height;
218492
+ setContentHeight(cMeasured.height);
218493
+ }
218494
+ }
218495
+ }, Math.max(10, 80 - elapsed));
218331
218496
  }
218332
218497
  }
218333
218498
  });
218334
218499
  import_react43.useEffect(() => {
218335
- if (!isGenerating && contentRef.current) {
218500
+ if (contentRef.current) {
218501
+ if (throttleTimerRef.current) {
218502
+ clearTimeout(throttleTimerRef.current);
218503
+ throttleTimerRef.current = null;
218504
+ }
218505
+ lastContentMeasureTimeRef.current = Date.now();
218336
218506
  const cMeasured = measure_element_default(contentRef.current);
218337
218507
  if (cMeasured.height !== prevContentHeightRef.current) {
218338
218508
  prevContentHeightRef.current = cMeasured.height;
@@ -218340,6 +218510,14 @@ var init_scroll_viewport = __esm(async () => {
218340
218510
  }
218341
218511
  }
218342
218512
  }, [isGenerating]);
218513
+ import_react43.useEffect(() => {
218514
+ return () => {
218515
+ if (throttleTimerRef.current) {
218516
+ clearTimeout(throttleTimerRef.current);
218517
+ throttleTimerRef.current = null;
218518
+ }
218519
+ };
218520
+ }, []);
218343
218521
  import_react43.useEffect(() => {
218344
218522
  if (controlledScrollFromBottom !== undefined) {
218345
218523
  if (controlledScrollFromBottom === 0) {
@@ -218439,6 +218617,17 @@ var init_scroll_viewport = __esm(async () => {
218439
218617
  handleScrollDown(3 * downCount);
218440
218618
  return;
218441
218619
  }
218620
+ if (/\[<32;\d+;\d+;M/.test(input)) {
218621
+ isDraggingRef.current = true;
218622
+ return;
218623
+ }
218624
+ if (/\[<(?:0|32);\d+;\d+;m/.test(input)) {
218625
+ if (isDraggingRef.current) {
218626
+ isDraggingRef.current = false;
218627
+ onCopy?.();
218628
+ }
218629
+ return;
218630
+ }
218442
218631
  const pageSize = Math.max(1, stateRef.current.viewportHeight - 2);
218443
218632
  if (key.pageUp) {
218444
218633
  handleScrollUp(pageSize);
@@ -220359,7 +220548,7 @@ function parseTuiError(message, cause, hint) {
220359
220548
  const cleanCause = (c) => c?.replace(/^Cause:\s*/i, "").trim();
220360
220549
  const cleanMessage = (m) => m.replace(/^Error:\s*/i, "").trim();
220361
220550
  const cleanHint = (h) => h?.replace(/^Hint:\s*/i, "").trim();
220362
- if (cause || hint) {
220551
+ if (hint) {
220363
220552
  return {
220364
220553
  message: cleanMessage(message),
220365
220554
  cause: cleanCause(cause),
@@ -220367,6 +220556,27 @@ function parseTuiError(message, cause, hint) {
220367
220556
  };
220368
220557
  }
220369
220558
  const clean = cleanMessage(message);
220559
+ if (clean.includes("Insufficient credits in December Wallet")) {
220560
+ const lines = clean.split(`
220561
+ `).map((l) => l.trim()).filter(Boolean);
220562
+ const firstLine = lines[0] || "";
220563
+ const rest = cleanCause(lines.slice(1).join(`
220564
+ `));
220565
+ const hintMatch = firstLine.match(/Please (?:add credits|top up|check|upgrade|run|switch|configure).*$/i);
220566
+ const summary = hintMatch ? firstLine.replace(/Please (?:add credits|top up|check|upgrade|run|switch|configure).*$/i, "").replace(/^402\s*/, "").trim() : firstLine.replace(/^402\s*/, "").trim() || "Insufficient credits in December Wallet.";
220567
+ return {
220568
+ message: summary || "Insufficient credits in December Wallet.",
220569
+ cause: rest || cleanCause(cause),
220570
+ hint: hintMatch ? hintMatch[0].trim() : "Please add credits at https://app.trydecember.com/settings/billing or configure Bring Your Own Key (BYOK) via `/login` to continue using December."
220571
+ };
220572
+ }
220573
+ if (cause) {
220574
+ return {
220575
+ message: cleanMessage(message),
220576
+ cause: cleanCause(cause),
220577
+ hint: cleanHint(hint)
220578
+ };
220579
+ }
220370
220580
  if (clean.includes(`
220371
220581
  `)) {
220372
220582
  const lines = clean.split(`
@@ -220374,6 +220584,12 @@ function parseTuiError(message, cause, hint) {
220374
220584
  const firstLine = lines[0] || "";
220375
220585
  const rest = cleanCause(lines.slice(1).join(`
220376
220586
  `));
220587
+ if (firstLine.startsWith("Unable to connect") || firstLine.includes("Connection error") || firstLine.includes("Connection refused") || firstLine.includes("timed out") || clean.includes("Endpoint:")) {
220588
+ return {
220589
+ message: clean,
220590
+ cause: cleanCause(cause)
220591
+ };
220592
+ }
220377
220593
  if (firstLine.includes("Rate limit or quota exhausted")) {
220378
220594
  const hintMatch = firstLine.match(/Please.*$/i);
220379
220595
  const summary = firstLine.replace(/Please.*$/i, "").trim();
@@ -220442,6 +220658,20 @@ function parseTuiError(message, cause, hint) {
220442
220658
  cause: rest
220443
220659
  };
220444
220660
  }
220661
+ const cleanLower = clean.toLowerCase();
220662
+ if (clean === "Connection error." || cleanLower === "connection error" || cleanLower.startsWith("connection error")) {
220663
+ return {
220664
+ message: "Unable to connect to LLM provider (Connection error).",
220665
+ cause: cleanCause(cause),
220666
+ hint: cleanHint(hint)
220667
+ };
220668
+ }
220669
+ if (clean.startsWith("Unable to connect to ") && !hint) {
220670
+ return {
220671
+ message: clean,
220672
+ cause: cleanCause(cause)
220673
+ };
220674
+ }
220445
220675
  return {
220446
220676
  message: clean
220447
220677
  };
@@ -263127,7 +263357,7 @@ function Mermaid({ code }) {
263127
263357
  flexDirection: "column",
263128
263358
  paddingX: 2,
263129
263359
  paddingY: 1,
263130
- borderStyle: "round",
263360
+ borderStyle: "single",
263131
263361
  borderColor: THEME.colors.border,
263132
263362
  children: [
263133
263363
  /* @__PURE__ */ jsx_runtime13.jsxs(Box_default, {
@@ -263193,7 +263423,7 @@ function RenderFlowchart({ code }) {
263193
263423
  return /* @__PURE__ */ jsx_runtime13.jsxs(import_react47.default.Fragment, {
263194
263424
  children: [
263195
263425
  /* @__PURE__ */ jsx_runtime13.jsx(Box_default, {
263196
- borderStyle: "round",
263426
+ borderStyle: "single",
263197
263427
  borderColor: THEME.colors.border,
263198
263428
  paddingX: 1,
263199
263429
  children: /* @__PURE__ */ jsx_runtime13.jsx(Text3, {
@@ -263233,7 +263463,7 @@ function RenderFlowchart({ code }) {
263233
263463
  flexDirection: "column",
263234
263464
  children: [
263235
263465
  /* @__PURE__ */ jsx_runtime13.jsx(Box_default, {
263236
- borderStyle: "round",
263466
+ borderStyle: "single",
263237
263467
  borderColor: THEME.colors.border,
263238
263468
  paddingX: 1,
263239
263469
  children: /* @__PURE__ */ jsx_runtime13.jsx(Text3, {
@@ -263316,7 +263546,7 @@ function RenderSequence({ code }) {
263316
263546
  flexDirection: "row",
263317
263547
  gap: 2,
263318
263548
  children: participants.map((p) => /* @__PURE__ */ jsx_runtime13.jsx(Box_default, {
263319
- borderStyle: "round",
263549
+ borderStyle: "single",
263320
263550
  borderColor: THEME.colors.border,
263321
263551
  paddingX: 1,
263322
263552
  children: /* @__PURE__ */ jsx_runtime13.jsx(Text3, {
@@ -263564,7 +263794,7 @@ function Table({ token }) {
263564
263794
  marginY: 1,
263565
263795
  children: [
263566
263796
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263567
- color: THEME.colors.dim,
263797
+ color: THEME.colors.border,
263568
263798
  children: topBorder
263569
263799
  }),
263570
263800
  headers.length > 0 && /* @__PURE__ */ jsx_runtime14.jsxs(jsx_runtime14.Fragment, {
@@ -263573,7 +263803,7 @@ function Table({ token }) {
263573
263803
  flexDirection: "row",
263574
263804
  children: [
263575
263805
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263576
- color: THEME.colors.dim,
263806
+ color: THEME.colors.border,
263577
263807
  children: "│"
263578
263808
  }),
263579
263809
  colWidths.map((w, c) => /* @__PURE__ */ jsx_runtime14.jsxs(import_react48.default.Fragment, {
@@ -263588,7 +263818,7 @@ function Table({ token }) {
263588
263818
  })
263589
263819
  }),
263590
263820
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263591
- color: THEME.colors.dim,
263821
+ color: THEME.colors.border,
263592
263822
  children: "│"
263593
263823
  })
263594
263824
  ]
@@ -263596,7 +263826,7 @@ function Table({ token }) {
263596
263826
  ]
263597
263827
  }, `h-${l}`)),
263598
263828
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263599
- color: THEME.colors.dim,
263829
+ color: THEME.colors.border,
263600
263830
  children: headerSep
263601
263831
  })
263602
263832
  ]
@@ -263609,7 +263839,7 @@ function Table({ token }) {
263609
263839
  flexDirection: "row",
263610
263840
  children: [
263611
263841
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263612
- color: THEME.colors.dim,
263842
+ color: THEME.colors.border,
263613
263843
  children: "│"
263614
263844
  }),
263615
263845
  colWidths.map((w, c) => /* @__PURE__ */ jsx_runtime14.jsxs(import_react48.default.Fragment, {
@@ -263623,7 +263853,7 @@ function Table({ token }) {
263623
263853
  })
263624
263854
  }),
263625
263855
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263626
- color: THEME.colors.dim,
263856
+ color: THEME.colors.border,
263627
263857
  children: "│"
263628
263858
  })
263629
263859
  ]
@@ -263633,7 +263863,7 @@ function Table({ token }) {
263633
263863
  }, r);
263634
263864
  }),
263635
263865
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263636
- color: THEME.colors.dim,
263866
+ color: THEME.colors.border,
263637
263867
  children: bottomBorder
263638
263868
  })
263639
263869
  ]
@@ -263767,16 +263997,16 @@ function parseMarkdownTokens(source) {
263767
263997
  astCache.set(source, tokens);
263768
263998
  return tokens;
263769
263999
  }
263770
- var import_cli_highlight, import_react48, jsx_runtime14, CALLOUT_BORDER, renderToken = (token, index) => {
264000
+ var import_cli_highlight, import_react48, jsx_runtime14, CALLOUT_BORDER, renderToken = (token, index, isStreaming) => {
263771
264001
  switch (token.type) {
263772
264002
  case "paragraph":
263773
264003
  return /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263774
- children: token.tokens?.map((t, i) => renderToken(t, i))
264004
+ children: token.tokens?.map((t, i) => renderToken(t, i, isStreaming))
263775
264005
  }, index);
263776
264006
  case "text":
263777
264007
  if ("tokens" in token && token.tokens) {
263778
264008
  return /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263779
- children: token.tokens.map((t, i) => renderToken(t, i))
264009
+ children: token.tokens.map((t, i) => renderToken(t, i, isStreaming))
263780
264010
  }, index);
263781
264011
  }
263782
264012
  return /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
@@ -263785,12 +264015,12 @@ var import_cli_highlight, import_react48, jsx_runtime14, CALLOUT_BORDER, renderT
263785
264015
  case "strong":
263786
264016
  return /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263787
264017
  bold: true,
263788
- children: token.tokens?.map((t, i) => renderToken(t, i))
264018
+ children: token.tokens?.map((t, i) => renderToken(t, i, isStreaming))
263789
264019
  }, index);
263790
264020
  case "em":
263791
264021
  return /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263792
264022
  italic: true,
263793
- children: token.tokens?.map((t, i) => renderToken(t, i))
264023
+ children: token.tokens?.map((t, i) => renderToken(t, i, isStreaming))
263794
264024
  }, index);
263795
264025
  case "codespan": {
263796
264026
  if (isFilePath(token.text)) {
@@ -263820,7 +264050,8 @@ var import_cli_highlight, import_react48, jsx_runtime14, CALLOUT_BORDER, renderT
263820
264050
  }, index);
263821
264051
  }
263822
264052
  return /* @__PURE__ */ jsx_runtime14.jsx(CodeBlock, {
263823
- token
264053
+ token,
264054
+ isStreaming
263824
264055
  }, index);
263825
264056
  case "list":
263826
264057
  return /* @__PURE__ */ jsx_runtime14.jsx(Box_default, {
@@ -263836,7 +264067,7 @@ var import_cli_highlight, import_react48, jsx_runtime14, CALLOUT_BORDER, renderT
263836
264067
  /* @__PURE__ */ jsx_runtime14.jsx(Box_default, {
263837
264068
  flexDirection: "column",
263838
264069
  flexShrink: 1,
263839
- children: item.tokens.map((t, j) => renderToken(t, j))
264070
+ children: item.tokens.map((t, j) => renderToken(t, j, isStreaming))
263840
264071
  })
263841
264072
  ]
263842
264073
  }, i))
@@ -263852,7 +264083,7 @@ var import_cli_highlight, import_react48, jsx_runtime14, CALLOUT_BORDER, renderT
263852
264083
  }),
263853
264084
  /* @__PURE__ */ jsx_runtime14.jsx(Text3, {
263854
264085
  color: THEME.colors.brand,
263855
- children: token.tokens?.map((t, i) => renderToken(t, i))
264086
+ children: token.tokens?.map((t, i) => renderToken(t, i, isStreaming))
263856
264087
  })
263857
264088
  ]
263858
264089
  }, index);
@@ -263914,13 +264145,19 @@ var init_markdown = __esm(async () => {
263914
264145
  };
263915
264146
  highlightCache = new Map;
263916
264147
  astCache = new Map;
263917
- CodeBlock = import_react48.default.memo(function CodeBlock({ token }) {
264148
+ CodeBlock = import_react48.default.memo(function CodeBlock({
264149
+ token,
264150
+ isStreaming
264151
+ }) {
263918
264152
  const lang = token.lang || "typescript";
263919
264153
  const highlighted = import_react48.default.useMemo(() => {
263920
264154
  if (!token.text)
263921
264155
  return "";
264156
+ if (isStreaming) {
264157
+ return token.text;
264158
+ }
263922
264159
  return getHighlightedCode(token.text, lang);
263923
- }, [token.text, lang]);
264160
+ }, [token.text, lang, isStreaming]);
263924
264161
  return /* @__PURE__ */ jsx_runtime14.jsx(Box_default, {
263925
264162
  flexDirection: "column",
263926
264163
  paddingY: 1,
@@ -263930,7 +264167,7 @@ var init_markdown = __esm(async () => {
263930
264167
  })
263931
264168
  });
263932
264169
  });
263933
- Markdown = import_react48.default.memo(function Markdown({ children }) {
264170
+ Markdown = import_react48.default.memo(function Markdown({ children, isStreaming }) {
263934
264171
  const tokens = import_react48.default.useMemo(() => {
263935
264172
  return parseMarkdownTokens(children);
263936
264173
  }, [children]);
@@ -263939,7 +264176,7 @@ var init_markdown = __esm(async () => {
263939
264176
  return /* @__PURE__ */ jsx_runtime14.jsx(Box_default, {
263940
264177
  flexDirection: "column",
263941
264178
  gap: 1,
263942
- children: tokens.map((token, index) => renderToken(token, index))
264179
+ children: tokens.map((token, index) => renderToken(token, index, isStreaming))
263943
264180
  });
263944
264181
  });
263945
264182
  });
@@ -263995,6 +264232,7 @@ function SmoothMarkdown({ text, isRunning }) {
263995
264232
  content: committed
263996
264233
  }) : null,
263997
264234
  sanitizedTail && sanitizedTail.trim() !== "" ? /* @__PURE__ */ jsx_runtime15.jsx(Markdown, {
264235
+ isStreaming: true,
263998
264236
  children: sanitizedTail
263999
264237
  }) : null
264000
264238
  ]
@@ -264885,6 +265123,102 @@ function getCwd() {
264885
265123
  return "~";
264886
265124
  }
264887
265125
  }
265126
+ function formatModelDisplayName(model) {
265127
+ if (!model)
265128
+ return "";
265129
+ const m = model.trim();
265130
+ const lower = m.toLowerCase();
265131
+ const curated = {
265132
+ "claude-3-7-sonnet": "Claude 3.7 Sonnet",
265133
+ "claude-3.7-sonnet": "Claude 3.7 Sonnet",
265134
+ "claude-3-5-sonnet": "Claude 3.5 Sonnet",
265135
+ "claude-3.5-sonnet": "Claude 3.5 Sonnet",
265136
+ "claude-3-5-haiku": "Claude 3.5 Haiku",
265137
+ "claude-3.5-haiku": "Claude 3.5 Haiku",
265138
+ "claude-4-5-opus": "Claude 4.5 Opus",
265139
+ "claude-4.5-opus": "Claude 4.5 Opus",
265140
+ "claude-opus-5": "Claude Opus 5",
265141
+ "claude-sonnet-4.6": "Claude Sonnet 4.6",
265142
+ "claude-sonnet-5": "Claude Sonnet 5",
265143
+ "gemini-2.5-flash": "Gemini 2.5 Flash",
265144
+ "gemini-2.5-pro": "Gemini 2.5 Pro",
265145
+ "gemini-3.7-flash": "Gemini 3.7 Flash",
265146
+ "gemini-3.6-flash": "Gemini 3.6 Flash",
265147
+ "gemini-3.8-flash": "Gemini 3.8 Flash",
265148
+ "gpt-5.6-sol": "GPT-5.6 Sol",
265149
+ "gpt-5.6-luna": "GPT-5.6 Luna",
265150
+ "gpt-4o": "GPT-4o",
265151
+ "gpt-4o-mini": "GPT-4o Mini",
265152
+ o1: "o1",
265153
+ "o1-mini": "o1-mini",
265154
+ o3: "o3",
265155
+ "o3-mini": "o3-mini",
265156
+ "o4-mini": "o4-mini",
265157
+ "december-auto": "Humans R1",
265158
+ auto: "Humans R1",
265159
+ "humans-r1": "Humans R1"
265160
+ };
265161
+ if (curated[lower])
265162
+ return curated[lower];
265163
+ const parts = m.split(/[/:]/);
265164
+ const last = parts[parts.length - 1];
265165
+ return last.split(/[-_]/).map((part) => {
265166
+ if (/^\d+(\.\d+)*$/.test(part))
265167
+ return part;
265168
+ if (/^(gpt|llm|ai|api|oss)$/i.test(part))
265169
+ return part.toUpperCase();
265170
+ return part.charAt(0).toUpperCase() + part.slice(1);
265171
+ }).join(" ");
265172
+ }
265173
+ function formatBillingLabel(authMethod, provider, model, isAuthenticated = true) {
265174
+ if (!isAuthenticated) {
265175
+ return "Not connected · Run /login";
265176
+ }
265177
+ const p = (provider || "").toLowerCase().trim();
265178
+ const m = (model || "").toLowerCase().trim();
265179
+ let brand = "API";
265180
+ if (p === "copilot" || p === "github") {
265181
+ brand = "Copilot";
265182
+ } else if (p === "claude" || p === "anthropic") {
265183
+ brand = "Claude";
265184
+ } else if (p === "codex" || p === "chatgpt") {
265185
+ brand = "ChatGPT";
265186
+ } else if (p === "openai") {
265187
+ brand = authMethod === "subscription" ? "ChatGPT" : "OpenAI";
265188
+ } else if (p === "gemini" || p === "google") {
265189
+ brand = "Gemini";
265190
+ } else if (p === "deepseek") {
265191
+ brand = "DeepSeek";
265192
+ } else if (p === "groq") {
265193
+ brand = "Groq";
265194
+ } else if (p === "mistral" || p.includes("mistral")) {
265195
+ brand = "Mistral";
265196
+ } else if (p === "openrouter") {
265197
+ brand = "OpenRouter";
265198
+ } else if (p === "ollama") {
265199
+ brand = "Ollama";
265200
+ } else if (p) {
265201
+ brand = p.charAt(0).toUpperCase() + p.slice(1);
265202
+ } else if (m.includes("claude") || m.includes("sonnet") || m.includes("opus") || m.includes("haiku")) {
265203
+ brand = "Claude";
265204
+ } else if (m.includes("gpt") || m.includes("o1") || m.includes("o3") || m.includes("o4")) {
265205
+ brand = authMethod === "subscription" ? "ChatGPT" : "OpenAI";
265206
+ } else if (m.includes("gemini")) {
265207
+ brand = "Gemini";
265208
+ } else if (m.includes("deepseek")) {
265209
+ brand = "DeepSeek";
265210
+ }
265211
+ if (authMethod === "december") {
265212
+ return "December Wallet";
265213
+ }
265214
+ if (authMethod === "subscription") {
265215
+ return `${brand} Subscription`;
265216
+ }
265217
+ if (authMethod === "byok" || authMethod === "env") {
265218
+ return brand === "Ollama" ? "Ollama Local" : `${brand} API`;
265219
+ }
265220
+ return brand ? `${brand} API` : "API";
265221
+ }
264888
265222
  var import_react51, jsx_runtime17, cachedBranch = undefined, Header;
264889
265223
  var init_header = __esm(async () => {
264890
265224
  init_theme();
@@ -264896,10 +265230,29 @@ var init_header = __esm(async () => {
264896
265230
  cliVersion = "0.1.0",
264897
265231
  latestVersion,
264898
265232
  userEmail,
264899
- announcement
265233
+ announcement,
265234
+ activeModel,
265235
+ modelLabel,
265236
+ authMethod,
265237
+ selectedProvider,
265238
+ isAuthenticated
264900
265239
  }) {
264901
265240
  const cwd = getCwd();
264902
265241
  const branch = getGitBranch();
265242
+ let modelStatusLine = null;
265243
+ if (isAuthenticated === false) {
265244
+ modelStatusLine = "Not connected · Run /login";
265245
+ } else {
265246
+ const modelName = modelLabel || formatModelDisplayName(activeModel);
265247
+ const billingLabel = formatBillingLabel(authMethod, selectedProvider, activeModel, isAuthenticated ?? true);
265248
+ if (modelName && billingLabel) {
265249
+ modelStatusLine = `${modelName} · ${billingLabel}`;
265250
+ } else if (modelName) {
265251
+ modelStatusLine = modelName;
265252
+ } else if (billingLabel) {
265253
+ modelStatusLine = billingLabel;
265254
+ }
265255
+ }
264903
265256
  return /* @__PURE__ */ jsx_runtime17.jsxs(Box_default, {
264904
265257
  flexDirection: "column",
264905
265258
  paddingLeft: THEME.padding.paddingLeft ?? THEME.padding.paddingX,
@@ -264931,6 +265284,10 @@ var init_header = __esm(async () => {
264931
265284
  color: THEME.colors.subtle,
264932
265285
  children: userEmail
264933
265286
  }),
265287
+ modelStatusLine && /* @__PURE__ */ jsx_runtime17.jsx(Text3, {
265288
+ color: THEME.colors.subtle,
265289
+ children: modelStatusLine
265290
+ }),
264934
265291
  /* @__PURE__ */ jsx_runtime17.jsxs(Box_default, {
264935
265292
  gap: 1,
264936
265293
  children: [
@@ -264989,7 +265346,7 @@ var init_header = __esm(async () => {
264989
265346
  })
264990
265347
  ]
264991
265348
  }),
264992
- announcement.bullets.slice(0, 3).map((bullet, idx) => /* @__PURE__ */ jsx_runtime17.jsxs(Box_default, {
265349
+ announcement.bullets.slice(0, 2).map((bullet, idx) => /* @__PURE__ */ jsx_runtime17.jsxs(Box_default, {
264993
265350
  children: [
264994
265351
  /* @__PURE__ */ jsx_runtime17.jsx(Text3, {
264995
265352
  color: THEME.colors.brand,
@@ -265074,7 +265431,6 @@ var init_user_message = __esm(async () => {
265074
265431
  // ../../packages/tui/src/components/message-list.tsx
265075
265432
  var import_react53, jsx_runtime19, MessageItem, MAX_WINDOW_MESSAGES = 20, MessageList;
265076
265433
  var init_message_list = __esm(async () => {
265077
- init_theme();
265078
265434
  await __promiseAll([
265079
265435
  init_build2(),
265080
265436
  init_header(),
@@ -265091,14 +265447,24 @@ var init_message_list = __esm(async () => {
265091
265447
  latestVersion,
265092
265448
  userEmail,
265093
265449
  expandCommands,
265094
- announcement
265450
+ announcement,
265451
+ activeModel,
265452
+ modelLabel,
265453
+ authMethod,
265454
+ selectedProvider,
265455
+ isAuthenticated
265095
265456
  }) {
265096
265457
  if (msg.role === "header") {
265097
265458
  return /* @__PURE__ */ jsx_runtime19.jsx(Header, {
265098
265459
  cliVersion,
265099
265460
  latestVersion,
265100
265461
  userEmail,
265101
- announcement
265462
+ announcement,
265463
+ activeModel,
265464
+ modelLabel,
265465
+ authMethod,
265466
+ selectedProvider,
265467
+ isAuthenticated
265102
265468
  });
265103
265469
  }
265104
265470
  if (msg.role === "user") {
@@ -265135,6 +265501,16 @@ var init_message_list = __esm(async () => {
265135
265501
  return false;
265136
265502
  if (prev.announcement !== next.announcement)
265137
265503
  return false;
265504
+ if (prev.isAuthenticated !== next.isAuthenticated)
265505
+ return false;
265506
+ if (prev.activeModel !== next.activeModel)
265507
+ return false;
265508
+ if (prev.modelLabel !== next.modelLabel)
265509
+ return false;
265510
+ if (prev.authMethod !== next.authMethod)
265511
+ return false;
265512
+ if (prev.selectedProvider !== next.selectedProvider)
265513
+ return false;
265138
265514
  return true;
265139
265515
  });
265140
265516
  MessageList = import_react53.default.memo(function MessageList({
@@ -265148,7 +265524,11 @@ var init_message_list = __esm(async () => {
265148
265524
  expandCommands,
265149
265525
  fullscreen = true,
265150
265526
  announcement,
265151
- isReadingMode = false
265527
+ isReadingMode = false,
265528
+ activeModel,
265529
+ modelLabel,
265530
+ authMethod,
265531
+ selectedProvider
265152
265532
  }) {
265153
265533
  if (fullscreen) {
265154
265534
  const allMessages = [...staticMessages, ...activeMessages];
@@ -265159,26 +265539,21 @@ var init_message_list = __esm(async () => {
265159
265539
  flexDirection: "column",
265160
265540
  width: "100%",
265161
265541
  children: [
265162
- hiddenCount > 0 && /* @__PURE__ */ jsx_runtime19.jsx(Box_default, {
265163
- paddingLeft: THEME.padding.paddingLeft ?? THEME.padding.paddingX,
265164
- paddingRight: THEME.padding.paddingRight ?? 4,
265165
- marginY: 1,
265166
- children: /* @__PURE__ */ jsx_runtime19.jsx(Box_default, {
265167
- children: /* @__PURE__ */ jsx_runtime19.jsx(Box_default, {
265168
- marginRight: 1,
265169
- children: /* @__PURE__ */ jsx_runtime19.jsx(Header, {
265170
- cliVersion,
265171
- latestVersion,
265172
- userEmail,
265173
- announcement
265174
- })
265175
- })
265176
- })
265542
+ hiddenCount > 0 && /* @__PURE__ */ jsx_runtime19.jsx(Header, {
265543
+ cliVersion,
265544
+ latestVersion,
265545
+ userEmail,
265546
+ announcement,
265547
+ activeModel,
265548
+ modelLabel,
265549
+ authMethod,
265550
+ selectedProvider,
265551
+ isAuthenticated
265177
265552
  }),
265178
265553
  visibleMessages.map((msg, index) => {
265179
265554
  const actualIndex = shouldWindow ? hiddenCount + index : index;
265180
265555
  const prevRole = actualIndex > 0 ? allMessages[actualIndex - 1]?.role : null;
265181
- const key = msg.id != null ? `${msg.id}-${actualIndex}` : `msg-idx-${actualIndex}`;
265556
+ const key = msg.id != null ? `${msg.id}` : `msg-idx-${actualIndex}`;
265182
265557
  return /* @__PURE__ */ jsx_runtime19.jsx(MessageItem, {
265183
265558
  msg,
265184
265559
  index: actualIndex,
@@ -265187,7 +265562,12 @@ var init_message_list = __esm(async () => {
265187
265562
  latestVersion,
265188
265563
  userEmail,
265189
265564
  expandCommands,
265190
- announcement
265565
+ announcement,
265566
+ activeModel,
265567
+ modelLabel,
265568
+ authMethod,
265569
+ selectedProvider,
265570
+ isAuthenticated
265191
265571
  }, key);
265192
265572
  })
265193
265573
  ]
@@ -265202,7 +265582,7 @@ var init_message_list = __esm(async () => {
265202
265582
  style: { width: "100%" },
265203
265583
  children: (msg, index) => {
265204
265584
  const prevRole = index > 0 ? staticMessages[index - 1]?.role : null;
265205
- const key = msg.id != null ? `${msg.id}-${index}` : `msg-idx-${index}`;
265585
+ const key = msg.id != null ? `${msg.id}` : `msg-idx-${index}`;
265206
265586
  return /* @__PURE__ */ jsx_runtime19.jsx(MessageItem, {
265207
265587
  msg,
265208
265588
  index,
@@ -265211,7 +265591,12 @@ var init_message_list = __esm(async () => {
265211
265591
  latestVersion,
265212
265592
  userEmail,
265213
265593
  expandCommands,
265214
- announcement
265594
+ announcement,
265595
+ activeModel,
265596
+ modelLabel,
265597
+ authMethod,
265598
+ selectedProvider,
265599
+ isAuthenticated
265215
265600
  }, key);
265216
265601
  }
265217
265602
  }, staticKey),
@@ -265219,7 +265604,7 @@ var init_message_list = __esm(async () => {
265219
265604
  const actualIndex = staticMessages.length + index;
265220
265605
  const all = [...staticMessages, ...activeMessages];
265221
265606
  const prevRole = actualIndex > 0 ? all[actualIndex - 1]?.role : null;
265222
- const key = msg.id != null ? `${msg.id}-${actualIndex}` : `msg-idx-${actualIndex}`;
265607
+ const key = msg.id != null ? `${msg.id}` : `msg-idx-${actualIndex}`;
265223
265608
  return /* @__PURE__ */ jsx_runtime19.jsx(MessageItem, {
265224
265609
  msg,
265225
265610
  index: actualIndex,
@@ -265228,7 +265613,12 @@ var init_message_list = __esm(async () => {
265228
265613
  latestVersion,
265229
265614
  userEmail,
265230
265615
  expandCommands,
265231
- announcement
265616
+ announcement,
265617
+ activeModel,
265618
+ modelLabel,
265619
+ authMethod,
265620
+ selectedProvider,
265621
+ isAuthenticated
265232
265622
  }, key);
265233
265623
  })
265234
265624
  ]
@@ -265392,8 +265782,9 @@ function ByokProviderMenu(props) {
265392
265782
  const {
265393
265783
  handleProviderSelect,
265394
265784
  handleByokSelect,
265785
+ handleSubscriptionSelect,
265395
265786
  setAuthMode,
265396
- items = PROVIDER_MENU_ITEMS
265787
+ items = UNIFIED_PROVIDER_MENU_ITEMS
265397
265788
  } = props;
265398
265789
  const [selectedIndex, setSelectedIndex] = import_react56.useState(0);
265399
265790
  const [windowStart, setWindowStart] = import_react56.useState(0);
@@ -265449,8 +265840,15 @@ function ByokProviderMenu(props) {
265449
265840
  return;
265450
265841
  }
265451
265842
  if (key.return) {
265452
- if (onSelect && filteredItems[selectedIndex]) {
265453
- onSelect(filteredItems[selectedIndex]);
265843
+ const item = filteredItems[selectedIndex];
265844
+ if (item) {
265845
+ if (item.isSubscription && handleSubscriptionSelect) {
265846
+ handleSubscriptionSelect(item);
265847
+ return;
265848
+ }
265849
+ if (onSelect) {
265850
+ onSelect(item);
265851
+ }
265454
265852
  }
265455
265853
  return;
265456
265854
  }
@@ -265471,6 +265869,22 @@ function ByokProviderMenu(props) {
265471
265869
  const visibleItems = filteredItems.slice(windowStart, windowEnd);
265472
265870
  const itemsAbove = windowStart;
265473
265871
  const itemsBelow = filteredItems.length - windowEnd;
265872
+ const hasInlineHeader = visibleItems.some((item, relIdx) => {
265873
+ const absIdx = windowStart + relIdx;
265874
+ const prevItem = absIdx > 0 ? filteredItems[absIdx - 1] : null;
265875
+ return Boolean(item.section && (!prevItem || prevItem.section !== item.section));
265876
+ });
265877
+ const topSection = visibleItems[0]?.section;
265878
+ let stickyHeader = null;
265879
+ if (!hasInlineHeader && topSection) {
265880
+ if (topSection === "subscription") {
265881
+ stickyHeader = `${THEME.glyphs.bullet} Subscriptions`;
265882
+ } else if (topSection === "popular") {
265883
+ stickyHeader = `${THEME.glyphs.bullet} Popular`;
265884
+ } else if (topSection === "all") {
265885
+ stickyHeader = `${THEME.glyphs.bullet} All Providers`;
265886
+ }
265887
+ }
265474
265888
  const footerItems = isSearching ? [
265475
265889
  { key: "enter / ↓", label: "Focus List" },
265476
265890
  { key: "esc", label: "Exit Search" }
@@ -265480,9 +265894,10 @@ function ByokProviderMenu(props) {
265480
265894
  { key: "/", label: "Search" },
265481
265895
  { key: "esc", label: "Back" }
265482
265896
  ];
265897
+ const hasSubscriptions = items.some((i) => i.isSubscription);
265898
+ const menuTitle = props.title || (hasSubscriptions ? "Select Provider (Key or Subscription):" : "Select API Provider (BYOK):");
265483
265899
  return /* @__PURE__ */ jsx_runtime23.jsxs(Box_default, {
265484
265900
  flexDirection: "column",
265485
- paddingX: THEME.padding.paddingX,
265486
265901
  children: [
265487
265902
  /* @__PURE__ */ jsx_runtime23.jsxs(Box_default, {
265488
265903
  marginBottom: 1,
@@ -265491,7 +265906,7 @@ function ByokProviderMenu(props) {
265491
265906
  children: [
265492
265907
  /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
265493
265908
  color: THEME.colors.text,
265494
- children: "Select API Provider (BYOK):"
265909
+ children: menuTitle
265495
265910
  }),
265496
265911
  /* @__PURE__ */ jsx_runtime23.jsxs(Box_default, {
265497
265912
  flexDirection: "row",
@@ -265528,54 +265943,92 @@ function ByokProviderMenu(props) {
265528
265943
  })
265529
265944
  ]
265530
265945
  }),
265531
- itemsAbove > 0 && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265532
- paddingLeft: 2,
265533
- children: /* @__PURE__ */ jsx_runtime23.jsxs(Text3, {
265534
- color: THEME.colors.muted,
265535
- children: [
265536
- "↑ ",
265537
- itemsAbove,
265538
- " more"
265539
- ]
265540
- })
265541
- }),
265542
- visibleItems.map((item, relIdx) => {
265543
- const absIdx = windowStart + relIdx;
265544
- const isSelected = absIdx === selectedIndex;
265545
- return /* @__PURE__ */ jsx_runtime23.jsxs(Box_default, {
265546
- paddingLeft: 0,
265547
- children: [
265548
- /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265549
- marginRight: 1,
265550
- children: /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
265551
- color: THEME.colors.brand,
265552
- children: isSelected ? THEME.glyphs.selector : " "
265553
- })
265554
- }),
265555
- /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
265556
- color: isSelected ? THEME.colors.brand : THEME.colors.text,
265557
- children: item.label
265946
+ /* @__PURE__ */ jsx_runtime23.jsxs(Box_default, {
265947
+ flexDirection: "column",
265948
+ minHeight: 10,
265949
+ children: [
265950
+ itemsAbove > 0 && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265951
+ paddingLeft: 2,
265952
+ children: /* @__PURE__ */ jsx_runtime23.jsxs(Text3, {
265953
+ color: THEME.colors.muted,
265954
+ children: [
265955
+ "↑ ",
265956
+ itemsAbove,
265957
+ " more"
265958
+ ]
265558
265959
  })
265559
- ]
265560
- }, item.value);
265561
- }),
265562
- itemsBelow > 0 && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265563
- paddingLeft: 2,
265564
- children: /* @__PURE__ */ jsx_runtime23.jsxs(Text3, {
265565
- color: THEME.colors.muted,
265566
- children: [
265567
- "↓ ",
265568
- itemsBelow,
265569
- " more"
265570
- ]
265571
- })
265572
- }),
265573
- filteredItems.length === 0 && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265574
- paddingLeft: 2,
265575
- children: /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
265576
- color: THEME.colors.muted,
265577
- children: "No providers found."
265578
- })
265960
+ }),
265961
+ stickyHeader && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265962
+ paddingLeft: 2,
265963
+ marginY: 0,
265964
+ children: /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
265965
+ color: THEME.colors.subtle,
265966
+ children: stickyHeader
265967
+ })
265968
+ }),
265969
+ visibleItems.map((item, relIdx) => {
265970
+ const absIdx = windowStart + relIdx;
265971
+ const isSelected = absIdx === selectedIndex;
265972
+ const prevItem = absIdx > 0 ? filteredItems[absIdx - 1] : null;
265973
+ const isFirstInSection = item.section && (!prevItem || prevItem.section !== item.section);
265974
+ let sectionHeader = null;
265975
+ if (isFirstInSection) {
265976
+ if (item.section === "subscription") {
265977
+ sectionHeader = `${THEME.glyphs.bullet} Subscriptions`;
265978
+ } else if (item.section === "popular") {
265979
+ sectionHeader = `${THEME.glyphs.bullet} Popular`;
265980
+ } else if (item.section === "all") {
265981
+ sectionHeader = `${THEME.glyphs.bullet} All Providers`;
265982
+ }
265983
+ }
265984
+ return /* @__PURE__ */ jsx_runtime23.jsxs(import_react56.default.Fragment, {
265985
+ children: [
265986
+ sectionHeader && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265987
+ paddingLeft: 2,
265988
+ marginY: 0,
265989
+ children: /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
265990
+ color: THEME.colors.subtle,
265991
+ children: sectionHeader
265992
+ })
265993
+ }),
265994
+ /* @__PURE__ */ jsx_runtime23.jsxs(Box_default, {
265995
+ paddingLeft: 0,
265996
+ children: [
265997
+ /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
265998
+ marginRight: 1,
265999
+ children: /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
266000
+ color: THEME.colors.brand,
266001
+ children: isSelected ? THEME.glyphs.selector : " "
266002
+ })
266003
+ }),
266004
+ /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
266005
+ color: isSelected ? THEME.colors.brand : THEME.colors.text,
266006
+ children: item.label
266007
+ })
266008
+ ]
266009
+ })
266010
+ ]
266011
+ }, `${item.value}-${absIdx}`);
266012
+ }),
266013
+ itemsBelow > 0 && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
266014
+ paddingLeft: 2,
266015
+ children: /* @__PURE__ */ jsx_runtime23.jsxs(Text3, {
266016
+ color: THEME.colors.muted,
266017
+ children: [
266018
+ "↓ ",
266019
+ itemsBelow,
266020
+ " more"
266021
+ ]
266022
+ })
266023
+ }),
266024
+ filteredItems.length === 0 && /* @__PURE__ */ jsx_runtime23.jsx(Box_default, {
266025
+ paddingLeft: 2,
266026
+ children: /* @__PURE__ */ jsx_runtime23.jsx(Text3, {
266027
+ color: THEME.colors.muted,
266028
+ children: "No providers found."
266029
+ })
266030
+ })
266031
+ ]
265579
266032
  }),
265580
266033
  /* @__PURE__ */ jsx_runtime23.jsx(MenuFooter, {
265581
266034
  items: footerItems
@@ -265583,7 +266036,7 @@ function ByokProviderMenu(props) {
265583
266036
  ]
265584
266037
  });
265585
266038
  }
265586
- var import_react56, jsx_runtime23, WINDOW_SIZE4 = 7, PROVIDER_MENU_ITEMS;
266039
+ var import_react56, jsx_runtime23, WINDOW_SIZE4 = 7, PROVIDER_MENU_ITEMS, POPULAR_PROVIDER_VALUES, SUBSCRIPTION_PROVIDER_ITEMS, POPULAR_BYOK_ITEMS, REMAINING_BYOK_ITEMS, UNIFIED_PROVIDER_MENU_ITEMS;
265587
266040
  var init_byok_provider_menu = __esm(async () => {
265588
266041
  init_theme();
265589
266042
  await __promiseAll([
@@ -265781,6 +266234,44 @@ var init_byok_provider_menu = __esm(async () => {
265781
266234
  { label: "Zenifra", value: "zenifra" },
265782
266235
  { label: "ZenMux", value: "zenmux" }
265783
266236
  ];
266237
+ POPULAR_PROVIDER_VALUES = [
266238
+ "anthropic",
266239
+ "openai",
266240
+ "google",
266241
+ "openrouter",
266242
+ "deepseek",
266243
+ "groq",
266244
+ "mistral",
266245
+ "xai",
266246
+ "ollama",
266247
+ "perplexity",
266248
+ "cohere",
266249
+ "together",
266250
+ "fireworks",
266251
+ "cerebras",
266252
+ "sambanova"
266253
+ ];
266254
+ SUBSCRIPTION_PROVIDER_ITEMS = [
266255
+ { label: "Anthropic (Claude)", value: "claude", isSubscription: true, section: "subscription" },
266256
+ { label: "GitHub (Copilot)", value: "copilot", isSubscription: true, section: "subscription" },
266257
+ {
266258
+ label: "Google (Gemini / Antigravity)",
266259
+ value: "gemini",
266260
+ isSubscription: true,
266261
+ section: "subscription"
266262
+ },
266263
+ { label: "OpenAI (ChatGPT)", value: "codex", isSubscription: true, section: "subscription" }
266264
+ ];
266265
+ POPULAR_BYOK_ITEMS = POPULAR_PROVIDER_VALUES.map((val) => {
266266
+ const found = PROVIDER_MENU_ITEMS.find((item) => item.value === val);
266267
+ return found ? { ...found, section: "popular" } : null;
266268
+ }).filter(Boolean);
266269
+ REMAINING_BYOK_ITEMS = PROVIDER_MENU_ITEMS.filter((item) => !POPULAR_PROVIDER_VALUES.includes(item.value)).map((item) => ({ ...item, section: "all" }));
266270
+ UNIFIED_PROVIDER_MENU_ITEMS = [
266271
+ ...SUBSCRIPTION_PROVIDER_ITEMS,
266272
+ ...POPULAR_BYOK_ITEMS,
266273
+ ...REMAINING_BYOK_ITEMS
266274
+ ];
265784
266275
  });
265785
266276
 
265786
266277
  // ../../packages/tui/src/components/menus/byok-key-menu.tsx
@@ -265796,7 +266287,6 @@ function ByokKeyMenu(props) {
265796
266287
  const keyNote = selectedProvider ? PROVIDER_KEY_NOTES[selectedProvider.toLowerCase().trim()] : undefined;
265797
266288
  return /* @__PURE__ */ jsx_runtime24.jsxs(Box_default, {
265798
266289
  flexDirection: "column",
265799
- paddingX: THEME.padding.paddingX,
265800
266290
  children: [
265801
266291
  /* @__PURE__ */ jsx_runtime24.jsxs(Box_default, {
265802
266292
  flexDirection: "column",
@@ -266291,11 +266781,11 @@ function ContextSelectMenu(props) {
266291
266781
  filled++;
266292
266782
  }
266293
266783
  };
266294
- addSquares(Math.round(basePromptTokens / maxTokens * totalSquares), THEME.glyphs.status, THEME.colors.muted);
266295
- addSquares(Math.round(rulesTokens / maxTokens * totalSquares), THEME.glyphs.status, THEME.colors.warning);
266296
- addSquares(Math.round(skillsTokens / maxTokens * totalSquares), THEME.glyphs.status, THEME.colors.error);
266297
- addSquares(Math.round(toolsTokens / maxTokens * totalSquares), THEME.glyphs.status, THEME.colors.brand);
266298
- addSquares(Math.round(conversationHistoryTokens / maxTokens * totalSquares), THEME.glyphs.status, THEME.colors.success);
266784
+ addSquares(Math.round(basePromptTokens / maxTokens * totalSquares), "■", THEME.colors.muted);
266785
+ addSquares(Math.round(rulesTokens / maxTokens * totalSquares), "■", THEME.colors.warning);
266786
+ addSquares(Math.round(skillsTokens / maxTokens * totalSquares), "■", THEME.colors.error);
266787
+ addSquares(Math.round(toolsTokens / maxTokens * totalSquares), "■", THEME.colors.brand);
266788
+ addSquares(Math.round(conversationHistoryTokens / maxTokens * totalSquares), "■", THEME.colors.success);
266299
266789
  while (filled < totalSquares) {
266300
266790
  squares.push(/* @__PURE__ */ jsx_runtime25.jsx(Text3, {
266301
266791
  color: THEME.colors.border,
@@ -266312,7 +266802,6 @@ function ContextSelectMenu(props) {
266312
266802
  }
266313
266803
  return /* @__PURE__ */ jsx_runtime25.jsxs(Box_default, {
266314
266804
  flexDirection: "column",
266315
- paddingX: THEME.padding.paddingX,
266316
266805
  children: [
266317
266806
  /* @__PURE__ */ jsx_runtime25.jsx(Box_default, {
266318
266807
  marginBottom: 1,
@@ -266363,7 +266852,7 @@ function ContextSelectMenu(props) {
266363
266852
  children: [
266364
266853
  /* @__PURE__ */ jsx_runtime25.jsx(Text3, {
266365
266854
  color: THEME.colors.muted,
266366
- children: THEME.glyphs.status
266855
+ children: "■"
266367
266856
  }),
266368
266857
  /* @__PURE__ */ jsx_runtime25.jsxs(Text3, {
266369
266858
  color: THEME.colors.muted,
@@ -266382,7 +266871,7 @@ function ContextSelectMenu(props) {
266382
266871
  children: [
266383
266872
  /* @__PURE__ */ jsx_runtime25.jsx(Text3, {
266384
266873
  color: THEME.colors.warning,
266385
- children: THEME.glyphs.status
266874
+ children: "■"
266386
266875
  }),
266387
266876
  /* @__PURE__ */ jsx_runtime25.jsxs(Text3, {
266388
266877
  color: THEME.colors.muted,
@@ -266401,7 +266890,7 @@ function ContextSelectMenu(props) {
266401
266890
  children: [
266402
266891
  /* @__PURE__ */ jsx_runtime25.jsx(Text3, {
266403
266892
  color: THEME.colors.error,
266404
- children: THEME.glyphs.status
266893
+ children: "■"
266405
266894
  }),
266406
266895
  /* @__PURE__ */ jsx_runtime25.jsxs(Text3, {
266407
266896
  color: THEME.colors.muted,
@@ -266420,7 +266909,7 @@ function ContextSelectMenu(props) {
266420
266909
  children: [
266421
266910
  /* @__PURE__ */ jsx_runtime25.jsx(Text3, {
266422
266911
  color: THEME.colors.brand,
266423
- children: THEME.glyphs.status
266912
+ children: "■"
266424
266913
  }),
266425
266914
  /* @__PURE__ */ jsx_runtime25.jsxs(Text3, {
266426
266915
  color: THEME.colors.muted,
@@ -266439,7 +266928,7 @@ function ContextSelectMenu(props) {
266439
266928
  children: [
266440
266929
  /* @__PURE__ */ jsx_runtime25.jsx(Text3, {
266441
266930
  color: THEME.colors.success,
266442
- children: THEME.glyphs.status
266931
+ children: "■"
266443
266932
  }),
266444
266933
  /* @__PURE__ */ jsx_runtime25.jsxs(Text3, {
266445
266934
  color: THEME.colors.muted,
@@ -267006,7 +267495,6 @@ function GrillQuestionMenu(props) {
267006
267495
  if (confirmExit) {
267007
267496
  return /* @__PURE__ */ jsx_runtime26.jsxs(Box_default, {
267008
267497
  flexDirection: "column",
267009
- paddingX: THEME.padding.paddingX,
267010
267498
  children: [
267011
267499
  /* @__PURE__ */ jsx_runtime26.jsxs(Box_default, {
267012
267500
  marginBottom: 1,
@@ -267071,7 +267559,6 @@ function GrillQuestionMenu(props) {
267071
267559
  ];
267072
267560
  return /* @__PURE__ */ jsx_runtime26.jsxs(Box_default, {
267073
267561
  flexDirection: "column",
267074
- paddingX: THEME.padding.paddingX,
267075
267562
  children: [
267076
267563
  /* @__PURE__ */ jsx_runtime26.jsxs(Box_default, {
267077
267564
  marginBottom: 1,
@@ -267193,7 +267680,6 @@ function LogoutSelectMenu(props) {
267193
267680
  const { handleLogoutSelect, logoutItems } = props;
267194
267681
  return /* @__PURE__ */ jsx_runtime27.jsxs(Box_default, {
267195
267682
  flexDirection: "column",
267196
- paddingX: THEME.padding.paddingX,
267197
267683
  children: [
267198
267684
  /* @__PURE__ */ jsx_runtime27.jsx(Box_default, {
267199
267685
  marginBottom: 1,
@@ -267232,23 +267718,58 @@ var init_logout_select_menu = __esm(async () => {
267232
267718
 
267233
267719
  // ../../packages/tui/src/components/menus/menu-menu.tsx
267234
267720
  function MenuMenu(props) {
267235
- const { handleAuthMenuSelect, setAuthMode } = props;
267721
+ const {
267722
+ handleAuthMenuSelect,
267723
+ setAuthMode,
267724
+ userEmail,
267725
+ currentEmail,
267726
+ isAuthenticated,
267727
+ authMethod,
267728
+ hasBothAuth,
267729
+ hasDecember,
267730
+ decemberEmail,
267731
+ addToast
267732
+ } = props;
267236
267733
  const [selectedIndex, setSelectedIndex] = import_react60.useState(0);
267734
+ const [confirmSwitch, setConfirmSwitch] = import_react60.useState(false);
267735
+ const email = decemberEmail || currentEmail || userEmail;
267736
+ const isDecemberLoggedIn = Boolean(hasDecember !== undefined ? hasDecember || authMethod === "december" : isAuthenticated && email && (authMethod === "december" || hasBothAuth || !authMethod));
267237
267737
  const items = [
267238
267738
  {
267239
- label: "Bring Your Own Key",
267739
+ label: "Bring Your Own Key or Subscription",
267240
267740
  value: "byok"
267241
267741
  },
267242
- {
267243
- label: "Use AI Subscription",
267244
- value: "subscriptions"
267245
- },
267246
267742
  {
267247
267743
  label: "Login via December",
267744
+ status: isDecemberLoggedIn ? email ? `(Logged in as ${email})` : "(Logged in)" : undefined,
267248
267745
  value: "december"
267249
267746
  }
267250
267747
  ];
267251
267748
  use_input_default((input, key) => {
267749
+ if (confirmSwitch) {
267750
+ if (input === "y" || input === "Y") {
267751
+ setConfirmSwitch(false);
267752
+ if (handleAuthMenuSelect) {
267753
+ handleAuthMenuSelect({
267754
+ label: "Login via December",
267755
+ value: "december",
267756
+ force: true
267757
+ });
267758
+ }
267759
+ return;
267760
+ }
267761
+ if (input === "n" || input === "N" || key.escape || input === "\x1B" || key.return) {
267762
+ setConfirmSwitch(false);
267763
+ if (setAuthMode) {
267764
+ setAuthMode("none");
267765
+ }
267766
+ if (addToast) {
267767
+ addToast(`Already logged in as ${email || "December user"}.`, "info");
267768
+ }
267769
+ return;
267770
+ }
267771
+ return;
267772
+ }
267252
267773
  if (key.upArrow || input === "k") {
267253
267774
  if (selectedIndex > 0) {
267254
267775
  setSelectedIndex(selectedIndex - 1);
@@ -267262,8 +267783,15 @@ function MenuMenu(props) {
267262
267783
  return;
267263
267784
  }
267264
267785
  if (key.return) {
267265
- if (handleAuthMenuSelect && items[selectedIndex]) {
267266
- handleAuthMenuSelect(items[selectedIndex]);
267786
+ const currentItem = items[selectedIndex];
267787
+ if (!currentItem)
267788
+ return;
267789
+ if (currentItem.value === "december" && isDecemberLoggedIn) {
267790
+ setConfirmSwitch(true);
267791
+ return;
267792
+ }
267793
+ if (handleAuthMenuSelect) {
267794
+ handleAuthMenuSelect(currentItem);
267267
267795
  }
267268
267796
  return;
267269
267797
  }
@@ -267274,9 +267802,44 @@ function MenuMenu(props) {
267274
267802
  return;
267275
267803
  }
267276
267804
  });
267805
+ if (confirmSwitch) {
267806
+ return /* @__PURE__ */ jsx_runtime28.jsxs(Box_default, {
267807
+ flexDirection: "column",
267808
+ children: [
267809
+ /* @__PURE__ */ jsx_runtime28.jsx(Box_default, {
267810
+ marginBottom: 1,
267811
+ children: /* @__PURE__ */ jsx_runtime28.jsxs(Text3, {
267812
+ color: THEME.colors.text,
267813
+ children: [
267814
+ "You are already logged in as",
267815
+ " ",
267816
+ /* @__PURE__ */ jsx_runtime28.jsx(Text3, {
267817
+ color: THEME.colors.brand,
267818
+ bold: true,
267819
+ children: email || "December user"
267820
+ }),
267821
+ "."
267822
+ ]
267823
+ })
267824
+ }),
267825
+ /* @__PURE__ */ jsx_runtime28.jsx(Box_default, {
267826
+ marginBottom: 1,
267827
+ children: /* @__PURE__ */ jsx_runtime28.jsx(Text3, {
267828
+ color: THEME.colors.warning,
267829
+ children: "Do you want to switch to a different account? (y/N)"
267830
+ })
267831
+ }),
267832
+ /* @__PURE__ */ jsx_runtime28.jsx(MenuFooter, {
267833
+ items: [
267834
+ { key: "y", label: "Switch Account" },
267835
+ { key: "n / esc", label: "Cancel" }
267836
+ ]
267837
+ })
267838
+ ]
267839
+ });
267840
+ }
267277
267841
  return /* @__PURE__ */ jsx_runtime28.jsxs(Box_default, {
267278
267842
  flexDirection: "column",
267279
- paddingX: THEME.padding.paddingX,
267280
267843
  children: [
267281
267844
  /* @__PURE__ */ jsx_runtime28.jsx(Box_default, {
267282
267845
  marginBottom: 1,
@@ -267300,7 +267863,14 @@ function MenuMenu(props) {
267300
267863
  /* @__PURE__ */ jsx_runtime28.jsx(Text3, {
267301
267864
  color: isSelected ? THEME.colors.brand : THEME.colors.text,
267302
267865
  children: item.label
267303
- })
267866
+ }),
267867
+ item.status ? /* @__PURE__ */ jsx_runtime28.jsxs(Text3, {
267868
+ color: THEME.colors.success,
267869
+ children: [
267870
+ " ",
267871
+ item.status
267872
+ ]
267873
+ }) : null
267304
267874
  ]
267305
267875
  }, item.value);
267306
267876
  }),
@@ -267379,7 +267949,6 @@ function ModelSelectMenu(props) {
267379
267949
  const itemsBelow = items.length - windowEnd;
267380
267950
  return /* @__PURE__ */ jsx_runtime29.jsxs(Box_default, {
267381
267951
  flexDirection: "column",
267382
- paddingX: THEME.padding.paddingX,
267383
267952
  children: [
267384
267953
  /* @__PURE__ */ jsx_runtime29.jsx(Box_default, {
267385
267954
  marginBottom: 1,
@@ -267479,7 +268048,6 @@ function OllamaSetupMenu({
267479
268048
  };
267480
268049
  return /* @__PURE__ */ jsx_runtime30.jsxs(Box_default, {
267481
268050
  flexDirection: "column",
267482
- paddingX: THEME.padding.paddingX,
267483
268051
  children: [
267484
268052
  /* @__PURE__ */ jsx_runtime30.jsx(Box_default, {
267485
268053
  marginBottom: 1,
@@ -267658,7 +268226,8 @@ function PlanItemComponent({
267658
268226
  color = THEME.colors.error;
267659
268227
  }
267660
268228
  return /* @__PURE__ */ jsx_runtime31.jsx(Text3, {
267661
- color,
268229
+ color: isSelected ? color : THEME.colors.muted,
268230
+ bold: isSelected,
267662
268231
  children: label
267663
268232
  });
267664
268233
  }
@@ -267683,7 +268252,6 @@ function PlanApproveMenu({ handlePlanApprovalSelect, planSummary }) {
267683
268252
  });
267684
268253
  return /* @__PURE__ */ jsx_runtime31.jsxs(Box_default, {
267685
268254
  flexDirection: "column",
267686
- paddingX: THEME.padding.paddingX,
267687
268255
  children: [
267688
268256
  /* @__PURE__ */ jsx_runtime31.jsxs(Box_default, {
267689
268257
  marginBottom: 1,
@@ -267691,7 +268259,7 @@ function PlanApproveMenu({ handlePlanApprovalSelect, planSummary }) {
267691
268259
  gap: 1,
267692
268260
  children: [
267693
268261
  planSummary && /* @__PURE__ */ jsx_runtime31.jsx(Box_default, {
267694
- borderStyle: "round",
268262
+ borderStyle: "single",
267695
268263
  borderColor: THEME.colors.border,
267696
268264
  paddingX: 1,
267697
268265
  children: /* @__PURE__ */ jsx_runtime31.jsx(Text3, {
@@ -267961,7 +268529,6 @@ function SessionSelectMenu(props) {
267961
268529
  ];
267962
268530
  return /* @__PURE__ */ jsx_runtime32.jsxs(Box_default, {
267963
268531
  flexDirection: "column",
267964
- paddingX: THEME.padding.paddingX,
267965
268532
  children: [
267966
268533
  /* @__PURE__ */ jsx_runtime32.jsxs(Box_default, {
267967
268534
  marginBottom: 1,
@@ -268138,47 +268705,47 @@ function SettingsMainMenu(props) {
268138
268705
  const providerName = providerKey === "december" || providerKey === "december_proxy" ? "December Cloud" : formatProviderName2(providerKey);
268139
268706
  const providerLabel = providerKey ? authMethod === "subscription" ? `${providerName} (Subscription)` : authMethod === "december" ? "December Cloud" : `${providerName} (BYOK)` : "Not configured";
268140
268707
  const modelLabel = activeModel || "default";
268708
+ const formatSettingRow = (title, value) => `${title.padEnd(25, " ")}[${value}]`;
268141
268709
  const mainItems = [
268142
268710
  {
268143
- label: `Active Provider [${providerLabel}]`,
268711
+ label: formatSettingRow("Active Provider", providerLabel),
268144
268712
  value: "switchProvider"
268145
268713
  },
268146
268714
  {
268147
- label: `Active Model [${modelLabel}]`,
268715
+ label: formatSettingRow("Active Model", modelLabel),
268148
268716
  value: "activeModel"
268149
268717
  },
268150
268718
  {
268151
- label: `Tool Permission [${settingsToolPermission}]`,
268719
+ label: formatSettingRow("Tool Permission", settingsToolPermission),
268152
268720
  value: "toolPermission"
268153
268721
  },
268154
268722
  {
268155
- label: `PathGuard Protection [${settingsPathGuard !== false ? "on" : "off"}]`,
268723
+ label: formatSettingRow("PathGuard Protection", settingsPathGuard !== false ? "on" : "off"),
268156
268724
  value: "pathGuard"
268157
268725
  },
268158
268726
  {
268159
- label: `Non-Workspace Access [${settingsNonWorkspace ? "on" : "off"}]`,
268727
+ label: formatSettingRow("Non-Workspace Access", settingsNonWorkspace ? "on" : "off"),
268160
268728
  value: "nonWorkspaceAccess"
268161
268729
  },
268162
268730
  {
268163
- label: `Thinking Level [${settingsThinkingLevel}]`,
268731
+ label: formatSettingRow("Thinking Level", settingsThinkingLevel),
268164
268732
  value: "thinkingLevel"
268165
268733
  },
268166
268734
  {
268167
- label: `Steering Mode [${settingsSteeringMode}]`,
268735
+ label: formatSettingRow("Steering Mode", settingsSteeringMode),
268168
268736
  value: "steeringMode"
268169
268737
  },
268170
268738
  {
268171
- label: `Follow-Up Mode [${settingsFollowUpMode}]`,
268739
+ label: formatSettingRow("Follow-Up Mode", settingsFollowUpMode),
268172
268740
  value: "followUpMode"
268173
268741
  },
268174
268742
  {
268175
- label: `Browser Window [${settingsBrowserVisible !== false ? "on" : "off"}]`,
268743
+ label: formatSettingRow("Browser Window", settingsBrowserVisible !== false ? "on" : "off"),
268176
268744
  value: "browserVisible"
268177
268745
  }
268178
268746
  ];
268179
268747
  return /* @__PURE__ */ jsx_runtime33.jsxs(Box_default, {
268180
268748
  flexDirection: "column",
268181
- paddingX: THEME.padding.paddingX,
268182
268749
  children: [
268183
268750
  /* @__PURE__ */ jsx_runtime33.jsx(Box_default, {
268184
268751
  marginBottom: 1,
@@ -268298,7 +268865,6 @@ function SubscriptionSelectMenu(props) {
268298
268865
  ];
268299
268866
  return /* @__PURE__ */ jsx_runtime34.jsxs(Box_default, {
268300
268867
  flexDirection: "column",
268301
- paddingX: THEME.padding.paddingX,
268302
268868
  children: [
268303
268869
  /* @__PURE__ */ jsx_runtime34.jsxs(Box_default, {
268304
268870
  marginBottom: 1,
@@ -268490,7 +269056,6 @@ function SwitchSelectMenu(props) {
268490
269056
  ];
268491
269057
  return /* @__PURE__ */ jsx_runtime35.jsxs(Box_default, {
268492
269058
  flexDirection: "column",
268493
- paddingX: THEME.padding.paddingX,
268494
269059
  children: [
268495
269060
  /* @__PURE__ */ jsx_runtime35.jsx(Box_default, {
268496
269061
  marginBottom: 1,
@@ -268892,7 +269457,6 @@ function TasksModeMenu(props) {
268892
269457
  if (!task) {
268893
269458
  return /* @__PURE__ */ jsx_runtime36.jsxs(Box_default, {
268894
269459
  flexDirection: "column",
268895
- paddingX: THEME.padding.paddingX,
268896
269460
  children: [
268897
269461
  /* @__PURE__ */ jsx_runtime36.jsx(Box_default, {
268898
269462
  marginBottom: 1,
@@ -268917,7 +269481,6 @@ function TasksModeMenu(props) {
268917
269481
  const gutterWidth = Math.max(2, outputLines.length.toString().length);
268918
269482
  return /* @__PURE__ */ jsx_runtime36.jsxs(Box_default, {
268919
269483
  flexDirection: "column",
268920
- paddingX: THEME.padding.paddingX,
268921
269484
  children: [
268922
269485
  /* @__PURE__ */ jsx_runtime36.jsxs(Box_default, {
268923
269486
  marginBottom: 1,
@@ -268988,7 +269551,7 @@ function TasksModeMenu(props) {
268988
269551
  }),
268989
269552
  /* @__PURE__ */ jsx_runtime36.jsx(Box_default, {
268990
269553
  borderColor: THEME.colors.border,
268991
- borderStyle: "round",
269554
+ borderStyle: "single",
268992
269555
  flexDirection: "column",
268993
269556
  paddingX: 1,
268994
269557
  children: visibleLines.length === 0 || visibleLines.length === 1 && visibleLines[0] === "" ? /* @__PURE__ */ jsx_runtime36.jsx(Text3, {
@@ -269061,7 +269624,6 @@ function TasksModeMenu(props) {
269061
269624
  }
269062
269625
  return /* @__PURE__ */ jsx_runtime36.jsxs(Box_default, {
269063
269626
  flexDirection: "column",
269064
- paddingX: THEME.padding.paddingX,
269065
269627
  children: [
269066
269628
  /* @__PURE__ */ jsx_runtime36.jsx(Box_default, {
269067
269629
  marginBottom: 1,
@@ -269512,7 +270074,6 @@ function ToolPermissionMenu({ toolCall, questions, onComplete }) {
269512
270074
  });
269513
270075
  return /* @__PURE__ */ jsx_runtime38.jsxs(Box_default, {
269514
270076
  flexDirection: "column",
269515
- paddingX: THEME.padding.paddingX,
269516
270077
  children: [
269517
270078
  /* @__PURE__ */ jsx_runtime38.jsxs(Box_default, {
269518
270079
  marginBottom: 1,
@@ -269525,7 +270086,7 @@ function ToolPermissionMenu({ toolCall, questions, onComplete }) {
269525
270086
  }),
269526
270087
  toolSummary && /* @__PURE__ */ jsx_runtime38.jsxs(Box_default, {
269527
270088
  flexDirection: "column",
269528
- borderStyle: "round",
270089
+ borderStyle: "single",
269529
270090
  borderColor: THEME.colors.border,
269530
270091
  paddingX: 1,
269531
270092
  marginTop: 1,
@@ -269708,7 +270269,6 @@ function UsageSelectMenu(props) {
269708
270269
  const topModelSummary = weekly.topModels && weekly.topModels.length > 0 ? `${weekly.topModels[0].model} (${weekly.topModels[0].percentage}%)` : "None";
269709
270270
  return /* @__PURE__ */ jsx_runtime39.jsxs(Box_default, {
269710
270271
  flexDirection: "column",
269711
- paddingX: THEME.padding.paddingX,
269712
270272
  children: [
269713
270273
  /* @__PURE__ */ jsx_runtime39.jsx(Box_default, {
269714
270274
  marginBottom: 1,
@@ -269746,7 +270306,7 @@ function UsageSelectMenu(props) {
269746
270306
  }),
269747
270307
  /* @__PURE__ */ jsx_runtime39.jsx(Text3, {
269748
270308
  color: THEME.colors.border,
269749
- children: "──────────────────────────"
270309
+ children: "─".repeat(34)
269750
270310
  }),
269751
270311
  dailyItems.map((item) => {
269752
270312
  const spark = getSpark(item.tokens);
@@ -269813,7 +270373,7 @@ function UsageSelectMenu(props) {
269813
270373
  }),
269814
270374
  /* @__PURE__ */ jsx_runtime39.jsx(Text3, {
269815
270375
  color: THEME.colors.border,
269816
- children: "──────────────────────────"
270376
+ children: "─".repeat(34)
269817
270377
  }),
269818
270378
  /* @__PURE__ */ jsx_runtime39.jsxs(Box_default, {
269819
270379
  gap: 1,
@@ -269859,7 +270419,7 @@ function UsageSelectMenu(props) {
269859
270419
  }),
269860
270420
  /* @__PURE__ */ jsx_runtime39.jsx(Text3, {
269861
270421
  color: THEME.colors.border,
269862
- children: "─────────────"
270422
+ children: "─".repeat(38)
269863
270423
  }),
269864
270424
  /* @__PURE__ */ jsx_runtime39.jsxs(Box_default, {
269865
270425
  gap: 1,
@@ -269947,7 +270507,7 @@ function UsageSelectMenu(props) {
269947
270507
  }),
269948
270508
  /* @__PURE__ */ jsx_runtime39.jsx(Text3, {
269949
270509
  color: THEME.colors.border,
269950
- children: "───────────────"
270510
+ children: "─".repeat(38)
269951
270511
  }),
269952
270512
  /* @__PURE__ */ jsx_runtime39.jsxs(Box_default, {
269953
270513
  gap: 1,
@@ -270195,7 +270755,6 @@ function AskQuestionMenu({ questions, onComplete }) {
270195
270755
  return null;
270196
270756
  return /* @__PURE__ */ jsx_runtime41.jsxs(Box_default, {
270197
270757
  flexDirection: "column",
270198
- paddingX: THEME.padding.paddingX,
270199
270758
  gap: 1,
270200
270759
  children: [
270201
270760
  /* @__PURE__ */ jsx_runtime41.jsxs(Box_default, {
@@ -270476,6 +271035,16 @@ function GlobalShortcuts(session) {
270476
271035
  }
270477
271036
  return;
270478
271037
  }
271038
+ if (session.pendingDeviceAuthUrl) {
271039
+ if (input === "o" || input === "O") {
271040
+ if (session.handleOpenDeviceAuthUrl) {
271041
+ session.handleOpenDeviceAuthUrl();
271042
+ }
271043
+ } else if (key.escape || input === "\x1B") {
271044
+ session.handleAbort();
271045
+ }
271046
+ return;
271047
+ }
270479
271048
  if (session.isStreaming && (key.escape || input === "\x1B")) {
270480
271049
  session.handleAbort();
270481
271050
  return;
@@ -270571,12 +271140,24 @@ function ChatApp({
270571
271140
  onLogin,
270572
271141
  onUpdateSuccess,
270573
271142
  session,
270574
- isInline = false,
270575
- announcement
271143
+ announcement,
271144
+ activeModel,
271145
+ authMethod,
271146
+ selectedProvider,
271147
+ modelLabel,
271148
+ onExit
270576
271149
  }) {
270577
271150
  const [exitConfirm, setExitConfirm] = import_react69.useState(false);
270578
271151
  const exitTimerRef = import_react69.useRef(null);
270579
271152
  const handleInterrupt = import_react69.useCallback(() => {
271153
+ if (session.pendingDeviceAuthUrl) {
271154
+ if (onExit) {
271155
+ onExit();
271156
+ } else {
271157
+ process.exit(0);
271158
+ }
271159
+ return;
271160
+ }
270580
271161
  if (session.isStreaming) {
270581
271162
  if (session.handleAbort) {
270582
271163
  session.handleAbort();
@@ -270589,7 +271170,11 @@ function ChatApp({
270589
271170
  clearTimeout(exitTimerRef.current);
270590
271171
  exitTimerRef.current = null;
270591
271172
  }
270592
- process.exit(0);
271173
+ if (onExit) {
271174
+ onExit();
271175
+ } else {
271176
+ process.exit(0);
271177
+ }
270593
271178
  } else {
270594
271179
  setExitConfirm(true);
270595
271180
  if (exitTimerRef.current) {
@@ -270600,7 +271185,7 @@ function ChatApp({
270600
271185
  exitTimerRef.current = null;
270601
271186
  }, 3000);
270602
271187
  }
270603
- }, [exitConfirm, session, agent]);
271188
+ }, [exitConfirm, session, agent, onExit]);
270604
271189
  import_react69.useEffect(() => {
270605
271190
  return () => {
270606
271191
  if (exitTimerRef.current) {
@@ -270610,18 +271195,33 @@ function ChatApp({
270610
271195
  };
270611
271196
  }, []);
270612
271197
  import_react69.useEffect(() => {
270613
- if (!process.stdout?.isTTY || isInline)
271198
+ if (!process.stdout?.isTTY)
270614
271199
  return;
271200
+ const originalWrite = process.stdout.write.bind(process.stdout);
271201
+ try {
271202
+ originalWrite("\x1B[?1049h\x1B[?1000h\x1B[?1002h\x1B[?1006h\x1B[?1007h");
271203
+ } catch {}
271204
+ const synchronizedWrite = (chunk, ...rest) => {
271205
+ if (typeof chunk === "string" && chunk.length > 0 && !chunk.startsWith("\x1B]52;") && !chunk.includes("\x1B[?2026h")) {
271206
+ return originalWrite(`\x1B[?2026h${chunk}\x1B[?2026l`, ...rest);
271207
+ }
271208
+ return originalWrite(chunk, ...rest);
271209
+ };
271210
+ process.stdout.write = synchronizedWrite;
270615
271211
  const handleResize = () => {
270616
271212
  try {
270617
- process.stdout.write("\x1B[?2026h\x1B[2J\x1B[H\x1B[?2026l");
271213
+ originalWrite("\x1B[?2026h\x1B[2J\x1B[H\x1B[?2026l");
270618
271214
  } catch {}
270619
271215
  };
270620
271216
  process.stdout.on("resize", handleResize);
270621
271217
  return () => {
270622
271218
  process.stdout.off("resize", handleResize);
271219
+ process.stdout.write = originalWrite;
271220
+ try {
271221
+ originalWrite("\x1B[?2026l\x1B[?1002l\x1B[?1000l\x1B[?1006l\x1B[?1007l\x1B[?1049l");
271222
+ } catch {}
270623
271223
  };
270624
- }, [isInline]);
271224
+ }, []);
270625
271225
  use_input_default((input, key) => {
270626
271226
  if (key.ctrl && input === "c") {
270627
271227
  handleInterrupt();
@@ -270700,9 +271300,10 @@ function ChatApp({
270700
271300
  const text = lastAssistant.blocks?.map((b) => b.content || "").join(`
270701
271301
  `) || "";
270702
271302
  writeToClipboard(text);
271303
+ session.addToast?.("Copied to clipboard.", "success");
270703
271304
  }
270704
271305
  }).catch(() => {});
270705
- }, [staticMessages, activeMessages]);
271306
+ }, [staticMessages, activeMessages, session]);
270706
271307
  const handleResetChat = import_react69.useCallback(() => {
270707
271308
  console.clear();
270708
271309
  setStaticMessages([{ id: "header-" + Date.now(), role: "header" }]);
@@ -270710,22 +271311,22 @@ function ChatApp({
270710
271311
  setActiveMessages([]);
270711
271312
  session.setQueuedPrompts?.([]);
270712
271313
  session.addToast?.("Started a new conversation.", "success");
270713
- }, [
270714
- setStaticMessages,
270715
- setStaticKey,
270716
- setActiveMessages,
270717
- session.setQueuedPrompts,
270718
- session.addToast
270719
- ]);
271314
+ }, [setStaticMessages, setStaticKey, setActiveMessages, session]);
271315
+ const effectiveModel = session.activeModel || activeModel || agent?.modelOptions?.model || "gemini-3.7-flash";
271316
+ const effectiveModelLabel = session.activeModel ? formatModelDisplayName(session.activeModel) : modelLabel || formatModelDisplayName(effectiveModel);
271317
+ const effectiveAuthMethod = session.authMethod || authMethod;
271318
+ const effectiveProvider = session.selectedProvider || selectedProvider;
271319
+ const isDeviceAuthPending = Boolean(session.pendingDeviceAuthUrl);
270720
271320
  const inputBarElement = /* @__PURE__ */ jsx_runtime43.jsx(InputBar, {
270721
271321
  onSubmit: handleFormSubmit,
270722
271322
  onScrollUp: handleScrollUp,
270723
271323
  onScrollDown: handleScrollDown,
270724
271324
  onStartVoice: session.onStartVoice,
270725
- disabled: authMode !== "none" || Boolean(workflowUI) && !session.customInputMode,
271325
+ disabled: authMode !== "none" || Boolean(workflowUI) && !session.customInputMode || isDeviceAuthPending,
270726
271326
  onCopy: handleCopy,
270727
- placeholder: "Ask December to build features, fix bugs, or work on your code...",
270728
- activeModel: session.activeModel || agent?.modelOptions?.model || "gemini-3.7-flash",
271327
+ placeholder: isDeviceAuthPending ? "Waiting for approval... Press [o] to open in browser" : "Ask December to build features, fix bugs, or work on your code...",
271328
+ activeModel: effectiveModel,
271329
+ modelLabel: effectiveModelLabel,
270729
271330
  contextTokens: totalTokens,
270730
271331
  authMethod: session.authMethod,
270731
271332
  isAuthenticated,
@@ -270743,33 +271344,9 @@ function ChatApp({
270743
271344
  planRefineMode: session.planRefineMode,
270744
271345
  customInputMode: session.customInputMode || false,
270745
271346
  showExitConfirm: exitConfirm,
270746
- tasks: session.tasks
271347
+ tasks: session.tasks,
271348
+ onExit
270747
271349
  });
270748
- if (isInline) {
270749
- return /* @__PURE__ */ jsx_runtime43.jsxs(Box_default, {
270750
- flexDirection: "column",
270751
- width: "100%",
270752
- children: [
270753
- /* @__PURE__ */ jsx_runtime43.jsx(GlobalShortcuts, {
270754
- ...session,
270755
- agent
270756
- }),
270757
- /* @__PURE__ */ jsx_runtime43.jsx(MessageList, {
270758
- staticKey,
270759
- staticMessages,
270760
- activeMessages,
270761
- isAuthenticated,
270762
- cliVersion,
270763
- latestVersion,
270764
- userEmail: currentEmail || userEmail,
270765
- expandCommands: session.expandCommands,
270766
- fullscreen: false,
270767
- announcement
270768
- }),
270769
- inputBarElement
270770
- ]
270771
- });
270772
- }
270773
271350
  return /* @__PURE__ */ jsx_runtime43.jsxs(Box_default, {
270774
271351
  flexDirection: "column",
270775
271352
  height: rows,
@@ -270784,6 +271361,7 @@ function ChatApp({
270784
271361
  ref: scrollViewportRef,
270785
271362
  isGenerating: session.isStreaming,
270786
271363
  isActive: authMode === "none",
271364
+ onCopy: handleCopy,
270787
271365
  onScrollChange: (linesBelow) => setIsReadingMode(linesBelow > 0),
270788
271366
  children: /* @__PURE__ */ jsx_runtime43.jsx(MessageList, {
270789
271367
  staticKey,
@@ -270796,7 +271374,11 @@ function ChatApp({
270796
271374
  expandCommands: session.expandCommands,
270797
271375
  fullscreen: true,
270798
271376
  announcement,
270799
- isReadingMode
271377
+ isReadingMode,
271378
+ activeModel: effectiveModel,
271379
+ modelLabel: effectiveModelLabel,
271380
+ authMethod: effectiveAuthMethod,
271381
+ selectedProvider: effectiveProvider
270800
271382
  })
270801
271383
  }),
270802
271384
  /* @__PURE__ */ jsx_runtime43.jsx(Box_default, {
@@ -270814,6 +271396,7 @@ var init_app = __esm(async () => {
270814
271396
  await __promiseAll([
270815
271397
  init_build2(),
270816
271398
  init_global_shortcuts(),
271399
+ init_header(),
270817
271400
  init_input_bar(),
270818
271401
  init_ask_question_menu(),
270819
271402
  init_auth_menus(),
@@ -270847,6 +271430,8 @@ var init_src7 = __esm(async () => {
270847
271430
  init_menu_items();
270848
271431
  init_auth_menus();
270849
271432
  init_ask_question_menu();
271433
+ init_command_menu();
271434
+ init_use_command_menu();
270850
271435
  init_header();
270851
271436
  init_use_delayed_tip();
270852
271437
  init_tips();
@@ -270975,6 +271560,10 @@ var init_store = __esm(() => {
270975
271560
  setAuthMethod: (authMethod) => set({ authMethod }),
270976
271561
  hasBothAuth: false,
270977
271562
  setHasBothAuth: (hasBothAuth) => set({ hasBothAuth }),
271563
+ hasDecember: false,
271564
+ setHasDecember: (hasDecember) => set({ hasDecember }),
271565
+ decemberEmail: undefined,
271566
+ setDecemberEmail: (decemberEmail) => set({ decemberEmail }),
270978
271567
  settingsAuthPriority: "byok",
270979
271568
  setSettingsAuthPriority: (settingsAuthPriority) => set({ settingsAuthPriority }),
270980
271569
  currentEmail: undefined,
@@ -270993,6 +271582,8 @@ var init_store = __esm(() => {
270993
271582
  setApiKey: (apiKey) => set({ apiKey }),
270994
271583
  authError: null,
270995
271584
  setAuthError: (authError) => set({ authError }),
271585
+ pendingDeviceAuthUrl: null,
271586
+ setPendingDeviceAuthUrl: (pendingDeviceAuthUrl) => set({ pendingDeviceAuthUrl }),
270996
271587
  openRouterModels: [],
270997
271588
  setOpenRouterModels: (openRouterModels) => set({ openRouterModels }),
270998
271589
  ollamaStatus: null,
@@ -271049,6 +271640,8 @@ var init_store = __esm(() => {
271049
271640
  setQueuedPrompts: (updater) => set((state) => ({
271050
271641
  queuedPrompts: typeof updater === "function" ? updater(state.queuedPrompts) : updater
271051
271642
  })),
271643
+ isInline: false,
271644
+ setIsInline: (isInline) => set({ isInline }),
271052
271645
  sessionItems: [],
271053
271646
  setSessionItems: (sessionItems) => set({ sessionItems }),
271054
271647
  sessionsData: [],
@@ -271687,6 +272280,35 @@ var init_usage_rates2 = __esm(() => {
271687
272280
 
271688
272281
  // src/utils/error-parser.ts
271689
272282
  import util5 from "util";
272283
+ function inferProviderEndpoint(provider, baseURL) {
272284
+ if (baseURL)
272285
+ return baseURL;
272286
+ const norm = (provider || "").toLowerCase().trim();
272287
+ switch (norm) {
272288
+ case "december":
272289
+ case "december_proxy":
272290
+ return "https://api.trydecember.com/api/v1/cli";
272291
+ case "anthropic":
272292
+ case "claude":
272293
+ return "https://api.anthropic.com/v1/messages";
272294
+ case "openai":
272295
+ case "chatgpt":
272296
+ return "https://api.openai.com/v1/chat/completions";
272297
+ case "gemini":
272298
+ case "google":
272299
+ return "https://generativelanguage.googleapis.com/v1beta";
272300
+ case "ollama":
272301
+ return "http://localhost:11434/v1";
272302
+ case "openrouter":
272303
+ return "https://openrouter.ai/api/v1/chat/completions";
272304
+ case "deepseek":
272305
+ return "https://api.deepseek.com/chat/completions";
272306
+ case "groq":
272307
+ return "https://api.groq.com/openai/v1/chat/completions";
272308
+ default:
272309
+ return;
272310
+ }
272311
+ }
271690
272312
  function isCreditOrBalanceError(combined) {
271691
272313
  return combined.includes("insufficient balance") || combined.includes("insufficient credits") || combined.includes("insufficient_balance") || combined.includes("insufficient_credits") || combined.includes("insufficient_quota") || combined.includes("balance is insufficient") || combined.includes("balance insufficient") || combined.includes("balance exhausted") || combined.includes("out of credits") || combined.includes("credit balance is too low") || combined.includes("credits exhausted") || combined.includes("requires more credits") || combined.includes("can only afford") || combined.includes("payment required") || combined.includes("quota exceeded") || combined.includes("quota_exhausted") || combined.includes("budget_exhausted") || combined.includes("budget exhausted") || combined.includes("budget exceeded") || combined.includes("budget_exceeded") || combined.includes("402") || combined.includes("1008") || combined.includes("20009") || (combined.includes("credits") || combined.includes("balance")) && (combined.includes("insufficient") || combined.includes("exhausted") || combined.includes("empty") || combined.includes("zero") || combined.includes("low") || combined.includes("top up") || combined.includes("recharge") || combined.includes("afford") || combined.includes("add credits"));
271692
272314
  }
@@ -272105,7 +272727,21 @@ function parseError(err, context) {
272105
272727
  }
272106
272728
  let explicitCause;
272107
272729
  if (err?.cause) {
272108
- explicitCause = typeof err.cause === "string" ? err.cause : err.cause?.message || (typeof err.cause === "object" ? util5.inspect(err.cause) : String(err.cause));
272730
+ if (typeof err.cause === "string") {
272731
+ explicitCause = err.cause;
272732
+ } else if (err.cause?.message) {
272733
+ const nested = err.cause?.cause;
272734
+ const nestedDetail = typeof nested === "string" ? nested : nested?.message || nested?.code || (typeof nested === "object" ? util5.inspect(nested) : undefined);
272735
+ if (nestedDetail && nestedDetail !== err.cause.message) {
272736
+ explicitCause = `${err.cause.message} (${nestedDetail})`;
272737
+ } else {
272738
+ explicitCause = err.cause.message;
272739
+ }
272740
+ } else if (typeof err.cause === "object") {
272741
+ explicitCause = util5.inspect(err.cause);
272742
+ } else {
272743
+ explicitCause = String(err.cause);
272744
+ }
272109
272745
  } else if (err?.originalError) {
272110
272746
  explicitCause = typeof err.originalError === "string" ? err.originalError : err.originalError?.message || (typeof err.originalError === "object" ? util5.inspect(err.originalError) : String(err.originalError));
272111
272747
  } else if (err?.response?.data) {
@@ -272128,20 +272764,33 @@ function parseError(err, context) {
272128
272764
  hint: rateDetails.hint
272129
272765
  };
272130
272766
  }
272131
- const isDecemberCredits = combined.includes("december wallet") || combined.includes("trydecember.com") || combined.includes("december cloud");
272132
- if (!isDecemberCredits) {
272133
- const creditRule = findMatchingCreditRule(combined, context);
272134
- if (creditRule) {
272135
- const parts = fullMessage.split(`
272767
+ const isDecemberCredits = combined.includes("december wallet") || isCreditOrBalanceError(combined) && (combined.includes("trydecember.com") || combined.includes("december cloud"));
272768
+ if (isDecemberCredits) {
272769
+ const parts = fullMessage.split(`
272770
+ `).map((l) => l.trim()).filter(Boolean);
272771
+ const firstLine = parts[0] || fullMessage;
272772
+ const cause = explicitCause || (parts.length > 1 ? parts.slice(1).join(`
272773
+ `).trim() : undefined);
272774
+ const hintMatch = firstLine.match(/Please (?:add credits|top up|check|upgrade|run|switch|configure).*$/i);
272775
+ const summary = hintMatch ? firstLine.replace(/Please (?:add credits|top up|check|upgrade|run|switch|configure).*$/i, "").replace(/^402\s*/, "").trim() : firstLine.replace(/^402\s*/, "").trim() || "Insufficient credits in December Wallet.";
272776
+ const hint = hintMatch ? hintMatch[0].trim() : "Please add credits at https://app.trydecember.com/settings/billing or configure Bring Your Own Key (BYOK) via `/login` to continue using December.";
272777
+ return {
272778
+ message: summary || "Insufficient credits in December Wallet.",
272779
+ cause: cause && !cause.startsWith(summary) ? cause : explicitCause,
272780
+ hint
272781
+ };
272782
+ }
272783
+ const creditRule = findMatchingCreditRule(combined, context);
272784
+ if (creditRule) {
272785
+ const parts = fullMessage.split(`
272136
272786
  `);
272137
- const cause = explicitCause || (parts.length > 1 ? parts.slice(1).join(`
272787
+ const cause = explicitCause || (parts.length > 1 ? parts.slice(1).join(`
272138
272788
  `).trim() : fullMessage);
272139
- return {
272140
- message: creditRule.message,
272141
- cause: cause && !cause.startsWith(creditRule.message) ? cause : explicitCause || parts[0],
272142
- hint: creditRule.hint
272143
- };
272144
- }
272789
+ return {
272790
+ message: creditRule.message,
272791
+ cause: cause && !cause.startsWith(creditRule.message) ? cause : explicitCause || parts[0],
272792
+ hint: creditRule.hint
272793
+ };
272145
272794
  }
272146
272795
  const isChannelError = combined.includes("无可用渠道") || combined.includes("no available channel") || combined.includes("channel not found");
272147
272796
  if (isChannelError) {
@@ -272213,12 +272862,54 @@ function parseError(err, context) {
272213
272862
  hint: "Check file permissions or run the command with appropriate access privileges."
272214
272863
  };
272215
272864
  }
272216
- if (combined.includes("econnrefused")) {
272217
- const primaryMessage = err?.message && !err.message.includes("ECONNREFUSED") ? err.message : "Connection refused by destination host.";
272865
+ const isNetworkOrConnectionError = combined.includes("connection error") || combined.includes("econnrefused") || combined.includes("enotfound") || combined.includes("etimedout") || combined.includes("econnreset") || combined.includes("ehostunreach") || combined.includes("enetunreach") || combined.includes("fetch failed") || combined.includes("socket hang up") || err?.name === "APIConnectionError";
272866
+ if (isNetworkOrConnectionError) {
272867
+ const inferred = context?.model ? inferProviderFromModel(context.model) : undefined;
272868
+ const rawProvider = context?.provider || inferred;
272869
+ const isDecember = rawProvider === "december_proxy" || rawProvider === "december";
272870
+ const providerDisplayName = isDecember ? "December Cloud" : rawProvider ? formatProviderName(rawProvider) : undefined;
272871
+ const endpoint = inferProviderEndpoint(rawProvider, context?.baseURL);
272872
+ const isLocalOllama = rawProvider === "ollama" || context?.baseURL?.includes("11434") || combined.includes("11434") || combined.includes("ollama");
272873
+ const modelLabel = context?.model ? isDecember && context.model === "december-auto" ? "Humans R1" : getModelLabel(context.model) : undefined;
272874
+ let headline;
272875
+ if (isDecember) {
272876
+ headline = `Unable to connect to December Cloud (${modelLabel || "Humans R1"}).`;
272877
+ } else if (isLocalOllama) {
272878
+ headline = "Unable to connect to Ollama (Connection refused).";
272879
+ } else if (combined.includes("enotfound")) {
272880
+ const target = providerDisplayName || "destination host";
272881
+ headline = modelLabel ? `Unable to connect to ${target} (${modelLabel}).` : `Unable to connect to ${target} (DNS lookup failed).`;
272882
+ } else if (combined.includes("etimedout") || combined.includes("timed out")) {
272883
+ const target = providerDisplayName || "destination host";
272884
+ headline = modelLabel ? `Connection to ${target} (${modelLabel}) timed out.` : `Connection to ${target} timed out.`;
272885
+ } else if (combined.includes("econnrefused") && !rawProvider && !isDecember) {
272886
+ const primaryMessage = err?.message && !err.message.includes("ECONNREFUSED") ? err.message : "Connection refused by destination host.";
272887
+ return {
272888
+ message: primaryMessage,
272889
+ cause: explicitCause || fullMessage,
272890
+ hint: "Verify that the server or target service is running and network is reachable."
272891
+ };
272892
+ } else if (combined.includes("econnrefused")) {
272893
+ headline = providerDisplayName ? `Connection to ${providerDisplayName} was refused.` : err?.message && !err.message.includes("ECONNREFUSED") ? err.message : "Connection refused by destination host.";
272894
+ } else {
272895
+ const target = providerDisplayName || "LLM provider";
272896
+ headline = modelLabel ? `Unable to connect to ${target} (${modelLabel}).` : err?.message && err.message !== "Connection error." && !err.message.includes("fetch failed") ? err.message : `Unable to connect to ${target} (Connection error).`;
272897
+ }
272898
+ const rawCause = explicitCause && explicitCause !== "Connection error." ? explicitCause : fullMessage && fullMessage !== "Connection error." && fullMessage !== headline && !headline.includes(fullMessage) ? fullMessage : undefined;
272899
+ let detailLine;
272900
+ if (endpoint && rawCause) {
272901
+ detailLine = `Endpoint: ${endpoint} (${rawCause})`;
272902
+ } else if (endpoint) {
272903
+ detailLine = `Endpoint: ${endpoint}`;
272904
+ } else if (rawCause) {
272905
+ detailLine = rawCause;
272906
+ }
272907
+ const fullMsg = detailLine ? `${headline}
272908
+ ${detailLine}` : headline;
272218
272909
  return {
272219
- message: primaryMessage,
272220
- cause: explicitCause || fullMessage,
272221
- hint: "Verify that the server or target service is running and network is reachable."
272910
+ message: fullMsg,
272911
+ cause: rawCause,
272912
+ hint: undefined
272222
272913
  };
272223
272914
  }
272224
272915
  const cleanMsg = err?.message || fullMessage;
@@ -272230,6 +272921,8 @@ function parseError(err, context) {
272230
272921
  }
272231
272922
  var PROVIDER_CREDIT_RULES, PROVIDER_BILLING_URLS, PROVIDER_CREDIT_DISPLAY_NAMES, UNIVERSAL_CREDIT_FALLBACK;
272232
272923
  var init_error_parser = __esm(() => {
272924
+ init_config();
272925
+ init_models5();
272233
272926
  init_usage_rates2();
272234
272927
  PROVIDER_CREDIT_RULES = [
272235
272928
  {
@@ -273265,12 +273958,19 @@ async function processAgentStream({
273265
273958
  let finalMsg = { ...msg };
273266
273959
  for (const event of eventsToProcess) {
273267
273960
  switch (event.type) {
273268
- case "TurnStart":
273269
- blocks.push({
273270
- type: "text",
273271
- content: event.initialStatus || "Thinking..."
273272
- });
273961
+ case "TurnStart": {
273962
+ const initialStatus = event.initialStatus || "Thinking...";
273963
+ const lastBlock = blocks[blocks.length - 1];
273964
+ if (lastBlock && lastBlock.type === "text" && isStatusMessage(lastBlock.content)) {
273965
+ lastBlock.content = initialStatus;
273966
+ } else {
273967
+ blocks.push({
273968
+ type: "text",
273969
+ content: initialStatus
273970
+ });
273971
+ }
273273
273972
  break;
273973
+ }
273274
273974
  case "AgentError": {
273275
273975
  finalizeThinking(blocks);
273276
273976
  const lastBlock = blocks[blocks.length - 1];
@@ -273414,7 +274114,7 @@ async function processAgentStream({
273414
274114
  flush();
273415
274115
  }
273416
274116
  pendingEvents.push(event);
273417
- const isImmediateEvent = event.type === "TurnStart" || event.type === "AgentError" || event.type === "AgentInterrupt" || event.type === "ToolCallStart" || event.type === "ToolCallResult" || event.type === "ThinkingChunk" && !thinkingStartTime;
274117
+ const isImmediateEvent = event.type === "TurnStart" || event.type === "AgentError" || event.type === "AgentInterrupt" || event.type === "ToolCallStart" || event.type === "ToolCallResult" || event.type === "AgentStatus" || event.type === "ThinkingChunk" && !thinkingStartTime;
273418
274118
  if (isImmediateEvent) {
273419
274119
  if (flushTimeout) {
273420
274120
  clearTimeout(flushTimeout);
@@ -273478,6 +274178,7 @@ function useAuthHandlers(agent, onLogin, onLoginHeadless) {
273478
274178
  setOllamaStatus,
273479
274179
  setSwitchItems
273480
274180
  } = useCliStore.getState();
274181
+ const deviceAuthAbortRef = { current: null };
273481
274182
  const handleAuthMenuSelect = async (item) => {
273482
274183
  if (item.value === "subscriptions" || item.value === "subscription_select") {
273483
274184
  setAuthMode("subscription_select");
@@ -273488,14 +274189,25 @@ function useAuthHandlers(agent, onLogin, onLoginHeadless) {
273488
274189
  return;
273489
274190
  }
273490
274191
  if (item.value === "december" || item.value === "december_headless") {
274192
+ if (useCliStore.getState().isStreaming) {
274193
+ return;
274194
+ }
274195
+ const hasDecember = useCliStore.getState().hasDecember || useCliStore.getState().authMethod === "december";
274196
+ if (!item.force && hasDecember) {
274197
+ setAuthMode("menu");
274198
+ return;
274199
+ }
273491
274200
  setAuthMode("none");
273492
274201
  setIsStreaming(true);
274202
+ const authAbortController = new AbortController;
274203
+ deviceAuthAbortRef.current = authAbortController;
274204
+ let codeMsgId = null;
273493
274205
  try {
273494
274206
  const loginFn = onLogin || onLoginHeadless;
273495
274207
  if (!loginFn) {
273496
274208
  throw new Error("Login functionality is not provided by the host environment.");
273497
274209
  }
273498
- const codeMsgId = getNextMsgId();
274210
+ codeMsgId = getNextMsgId();
273499
274211
  setStaticMessages((prev) => [...prev, ...useCliStore.getState().activeMessages]);
273500
274212
  setActiveMessages([
273501
274213
  {
@@ -273505,6 +274217,8 @@ function useAuthHandlers(agent, onLogin, onLoginHeadless) {
273505
274217
  }
273506
274218
  ]);
273507
274219
  const onCode = (code, uri) => {
274220
+ const fullUrl = uri.includes("?") ? `${uri}&code=${encodeURIComponent(code)}` : `${uri}?code=${encodeURIComponent(code)}`;
274221
+ useCliStore.getState().setPendingDeviceAuthUrl(fullUrl);
273508
274222
  setActiveMessages([
273509
274223
  {
273510
274224
  id: codeMsgId,
@@ -273513,17 +274227,18 @@ function useAuthHandlers(agent, onLogin, onLoginHeadless) {
273513
274227
  {
273514
274228
  type: "text",
273515
274229
  content: `
273516
- Please open [${uri}](${uri}) on any device and enter code: \`${code}\``
273517
- },
273518
- {
273519
- type: "text",
273520
- content: "Waiting for authorization..."
274230
+ Confirm code: \`${code}\`
274231
+ Open URL: [${fullUrl}](${fullUrl})
274232
+
274233
+ Press [o] to open in browser · Esc to cancel
274234
+ Waiting for approval...`
273521
274235
  }
273522
274236
  ]
273523
274237
  }
273524
274238
  ]);
273525
274239
  };
273526
- const { token, email } = await loginFn(onCode);
274240
+ const { token, email } = await loginFn(onCode, authAbortController.signal);
274241
+ useCliStore.getState().setPendingDeviceAuthUrl(null);
273527
274242
  const config = await loadConfig();
273528
274243
  config.decemberToken = token;
273529
274244
  config.authPriority = "december";
@@ -273554,30 +274269,118 @@ Please open [${uri}](${uri}) on any device and enter code: \`${code}\``
273554
274269
  setAuthMethod(providerConfig.authMethod);
273555
274270
  setHasBothAuth(authStatus.hasByok && authStatus.hasDecember);
273556
274271
  setSettingsAuthPriority(authStatus.authPriority);
274272
+ useCliStore.getState().setHasDecember(authStatus.hasDecember);
274273
+ if (email || config.email) {
274274
+ useCliStore.getState().setDecemberEmail(email || config.email);
274275
+ }
274276
+ }
274277
+ const cleanActiveMessages = useCliStore.getState().activeMessages.map((m) => {
274278
+ if (m.id === codeMsgId) {
274279
+ return {
274280
+ ...m,
274281
+ blocks: m.blocks?.map((b) => {
274282
+ if (b.type === "text") {
274283
+ return {
274284
+ ...b,
274285
+ content: b.content.replace(/\n\s*Waiting for approval\.\.\./g, "").replace(/\n\s*Press \[o\].*$/gm, "").trim()
274286
+ };
274287
+ }
274288
+ return b;
274289
+ })
274290
+ };
274291
+ }
274292
+ return m;
274293
+ });
274294
+ setStaticMessages((prev) => [...prev, ...cleanActiveMessages]);
274295
+ const successBlocks = [
274296
+ {
274297
+ type: "text",
274298
+ content: `
274299
+ ${MESSAGES.AUTH.LOGIN_SUCCESS_DEVICE}`,
274300
+ color: "#6EE7B7"
274301
+ }
274302
+ ];
274303
+ if (providerConfig?.authMethod === "december" && token) {
274304
+ try {
274305
+ const serverUrl = process.env.SERVER_URL || "https://api.trydecember.com";
274306
+ const overviewRes = await fetch(`${serverUrl}/api/v1/billing/overview`, {
274307
+ headers: { Authorization: `Bearer ${token}` },
274308
+ signal: AbortSignal.timeout(2000)
274309
+ });
274310
+ if (overviewRes.ok) {
274311
+ const overviewJson = await overviewRes.json();
274312
+ const balanceCents = overviewJson.data?.creditBalance ?? 0;
274313
+ if (balanceCents <= 0) {
274314
+ successBlocks.push({
274315
+ type: "text",
274316
+ content: `
274317
+ Your December Wallet balance is $0.00.
274318
+ To add credits, visit [https://app.trydecember.com/settings/billing](https://app.trydecember.com/settings/billing).
274319
+ You can also connect an AI Subscription or API key anytime with \`/login\`.`
274320
+ });
274321
+ } else {
274322
+ successBlocks.push({
274323
+ type: "text",
274324
+ content: `
274325
+ December Wallet: $${(balanceCents / 100).toFixed(2)}. Ready to code!`
274326
+ });
274327
+ }
274328
+ }
274329
+ } catch {}
273557
274330
  }
273558
- setStaticMessages((prev) => [...prev, ...useCliStore.getState().activeMessages]);
273559
274331
  setActiveMessages([
273560
274332
  {
273561
274333
  id: getNextMsgId(),
273562
274334
  role: "assistant",
273563
- blocks: [
273564
- {
273565
- type: "text",
273566
- content: MESSAGES.AUTH.LOGIN_SUCCESS_DEVICE,
273567
- color: "#6EE7B7"
273568
- }
273569
- ]
274335
+ blocks: successBlocks
273570
274336
  }
273571
274337
  ]);
273572
274338
  } catch (err) {
274339
+ useCliStore.getState().setPendingDeviceAuthUrl(null);
274340
+ const cleanActiveMessages = useCliStore.getState().activeMessages.map((m) => {
274341
+ if (m.id === codeMsgId) {
274342
+ return {
274343
+ ...m,
274344
+ blocks: m.blocks?.map((b) => {
274345
+ if (b.type === "text") {
274346
+ return {
274347
+ ...b,
274348
+ content: b.content.replace(/\n\s*Waiting for approval\.\.\./g, "").replace(/\n\s*Press \[o\].*$/gm, "").trim()
274349
+ };
274350
+ }
274351
+ return b;
274352
+ })
274353
+ };
274354
+ }
274355
+ return m;
274356
+ });
274357
+ setStaticMessages((prev) => [...prev, ...cleanActiveMessages]);
274358
+ if (err?.name === "AbortError" || err?.message?.includes("cancelled")) {
274359
+ setActiveMessages([
274360
+ {
274361
+ id: getNextMsgId(),
274362
+ role: "assistant",
274363
+ blocks: [
274364
+ {
274365
+ type: "text",
274366
+ content: "Login cancelled. Run /login anytime to connect an account.",
274367
+ color: "#888888"
274368
+ }
274369
+ ]
274370
+ }
274371
+ ]);
274372
+ setAuthMode("none");
274373
+ return;
274374
+ }
273573
274375
  const parsed = parseError(err);
273574
274376
  let cleanMsg = parsed.message;
273575
274377
  if (cleanMsg.includes("fetch failed") || cleanMsg.includes("ECONNREFUSED") || cleanMsg.includes("ENOTFOUND") || cleanMsg.includes("Failed to fetch") || cleanMsg.includes("Unable to connect")) {
273576
- cleanMsg = "Unable to connect. Is the computer able to access the url?";
274378
+ cleanMsg = "Unable to connect to December. Check your connection and run /login again.";
274379
+ } else if (cleanMsg.toLowerCase().includes("expired")) {
274380
+ cleanMsg = "Device code expired. Run /login to generate a new code.";
273577
274381
  }
273578
274382
  const errorText = `Login failed: ${cleanMsg}`;
273579
274383
  setAuthError(errorText);
273580
- setStaticMessages((prev) => [...prev, ...useCliStore.getState().activeMessages]);
273581
274384
  setActiveMessages([
273582
274385
  {
273583
274386
  id: getNextMsgId(),
@@ -273587,7 +274390,10 @@ Please open [${uri}](${uri}) on any device and enter code: \`${code}\``
273587
274390
  hint: parsed.hint || "Check your network connection or verify the authentication endpoint."
273588
274391
  }
273589
274392
  ]);
274393
+ setAuthMode("none");
273590
274394
  } finally {
274395
+ useCliStore.getState().setPendingDeviceAuthUrl(null);
274396
+ deviceAuthAbortRef.current = null;
273591
274397
  setIsStreaming(false);
273592
274398
  }
273593
274399
  } else if (item.value === "byok") {
@@ -273682,8 +274488,9 @@ Please open [${uri}](${uri}) on any device and enter code: \`${code}\``
273682
274488
  if (isOauthProvider) {
273683
274489
  setAuthMode("none");
273684
274490
  setIsStreaming(true);
274491
+ let codeMsgId = null;
273685
274492
  try {
273686
- const codeMsgId = getNextMsgId();
274493
+ codeMsgId = getNextMsgId();
273687
274494
  setStaticMessages((prev) => [...prev, ...useCliStore.getState().activeMessages]);
273688
274495
  setActiveMessages([
273689
274496
  {
@@ -273749,7 +274556,24 @@ Please open [${uri}](${uri}) on your device and enter code: \`${code}\``;
273749
274556
  const authStatus = await getAuthStatus();
273750
274557
  setHasBothAuth(authStatus.hasByok && authStatus.hasDecember);
273751
274558
  setSettingsAuthPriority(authStatus.authPriority);
273752
- setStaticMessages((prev) => [...prev, ...useCliStore.getState().activeMessages]);
274559
+ const cleanActiveMessages = useCliStore.getState().activeMessages.map((m) => {
274560
+ if (m.id === codeMsgId) {
274561
+ return {
274562
+ ...m,
274563
+ blocks: m.blocks?.filter((b) => b.type !== "text" || !b.content.includes("Waiting for authorization")).map((b) => {
274564
+ if (b.type === "text") {
274565
+ return {
274566
+ ...b,
274567
+ content: b.content.replace(/\n\s*Waiting for authorization.*$/gm, "").trim()
274568
+ };
274569
+ }
274570
+ return b;
274571
+ })
274572
+ };
274573
+ }
274574
+ return m;
274575
+ });
274576
+ setStaticMessages((prev) => [...prev, ...cleanActiveMessages]);
273753
274577
  setActiveMessages([
273754
274578
  {
273755
274579
  id: getNextMsgId(),
@@ -273758,7 +274582,12 @@ Please open [${uri}](${uri}) on your device and enter code: \`${code}\``;
273758
274582
  {
273759
274583
  type: "text",
273760
274584
  content: `
273761
- ${formatSubscriptionCard(bundle, targetModel)}`
274585
+ ${formatSubscriptionSuccessMessage(bundle.provider)}`,
274586
+ color: "#6EE7B7"
274587
+ },
274588
+ {
274589
+ type: "text",
274590
+ content: formatSubscriptionCard(bundle, targetModel)
273762
274591
  }
273763
274592
  ]
273764
274593
  }
@@ -273770,7 +274599,24 @@ ${formatSubscriptionCard(bundle, targetModel)}`
273770
274599
  const parsed = parseError(err);
273771
274600
  const errorText = parsed.message.startsWith("Subscription verification failed") || parsed.message.startsWith("No active GitHub Copilot subscription") ? parsed.message : `Subscription verification failed: ${parsed.message}`;
273772
274601
  setAuthError(errorText);
273773
- setStaticMessages((prev) => [...prev, ...useCliStore.getState().activeMessages]);
274602
+ const cleanActiveMessages = useCliStore.getState().activeMessages.map((m) => {
274603
+ if (m.id === codeMsgId) {
274604
+ return {
274605
+ ...m,
274606
+ blocks: m.blocks?.filter((b) => b.type !== "text" || !b.content.includes("Waiting for authorization")).map((b) => {
274607
+ if (b.type === "text") {
274608
+ return {
274609
+ ...b,
274610
+ content: b.content.replace(/\n\s*Waiting for authorization.*$/gm, "").trim()
274611
+ };
274612
+ }
274613
+ return b;
274614
+ })
274615
+ };
274616
+ }
274617
+ return m;
274618
+ });
274619
+ setStaticMessages((prev) => [...prev, ...cleanActiveMessages]);
273774
274620
  setActiveMessages([
273775
274621
  {
273776
274622
  id: getNextMsgId(),
@@ -273932,6 +274778,7 @@ ${formatSubscriptionCard(bundle, targetModel)}`
273932
274778
  await Promise.resolve().then(() => init_models5());
273933
274779
  const finalModel = testModel || getDefaultModelForProvider(selectedProvider);
273934
274780
  const config = await loadConfig();
274781
+ config.providers = config.providers || {};
273935
274782
  config.providers[selectedProvider] = trimmedKey;
273936
274783
  config.activeProvider = selectedProvider;
273937
274784
  config.activeModel = finalModel;
@@ -273966,6 +274813,7 @@ ${formatSubscriptionCard(bundle, targetModel)}`
273966
274813
  await Promise.resolve().then(() => init_models5());
273967
274814
  const finalModel = testModel || getDefaultModelForProvider(selectedProvider);
273968
274815
  const config = await loadConfig();
274816
+ config.providers = config.providers || {};
273969
274817
  config.providers[selectedProvider] = trimmedKey;
273970
274818
  config.activeProvider = selectedProvider;
273971
274819
  config.activeModel = finalModel;
@@ -274041,6 +274889,8 @@ ${formatSubscriptionCard(bundle, targetModel)}`
274041
274889
  config.decemberToken = undefined;
274042
274890
  config.email = undefined;
274043
274891
  setCurrentEmail(undefined);
274892
+ useCliStore.getState().setHasDecember(false);
274893
+ useCliStore.getState().setDecemberEmail(undefined);
274044
274894
  removedName = "December Cloud Wallet";
274045
274895
  if (config.activeProvider === "december" || config.activeProvider === "december_proxy") {
274046
274896
  config.activeProvider = Object.keys(config.subscriptions || {})[0] || Object.keys(config.providers || {})[0] || undefined;
@@ -274060,7 +274910,7 @@ ${formatSubscriptionCard(bundle, targetModel)}`
274060
274910
  delete config.providers[provider];
274061
274911
  removedName = `${provider.charAt(0).toUpperCase() + provider.slice(1)} API Key`;
274062
274912
  if (config.activeProvider === provider) {
274063
- config.activeProvider = Object.keys(config.subscriptions || {})[0] || Object.keys(config.providers)[0] || (config.decemberToken ? "december_proxy" : undefined);
274913
+ config.activeProvider = Object.keys(config.subscriptions || {})[0] || Object.keys(config.providers || {})[0] || (config.decemberToken ? "december_proxy" : undefined);
274064
274914
  }
274065
274915
  }
274066
274916
  }
@@ -274070,6 +274920,7 @@ ${formatSubscriptionCard(bundle, targetModel)}`
274070
274920
  const authStatus = await getAuthStatus();
274071
274921
  setIsAuthenticated(!!providerConfig);
274072
274922
  setHasBothAuth(authStatus.hasByok && authStatus.hasDecember);
274923
+ useCliStore.getState().setHasDecember(authStatus.hasDecember);
274073
274924
  setSettingsAuthPriority(authStatus.authPriority);
274074
274925
  if (providerConfig && agent) {
274075
274926
  const llm = instantiateProvider(providerConfig.provider, providerConfig.apiKey, {
@@ -274187,6 +275038,23 @@ ${formatSubscriptionCard(bundle, targetModel)}`
274187
275038
  const targetModel = modelName || getDefaultModelForProvider(currentProvider) || "default";
274188
275039
  await applyOllamaConfig(urlToUse, targetModel, currentProvider);
274189
275040
  };
275041
+ const handleOpenDeviceAuthUrl = async () => {
275042
+ const url = useCliStore.getState().pendingDeviceAuthUrl;
275043
+ if (url) {
275044
+ await Promise.resolve().then(() => init_open());
275045
+ await openUrl(url).catch(() => {});
275046
+ addToast("Opening authorization link in browser...", "info");
275047
+ }
275048
+ };
275049
+ const handleAbortAuth = () => {
275050
+ if (deviceAuthAbortRef.current) {
275051
+ deviceAuthAbortRef.current.abort();
275052
+ deviceAuthAbortRef.current = null;
275053
+ }
275054
+ useCliStore.getState().setPendingDeviceAuthUrl(null);
275055
+ useCliStore.getState().setIsStreaming(false);
275056
+ useCliStore.getState().setAuthMode("none");
275057
+ };
274190
275058
  return {
274191
275059
  handleAuthMenuSelect,
274192
275060
  handleModelSelect,
@@ -274200,7 +275068,9 @@ ${formatSubscriptionCard(bundle, targetModel)}`
274200
275068
  handleSessionSelect,
274201
275069
  handleOllamaRetry,
274202
275070
  handleOllamaCancel,
274203
- handleOllamaProceed
275071
+ handleOllamaProceed,
275072
+ handleOpenDeviceAuthUrl,
275073
+ handleAbortAuth
274204
275074
  };
274205
275075
  }
274206
275076
  var init_use_auth_handlers = __esm(async () => {
@@ -274921,6 +275791,8 @@ function useAgentSession({
274921
275791
  isAuthenticated: initialAuth,
274922
275792
  authMethod: initialAuthMethod,
274923
275793
  hasBothAuth: initialHasBothAuth,
275794
+ hasDecember: initialHasDecember,
275795
+ decemberEmail: initialDecemberEmail,
274924
275796
  settingsAuthPriority: initialSettingsAuthPriority,
274925
275797
  cliVersion,
274926
275798
  userEmail,
@@ -274936,6 +275808,10 @@ function useAgentSession({
274936
275808
  setAuthMethod,
274937
275809
  hasBothAuth,
274938
275810
  setHasBothAuth,
275811
+ hasDecember,
275812
+ setHasDecember,
275813
+ decemberEmail,
275814
+ setDecemberEmail,
274939
275815
  settingsAuthPriority,
274940
275816
  setSettingsAuthPriority,
274941
275817
  currentEmail,
@@ -275068,10 +275944,20 @@ function useAgentSession({
275068
275944
  isAuthenticated: initialAuth,
275069
275945
  authMethod: initialAuthMethod,
275070
275946
  hasBothAuth: initialHasBothAuth !== undefined ? initialHasBothAuth : prev.hasBothAuth,
275947
+ hasDecember: initialHasDecember !== undefined ? initialHasDecember : prev.hasDecember,
275948
+ decemberEmail: initialDecemberEmail !== undefined ? initialDecemberEmail : prev.decemberEmail,
275071
275949
  settingsAuthPriority: initialSettingsAuthPriority !== undefined ? initialSettingsAuthPriority : prev.settingsAuthPriority,
275072
275950
  currentEmail: userEmail !== undefined ? userEmail : prev.currentEmail
275073
275951
  }));
275074
- }, [initialAuth, initialAuthMethod, initialHasBothAuth, initialSettingsAuthPriority, userEmail]);
275952
+ }, [
275953
+ initialAuth,
275954
+ initialAuthMethod,
275955
+ initialHasBothAuth,
275956
+ initialHasDecember,
275957
+ initialDecemberEmail,
275958
+ initialSettingsAuthPriority,
275959
+ userEmail
275960
+ ]);
275075
275961
  import_react71.useEffect(() => {
275076
275962
  if (agent) {
275077
275963
  setupAgentInterceptors(agent, {
@@ -275384,7 +276270,11 @@ function useAgentSession({
275384
276270
  role: "user",
275385
276271
  text: `Generate plan from grill interview for: "${originalPrompt}"`
275386
276272
  },
275387
- { id: assistantMsgId, role: "assistant", blocks: [] }
276273
+ {
276274
+ id: assistantMsgId,
276275
+ role: "assistant",
276276
+ blocks: [{ type: "text", content: "Thinking..." }]
276277
+ }
275388
276278
  ]);
275389
276279
  let planSuccess = false;
275390
276280
  const errorContext = {
@@ -275467,7 +276357,11 @@ function useAgentSession({
275467
276357
  role: "user",
275468
276358
  text: `Refine plan: "${feedback}"`
275469
276359
  },
275470
- { id: assistantMsgId, role: "assistant", blocks: [] }
276360
+ {
276361
+ id: assistantMsgId,
276362
+ role: "assistant",
276363
+ blocks: [{ type: "text", content: "Thinking..." }]
276364
+ }
275471
276365
  ]);
275472
276366
  let planSuccess = false;
275473
276367
  const errorContext = {
@@ -275570,7 +276464,11 @@ function useAgentSession({
275570
276464
  role: "user",
275571
276465
  text: `/plan ${trimmedGoal}`
275572
276466
  },
275573
- { id: assistantMsgId, role: "assistant", blocks: [] }
276467
+ {
276468
+ id: assistantMsgId,
276469
+ role: "assistant",
276470
+ blocks: [{ type: "text", content: "Thinking..." }]
276471
+ }
275574
276472
  ]);
275575
276473
  let planSuccess = false;
275576
276474
  const errorContext = {
@@ -276527,6 +277425,25 @@ ${decStatus}
276527
277425
  setAuthMode("tasks_mode");
276528
277426
  return;
276529
277427
  }
277428
+ if (text.trim() === "/tui" || text.trim().startsWith("/tui ")) {
277429
+ const subArg = text.trim().slice("/tui".length).trim().toLowerCase();
277430
+ const currentIsInline = useCliStore.getState().isInline;
277431
+ let targetInline;
277432
+ if (subArg === "fullscreen" || subArg === "full") {
277433
+ targetInline = false;
277434
+ } else if (subArg === "classic" || subArg === "inline") {
277435
+ targetInline = true;
277436
+ } else {
277437
+ targetInline = !currentIsInline;
277438
+ }
277439
+ useCliStore.getState().setIsInline(targetInline);
277440
+ if (!targetInline) {
277441
+ addToast("Switched to fullscreen renderer (DEC 2026 synchronized updates, alternate buffer, mouse auto-copy).", "info");
277442
+ } else {
277443
+ addToast("Switched to classic inline renderer.", "info");
277444
+ }
277445
+ return;
277446
+ }
276530
277447
  if (text.trim() === "/usage") {
276531
277448
  await fetchUsageData();
276532
277449
  setAuthMode("usage");
@@ -276645,6 +277562,7 @@ If it doesn't open automatically, please click here:
276645
277562
  "skill",
276646
277563
  "skills",
276647
277564
  "tasks",
277565
+ "tui",
276648
277566
  "update",
276649
277567
  "usage"
276650
277568
  ]);
@@ -276680,7 +277598,13 @@ If it doesn't open automatically, please click here:
276680
277598
  });
276681
277599
  return [...prev, ...currentActive, newUserMsg];
276682
277600
  });
276683
- setActiveMessages([{ id: assistantMsgId, role: "assistant", blocks: [] }]);
277601
+ setActiveMessages([
277602
+ {
277603
+ id: assistantMsgId,
277604
+ role: "assistant",
277605
+ blocks: [{ type: "text", content: "Thinking..." }]
277606
+ }
277607
+ ]);
276684
277608
  const errorContext = {
276685
277609
  provider: agent?.modelOptions?.provider || useCliStore.getState().selectedProvider,
276686
277610
  model: agent?.modelOptions?.model || useCliStore.getState().activeModel
@@ -276775,19 +277699,6 @@ If it doesn't open automatically, please click here:
276775
277699
  setSettingsAuthPriority,
276776
277700
  setSwitchItems
276777
277701
  ]);
276778
- const handleAbort = import_react71.useCallback(() => {
276779
- if (activeShellAbortRef.current) {
276780
- activeShellAbortRef.current();
276781
- activeShellAbortRef.current = null;
276782
- }
276783
- if (isStreaming && agent) {
276784
- agent.abort();
276785
- setQueuedPrompts([]);
276786
- }
276787
- if (useCliStore.getState().planWorkflow.phase === "executing") {
276788
- setPlanWorkflow({ phase: "idle" });
276789
- }
276790
- }, [isStreaming, agent, setQueuedPrompts, setPlanWorkflow]);
276791
277702
  const { handleSettingsMainSelect } = useSettingsHandlers();
276792
277703
  const {
276793
277704
  handleAuthMenuSelect,
@@ -276802,8 +277713,46 @@ If it doesn't open automatically, please click here:
276802
277713
  handleSessionSelect,
276803
277714
  handleOllamaRetry,
276804
277715
  handleOllamaCancel,
276805
- handleOllamaProceed
277716
+ handleOllamaProceed,
277717
+ handleOpenDeviceAuthUrl,
277718
+ handleAbortAuth
276806
277719
  } = useAuthHandlers(agent, onLogin, onLoginHeadless);
277720
+ const handleAbort = import_react71.useCallback(() => {
277721
+ if (activeShellAbortRef.current) {
277722
+ activeShellAbortRef.current();
277723
+ activeShellAbortRef.current = null;
277724
+ }
277725
+ if (handleAbortAuth) {
277726
+ handleAbortAuth();
277727
+ }
277728
+ if (isStreaming && agent) {
277729
+ agent.abort();
277730
+ setQueuedPrompts([]);
277731
+ }
277732
+ if (useCliStore.getState().planWorkflow.phase === "executing") {
277733
+ setPlanWorkflow({ phase: "idle" });
277734
+ }
277735
+ }, [isStreaming, agent, setQueuedPrompts, setPlanWorkflow, handleAbortAuth]);
277736
+ const hasTriggeredFirstLaunchRef = import_react71.useRef(false);
277737
+ const handleAuthMenuSelectRef = import_react71.useRef(handleAuthMenuSelect);
277738
+ handleAuthMenuSelectRef.current = handleAuthMenuSelect;
277739
+ import_react71.useEffect(() => {
277740
+ if (hasTriggeredFirstLaunchRef.current)
277741
+ return;
277742
+ hasTriggeredFirstLaunchRef.current = true;
277743
+ let isMounted = true;
277744
+ const checkFirstLaunchAuth = async () => {
277745
+ await Promise.resolve().then(() => init_config());
277746
+ const config = await loadConfig();
277747
+ if (!config.email && !config.decemberToken && !initialAuth && isMounted) {
277748
+ await handleAuthMenuSelectRef.current({ value: "december" });
277749
+ }
277750
+ };
277751
+ checkFirstLaunchAuth().catch(() => {});
277752
+ return () => {
277753
+ isMounted = false;
277754
+ };
277755
+ }, [initialAuth]);
276807
277756
  const handlePlanApprovalSelect = import_react71.useCallback(async (item) => {
276808
277757
  const originalPrompt = currentPlannedPrompt || useCliStore.getState().currentPlannedPrompt || "";
276809
277758
  const planText = currentPlanText || useCliStore.getState().currentPlanText || "";
@@ -276855,7 +277804,13 @@ If it doesn't open automatically, please click here:
276855
277804
  });
276856
277805
  return [...prev, ...currentActive, newUserMsg];
276857
277806
  });
276858
- setActiveMessages([{ id: assistantMsgId, role: "assistant", blocks: [] }]);
277807
+ setActiveMessages([
277808
+ {
277809
+ id: assistantMsgId,
277810
+ role: "assistant",
277811
+ blocks: [{ type: "text", content: "Thinking..." }]
277812
+ }
277813
+ ]);
276859
277814
  const errorContext = {
276860
277815
  provider: agent?.modelOptions?.provider || useCliStore.getState().selectedProvider,
276861
277816
  model: agent?.modelOptions?.model || useCliStore.getState().activeModel
@@ -277016,6 +277971,10 @@ If it doesn't open automatically, please click here:
277016
277971
  setIsAuthenticated,
277017
277972
  authMethod,
277018
277973
  hasBothAuth,
277974
+ hasDecember,
277975
+ setHasDecember,
277976
+ decemberEmail,
277977
+ setDecemberEmail,
277019
277978
  settingsAuthPriority,
277020
277979
  currentEmail,
277021
277980
  setCurrentEmail,
@@ -277105,7 +278064,13 @@ If it doesn't open automatically, please click here:
277105
278064
  handleRefreshUsage: fetchUsageData,
277106
278065
  handleOpenBilling,
277107
278066
  onRefresh: fetchUsageData,
277108
- onOpenBilling: handleOpenBilling
278067
+ onOpenBilling: handleOpenBilling,
278068
+ isInline: useCliStore((state) => state.isInline),
278069
+ setIsInline: useCliStore((state) => state.setIsInline),
278070
+ handleOpenDeviceAuthUrl,
278071
+ handleAbortAuth,
278072
+ pendingDeviceAuthUrl: useCliStore((state) => state.pendingDeviceAuthUrl),
278073
+ setPendingDeviceAuthUrl: useCliStore((state) => state.setPendingDeviceAuthUrl)
277109
278074
  };
277110
278075
  }
277111
278076
  var import_react71;
@@ -277147,7 +278112,7 @@ function resolveAnnouncement(options) {
277147
278112
  }
277148
278113
  return {
277149
278114
  ...releaseHighlights,
277150
- bullets: releaseHighlights.bullets.slice(0, 3)
278115
+ bullets: releaseHighlights.bullets.slice(0, 2)
277151
278116
  };
277152
278117
  }
277153
278118
 
@@ -277171,7 +278136,6 @@ function parseCliArgs(args) {
277171
278136
  global: { type: "boolean", short: "g" },
277172
278137
  local: { type: "boolean", short: "l" },
277173
278138
  resume: { type: "boolean", short: "r" },
277174
- inline: { type: "boolean" },
277175
278139
  model: { type: "string", short: "m" },
277176
278140
  provider: { type: "string", short: "p" },
277177
278141
  "session-id": { type: "string" },
@@ -277190,7 +278154,7 @@ function parseCliArgs(args) {
277190
278154
  const isGlobal = Boolean(values.global);
277191
278155
  const isLocal = Boolean(values.local);
277192
278156
  const isResume = Boolean(values.resume);
277193
- const isInline = Boolean(values.inline);
278157
+ const isInline = false;
277194
278158
  const model = values.model;
277195
278159
  const provider = values.provider;
277196
278160
  const sessionId = values["session-id"];
@@ -277291,12 +278255,11 @@ Options:
277291
278255
  }
277292
278256
  // src/constants/release-highlights.json
277293
278257
  var release_highlights_default = {
277294
- version: "0.4.10",
277295
- title: "What's New in v0.4.10",
278258
+ version: "0.4.11",
278259
+ title: "What's New in v0.4.11",
277296
278260
  bullets: [
277297
- "Restore curl and powershell installers with client os detection and binary releases",
277298
- "Use official gnu bash and powershell vector icons in install dropdown",
277299
- "Show changelog highlights on every launch capped to 3 bullets"
278261
+ "Add fullscreen renderer mode with synchronized updates and mouse auto-copy",
278262
+ "Update december billing label to december wallet and clean up inline mode"
277300
278263
  ],
277301
278264
  url: "https://trydecember.com/docs/changelog"
277302
278265
  };
@@ -277539,7 +278502,7 @@ Executing Headless Task: "${parsedArgs.prompt}"
277539
278502
  { useAgentSession },
277540
278503
  { localOperations, setActiveScopeDir },
277541
278504
  { instantiateProvider },
277542
- { ensureValidModelForProvider },
278505
+ { ensureValidModelForProvider, getModelLabel },
277543
278506
  { useCliStore }
277544
278507
  ] = await Promise.all([
277545
278508
  Promise.resolve().then(() => (init_src5(), exports_src3)),
@@ -277595,6 +278558,21 @@ Executing Headless Task: "${parsedArgs.prompt}"
277595
278558
  const initialModel = providerConfig?.authMethod === "december" ? "december-auto" : parsedArgs.model || providerConfig?.model || ensureValidModelForProvider(activeProvider, config.activeModel);
277596
278559
  useCliStore.getState().setActiveModel(initialModel);
277597
278560
  useCliStore.getState().setSelectedProvider(activeProvider);
278561
+ useCliStore.getState().setIsAuthenticated(isAuthenticated);
278562
+ useCliStore.getState().setHasDecember(authStatus.hasDecember);
278563
+ if (config.decemberToken && config.email) {
278564
+ useCliStore.getState().setDecemberEmail(config.email);
278565
+ }
278566
+ if (providerConfig?.authMethod) {
278567
+ useCliStore.getState().setAuthMethod(providerConfig.authMethod);
278568
+ }
278569
+ if (!isAuthenticated) {
278570
+ if (!config.email && !config.decemberToken) {
278571
+ useCliStore.getState().setAuthMode("none");
278572
+ } else {
278573
+ useCliStore.getState().setAuthMode("menu");
278574
+ }
278575
+ }
277598
278576
  const harness = new AgentHarness({
277599
278577
  llm,
277600
278578
  tools: CORE_TOOLS,
@@ -277635,7 +278613,6 @@ Executing Headless Task: "${parsedArgs.prompt}"
277635
278613
  await Promise.resolve();
277636
278614
  const announcement = resolveAnnouncement({
277637
278615
  config,
277638
- isInline: parsedArgs.isInline,
277639
278616
  isNewVersion,
277640
278617
  releaseHighlights: release_highlights_default
277641
278618
  });
@@ -277662,37 +278639,57 @@ Executing Headless Task: "${parsedArgs.prompt}"
277662
278639
  session
277663
278640
  });
277664
278641
  }
277665
- const userEmail = config.decemberToken ? config.email : undefined;
277666
- const isFullscreen = !parsedArgs.isInline;
278642
+ const userEmail = config.decemberToken ? config.email : providerConfig?.subscription?.email || config.email || undefined;
278643
+ let inkInstance = null;
278644
+ const handleExit = () => {
278645
+ if (inkInstance) {
278646
+ try {
278647
+ inkInstance.clear();
278648
+ inkInstance.unmount();
278649
+ } catch {}
278650
+ }
278651
+ process.exit(0);
278652
+ };
277667
278653
  if (process.stdout.isTTY) {
277668
- const enterSequences = isFullscreen ? "\x1B[?2004h\x1B[?1000h\x1B[?1002h\x1B[?1006h\x1B[?1007h" : "\x1B[?2004h";
277669
- const exitSequences = isFullscreen ? "\x1B[?2026l\x1B[?2004l\x1B[?1002l\x1B[?1000l\x1B[?1006l\x1B[?1007l" : "\x1B[?2026l\x1B[?2004l";
277670
- process.stdout.write(enterSequences);
278654
+ const exitSequences = "\x1B[?2026l\x1B[?2004l\x1B[?1002l\x1B[?1000l\x1B[?1006l\x1B[?1007l\x1B[?1049l\x1B[?25h";
277671
278655
  const cleanupTerminal = () => {
277672
278656
  try {
278657
+ if (inkInstance) {
278658
+ try {
278659
+ inkInstance.clear();
278660
+ inkInstance.unmount();
278661
+ } catch {}
278662
+ }
277673
278663
  process.stdout.write(exitSequences);
277674
278664
  } catch {}
277675
278665
  };
277676
278666
  process.on("exit", cleanupTerminal);
277677
- process.on("SIGINT", cleanupTerminal);
277678
- process.on("SIGTERM", cleanupTerminal);
278667
+ process.on("SIGINT", handleExit);
278668
+ process.on("SIGTERM", handleExit);
277679
278669
  }
277680
- render_default(React.createElement(RootLayout, { fullscreen: isFullscreen }, React.createElement(AppWrapper, {
278670
+ inkInstance = render_default(React.createElement(RootLayout, { fullscreen: true }, React.createElement(AppWrapper, {
277681
278671
  agent,
277682
278672
  isAuthenticated,
277683
278673
  authMethod: providerConfig?.authMethod,
277684
278674
  hasBothAuth: authStatus.hasByok && authStatus.hasDecember,
278675
+ hasDecember: authStatus.hasDecember,
278676
+ decemberEmail: config.decemberToken ? config.email : undefined,
277685
278677
  settingsAuthPriority: authStatus.authPriority,
277686
278678
  cliVersion: package_default.version,
277687
278679
  userEmail,
278680
+ activeModel: initialModel,
278681
+ modelLabel: getModelLabel(initialModel),
278682
+ selectedProvider: activeProvider,
277688
278683
  sessionRepository,
277689
- isInline: parsedArgs.isInline,
277690
- onLogin: (onCode) => Promise.resolve().then(() => (init_auth(), {})).then(({}) => loginViaDeviceCode(undefined, onCode))
278684
+ onExit: handleExit,
278685
+ onLogin: (onCode, signal) => Promise.resolve().then(() => (init_auth(), {})).then(({}) => loginViaDeviceCode(undefined, onCode, signal))
277691
278686
  })), {
277692
- alternateScreen: isFullscreen,
278687
+ alternateScreen: true,
277693
278688
  exitOnCtrlC: false,
277694
278689
  maxFps: 60
277695
278690
  });
278691
+ await inkInstance.waitUntilExit();
278692
+ handleExit();
277696
278693
  }
277697
278694
  main().catch(console.error);
277698
278695
  export {