docs(02): complete telegram-integration phase
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
aa5eacf9ce
commit
d31675f98c
4 changed files with 163 additions and 36 deletions
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
### Core Messaging
|
||||
|
||||
- [ ] **MSG-01**: Incoming Telegram message auto-triggers Claude Code session and sends response back
|
||||
- [ ] **MSG-02**: Typing indicator shown in Telegram while Claude is processing
|
||||
- [ ] **MSG-03**: Brief tool-call progress notifications sent to Telegram (e.g. "Reading file...")
|
||||
- [ ] **MSG-04**: Files/photos attached in Telegram saved to session folder and available to Claude
|
||||
- [x] **MSG-01**: Incoming Telegram message auto-triggers Claude Code session and sends response back
|
||||
- [x] **MSG-02**: Typing indicator shown in Telegram while Claude is processing
|
||||
- [x] **MSG-03**: Brief tool-call progress notifications sent to Telegram (e.g. "Reading file...")
|
||||
- [x] **MSG-04**: Files/photos attached in Telegram saved to session folder and available to Claude
|
||||
|
||||
### Session Management
|
||||
|
||||
|
|
@ -28,13 +28,13 @@
|
|||
|
||||
### Output Modes
|
||||
|
||||
- [ ] **OUT-01**: Default mode: final answer + brief tool-call progress notifications
|
||||
- [x] **OUT-01**: Default mode: final answer + brief tool-call progress notifications
|
||||
- [ ] **OUT-02**: `/verbose` mode: stream full Claude Code output across multiple messages
|
||||
- [ ] **OUT-03**: `/smart` mode: smart truncation with long outputs sent as file attachments
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- [ ] **INFRA-01**: Runs as systemd user service alongside existing bot
|
||||
- [x] **INFRA-01**: Runs as systemd user service alongside existing bot
|
||||
- [x] **INFRA-02**: Async subprocess management via asyncio (no PIPE deadlocks)
|
||||
- [x] **INFRA-03**: Concurrent stdout/stderr draining prevents buffer overflow
|
||||
|
||||
|
|
@ -67,10 +67,10 @@
|
|||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| MSG-01 | Phase 2 | Pending |
|
||||
| MSG-02 | Phase 2 | Pending |
|
||||
| MSG-03 | Phase 2 | Pending |
|
||||
| MSG-04 | Phase 2 | Pending |
|
||||
| MSG-01 | Phase 2 | Complete |
|
||||
| MSG-02 | Phase 2 | Complete |
|
||||
| MSG-03 | Phase 2 | Complete |
|
||||
| MSG-04 | Phase 2 | Complete |
|
||||
| SESS-01 | Phase 1 | Complete |
|
||||
| SESS-02 | Phase 1 | Complete |
|
||||
| SESS-03 | Phase 3 | Pending |
|
||||
|
|
@ -79,10 +79,10 @@
|
|||
| LIFE-02 | Phase 3 | Pending |
|
||||
| LIFE-03 | Phase 3 | Pending |
|
||||
| LIFE-04 | Phase 3 | Pending |
|
||||
| OUT-01 | Phase 2 | Pending |
|
||||
| OUT-01 | Phase 2 | Complete |
|
||||
| OUT-02 | Phase 4 | Pending |
|
||||
| OUT-03 | Phase 4 | Pending |
|
||||
| INFRA-01 | Phase 2 | Pending |
|
||||
| INFRA-01 | Phase 2 | Complete |
|
||||
| INFRA-02 | Phase 1 | Complete |
|
||||
| INFRA-03 | Phase 1 | Complete |
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ This project transforms Telegram into a mobile interface for Claude Code, enabli
|
|||
Decimal phases appear between their surrounding integers in numeric order.
|
||||
|
||||
- [x] **Phase 1: Session & Process Foundation** - Multi-session filesystem structure with subprocess management
|
||||
- [ ] **Phase 2: Telegram Integration** - Core messaging loop with file handling and typing indicators
|
||||
- [x] **Phase 2: Telegram Integration** - Core messaging loop with file handling and typing indicators
|
||||
- [ ] **Phase 3: Lifecycle Management** - Idle timeout, suspend/resume, and graceful cleanup
|
||||
- [ ] **Phase 4: Output Modes** - Advanced output control for verbose and smart modes
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ Plans:
|
|||
|
||||
Plans:
|
||||
- [x] 02-01-PLAN.md -- Persistent subprocess engine + message formatting utilities
|
||||
- [ ] 02-02-PLAN.md -- Bot integration with batching, file handling, and systemd service
|
||||
- [x] 02-02-PLAN.md -- Bot integration with batching, file handling, and systemd service
|
||||
|
||||
### Phase 3: Lifecycle Management
|
||||
**Goal**: Sessions suspend automatically after idle period and resume transparently with full context
|
||||
|
|
@ -89,6 +89,6 @@ Phases execute in numeric order: 1 → 2 → 3 → 4
|
|||
| Phase | Plans Complete | Status | Completed |
|
||||
|-------|----------------|--------|-----------|
|
||||
| 1. Session & Process Foundation | 3/3 | Complete | 2026-02-04 |
|
||||
| 2. Telegram Integration | 1/2 | In progress | - |
|
||||
| 2. Telegram Integration | 2/2 | Complete | 2026-02-04 |
|
||||
| 3. Lifecycle Management | 0/TBD | Not started | - |
|
||||
| 4. Output Modes | 0/TBD | Not started | - |
|
||||
|
|
|
|||
|
|
@ -5,34 +5,34 @@
|
|||
See: .planning/PROJECT.md (updated 2026-02-04)
|
||||
|
||||
**Core value:** Frictionless conversation with Claude Code from anywhere via Telegram — no SSH, no manual inbox checking, just message and get a response.
|
||||
**Current focus:** Phase 2 (Telegram Integration)
|
||||
**Current focus:** Phase 2 complete, ready for Phase 3
|
||||
|
||||
## Current Position
|
||||
|
||||
Phase: 2 of 4 (Telegram Integration)
|
||||
Plan: 02-01 complete (1 of 2 plans completed)
|
||||
Status: In progress
|
||||
Last activity: 2026-02-04 — Completed 02-01-PLAN.md (Persistent subprocess + telegram utils)
|
||||
Phase: 2 of 4 (Telegram Integration) — COMPLETE
|
||||
Plan: 02-02 complete (2 of 2 plans completed)
|
||||
Status: Complete
|
||||
Last activity: 2026-02-04 — Completed 02-02-PLAN.md (Bot integration with batching, file handling, systemd service)
|
||||
|
||||
Progress: [████░░░░░░░░░░░] 33%
|
||||
Progress: [██████████░░░░░] 50%
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
**Velocity:**
|
||||
- Total plans completed: 4
|
||||
- Average duration: 8 min
|
||||
- Total execution time: 0.53 hours
|
||||
- Total plans completed: 5
|
||||
- Average duration: 23 min
|
||||
- Total execution time: 1.95 hours
|
||||
|
||||
**By Phase:**
|
||||
|
||||
| Phase | Plans | Total | Avg/Plan |
|
||||
|-------|-------|-------|----------|
|
||||
| 1 | 3 | 27min | 9min |
|
||||
| 2 | 1 | 5min | 5min |
|
||||
| 2 | 2 | 95min | 48min |
|
||||
|
||||
**Recent Trend:**
|
||||
- Last 3 plans: 01-02 (9min), 01-03 (15min), 02-01 (5min)
|
||||
- Trend: Improved velocity (yolo mode + better planning)
|
||||
- Last 3 plans: 01-03 (15min), 02-01 (5min), 02-02 (90min)
|
||||
- 02-02 included interactive debugging and human verification
|
||||
|
||||
*Updated after each plan completion*
|
||||
|
||||
|
|
@ -57,6 +57,11 @@ Recent decisions affecting current work:
|
|||
- Persistent subprocess instead of fresh per turn: Eliminates ~1s spawn overhead, maintains context (02-01)
|
||||
- Split messages at 4000 chars (not 4096): Leaves room for MarkdownV2 escape expansion (02-01)
|
||||
- Never split inside code blocks: Track in_code_block state, only split when safe (02-01)
|
||||
- Dynamic typing event lookup: Callbacks reference typing_tasks dict by session name, not captured event (02-02)
|
||||
- --append-system-prompt instead of --system-prompt: Preserves Claude Code model identity (02-02)
|
||||
- --dangerously-skip-permissions: Full tool access in non-interactive subprocess (02-02)
|
||||
- Full model ID in persona: Use claude-sonnet-4-5-20250929 instead of alias (02-02)
|
||||
- Stream-json NDJSON format: {type: user, message: {role: user, content: text}} (02-02)
|
||||
|
||||
### Pending Todos
|
||||
|
||||
|
|
@ -65,17 +70,19 @@ None yet.
|
|||
### Blockers/Concerns
|
||||
|
||||
**Phase 1 (Session & Process Foundation) — COMPLETE**
|
||||
- ~~Claude Code CLI --resume behavior with pipes vs PTY unknown~~ — RESOLVED: Research confirms pipes + stream-json is correct approach
|
||||
- ~~Output format for tool calls not documented~~ — RESOLVED: stream-json format documented and implemented
|
||||
- ~~Claude Code CLI --resume behavior with pipes vs PTY unknown~~ — RESOLVED
|
||||
- ~~Output format for tool calls not documented~~ — RESOLVED
|
||||
|
||||
**Phase 2 (Telegram Integration) — IN PROGRESS:**
|
||||
- ~~Non-persistent process model (spawned fresh per turn)~~ — RESOLVED: Refactored to persistent subprocess with stream-json stdin (02-01)
|
||||
- Message batching strategy needs validation against actual Claude output patterns
|
||||
- File upload flow (save to session dir, notify Claude) needs end-to-end testing
|
||||
**Phase 2 (Telegram Integration) — COMPLETE**
|
||||
- ~~Non-persistent process model (spawned fresh per turn)~~ — RESOLVED (02-01)
|
||||
- ~~Message batching strategy needs validation~~ — RESOLVED: Works with 2s debounce (02-02)
|
||||
- ~~File upload flow needs end-to-end testing~~ — RESOLVED: User-verified (02-02)
|
||||
- ~~Typing indicator not visible despite API success~~ — RESOLVED: Stale task cleanup + dynamic event lookup (02-02)
|
||||
- ~~Model identifies as wrong version~~ — RESOLVED: --append-system-prompt preserves CLI defaults (02-02)
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-02-04T19:17:24Z
|
||||
Stopped at: Completed 02-01-PLAN.md (Persistent subprocess + telegram utils)
|
||||
Last session: 2026-02-04T22:10:00Z
|
||||
Stopped at: Completed Phase 2 (Telegram Integration)
|
||||
Resume file: None
|
||||
Next: 02-02-PLAN.md (Bot integration with batching, file handling, systemd service)
|
||||
Next: Phase 3 (Lifecycle Management)
|
||||
|
|
|
|||
120
.planning/phases/02-telegram-integration/02-02-SUMMARY.md
Normal file
120
.planning/phases/02-telegram-integration/02-02-SUMMARY.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
---
|
||||
phase: 02-telegram-integration
|
||||
plan: 02
|
||||
subsystem: telegram
|
||||
tags: [telegram, bot, typing-indicator, batching, file-handling, systemd, markdownv2]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 02-telegram-integration
|
||||
plan: 01
|
||||
provides: Persistent subprocess and telegram utils
|
||||
provides:
|
||||
- End-to-end Telegram-Claude Code messaging with typing indicators
|
||||
- Message batching with debounce for rapid sequential messages
|
||||
- Photo/document handling with auto-analysis
|
||||
- Tool call progress notifications
|
||||
- Systemd user service for reliability
|
||||
affects: [03-lifecycle-management, bot-reliability]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added:
|
||||
- MessageBatcher (asyncio.Queue + debounce timer)
|
||||
- systemd user service (KillMode=mixed)
|
||||
patterns:
|
||||
- "Dynamic typing event lookup via session name in typing_tasks dict"
|
||||
- "Debounce-based message batching with asyncio.Queue"
|
||||
- "--append-system-prompt preserves Claude Code defaults while adding persona"
|
||||
- "--dangerously-skip-permissions for full tool access in non-interactive mode"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- telegram/message_batcher.py
|
||||
- ~/.config/systemd/user/telegram-bot.service
|
||||
modified:
|
||||
- telegram/bot.py
|
||||
- telegram/claude_subprocess.py
|
||||
- telegram/telegram_utils.py
|
||||
- telegram/personas/default.json
|
||||
|
||||
key-decisions:
|
||||
- "Dynamic typing event lookup: callbacks reference typing_tasks dict by session name, not captured event"
|
||||
- "--append-system-prompt instead of --system-prompt: preserves Claude Code model identity"
|
||||
- "--dangerously-skip-permissions: allows all tools in non-interactive subprocess"
|
||||
- "Full model ID in persona (claude-sonnet-4-5-20250929) instead of alias"
|
||||
- "Stream-json NDJSON format: {type: user, message: {role: user, content: text}}"
|
||||
|
||||
patterns-established:
|
||||
- "Pattern 1: Dynamic callback binding - closures look up mutable state by key instead of capturing immutable reference"
|
||||
- "Pattern 2: Stale task cleanup - check task.done() and delete from dict before creating replacement"
|
||||
- "Pattern 3: Persona via append - use --append-system-prompt to layer persona on top of CLI defaults"
|
||||
|
||||
# Metrics
|
||||
duration: ~90min (including interactive debugging with user)
|
||||
completed: 2026-02-04
|
||||
---
|
||||
|
||||
# Phase 2 Plan 2: Bot Integration Summary
|
||||
|
||||
**End-to-end Telegram-Claude Code messaging with typing, batching, file handling, and systemd service**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** ~90 minutes (including interactive testing and bug fixes)
|
||||
- **Started:** 2026-02-04T19:30:00Z
|
||||
- **Completed:** 2026-02-04T22:10:00Z
|
||||
- **Tasks:** 3 (2 auto + 1 human-verify checkpoint)
|
||||
- **Files created:** 2
|
||||
- **Files modified:** 4
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Created MessageBatcher with debounce-based batching (2s timer, asyncio.Queue)
|
||||
- Overhauled bot.py: typing indicators, tool call progress, message batching, file handling
|
||||
- Created systemd user service with KillMode=mixed for subprocess cleanup
|
||||
- Fixed stream-json NDJSON input format (nested message object required)
|
||||
- Fixed typing indicator lifecycle (stale task cleanup + dynamic event lookup)
|
||||
- Switched to --append-system-prompt to preserve Claude Code model identity
|
||||
- Added --dangerously-skip-permissions for full tool access
|
||||
- Set full model ID (claude-sonnet-4-5-20250929) in default persona
|
||||
- Human-verified: messages flow, typing indicators show, model identifies correctly
|
||||
|
||||
## Task Commits
|
||||
|
||||
1. **Task 1: MessageBatcher + bot.py overhaul** - `f246d18` (feat)
|
||||
2. **Task 2: Systemd user service** - created during same executor run
|
||||
3. **Task 3: Human verification** - bugs found and fixed:
|
||||
- `2d0d4da` - typing indicator lifecycle, model identity, tool permissions
|
||||
|
||||
## Bugs Found During Testing
|
||||
|
||||
1. **Stream-json input format**: `{"type":"user","content":"..."}` rejected by Claude Code; correct format is `{"type":"user","message":{"role":"user","content":"..."}}`
|
||||
2. **Typing indicator stale tasks**: After completion, typing task stayed in dict with set event; next message reused dead task and typing never started
|
||||
3. **Typing indicator event mismatch**: Subprocess callbacks captured specific stop_typing event at creation time; new messages created new events but callbacks still set the old one
|
||||
4. **Model identity lost**: `--system-prompt` overwrote Claude Code's built-in system prompt (which includes model version); fixed with `--append-system-prompt`
|
||||
5. **Tool permissions blocked**: Non-interactive `-p` mode blocked tools requiring permission prompts; fixed with `--dangerously-skip-permissions`
|
||||
6. **Model alias resolution**: `sonnet` alias resolved to 3.5 Sonnet in CLI; fixed by using full model ID
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
**Created:**
|
||||
- `telegram/message_batcher.py` - Debounce-based message batching with asyncio.Queue
|
||||
- `~/.config/systemd/user/telegram-bot.service` - Systemd user service with KillMode=mixed
|
||||
|
||||
**Modified:**
|
||||
- `telegram/bot.py` - Full overhaul: dynamic typing callbacks, stale task cleanup, batching, file handling
|
||||
- `telegram/claude_subprocess.py` - NDJSON fix, --dangerously-skip-permissions, --append-system-prompt, full cmd logging
|
||||
- `telegram/telegram_utils.py` - Debug logging for typing indicator
|
||||
- `telegram/personas/default.json` - Full model ID instead of alias
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
1. **Typing indicator architecture changed**: Plan assumed capturing stop_typing event in callbacks; changed to dynamic lookup from typing_tasks dict by session name to fix lifecycle bugs
|
||||
2. **System prompt approach changed**: Plan used `--system-prompt`; changed to `--append-system-prompt` to preserve Claude Code defaults
|
||||
3. **Added --dangerously-skip-permissions**: Not in original plan; needed for tool access in non-interactive mode
|
||||
4. **Model ID changed**: Plan used `sonnet` alias; changed to full ID after alias resolution issues
|
||||
|
||||
---
|
||||
*Phase: 02-telegram-integration*
|
||||
*Completed: 2026-02-04*
|
||||
Loading…
Add table
Reference in a new issue