shadok-ai 0.15.24 → 0.15.26

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/README.md CHANGED
@@ -296,6 +296,9 @@ Enter to skip; you can add it later from the web UI).
296
296
 
297
297
  ### Telegram (optional)
298
298
 
299
+ The Telegram panel (header icon) carries a folded *How to set it up, step by step*
300
+ guide, open until a token is saved and a group is bound.
301
+
299
302
  Add your bot to a group with **Topics** enabled, make it an admin with *Manage
300
303
  topics* (and *Delete messages* so `/secret` can scrub values), then in the group:
301
304
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shadok-ai",
3
- "version": "0.15.24",
3
+ "version": "0.15.26",
4
4
  "main": "dist/session.js",
5
5
  "scripts": {
6
6
  "test": "node --import tsx --test --test-timeout=120000 test/*.ts context/*/test/*.test.mjs",
package/public/index.html CHANGED
@@ -836,6 +836,10 @@
836
836
  .fold > summary:hover { color: var(--text); }
837
837
  .fold > *:not(summary) { margin-top: 8px; }
838
838
  .fold-count { color: var(--amber); }
839
+ .tg-guide { margin-bottom: 12px; }
840
+ .tg-guide ol { margin: 8px 0 0; padding-left: 20px; font-size: 13px; line-height: 1.5; }
841
+ .tg-guide li { margin-bottom: 4px; }
842
+ .tg-guide code { font-size: 12px; }
839
843
  /* A field with no effect in the current mode (resume/continue) — visible but inert. */
840
844
  .na { opacity: .45; pointer-events: none; }
841
845
 
@@ -2354,6 +2358,18 @@
2354
2358
  <p class="sec-note" id="tgStatus">…</p>
2355
2359
  </div>
2356
2360
  <div class="pin-body">
2361
+ <details class="fold tg-guide" id="tgGuide">
2362
+ <summary>How to set it up, step by step</summary>
2363
+ <ol>
2364
+ <li>In Telegram, open <b>@BotFather</b>, send <code>/newbot</code>, pick a name and a username ending in <code>bot</code>. It answers with a <b>token</b>.</li>
2365
+ <li>Paste that token below and click <b>Save</b>. The status above turns 🟢 with the bot's name.</li>
2366
+ <li>Create a Telegram <b>group</b>, open its settings and turn on <b>Topics</b>.</li>
2367
+ <li>Add your bot to the group and make it an <b>admin</b> with <i>Manage topics</i> (and <i>Delete messages</i>, so <code>/secret</code> can scrub values).</li>
2368
+ <li>In the group, send <code>/setup</code>. The status above now shows the bound group.</li>
2369
+ <li>Send <code>/spawn &lt;name&gt;</code> (or create a topic by hand): each topic is one agent, also visible here as a tab.</li>
2370
+ </ol>
2371
+ <p class="check-hint">Optional: list chat ids under <i>Allowed chats</i> so only they can reach the bot.</p>
2372
+ </details>
2357
2373
  <button id="tgUnbind" hidden title="Unbind the board group so you can /setup a fresh one (e.g. after it became a supergroup)">Unbind group</button>
2358
2374
  <label class="check"><input type="checkbox" id="tgEnabled"><span>Bot enabled</span></label>
2359
2375
  <div class="field">
@@ -2384,9 +2400,14 @@
2384
2400
  <div id="authOverlay" class="overlay" hidden>
2385
2401
  <div id="authPanel" class="sec-panel">
2386
2402
  <div class="sec-head">
2387
- <strong>Sign in to Claude</strong>
2403
+ <strong id="authTitle">Sign in to Claude</strong>
2404
+ <!-- Shown only for a VOLUNTARY re-login (opened from the panel / banner
2405
+ while already signed in): that card is optional, so it must close.
2406
+ The signed-OUT card has no ✕ on purpose — signing in is the only way
2407
+ to make the instance usable, so it stays a funnel. -->
2408
+ <button id="authClose" type="button" title="Cancel" hidden aria-label="Cancel">✕</button>
2388
2409
  </div>
2389
- <p class="sec-note">This instance isn't signed in to Claude, so it can't start any agent.</p>
2410
+ <p class="sec-note" id="authNote">This instance isn't signed in to Claude, so it can't start any agent.</p>
2390
2411
  <div class="field">
2391
2412
  <span class="label">1 — Open this link and authorise</span>
2392
2413
  <a id="authLink" target="_blank" rel="noopener">starting…</a>
@@ -7655,6 +7676,8 @@
7655
7676
  if (!$("setupOverlay").hidden) { closeSetup(); e.preventDefault(); return; }
7656
7677
  if (!$("cronOverlay").hidden) { $("cronOverlay").hidden = true; e.preventDefault(); return; }
7657
7678
  if (!$("telegramOverlay").hidden) { $("telegramOverlay").hidden = true; e.preventDefault(); return; }
7679
+ // Only a voluntary (dismissable) re-login card; the signed-out funnel ignores Escape.
7680
+ if (!$("authOverlay").hidden && authDismissable) { closeAuthCard(); e.preventDefault(); return; }
7658
7681
  if ($("diffpanel").classList.contains("open")) { $("diffpanel").classList.remove("open"); e.preventDefault(); return; }
7659
7682
  // 2. A clickable dialog awaiting an answer → do nothing.
7660
7683
  if (active && active.dialogBubble) return;
@@ -8953,6 +8976,13 @@
8953
8976
  const err = s.tokenError ? ` — ${s.tokenError}` : "";
8954
8977
  $("tgStatus").textContent = `${dot} ${who}${grp}${err}`;
8955
8978
  $("tgUnbind").hidden = !s.boundGroup; // only offer unbind when a group is bound
8979
+ // The guide unfolds on its own until the setup is done (token + bound group);
8980
+ // once it is, it stays folded unless opened — decided once per opening of
8981
+ // the panel, so saving a token never folds a guide the user is reading.
8982
+ if (!$("tgGuide").dataset.auto) {
8983
+ $("tgGuide").open = !(s.hasToken && s.boundGroup);
8984
+ $("tgGuide").dataset.auto = "1";
8985
+ }
8956
8986
  $("tgEnabled").checked = s.enabled;
8957
8987
  const tok = $("tgToken");
8958
8988
  tok.disabled = s.envOverride;
@@ -8970,6 +9000,7 @@
8970
9000
  }
