electron-updater is a CommonJS module — ESM named imports fail at
runtime. Switch to default import with destructuring.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The heartbeat runner used agent.write() (normal write), which persisted
both the heartbeat prompt and HEARTBEAT_OK response as regular messages
visible in the UI chat history.
Switch to runInternalForResult() — a new AsyncAgent method that runs
via runInternal() (messages marked internal: true, rolled back from
in-memory state). This hides both the heartbeat prompt and response
from the UI entirely, while still persisting to JSONL for diagnostics.
The previous commit's event-stream heartbeat ACK filter remains as a
defense-in-depth layer for edge cases.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The heartbeat runner uses agent.write() (normal write), so heartbeat
ACK responses like "HEARTBEAT_OK" were not suppressed by the internal
run filter and leaked into the desktop UI chat. The Gateway path was
already fixed (Hub has delayed-start + isHeartbeatAckEvent filtering),
but the local Desktop path through AsyncAgent had no such filtering.
Add createFilteredHandler() to AsyncAgent that buffers message_start
for assistant messages and checks subsequent events with
isHeartbeatAckEvent(). Pure heartbeat ACKs are suppressed end-to-end;
all other messages are forwarded normally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changed forwardAssistant from false to true in sendAnnounceDirect() so
the assistant's summary response is streamed to the desktop UI in
real-time. The announcement prompt stays internal (hidden from UI), but
the user now sees the completion notification.
Previously, persistAssistantSummary saved the response to JSONL but
never emitted events to the UI subscriber, leaving users with no
visible feedback after subagent tasks completed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
setProvider() updated toolsOptions.provider but didn't reload tool
instances. The sessions_spawn tool captured the old provider in its
closure at creation time, causing subagents to inherit a stale provider.
Now calls resolveTools() + setTools() after updating toolsOptions so
sessions_spawn gets a fresh closure with the correct provider.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add an `announce` parameter to sessions_spawn that controls when findings
are delivered to the parent agent:
- "immediate" (default): announce per-completion (existing behavior)
- "silent": defer until ALL silent runs from the same requester complete,
then deliver ONE coalesced announcement with all findings
This enables workflows like "spawn 10 parallel subagents to collect data,
then summarize everything at once" without intermediate results.
Changes:
- types.ts: add `announce` field to SubagentRunRecord & RegisterSubagentRunParams
- sessions-spawn.ts: add `announce` parameter to tool schema
- registry.ts: split checkAndAnnounce into immediate/silent groups,
extract announceGroup helper, use count-match guard for silent readiness
- sections.ts: add announce mode guidance to system prompt
- registry.test.ts: add silent mode tests (field storage, group isolation)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract SILENT_REPLY_TOKEN and isSilentReplyText() into a shared
module. Detects NO_REPLY at the start or end of text (with optional
whitespace/punctuation) to filter out silent announcement responses
that should not be forwarded to the user.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document the full subagent lifecycle: spawn, concurrency queue,
execution, completion handling, two-tier announcement delivery,
and record archival. Include provider inheritance chain and
error propagation diagrams.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add error reporting rule to subagent system prompt: subagents must
explicitly report tool failures and missing credentials in their
final message. Add timeout guidelines to parent system prompt with
recommended values by task complexity (10-30 min).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When subagents are still running, sessions_list now returns an
explicit instruction telling the LLM not to poll again and wait
for automatic result delivery. Normalizes status display to
uppercase ([RUNNING], [OK], [ERROR]).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass parent's resolvedProvider through the tool chain (tools.ts →
sessions-spawn.ts → hub.createSubagent) so subagents use the same
LLM provider as the parent. Previously subagents fell back to the
hardcoded default provider, causing API key errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace immediate record deletion with archiveAtMs-based deferred
cleanup (60min retention). This keeps records queryable via
sessions_list after completion. Add sweeper to clean expired records.
Check childAgent.lastRunError after waitForIdle to detect failed runs
that resolve the promise without throwing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add isRunning flag to Agent (runner.ts) for detecting active runs.
Add lastRunError to AsyncAgent for propagating child run errors to
the registry. Fix duplicate message emission in writeInternal by
resetting forwardInternalAssistant before persistAssistantSummary.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add announce-queue.ts for batching nearby subagent completions with
debounce (1s) and collect mode. Implement two-tier delivery in
announce.ts: queue when parent is busy, writeInternal when idle.
All delivery uses writeInternal() to mark messages as internal,
preventing announcement bubbles from appearing in the UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display the label (or truncated task) as subtitle for SpawnSession tool
calls, so users can see what each spawned session is working on.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add chart icon, smart subtitle (shows action + ticker, e.g. "price_snapshot AAPL"),
and running state label for the data tool in the tool call UI component.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use credentialManager.getToolConfig("data") as the primary source for
the Financial Datasets API key, with FINANCIAL_DATASETS_API_KEY env var
as fallback. Also add data tool entry to the credentials template.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- finance-research: guides agent on financial data retrieval and analysis
workflows using the data tool
- dcf-valuation: 8-step DCF valuation workflow with sector WACC reference
data, sensitivity analysis, and validation checks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces a `data` tool that provides structured access to the Financial
Datasets API (financialdatasets.ai). Supports 18 finance actions covering
stock prices, financial statements, key metrics, SEC filings, analyst
estimates, insider trades, news, and crypto data.
Designed as a stable interface — the backend can be swapped from direct
API calls to a Multica Data Service without changing the tool schema.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement one-click desktop auto-update with version checking, download progress, and automatic installation. Includes toast notification UI in bottom-right corner showing update status (checking, available, downloading, ready, or error).
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add description, author, and homepage fields to package.json
required by electron-builder when building .deb packages on Linux CI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change productName from "YourAppName" to "Multica"
- Change appId from "YourAppID" to "com.multica.app"
- Add app icons (icns, ico, png) for all platforms
- Disable hardenedRuntime to fix ad-hoc signing on ARM Macs
- Add build:desktop script to root package.json
- Simplify desktop .gitignore with !build/ exception
- Remove unused asarUnpack and entitlements config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
completeOnboarding() only set completed=true but never cleared the
forceOnboarding flag, causing OnboardingGuard to redirect back to
onboarding in an infinite loop when --force-onboarding was used.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
setProvider() updated the resolved provider and model but did not
rebuild the system prompt, so the runtime info line still showed the
old provider/model (e.g. claude-code/claude-opus-4-6) after switching.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, configured providers only showed a checkmark with no way to
reconfigure them. Now shows a "Reconfigure" button alongside the checkmark.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Registry model IDs used hyphens (claude-sonnet-4-5) but pi-ai expects
dots (claude-sonnet-4.5). Also adds a fallback model config for OpenRouter
models not in pi-ai's registry, since OpenRouter supports thousands of models.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add min-w-0 to SamplePrompt text container so truncate works in
flex layout. Always show ChatView when agent is ready so the message
input is visible (ChatView has its own empty state).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove strict model validation from provider:set IPC handler that
rejected custom models not in the static registry list (broke OpenRouter
with user-typed models). Add error display to setup page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Zustand persist middleware with localStorage to remember onboarding
completion across app restarts. Only the completed flag is persisted;
transient UI state resets each launch. Add --force-onboarding CLI flag
to re-show onboarding even when already completed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove Combobox component and use a plain text input for model name,
allowing users to enter any model identifier manually.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Save & Test flow: saves API key, then sends a minimal prompt to verify
the provider is reachable. Shows phase-based status (saving/testing/
success/error) with auto-close on success.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Queued through the serialization queue to safely switch provider,
send a minimal test prompt, and restore the previous provider.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace plain text input with Combobox for model selection. Users can
search and select from the provider's model list via dropdown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace bg-muted/30 with border-l for a clean separator between the
prompt list and ChatView panels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changed check from availableProviders.length > 0 to current?.available,
so Continue is only enabled when a provider is both configured and
selected as the active default.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace simple prompts with ones that demonstrate real agent
capabilities: web search, project analysis, and shell execution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Continue button is now disabled until the bot status is 'running'.
Skip remains available when no token has been entered.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fake sample prompts with real agent interaction. Clicking a
prompt sends it via localChat and shows the live ChatView on the right
panel with streaming responses.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
OpenRouter requires both API key and model name. Adds optional model
input field to ApiKeyDialog, enabled via showModelInput prop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents pre-selecting an unconfigured provider and enabling Continue
when no provider is configured. Also passes modelId through on success.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add complete onboarding wizard: Permissions > Provider > Connect > Try it
Step 1 (Permissions): Privacy & Trust acknowledgements with toggles for
file system, shell execution, LLM requests, and local storage access.
Step 2 (Provider): LLM provider setup with 4 supported providers
(Kimi Code, Claude Code OAuth, Codex OAuth, OpenRouter), default
provider selection via radio indicator, and contextual setup tutorials
in the right panel that change on hover.
Step 3 (Connect): Optional Telegram bot connection with token input and
BotFather tutorial. Reuses existing useChannels() hook.
Step 4 (Try it): Sample prompts and completion.
Includes OnboardingGuard, Zustand store (no persist - resets on launch),
breadcrumb stepper with progress bar, and left-right split layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add titleBarStyle hiddenInset and trafficLightPosition to BrowserWindow.
Add drag region to main layout header with no-drag on interactive elements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>