- Add search/filtering to the `/model` command with multi-word matching
- Finalize partial stream previews (e.g. thinking blocks) on turn abort instead of clearing them
- Dynamically format low-cost `$ value` metrics up to 5 decimal places in status outputs
- Update queue tests to expect text-turn plans for aborted turns with partial text
Tool call blocks (and thinking) arrive in streaming updates before their
args are populated — emitting immediately gave `Tool call bash {}`.
Buffer non-text blocks during onMessageUpdate; flush them in
onMessageStart (previous message now complete, args fully populated)
and onAgentEnd (single-message turns that never trigger onMessageStart).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Each pi output block (thinking, tool_call, tool_result) emits a
separate Telegram message as it arrives; text content still streams
in a single edit-in-place preview message
- Replace traceVisible bool with displayMode: "full" | "compact" | "text"
(/trace cycles through all three; compact is default)
- Add renderBlockMessage() to lib/rendering.ts; delete old transcript
aggregation helpers (buildTelegramAssistantTranscriptMarkdown, etc.)
- registerTelegramBotCommands now pulls extension commands from
pi.getCommands() in addition to local bot commands
- Update rendering tests for new block rendering API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The first-DM auto-pair behavior combined with ! shell passthrough meant
the first account to DM the bot gained arbitrary shell access. This
removes that footgun entirely.
- allowedUserId must be set before polling starts; missing config blocks
polling with a TUI warning rather than silently accepting any sender
- TELEGRAM_ALLOWED_USER_ID env var is read on session start and
overwrites the saved config value, so rotating the allowed user is a
restart away
- /telegram-setup now prompts for a numeric user ID after the bot token
if one is not already configured
- Denied senders receive an auth error reply; their numeric ID is also
logged to the pi TUI as a warning so operators can identify themselves
on a fresh install without needing @userinfobot
- Dropped the {kind: "pair"} authorization state entirely; undefined
allowedUserId now produces deny, not pair
- Removed pairTelegramUserIfNeeded, shouldPair, shouldNotifyPaired
Existing installs with allowedUserId already in telegram.json are
unaffected. Fresh installs require explicit configuration.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>