* feat(runtime): support CLI update from web runtime page
Add the ability to update the CLI daemon from the web Runtime detail page.
When a newer version is available on GitHub Releases, an update button
appears. Clicking it sends an update command through the server to the
daemon via the heartbeat mechanism (same pattern as ping). The daemon
executes `brew upgrade`, reports the result, and restarts itself with the
new binary.
Changes across all three layers:
- Frontend: version display, GitHub latest check, UpdateSection component
- Server: UpdateStore (in-memory), heartbeat extension, 3 new endpoints
- CLI: shared update logic, daemon handleUpdate + graceful restart
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(runtime): handle 'running' status in ReportUpdateResult
The daemon sends {"status":"running"} when it starts executing the
update, but ReportUpdateResult treated any non-"completed" status as
failure — immediately marking the update as failed before brew upgrade
even ran.
Fix: use a switch statement to handle "running" as a no-op (status is
already "running" from PopPending), and also timeout running updates
after 120 seconds in case brew upgrade hangs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add NOT EXISTS check to ClaimAgentTask SQL to prevent claiming a queued
task when the same issue already has a dispatched/running task. This
ensures serial execution within an issue while preserving parallel
execution across different issues (concurrency group pattern).
Also add defensive guard in the frontend task:dispatch handler to avoid
replacing an active task's LiveLog timeline mid-execution.
Closes MUL-183
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(upload): remove file type allowlist to support all file types
Removes the hardcoded MIME type allowlist from both frontend and backend
that was blocking uploads of file types like Word documents (.docx).
File size limit (10 MB) is still enforced. Content type detection is
preserved for metadata storage.
Closes MUL-123
* feat(upload): increase file size limit from 10 MB to 100 MB
Updates both frontend and backend to allow uploads up to 100 MB.
* feat(mentions): support @mentioning issues in comments
- Extend MentionItem type to include "issue" alongside "member"/"agent"
- Add issue search (by identifier and title) to mention suggestion dropdown
- Render issue mentions with CircleDot icon in autocomplete popup
- Issue mentions serialize as [MUL-117 Title](mention://issue/id) (no @ prefix)
- Markdown renderer shows issue mentions as clickable links to /issues/:id
- Backend mentionRe regex updated to match issue mention type
* feat(mentions): auto-expand issue identifiers and add mention format to agent instructions
1. Path A — CLAUDE.md template (runtime_config.go):
Add a "## Mentions" section teaching agents the mention serialization
format for issues, members, and agents. All agents automatically
receive this via the auto-generated CLAUDE.md.
2. Approach 2 — Server-side auto-conversion (internal/mention/):
New ExpandIssueIdentifiers() utility that scans comment content for
bare issue identifiers (e.g. MUL-117) and replaces them with
[MUL-117](mention://issue/<uuid>) mention links. Skips code blocks,
inline code, and existing markdown links. Integrated into both:
- handler.CreateComment (HTTP API path)
- service.createAgentComment (agent task output path)
When clicking an inbox notification, the issue detail now scrolls to and
briefly highlights the relevant comment. Also adds a floating "Jump to
bottom" button on issue pages with long timelines.
Backend: store comment_id in inbox notification details for new_comment
and reaction_added events. Frontend: pass highlightCommentId through to
IssueDetail, add id attributes to comment elements, and track scroll
position for the jump-to-bottom button.
- ListAgents: private agents are now visible to all workspace members
(previously hidden from non-owner members)
- Mentions: private agents can only be @mentioned by the agent owner or
workspace admin/owner; regular members' mentions of private agents are
silently ignored
- Settings (update/delete/skills) and assign were already correctly
restricted in previous PRs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SetAgentSkills previously only allowed workspace owner/admin roles,
blocking members from adding skills to their own agents. Now uses
canManageAgent which allows agent owners too.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the Repositories section from the General workspace settings page
into its own dedicated tab in the Settings sidebar, making it a
first-class entry alongside General and Members. This reduces the
navigation depth from 3 clicks + scroll to a single click.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Members could previously modify any workspace-visible agent. Now only
the agent owner or workspace owner/admin can update or delete an agent,
regardless of visibility.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add two new CLI commands so agents can access execution history:
- `multica issue runs <issue-id>` lists all task executions for an issue
- `multica issue run-messages <task-id>` lists messages for an execution
Also adds --since query param support to the ListTaskMessages backend
handler for incremental message fetching.
Tests verify:
- Stale running tasks: task:failed event has WorkspaceID set
- Agent status reconciliation: agent returns to "idle" after sweep
- Stale dispatched tasks: same correctness for dispatch timeout path
The runtime sweeper was publishing task:failed events without a
WorkspaceID, causing them to be silently dropped by the WS listener.
This meant frontends never received notification when stale/orphaned
tasks were failed by the sweeper — the live log card kept showing
"Agent is working" and the agent status remained "working" indefinitely.
- Look up workspace_id from issue table for each swept task
- Set WorkspaceID on published events so they reach the correct WS room
- Reconcile agent status after sweeping so agents return to "idle"
- Replace "project management platform" framing with landing page
positioning: "turns coding agents into real teammates"
- Use landing page hero subheading for tagline
- Rewrite "What is Multica?" to emphasize agent autonomy, not PM features
- Update features to match landing page sections (autonomous execution,
reusable skills, unified runtimes)
- Apply same changes to Chinese README using landing page zh translations
- Change Cloud link from app.multica.ai to multica.ai/app
- Add README.zh-CN.md with full Chinese translation
- Add language switcher (English | 简体中文) to both READMEs
- Move banner image to very top, remove feature background images
- Move product screenshot into "What is Multica?" section
- Fix logo SVG: use icon-only (no text) for reliable GitHub rendering
- Use markdown heading for "Multica" text instead of SVG text element
- Clean up features into a single bullet list
- Add centered header with logo (dark/light mode), badges, and nav links
- Use landing page headline "Your next 10 hires won't be human."
- Add hero banner illustration and product screenshot from landing page
- Feature sections with inline images (teammates, runtimes)
- Rewrite feature descriptions to match landing page messaging
- Add architecture table alongside diagram
- Create logo SVGs in docs/assets/
- All links verified against main branch (CLI_AND_DAEMON.md, CONTRIBUTING.md, etc.)
@all is a broadcast to all workspace members — it should not trigger
the assignee agent's on_comment. Previously @all was treated as
"includes everyone" and allowed the trigger.
Changes:
- commentMentionsOthersButNotAssignee now checks HasMentionAll() early
and returns true (suppress) when @all is present
- Fix authRequestWithAgent test helper that was making a duplicate HTTP
request (one as member, one as agent)
Tests: 5 new @all unit test cases, 2 new @all integration test cases.
End-to-end tests through the full HTTP router + real database:
TestCommentTriggerOnComment (6 subtests):
- Top-level comment without mentions → triggers agent
- Top-level comment mentioning only others → suppresses trigger
- Top-level comment mentioning assignee → triggers agent
- Reply to agent thread without mentions → triggers agent
- Reply to member thread without mentions → suppresses trigger (Bohan's bug)
- Reply to member thread mentioning assignee → triggers agent
TestCommentTriggerOnAssignNoStatusGate:
- Assigning agent to in_progress issue → triggers (no todo restriction)
TestCommentTriggerOnMentionNoStatusGate:
- @mentioning agent on done issue → triggers (no status gate)
TestCommentTriggerCoalescing:
- Rapid-fire comments → only 1 task created (dedup)
Add search functionality to quickly find issues by title:
- Backend: add search param (ILIKE) to ListIssues query
- Frontend: search modal using CommandDialog with skeleton loading
- Sidebar: ghost-style search button next to create issue button
- Handle CJK input method composition to avoid premature searches
- Responsive max-height for small screens
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
on_assign: Remove the todo-only restriction. Assignment is an explicit
human action — if someone assigns an agent to a done/in_progress issue,
they want the agent triggered (e.g. to fix a problem found after close).
on_mention: Remove the done/cancelled check. @mention is an explicit
action and should work on any issue status. The agent can reopen the
issue if needed.
- Add thread-aware on_comment suppression: when a member replies in a
thread started by another member without @mentioning the assignee
agent, the on_comment trigger is now suppressed. This fixes the bug
where member-to-member conversations incorrectly triggered the
assigned agent.
- Add terminal status check to on_mention: enqueueMentionedAgentTasks
now skips done/cancelled issues, consistent with on_comment behavior.
- Write explicit default triggers on agent creation: new agents get
[on_assign, on_comment, on_mention] all enabled, instead of relying
on null/empty = all enabled. Existing agents with empty triggers
still work via backwards-compat fallback in agentHasTriggerEnabled.
- Consolidate trigger check logic into shared agentHasTriggerEnabled
helper, fixing inconsistency where empty [] was handled differently
by isAgentTriggerEnabled (returned false) vs isAgentMentionTriggerEnabled
(returned true).
- Add documentation comments explaining the intentional status gate
difference: on_assign fires only for todo (start new work), while
on_comment fires for any non-terminal status (conversational).
Add @all mention type that notifies all workspace members (excluding
agents). Includes backend parsing, notification expansion to all members,
and frontend UI with autocomplete suggestion, rendering, and hover card.
- Replace inline initials/Bot icon with ActorAvatar component so
mention suggestions show real profile pictures consistently
- Add scrollIntoView on keyboard navigation so the selected item
stays visible when the list overflows
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Right-side icon buttons (filter, display, view) were using default foreground
color while left-side scope buttons used text-muted-foreground, causing visual
inconsistency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Redesign both Issues and My Issues headers with Linear-style layout:
- Left: scope pill buttons (All/Members/Agents for Issues; Assigned/Created/My Agents for My Issues)
- Right: compact icon buttons for Filter, Display, and View toggle
- Selected scope has accent background, all buttons use consistent outline variant
- Filter active indicator uses brand-colored dot
- Tooltips on all buttons with 500ms global delay
- Remove New Issue button and issue count from headers
- Scope selection persisted to localStorage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>