shadok-ai 0.2.7 → 0.2.8

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 +49 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shadok-ai",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
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
@@ -869,6 +869,25 @@
869
869
  #chanBar .gauge { flex-direction: row; align-items: baseline; gap: 4px; }
870
870
  #chanBar .gauge .label { font-size: 10px; }
871
871
  #chanBar #cwdView { display: inline-block; max-width: 200px; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
872
+ /* Sélecteur de canal : masqué sur desktop (la sidebar est la navigation). */
873
+ #chanSelect {
874
+ display: none;
875
+ font-family: var(--mono); font-size: 13px;
876
+ background: var(--bg-inset); color: var(--text);
877
+ border: 1px solid var(--line); border-radius: 6px; padding: 5px 8px;
878
+ max-width: 55vw;
879
+ }
880
+ /* ── Mobile : sidebar cachée, navigation par le sélecteur du header canal ── */
881
+ @media (max-width: 640px) {
882
+ #tabbar { display: none; }
883
+ #chanSelect { display: inline-block; }
884
+ #chanBar #chanBarName { display: none; }
885
+ /* Bandeau canal condensé : on garde Status + Session, on cache le reste. */
886
+ #chanBar #dirGauge, #chanBar #branchGauge { display: none !important; }
887
+ #chanBar .gauge .label { display: none; } /* valeurs seules, plus compact */
888
+ #chanBar { gap: 6px; padding: 6px 10px; }
889
+ header { flex-wrap: wrap; row-gap: 4px; }
890
+ }
872
891
  #xtermHost { flex: 1; min-height: 0; overflow: auto; padding: 8px 10px; }
873
892
  #xtermHost .xterm { height: 100%; }
874
893
  /* Aucun agent ouvert. Le panneau central n'affiche plus un formulaire à demi
@@ -1320,11 +1339,13 @@
1320
1339
  séparé, donc ses actions n'ont pas de raison d'apparaître avec lui. -->
1321
1340
  <div id="chanBar" hidden>
1322
1341
  <span class="label" id="chanBarName"></span>
1342
+ <!-- Mobile: sidebar cachée → ce sélecteur change de canal / en crée un. -->
1343
+ <select id="chanSelect" title="Canal"></select>
1323
1344
  <div class="gauge">
1324
1345
  <span class="label">Status</span>
1325
1346
  <span class="value"><span id="led" class="led"></span><span id="state">—</span></span>
1326
1347
  </div>
1327
- <div class="gauge">
1348
+ <div class="gauge" id="dirGauge">
1328
1349
  <span class="label">Directory</span>
1329
1350
  <span class="value" id="cwdView">—</span>
1330
1351
  </div>
@@ -1646,6 +1667,7 @@
1646
1667
  tab.nameEl.textContent = v;
1647
1668
  saveName(tab, v);
1648
1669
  persistChannels();
1670
+ rebuildChanSelect(); // le nom change → mettre à jour le sélecteur mobile
1649
1671
  });
1650
1672
  }
1651
1673
 
@@ -2329,7 +2351,33 @@
2329
2351
  * un formulaire à la place. Tout ce qui décrit un canal retombe alors sur « — »
2330
2352
  * et le panneau central montre l'invitation.
2331
2353
  */
2354
+ /** (Re)construit le sélecteur mobile : une option par canal + « + New agent ». */
2355
+ function rebuildChanSelect() {
2356
+ const sel = $("chanSelect");
2357
+ if (!sel) return;
2358
+ const cur = active ? String(active.id) : "";
2359
+ sel.innerHTML = "";
2360
+ for (const t of tabs) {
2361
+ const o = document.createElement("option");
2362
+ o.value = String(t.id);
2363
+ o.textContent = t.nameEl ? t.nameEl.textContent : "agent " + t.id;
2364
+ sel.appendChild(o);
2365
+ }
2366
+ const nw = document.createElement("option");
2367
+ nw.value = "__new__";
2368
+ nw.textContent = "+ New agent";
2369
+ sel.appendChild(nw);
2370
+ sel.value = cur;
2371
+ }
2372
+ $("chanSelect").addEventListener("change", () => {
2373
+ const v = $("chanSelect").value;
2374
+ if (v === "__new__") { createTab(); return; }
2375
+ const t = tabs.find((x) => String(x.id) === v);
2376
+ if (t) activate(t);
2377
+ });
2378
+
2332
2379
  function refreshChrome() {
2380
+ rebuildChanSelect(); // garde le sélecteur mobile en phase (liste + actif)
2333
2381
  const t = active;
2334
2382
  if (!t) {
2335
2383
  $("led").className = "led ";