Skip to content

feat(telegram): add Telegram support and unify config schema - #2

Merged
e-mon merged 10 commits into
mainfrom
feat/telegram-setup-wizard
Mar 13, 2026
Merged

feat(telegram): add Telegram support and unify config schema#2
e-mon merged 10 commits into
mainfrom
feat/telegram-setup-wizard

Conversation

@e-mon

@e-mon e-mon commented Mar 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • Telegram チャンネル完全対応 — Chat SDK adapter, setup wizard, MCP ツール, 通知, bootstrap, emoji reactions
  • Chat SDK 4.20.0 統一アップグレード — 全 @chat-adapter/* + chat パッケージ
  • Config スキーマ再設計home/notificationsz.enum で型安全化、heartbeat.notifications ネスト廃止
  • レガシー config 自動マイグレーション — 旧 homeChannel, 旧 heartbeat.notifications, 旧 notifications 形式を自動変換

変更ファイル (25 files)

Core config

  • src/config/schema.tsz.enum(['discord','slack','telegram']) for home/notifications, heartbeat.desktop flat field, telegram mode/respondInChannels
  • src/config/io.ts — Legacy migration (pre-Zod parse), generic respondInChannels merge, telegram workspace config

Telegram backend

  • src/channels/chat-setup.ts — Telegram adapter registration (polling mode)
  • src/channels/chat-handlers.ts — telegram session ID, extractRawChannelId, isHomeChannel, Chat SDK 4.20 nullable fix
  • src/channels/reply.ts — telegram postToChannel/encodeThreadId
  • src/channels/list-channels.ts — fetchTelegramChats, pollForTelegramChat
  • src/channels/progress/platform-behavior.ts — telegram ReactionPlatformBehavior
  • src/mcp/admin-server.ts — telegram in list_channels/post_message

Setup wizard

  • src/cli/commands/setup.ts — stepTelegram, unified stepHome (mandatory, polling UX), collectSecrets, stepHeartbeatNotifications rewrite, printSummary

Agent

  • src/agent/bootstrap.ts — telegram trigger
  • src/agent/turn/finalize.ts — unified config.notifications
  • src/agent/context-builder.ts — telegram channel context markdown

Other

  • src/cli/commands/start.ts — telegram bootstrap greeting
  • src/inngest/cron-scheduler.ts — config.home only (no legacy fallback)
  • src/cron/types.ts, src/cron/cli.ts — telegram reply channel
  • Templates (cron, daily-briefing, topic-patrol, self-manage)

Test plan

  • bun run build — コンパイルエラーなし
  • bun vitest run — 529 tests pass (config migration テスト含む)
  • Manual: Discord のみ → home 自動設定
  • Manual: Telegram polling UX → チャット発見 → home 設定
  • Manual: 複数 adapter → home 選択画面(Skip なし)
  • Manual: レガシー config.json → 自動マイグレーション確認

🤖 Generated with Claude Code

e-mon and others added 10 commits March 12, 2026 19:39
node-llama-cpp (QMD dependency) requires native compilation tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The translate-preview skill failed to capture CSS on sites that SSR with
localhost URLs (e.g. Next.js on Vercel). The fetch-based CSS inlining
silently failed and removed all <link rel="stylesheet"> tags, producing
unstyled preview HTML.

CSS capture:
- Primary: extract CSS from CSSOM (browser-loaded, URL-independent)
- Fallback: rewrite localhost URLs to page origin before fetching
- Absolutize relative url() in CSSOM CSS using each sheet's href
- Remove localhost preload/prefetch links from saved HTML

Block toggle (unify with twitter-render.js):
- Wrap block pairs in .tp-block container with data-state attribute
- Replace !important + body class + style.display hack with
  data-state driven CSS (no specificity conflicts with site CSS)
- Simplify interaction script: 3-line tpToggle vs getComputedStyle hack

CSP: revert PR#1's over-relaxation (http:, *, blob:) back to the
https:-only policy from ffb8356. The localhost errors were
ERR_CONNECTION_REFUSED, not CSP violations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…onfig

- Add @chat-adapter/telegram with long polling mode
- Introduce unified `config.home` (channel + channelId) replacing
  per-channel `channels.*.homeChannel` fields
- Add `config.notifications` for optional background job notifications
- Setup wizard: stepTelegram with BotFather guide, stepHome with
  Telegram polling UX (retry/manual fallback), mandatory home selection
- Remove stepNotifications from main wizard flow (still available via
  --step notifications)
- Full Telegram support across all subsystems: chat-setup, chat-handlers
  (session ID, isHomeChannel, extractRawChannelId), reply (postToChannel),
  admin-server (post_message, list_channels), cron delivery, bootstrap
  greeting, context-builder markdown guidance, finalize notifications
- Update SKILL.md templates to use 'home channel' terminology

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Upgrade all @chat-adapter/* and chat packages to ^4.20.0
- Replace heartbeat.notifications nested structure with flat
  heartbeat.desktop + top-level config.notifications
- Use z.enum(['discord','slack','telegram']) for home/notifications
  channel field (type-safe validation)
- Add legacy config auto-migration in io.ts (old homeChannel,
  old heartbeat.notifications, old notifications format)
- Add telegram.mode, telegram.respondInChannels to schema
- Add telegram to WorkspaceConfigSchema
- Update finalize.ts to use unified config.notifications
- Add telegram trigger to bootstrap.ts
- Add telegram to ReactionPlatformBehavior
- Fix Chat SDK 4.20 event.thread nullable in chat-handlers.ts
- Rewrite stepHeartbeatNotifications() for new config format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- D-1: shouldRespondInChannel() now includes telegram adapter
  (was returning false, making respondInChannels ineffective)
- T-1: Replace notifications!.channel with ?.channel in catch handler
- D-2: Remove misplaced Slack JSDoc above Telegram interfaces
- R-3: Update comment to include Telegram in respondInChannels note

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract migrateLegacyConfig() and write back to config.json on first
load so old keys (homeChannel, heartbeat.notifications, old
notifications format) are cleaned up permanently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…onfig

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ng UX

- notifyBackgroundJob falls back to config.home when notifications unset
- deriveChannelSessionPrefix handles Telegram adapter
- pollForTelegramChat uses AbortSignal.timeout to prevent hang
- Telegram polling loop adds skip option for using other channel as home
- Chat ID manual input validates numeric format
- parseHomeValue guards against missing colon
- migrateLegacyConfig preserves homeChannel from disabled platforms
- printBanner shows Telegram connection status

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
QMD 1.1.6 added an exports field that only exposes ".", blocking
Node.js ESM resolution of ./dist/store.js and ./dist/mcp.js imports
used by serve.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@e-mon
e-mon merged commit 1844fd8 into main Mar 13, 2026
4 checks passed
@e-mon
e-mon deleted the feat/telegram-setup-wizard branch March 13, 2026 04:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant