Replace raw fmt/log calls with structured slog logger (Go) and
console-based logger (TypeScript). Add request logging middleware.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge origin/main which added the skills system (structured skills
with meta skill runtime injection). Resolve 4 conflicts:
- workspace/store.ts: keep both skills state + issue/inbox fetch
- types/index.ts: keep Skill types + our event exports
- handler/agent.go: merge visibility filtering + skills batch loading
- pnpm-lock.yaml: accept main's lockfile with skills deps
Also fix skill.go: migrate h.broadcast → h.publish (event bus)
to match our architecture where all WS events go through the bus.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace agent.skills TEXT field with structured skill/skill_file/agent_skill
tables. Skills are workspace-level entities with supporting files, reusable
across agents via many-to-many bindings.
Backend: migration 008, sqlc queries, CRUD handler, agent-skill junction,
structured skill loading in task context snapshot.
Daemon: meta skill injection via runtime-native config (.claude/CLAUDE.md
for Claude, AGENTS.md for Codex) so agents discover .agent_context/ skills
through their native mechanism. Lean prompt without inlined skill content.
Frontend: Skills management page, agent Skills tab picker, SDK methods,
TypeScript types, workspace store integration.
Also removes auto-creation of init issues when creating agents.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add internal event bus (server/internal/events/) with synchronous
pub/sub and panic isolation per listener
- Upgrade WebSocket Hub to workspace-scoped rooms with JWT auth
and membership verification on connect
- Add 10 new WS event types (comment CRUD, inbox read/archive,
agent create/delete, workspace/member events)
- Refactor all handlers and TaskService to publish events via Bus
instead of direct Hub.Broadcast calls
- Add WS broadcast listener that routes events to correct workspace
- Frontend: WSClient sends token + workspace_id on connect with
auto-reconnect refetch
- Frontend: centralized useRealtimeSync hook dispatches all WS
events to global Zustand stores
- Migrate issues and inbox pages from local useState to global
useIssueStore/useInboxStore
- Make store addIssue/addItem idempotent to prevent duplicates
- Remove dead packages/hooks/src/use-realtime.ts
- Add feature tracking files for 4 planned features
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a `context` text field to workspaces, allowing users to provide
background information and context for AI agents working in the
workspace. Full stack: migration, sqlc queries, Go handler, TS types,
SDK, and settings page UI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add UpdateComment and DeleteComment handlers with /api/comments/{commentId} routes
- Add broadcast for comment create/update/delete WebSocket events
- Support status, priority, and assignee_id filters on ListIssues
- Extend UpdateIssue to handle due_date, acceptance_criteria, context_refs, repository
- Properly distinguish "field not sent" vs "field sent as null" in UpdateIssue
- Add corresponding SDK methods and TypeScript types
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Complete agents management page with create dialog, runtime device selector,
skills/tools/triggers/tasks tabs, and agent detail view
- Add AssigneePicker to issue detail page for assigning to members or agents
- Extend agent types with description, skills, tools, triggers, RuntimeDevice
- Add SDK methods for agent CRUD and task listing
- Add migration 002 for agent config columns (skills, tools, triggers)
- Update seed data with realistic agent configurations
- Use auth context as single source of truth for agents (fixes state sync)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add HTTP handlers for issues, comments, agents, workspaces, inbox, members, and activity
- Implement JWT authentication middleware with Bearer token validation
- Add sqlc queries for all entities (CRUD operations)
- Extract router into reusable NewRouter() for testability
- Expand SDK with full API client methods (CRUD for all resources)
- Add updateWorkspace to SDK, add Member type to shared types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Compaction was reporting only 189 tokens removed for 6 messages because
Phase 1 (tool result pruning) hollowed out messages before Phase 2
(summary compaction) measured them. Now captures pre-pruning token count
and reports combined savings from both phases.
Also threads RunLog through SessionManager to emit tool_result_pruning
and compaction_detail events, and adds preflight pruning stats logging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add MessageSource type to track where user messages originate (local, gateway, channel)
- Broadcast inbound messages from all channels to local Desktop UI via Hub.onInboundMessage()
- Persist source field in JSONL session storage so it survives page refresh
- Display source icon (Monitor/Smartphone/Send) with tooltip for non-local user messages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add clientName field to DeviceMeta so non-browser clients (Telegram,
Discord, etc.) can provide a human-readable label instead of relying on
userAgent parsing. Desktop UI now prioritizes clientName over parsed UA
string, fixing "Unknown on Unknown" display for Telegram connections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the agent encounters an error (e.g. no API key configured),
the Chat UI now shows an error banner instead of silently hanging.
The user can still type and retry after fixing their configuration.
- Add AgentErrorEvent to SDK stream types
- Forward agent_error events through IPC to renderer
- Handle error events in useLocalChat hook
- Keep chat input enabled for AGENT_ERROR (retriable)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Return latest messages by default instead of oldest. Support paginated
loading of older messages when scrolling up via IntersectionObserver,
with scrollHeight compensation to preserve scroll position.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Forward compaction_start/compaction_end events through Hub (Gateway path)
and Desktop IPC (local path) to the Zustand messages store. Adds
CompactionEvent types to the SDK, compacting/lastCompaction state to
useMessagesStore, and event routing in both connection-store and
use-local-chat.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a "verifying" connection state between "connected" and "registered"
so collaborators see clear feedback while waiting for the device owner
to approve their connection on Desktop.
Changes across the stack:
- Hub: verify RPC returns isNewDevice flag to distinguish new vs whitelisted
- SDK: emit "verifying" state before verify RPC, pass isNewDevice through
- Store: capture isNewDevice via onVerified, capture rejection via onError
- UI: ConnectionStatus (waiting), RejectedStatus (declined), and
verify success overlay (approved) replace the stuck scanner screen
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove backward-compatible aliases (TextBlock, ThinkingBlock, ToolCallBlock)
and extractTextFromEvent from SDK — unused after prior refactors
- Add explicit ContentBlock doc comment explaining the wider union tradeoff
- Scope endStream tool interruption to the same agentId (prevents
cross-agent interference in multi-agent scenarios)
- Handle tool_execution_update event (no-op for now, avoids unhandled case)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hand-written message/content types in @multica/sdk with
`import type` from @mariozechner/pi-ai and @mariozechner/pi-agent-core.
This ensures compile-time correctness and eliminates type drift between
backend and frontend (e.g. "tool_use" vs "toolCall", "tool_result" vs
"toolResult").
- stream.ts: re-export TextContent, ThinkingContent, ToolCall,
ImageContent from pi-ai; use AgentEvent from pi-agent-core
- rpc.ts: AgentMessageItem = pi-ai Message (no more manual mirroring)
- connection-store.ts: use SDK types instead of inline hand-written ones
- ContentBlock now includes ImageContent to match backend reality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update StreamMessageEvent content type to include thinking blocks.
Add extractThinkingFromEvent() helper and export it, enabling clients
to access reasoning content from streamed agent responses.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Auto-collect navigator.userAgent, platform, and language in the SDK
verify RPC payload. Add DeviceMeta type. Hub receives this metadata
for display in the Desktop UI device list and confirmation dialog.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Embed transparent verification logic in GatewayClient that automatically
sends an RPC "verify" request to the Hub after REGISTERED event. Adds
hubId, token, and verifyTimeout options. Upper-layer callers see no change
— "registered" state means both gateway registration and Hub verification
are complete. Failures surface via onError callback.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend Hub now sends raw AgentEvent in stream payloads instead of the
old delta/final/error state machine. Update StreamPayload type to use
event field, add extractTextFromEvent helper, and rewrite gateway store
handler to dispatch on event.type (message_start/update/end).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AsyncAgent now subscribes to pi-agent-core events (message_start,
message_update, message_end) and forwards incremental text deltas
through a stream callback. Hub registers the callback and sends
stream payloads to the requesting client via Gateway.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change package exports from dist/ to src/ (consistent with @multica/store and @multica/ui)
- Add private: true since SDK is an internal monorepo package
- Switch tsconfig from NodeNext to bundler moduleResolution
- Remove .js suffixes from all internal imports for Turbopack compatibility
Eliminates the need to build SDK before running dev server or Next.js build.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add typed AgentMessageItem to SDK with proper content block types
- Add fetchAgentMessages action to hub store using getAgentMessages RPC
- Extract text from complex content blocks (user string, assistant array)
- Auto-load history when selecting an agent with no local messages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add LIST_DEVICES event and "hub" device type to SDK
- Add listDevices() method to GatewayClient
- Add handleListDevices handler in Gateway
- Change Hub deviceType from "client" to "hub"
- Refactor gateway store: auto-connect WS, separate hubId selection
- Hub-init: auto-connect on mount, discover hubs on registered
- Hub-sidebar: show discovered hubs list with connect/disconnect UI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 5 new RPC methods (getHubInfo, listAgents, createAgent, deleteAgent,
updateGateway) mirroring the existing Console HTTP API, enabling pure
WebSocket communication from the frontend.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add request<T>() method that handles full request/response lifecycle
with auto-generated requestId, timeout handling, and pending request
cleanup on disconnect. Also add GetAgentMessagesParams and
GetAgentMessagesResult type definitions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sync latest code from src/shared/gateway-sdk/ into packages/sdk/,
update all backend imports to use @multica/sdk, and remove the
duplicate src/shared/gateway-sdk/ directory.
- Translate Chinese comments to English in SDK source
- Fix package.json exports with default condition
- Add @multica/sdk as workspace dependency for backend
- Update imports in gateway, test-client, and hub
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add pnpm workspace and Turborepo configuration
- Extract Gateway SDK to packages/sdk as independent package
- Add Next.js + shadcn Web client in apps/web
- Update root package.json with turbo scripts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>