@tiens.nguyen/gu-cli 1.0.710 → 1.0.712

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gu-repl.mjs CHANGED
@@ -2070,6 +2070,7 @@ const identityLineText = () =>
2070
2070
  ),
2071
2071
  folder: folderLabel(),
2072
2072
  keyUnchosen: keyChoicePending,
2073
+ apiKeyTail: sessionApiKeyTail,
2073
2074
  },
2074
2075
  { orange, cyan: accent, dim, red },
2075
2076
  );
@@ -5883,6 +5884,7 @@ async function addCodingProvider(roleName = "coding") {
5883
5884
  sessionCodingLabel = model;
5884
5885
  sessionCodingUrl = url;
5885
5886
  sessionCodingKeyId = keyId;
5887
+ sessionApiKeyTail = secret.slice(-4); // store the tail for the bottom bar
5886
5888
  keyChoicePending = false; // the provider's own key was just bound to this folder
5887
5889
  await saveSessionCoding(cwd);
5888
5890
  await saveSessionCodingKeyId(cwd);
@@ -6045,6 +6047,12 @@ async function chooseModel() {
6045
6047
  // what made a rejected key confusing. The masked tail answers it; ctrl+k replaces it without
6046
6048
  // a trip to the web app, which was previously the only way to change a key already saved.
6047
6049
  const ks = await coderKeyState(sessionCodingModel);
6050
+ // BOTTOM BAR TRUTH (follow-up to task #223): the tail beside the model name must name the
6051
+ // key THIS coder will actually be handed, not whichever key was last added or ctrl+k-chosen.
6052
+ // Nothing updated it on /model, so the bar kept the OLD provider's tail while the key line
6053
+ // above — and the request itself — used the new one. coderKeyState already asked the API for
6054
+ // exactly this key (provider-scoped), so mirror it here; a keyless coder shows no tail.
6055
+ sessionApiKeyTail = ks.needsKey && !ks.missing && ks.stored ? ks.stored.slice(-4) : "";
6048
6056
  if (!ks.needsKey) keyChoicePending = false; // Ollama or local MLX — nothing to choose
6049
6057
  if (ks.needsKey && ks.missing) await promptForCodingKey(sessionCodingModel);
6050
6058
  else if (ks.needsKey) {
@@ -7675,6 +7683,9 @@ async function manageCodingKeys(ks, keys) {
7675
7683
  await saveSessionCodingKeyId(resolve(process.cwd()));
7676
7684
  keyChoicePending = false; // chosen — the bar's mark comes off
7677
7685
  codingKeyMissingKnown = false;
7686
+ // Fetch the key to get its tail for the bottom bar
7687
+ const keyData = await fetchCodingKey(keys[idx].backendId || "");
7688
+ sessionApiKeyTail = keyData.key ? keyData.key.slice(-4) : "";
7678
7689
  console.log(
7679
7690
  accent(` ✓ ${folderLabel()} → ${keys[idx].name}`) + dim(` ····${keys[idx].tail}\n`)
7680
7691
  );
@@ -8306,6 +8317,8 @@ let sessionCodingModel = "";
8306
8317
  * a folder keeps meaning until someone picks.
8307
8318
  */
8308
8319
  let sessionCodingKeyId = "";
8320
+ // Last 4 characters of the current API key, for display in the bottom bar
8321
+ let sessionApiKeyTail = "";
8309
8322
  // The friendly model name behind sessionCodingModel, for display only: the token footer
8310
8323
  // must never show a raw "<kind>::<model>" wire id. Empty = running the account default.
8311
8324
  let sessionCodingLabel = "";
@@ -9973,6 +9986,13 @@ async function main() {
9973
9986
  }
9974
9987
  }
9975
9988
  sessionCodingKeyId = await loadSessionCodingKeyId(resolve(process.cwd())); // task #222
9989
+ // Fetch the API key tail after loading the session, if a key is configured
9990
+ if (sessionCodingKeyId) {
9991
+ try {
9992
+ const keyData = await fetchCodingKey("");
9993
+ sessionApiKeyTail = keyData.key ? keyData.key.slice(-4) : "";
9994
+ } catch { /* ignore — the bar works without the tail */ }
9995
+ }
9976
9996
  sessionShowThought = await loadSessionShowThought(resolve(process.cwd())); // task #148
9977
9997
  sessionUnfinishedTask = await loadSessionUnfinishedTask(resolve(process.cwd()));
9978
9998
  // Task #104: seed the ↓ global OUTPUT-token total (user + coding-URL) from the API.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiens.nguyen/gu-cli",
3
- "version": "1.0.710",
3
+ "version": "1.0.712",
4
4
  "description": "Gu CLI — the gu terminal plus the local worker that runs agent / OCR / PDF / embedding jobs on your Mac (Ollama / MLX / OpenAI-compatible).",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -2078,7 +2078,7 @@ export function activeCoderName({
2078
2078
  const passthrough = (v) => v;
2079
2079
 
2080
2080
  export function identityRow(
2081
- { coder = "", folder = "", keyUnchosen = false } = {},
2081
+ { coder = "", folder = "", keyUnchosen = false, apiKeyTail = "" } = {},
2082
2082
  { orange = passthrough, cyan = passthrough, dim = passthrough, red = passthrough } = {},
2083
2083
  ) {
2084
2084
  const name = String(coder ?? "").trim();
@@ -2086,7 +2086,9 @@ export function identityRow(
2086
2086
  // The mark only means anything beside a named coder: with none shown there is nothing for it
2087
2087
  // to be about, and it would read as a fault in the folder.
2088
2088
  const mark = name && keyUnchosen ? red(" ⚠ key not chosen") : "";
2089
- return (name ? orange(name) + mark + dim(" | ") : "") + cyan(where);
2089
+ // API key tail: show the last 4 characters of the API key when available (e.g., "| abcd")
2090
+ const keyIndicator = apiKeyTail ? dim(" | ") + dim(apiKeyTail) : "";
2091
+ return (name ? orange(name) + mark + keyIndicator + dim(" | ") : "") + cyan(where);
2090
2092
  }
2091
2093
 
2092
2094
  /**