This refactor decouples core task pipeline logic from the Telegram transport layer, making bot operations independently testable and enabling future transport adapters (Slack, web UI, etc.).
Hooks (share-plan.py)
│
v
internalctl (core logic)
create-task, advance-task, list-tasks, show-task, delete-task, accept-task-plan
│
v (optional)
telegramctl (transport adapter)
notify-task, await-callbacks
| Command | Description |
|---|---|
create-task |
Create a task with --url, --title, --project, --session-id, --cwd |
list-tasks |
List tasks, optionally filtered by --stage |
show-task <id> |
Show full task details |
advance-task <id> |
Move task to next stage with --target and --user-name |
delete-task <id> |
Remove a task |
accept-task-plan |
Auto-accept plan in Claude via tmux (--session-id, --cwd) |
Core state in ~/.local/share/internalctl/tasks/{task_id}.yaml:
id: 42
stage: "1 → Plan"
url: "https://telegra.ph/..."
title: "Feature X"
project: myproject
metadata:
session_id: abc123
cwd: /Users/mike/code/project
history:
- stage: "1 → Plan"
timestamp: "2026-02-02T..."
created_at: "2026-02-02T..."Telegram state in ~/.local/share/telegramctl/tasks/{message_id}.yaml:
task_id: 42
message_id: 12345
topic_id: 48
topic_name: "1 → Plan"
callback_data: "move:12345:2 → Work"
sent_at: "2026-02-02T..."task_helpers.py- Core task state managementrun_create_task.py- Create taskrun_list_tasks.py- List tasksrun_show_task.py- Show task detailsrun_advance_task.py- Advance task stagerun_delete_task.py- Delete taskrun_accept_task_plan.py- Auto-accept in Claude
tg_task_helpers.py- Telegram-specific state managementrun_notify_task.py- Send notification for internalctl task
scripts/bin/commands/internalctl/cli.py- Added task subcommandsscripts/bin/commands/telegramctl/cli.py- Added notify-task, removed send-questionscripts/bin/commands/telegramctl/run_await_callbacks.py- Uses split state, calls internalctlscripts/bin/commands/telegramctl/helpers.py- Removed question functionsmarketplace/plugins/claude/hooks/share-plan.py- Uses internalctl create-task + notify-task
marketplace/plugins/claude/hooks/share-question.py- Questions no longer supportedscripts/bin/commands/telegramctl/run_send_question.py- Questions no longer supported
A one-time migration script is available at /tmp/migrate-legacy-tasks.py:
uv run /tmp/migrate-legacy-tasks.pyThis will:
- Backup
~/.local/share/telegramctl/to~/Desktop/telegramctl-backup-{timestamp}/ - Migrate pending files to the new split state format
- Remove old
pending/directory
# List tasks in Plan stage
internalctl list-tasks --stage "1 → Plan"
# Review a task
internalctl show-task 42
# Approve it (auto-accepts in Claude if session active)
internalctl advance-task 42 --target "2 → Work" --user-name "CLI User"- Testable - Each internalctl command can be unit tested without Telegram
- Composable - Other tools can use the task state
- Extensible - Easy to add Slack, Discord, or web UI adapters
- Debuggable - Can inspect and manipulate state via CLI
- Offline-capable - Core workflow works without network