shadok-ai 0.2.64 → 0.2.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/index.html +22 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shadok-ai",
3
- "version": "0.2.64",
3
+ "version": "0.2.65",
4
4
  "main": "dist/session.js",
5
5
  "scripts": {
6
6
  "test": "node --import tsx --test test/*.ts .claude/skills/shadok-ai-agents/test/*.test.mjs",
package/public/index.html CHANGED
@@ -2895,7 +2895,7 @@
2895
2895
  }
2896
2896
  }
2897
2897
 
2898
- // ── Window title: tokens consumed ───────────────────────
2898
+ // ── Window title: instance name, then tokens consumed ───────────────────
2899
2899
  const BASE_TITLE = document.title;
2900
2900
 
2901
2901
  // ── Notifications: favicon badge + title badge + sound ──────────────
@@ -2904,6 +2904,20 @@
2904
2904
  // channel you're not already looking at. All driven off setTabMood.
2905
2905
  const favicon = $("favicon");
2906
2906
  let titleBase = BASE_TITLE; // current title without the notification badge
2907
+ let titleTokens = 0; // summed tokens across open channels (0 = none yet)
2908
+
2909
+ // The tab title is: INSTANCE NAME first, then the tokens consumed —
2910
+ // "Prod — 12.3k tok". Name alone when there are no tokens yet; the default
2911
+ // "shadok-ai — cockpit" only when neither a custom name nor tokens exist.
2912
+ // Both the name change and the token tick funnel through here, so one no
2913
+ // longer clobbers the other (they used to fight over titleBase).
2914
+ function recomposeTitle() {
2915
+ const name = cockpitTitle || "shadok-ai";
2916
+ titleBase = titleTokens
2917
+ ? name + " — " + fmtTokens(titleTokens) + " tok"
2918
+ : (cockpitTitle || BASE_TITLE);
2919
+ paint(); // re-stamp document.title (with any notification badge)
2920
+ }
2907
2921
 
2908
2922
  // ── Cockpit name: editable header brand, persisted server-side ──────────
2909
2923
  // Several cockpits (one per launch directory) are easy to confuse; a custom
@@ -2914,8 +2928,7 @@
2914
2928
  cockpitTitle = title && title.trim() ? title.trim() : null;
2915
2929
  const brandName = $("brandName");
2916
2930
  if (brandName && !brandName.isContentEditable) brandName.textContent = cockpitTitle || "shadok-ai";
2917
- titleBase = cockpitTitle || BASE_TITLE;
2918
- paint(); // re-stamp document.title (with any notification badge)
2931
+ recomposeTitle(); // name goes first in the tab title, tokens after
2919
2932
  if (typeof scheduleReflow === "function") scheduleReflow(); // name width changed
2920
2933
  }
2921
2934
 
@@ -3125,17 +3138,18 @@
3125
3138
  }
3126
3139
 
3127
3140
  /**
3128
- * Shows the tokens consumed by the open channels in the tab title.
3129
- * Counts fresh input + cache writes + output; cache READS are excluded —
3130
- * they re-bill the whole context on every turn and would drown the number.
3141
+ * The tokens consumed by the open channels, shown AFTER the instance name in
3142
+ * the tab title. Counts fresh input + cache writes + output; cache READS are
3143
+ * excluded — they re-bill the whole context on every turn and would drown the
3144
+ * number. The name/tokens composition lives in recomposeTitle.
3131
3145
  */
3132
3146
  function refreshTitle() {
3133
3147
  let sum = 0;
3134
3148
  for (const t of tabs) {
3135
3149
  if (t.tokens) sum += t.tokens.input + t.tokens.cacheCreation + t.tokens.output;
3136
3150
  }
3137
- titleBase = sum ? fmtTokens(sum) + " tok — shadok-ai" : BASE_TITLE;
3138
- refreshBadge();
3151
+ titleTokens = sum;
3152
+ recomposeTitle();
3139
3153
  }
3140
3154
 
3141
3155
  /**