dsh-tg-bridge 1.2.3 → 1.2.5

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/bridge.mjs +22 -2
  2. package/control.mjs +11 -0
  3. package/package.json +1 -1
package/bridge.mjs CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  } from 'node:fs';
13
13
  import { homedir } from 'node:os';
14
14
  import { join, basename } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
15
16
  // Force IPv4 for every fetch. DNS returns an AAAA next to the A record, and
16
17
  // Happy Eyeballs happily picks the IPv6 path, which here costs ~5 s or dies
17
18
  // outright ("fetch failed" every 6 s, measured 22.10.2026: IPv4 0.34 s, IPv6
@@ -36,6 +37,10 @@ const CRED = join(DSH_HOME, '.credentials.yaml');
36
37
  const PENDING_DIR = join(DIR, 'pending');
37
38
  const DONE_FILE = join(DIR, 'done.json');
38
39
  const RESTART_MARKER = join(DIR, 'restart.pending');
40
+ // `/restart confirm` leaves a note here for the process that replaces it: the
41
+ // old code exits ~300 ms after spawning the new one, and without this the chat
42
+ // saw "Перезапускаю мост…" and then silence — no proof the bot came back.
43
+ const RESTART_NOTICE = join(fileURLToPath(new URL('.', import.meta.url)), 'restart-notice.json');
39
44
  const DONE_TTL_MS = 24 * 60 * 60 * 1000;
40
45
  // dsh.cmd runs the Electron binary as Node against this CLI entrypoint; the
41
46
  // bridge mirrors that exactly so no shell quoting of task text is needed.
@@ -480,9 +485,7 @@ const IMMEDIATE_COMMANDS = new Set([
480
485
  'stop',
481
486
  'logs',
482
487
  'status',
483
- 'queue',
484
488
  'help',
485
- 'version',
486
489
  'doctor',
487
490
  'restart',
488
491
  ]);
@@ -1672,6 +1675,23 @@ async function main() {
1672
1675
  const me = await tg('getMe');
1673
1676
  botUsername = me.username || '';
1674
1677
  log(`bot @${me.username}`);
1678
+ // Confirm the restart in the topic it was asked from, not in the DM: the
1679
+ // person who typed `/restart confirm` was looking at that thread.
1680
+ try {
1681
+ if (existsSync(RESTART_NOTICE)) {
1682
+ const notice = JSON.parse(readFileSync(RESTART_NOTICE, 'utf8'));
1683
+ unlinkSync(RESTART_NOTICE);
1684
+ if (Date.now() - Number(notice.at || 0) < 10 * 60 * 1000) {
1685
+ await send(
1686
+ notice.chatId,
1687
+ `✅ Мост перезапущен — на связи (pid ${process.pid}).\nТема и сессия прежние, можно продолжать.`,
1688
+ notice.threadId || 0,
1689
+ );
1690
+ }
1691
+ }
1692
+ } catch (error) {
1693
+ log(`restart notice failed: ${error.message}`);
1694
+ }
1675
1695
  for (const id of config.allowedUserIds) {
1676
1696
  try { await send(id, `🤖 ${t(config.lang || 'ru', 'msg.started')}`); } catch {}
1677
1697
  }
package/control.mjs CHANGED
@@ -554,6 +554,17 @@ export async function handleControl(ctx) {
554
554
  }
555
555
  say('Перезапускаю мост…');
556
556
  const bridge = fileURLToPath(new URL('./bridge.mjs', import.meta.url));
557
+ // Tell the replacement process where to confirm, so the chat does not go
558
+ // silent after "Перезапускаю мост…" (it did, twice on 2026-10-24).
559
+ try {
560
+ writeFileSync(
561
+ fileURLToPath(new URL('./restart-notice.json', import.meta.url)),
562
+ JSON.stringify({ chatId: ctx.chatId, threadId: ctx.threadId || 0, at: Date.now() }),
563
+ 'utf8',
564
+ );
565
+ } catch (error) {
566
+ log(`restart notice not written: ${error.message}`);
567
+ }
557
568
  spawn(process.execPath, [bridge], { detached: true, stdio: 'ignore', windowsHide: true }).unref();
558
569
  setTimeout(() => process.exit(0), 300);
559
570
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-tg-bridge",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "Telegram bridge for DeepSeek Harness: text, voice, photos and project-per-topic sessions without opening the desktop app",
5
5
  "type": "module",
6
6
  "main": "bridge.mjs",