The empty ~/.super-multica/channels.json5 file was accidentally added
during a merge conflict resolution. Remove it and add ~/.super-multica/
to .gitignore to prevent future accidents.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Track bundled skill IDs in a .bundled-manifest.json file. On each
initialization, remove managed skills that were previously bundled
but are no longer present in the bundle directory. User-installed
skills are not affected since they are never recorded in the manifest.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The provider & model dropdown now scrolls internally instead of
causing the whole page to scroll when content exceeds viewport.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Upgrade @mariozechner/pi-ai and @mariozechner/pi-agent-core from 0.50.3
to 0.52.9 to support latest models (claude-opus-4-6, o3, o3-mini).
Breaking type changes addressed:
- exactOptionalPropertyTypes: use conditional spread or `| undefined`
- TOOL_PROFILES removed: strip all profile references from CLI
- AgentMessage union requires timestamp: cast test fixtures
- AsyncAgent.id → sessionId
- Add explicit callback parameter types for SDK event handlers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clarify that local whisper is the primary provider (free, offline),
OpenAI API is the fallback, and the skill only activates when both
are unavailable. Add setup instructions noting no restart is required.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Only cache successful whisper binary lookups. When whisper is not found,
leave the cache empty so subsequent calls re-check PATH. This allows
the app to detect a newly installed whisper without requiring a restart.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document the new channel system design: FIFO pendingRoutes queue,
activeRoute/activeAcks state, agent_start/agent_end lifecycle,
InboundDebouncer, typing/reaction lifecycle, and UI metadata stripping.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add stripUserMetadata() to remove timestamp envelopes and media type
labels ([Voice Message] Transcript:, [Image] Description:, etc.) that
are injected for LLM context but should not appear in the desktop UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace global lastRoute-based reply targeting with a FIFO route queue
(pendingRoutes) that snapshots route + ack targets at each debouncer flush.
Use agent_start/agent_end lifecycle instead of message_end to ensure stable
routing across multi-turn runs. Track per-message 👀 acks in ackBuffer →
activeAcks for precise cleanup. Two-gate typing stop: only stop when all
queued runs complete.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add model selector section below the provider grid in the dropdown.
Shows available models for the current provider with active model
indicator. Clicking a model calls setProvider with the modelId.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously all agent errors (including 400 invalid_request_error) were
emitted as agent_error events, triggering the UI error banner and
interrupting the chat flow. Now only auth-related errors (401, no API key)
emit agent_error so the "Configure" banner appears. Runtime errors like
400 are still shown as chat messages but don't block the agent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
setProvider() was saving the alias-resolved provider (e.g. "anthropic"
instead of "claude-code") to session metadata. On restart, this caused
the wrong provider to be selected. Now saves the original providerId
so the exact user selection is preserved.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move session metadata loading before provider resolution so that
the stored provider from a previous setProvider() call is used
in the fallback chain (options > session meta > credentials > default)
instead of always falling back to "kimi-coding".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
grammy was not in rollupOptions.external, causing the channels IPC
handlers to fail at runtime with 'No handler registered'.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cron reminders were silently skipped when heartbeat.md had no actionable
content. Now cron: and exec-event reasons both bypass the empty-file
guard so scheduled reminders always reach the agent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge main's run mutex + soft error return with branch's refreshAuthState(),
keeping getApiKey defensive throw as defense-in-depth.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Style is now solely managed by the agent editing soul.md directly,
removing the need for UI controls, IPC handlers, and typed constants.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the agent fails due to missing API key, the error banner now
shows a "Configure" button that opens the same ApiKeyDialog (or
OAuthDialog) used on the home page. After successful configuration
the error clears and the user can immediately start chatting.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
getApiKey errors thrown inside PiAgentCore's internal async context
result in UnhandledPromiseRejection instead of propagating to the
caller. Return a graceful error early so AsyncAgent can emit it
through the subscriber mechanism to the UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix double useChannels() instantiation: call once in ChannelsPage,
pass as props to TelegramCard
- Mask bot tokens in channels:getConfig before sending to renderer
- Add input validation (isValidId, token length) on all IPC handlers
- Fix stopAccount() to clean up typingTimer, lastRoute, aggregator,
and debouncer when stopping the account they belong to
- Add try/catch to stopChannel/startChannel in useChannels hook
- Consistent return type { ok, error? } on channels:stop handler
- Add tooltip hint on disabled Remove button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add IPC handlers, preload API, useChannels hook, and Channels page UI.
Users can save/remove Telegram bot tokens and start/stop bots directly
from the desktop app with immediate effect and persistence across restarts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add setChannelAccountConfig/removeChannelAccountConfig to CredentialManager
for persisting channel tokens. Make ChannelManager.startAccount public and
add stopAccount for individual account lifecycle control via IPC.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- InboundDebouncer: batches rapid-fire messages from the same conversation
into a single agent.write() call (500ms idle, 2s hard cap)
- ACK reactions: add 👀 emoji on message receipt, remove on completion
(addReaction/removeReaction on ChannelOutboundAdapter interface)
- Grammy sequentialize middleware: ensures same-chat updates are processed
in order, preventing race conditions on shared state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>