8971
9001
  }
8972
9002
  async function loadTelegram() {
9003
+ delete $("tgGuide").dataset.auto; // each opening of the panel re-decides the fold
8973
9004
  renderTelegram(await (await fetch("/telegram")).json());
8974
9005
  }
8975
9006
  async function putTelegram(patch) {
@@ -9113,8 +9144,31 @@
9113
9144
  // button and the expiry banner). Without it the server short-circuits to
9114
9145
  // {alreadySignedIn} and the card closes doing nothing — which is exactly the
9115
9146
  // no-op the signed-in re-login affordances would otherwise be.
9147
+ // A voluntary re-login (force) is dismissable; the signed-out funnel is not.
9148
+ // Tracked so Escape and a backdrop click only close the card they should.
9149
+ let authDismissable = false;
9150
+
9151
+ // Close a VOLUNTARY re-login card, cancelling the pending `claude auth login`
9152
+ // child on the server so it is not left waiting on stdin (DELETE /auth/login
9153
+ // → cancelLogin). Never the way out of the signed-out funnel.
9154
+ function closeAuthCard() {
9155
+ if (!authDismissable) return;
9156
+ fetch("/auth/login", { method: "DELETE" }).catch(() => {});
9157
+ authDismissable = false;
9158
+ $("authClose").hidden = true;
9159
+ $("authOverlay").hidden = true;
9160
+ }
9161
+
9116
9162
  async function openAuthCard(force = false) {
9117
9163
  if (!$("authOverlay").hidden) return; // a flow is already on screen
9164
+ authDismissable = force;
9165
+ $("authClose").hidden = !force;
9166
+ // A forced re-login comes from a SIGNED-IN instance, so the "not signed in"
9167
+ // copy would be wrong there; say what the card actually does.
9168
+ $("authTitle").textContent = force ? "Re-login to Claude" : "Sign in to Claude";
9169
+ $("authNote").textContent = force
9170
+ ? "Renew this instance's Claude sign-in. Your agents keep running in the meantime."
9171
+ : "This instance isn't signed in to Claude, so it can't start any agent.";
9118
9172
  $("authOverlay").hidden = false;
9119
9173
  $("authMsg").hidden = true;
9120
9174
  const link = $("authLink");
@@ -9175,6 +9229,10 @@
9175
9229
  }
9176
9230
  });
9177
9231
 
9232
+ $("authClose").addEventListener("click", closeAuthCard);
9233
+ // Backdrop click closes a dismissable (voluntary) card; the panel itself does not.
9234
+ $("authOverlay").addEventListener("click", (e) => { if (e.target === $("authOverlay")) closeAuthCard(); });
9235
+
9178
9236
  $("tgUnbind").addEventListener("click", () => { if (confirm("Unbind the current board group? You'll need to /setup a group again in Telegram.")) putTelegram({ unbindGroup: true }); });
9179
9237
  $("telegramBtn").addEventListener("click", () => { $("telegramOverlay").hidden = false; loadTelegram(); });
9180
9238
  $("telegramClose").addEventListener("click", () => { $("telegramOverlay").hidden = true; });