Commit graph

1493 commits

Author SHA1 Message Date
Jiayuan
8a61c94b98 feat(ui): restyle issue status and priority with colored badges
- Status labels use colored pill badges (solid bg for active, muted for inactive)
- Board columns have tinted backgrounds matching their status color
- Priority badges use orange (--priority) design token for clear distinction from status
- Issue cards restructured: identifier, title, then assignee/priority/date row
- Agent avatar default color changed from blue to gray
- New Issue button in header changed to solid/primary style
- Reduced hover shadow on board cards
- Added inheritColor prop to StatusIcon and PriorityIcon for badge use
2026-03-31 03:26:43 +08:00
Jiayuan Zhang
32e19f847f
Merge pull request #201 from multica-ai/forrestchang/agent-live-output
feat(agent): stream live agent output and execution history
2026-03-30 23:51:07 +08:00
Jiayuan
a00485cf13 feat(security): redact sensitive information in agent live output
Server-side (primary): Apply redact.Text/InputMap on task message
content, output, and input fields before DB persistence and WebSocket
broadcast. Extended redact package with GitLab tokens, JWTs, connection
strings, and PASSWORD/SECRET/TOKEN env var patterns.

Frontend (fallback): redactSecrets utility mirrors server patterns,
applied in buildTimeline and ToolCallRow render as a safety net.
2026-03-30 23:38:49 +08:00
Jiayuan
e20e1b74dc merge: resolve conflicts with main (reactions feature)
Main added reaction routes and event types while this branch added
task message routes and event types. Both sides kept — no code lost.
2026-03-30 23:29:42 +08:00
Jiayuan
83f325c586 fix(ui): apply mono font directly to code/pre elements
Browser UA stylesheet sets font-family: monospace on <code> and <pre>,
overriding the inherited Geist Mono from parent containers. Apply
font-mono explicitly on these elements so they use the project's
monospace font instead of the browser default.
2026-03-30 23:27:09 +08:00
Jiayuan
1e2052c689 feat(agent): improve live output UI and add execution history
- Fix duplicate icons in tool call rows (use chevron only for expand/collapse)
- Show detailed tool information (WebSearch queries, Agent prompts, Skill names)
- Add thinking/reasoning rows with Brain icon and expandable content
- Show tool results as separate chronological entries with previews
- Add TaskRunHistory component for viewing past agent execution logs
- Add listTasksByIssue API endpoint and task-runs route
- Support thinking content blocks in agent SDK (MessageThinking type)
- Improve callID→toolName mapping in daemon message forwarding
2026-03-30 23:10:54 +08:00
Jiayuan
3c93ebaf1c feat(agent): stream live agent output to issue detail page
When an agent is working on an issue, users can now see real-time output
in the issue detail page instead of waiting for completion.

Backend:
- Add task_message table and migration for persisting agent messages
- Add POST /api/daemon/tasks/{id}/messages endpoint for daemon to report
  structured messages (tool_use, tool_result, text, error) in batches
- Add GET /api/daemon/tasks/{id}/messages for catch-up after reconnect
- Add GET /api/issues/{id}/active-task to check for running tasks
- Broadcast task:message events via WebSocket
- Daemon forwards agent session messages with 500ms text throttling

Frontend:
- Add AgentLiveCard component showing live tool calls, text output,
  and progress indicators with auto-scroll
- Wire into issue detail timeline with WS subscription and HTTP catch-up
- Card appears when agent is working, disappears on completion/failure
2026-03-30 22:53:28 +08:00
Jiayuan Zhang
a526b96b6c
Merge pull request #200 from multica-ai/forrestchang/comment-reactions
feat(reactions): emoji reactions for comments and issues
2026-03-30 22:40:54 +08:00
Jiayuan
7c1aabbe3a feat(reactions): add emoji reactions for comments and issue descriptions
Add Slack-style emoji reactions to comments and issue descriptions with
full-stack support: database tables, REST API endpoints, real-time
WebSocket sync, optimistic UI updates, and inbox notifications.

- New `comment_reaction` and `issue_reaction` tables with migrations
- POST/DELETE endpoints for adding/removing reactions on both comments
  and issue descriptions
- Real-time WS events (reaction:added/removed, issue_reaction:added/removed)
- Shared ReactionBar component with quick emoji picker and full emoji-mart
  picker (lazy-loaded)
- Optimistic add/remove with rollback on failure
- Inbox notifications for comment author and issue creator when reacted to
- Reactions included in timeline, comment list, and issue detail responses
2026-03-30 22:37:59 +08:00
Jiayuan Zhang
e07b121fa8
Merge pull request #198 from multica-ai/forrestchang/agent-sandbox-security
feat(security): agent output redaction and private agent visibility
2026-03-30 22:30:27 +08:00
Jiayuan
ad697e0029 feat(security): restrict agent management to owner for private agents
Replace blanket owner/admin role check in UpdateAgent and DeleteAgent
with canManageAgent, which requires the requesting user to be the
agent's owner (or a workspace owner/admin) for private agents.
2026-03-30 22:27:19 +08:00
Jiayuan
0491350f1b feat(security): add agent output redaction and private agent assignment enforcement
- Add redact package to detect and mask secrets (AWS keys, private keys,
  API tokens, bearer tokens, credentials, home paths) in agent output
  before posting as comments in TaskService
- Enforce agent visibility on issue assignment: private agents can only
  be assigned by their owner or workspace admins
- Add visibility picker (workspace/private) to CreateAgentDialog,
  default to private
- Grey out unassignable private agents in the assignee picker with
  lock icon indicator
2026-03-30 22:22:04 +08:00
Jiayuan Zhang
72e3ccfe33
Merge pull request #197 from multica-ai/forrestchang/daemon-profile
feat(daemon): add --profile flag for multi-environment isolation
2026-03-30 20:24:03 +08:00
Jiayuan
8fa1b163a6 feat(daemon): add --profile flag for multi-environment isolation
Allow running multiple daemon instances against different servers (e.g.
production and local dev) simultaneously. Each profile gets isolated
config, PID file, log file, health port, and workspaces root.

Usage:
  multica login --profile dev --server-url http://localhost:8080
  multica daemon start --profile dev

Default profile (no --profile flag) behavior is unchanged.

Closes MUL-42
2026-03-30 20:21:23 +08:00
Jiayuan Zhang
564eb55f90
Merge pull request #196 from multica-ai/forrestchang/task-workspace-dir
feat(daemon): group task directories by workspace ID
2026-03-30 20:15:34 +08:00
Jiayuan
7d126cc549 feat(daemon): group task directories by workspace ID
Task execution environments were all created flat under WorkspacesRoot,
mixing tasks from different workspaces. Now tasks are nested under their
workspace ID for clearer organization and easier per-workspace cleanup.
2026-03-30 20:13:30 +08:00
Jiayuan Zhang
9c3ff52363
Merge pull request #194 from multica-ai/fix/daemon-auto-discover-new-workspaces
fix(daemon): auto-discover new workspaces without restart
2026-03-30 19:34:04 +08:00
Jiayuan
219b174819 fix(daemon): sync workspaces immediately on startup
Run syncWorkspacesFromAPI once before entering the periodic ticker
loop so newly created workspaces are discovered without the initial
30-second delay.
2026-03-30 19:32:24 +08:00
Jiayuan Zhang
e27afce90a
Merge pull request #195 from multica-ai/mul-39/remove-default-shortcuts
Remove default keyboard shortcuts
2026-03-30 18:48:51 +08:00
Jiayuan
b2e800b605 refactor(web): remove default keyboard shortcuts
Remove the sidebar toggle shortcut (Ctrl/Cmd+B) and theme toggle
hotkey (D key) global keyboard listeners.
2026-03-30 18:47:14 +08:00
Jiayuan
25ed043117 fix(daemon): auto-discover new workspaces without restart
The daemon now periodically fetches the user's workspace list from the
API (every 30s) and adds any new workspaces to the watched config. The
existing config-watch loop then picks up the change and registers
runtimes. This fixes the issue where workspaces created after
`multica login` were not discovered until the daemon was restarted.
2026-03-30 18:08:58 +08:00
LinYushen
457a3eb555
feat(agents): add on_comment trigger option to agent triggers UI (#193)
The backend already supports on_comment triggers but the frontend was
missing the UI to configure them. Adds the "On Comment" trigger type
and "Add On Comment" button alongside the existing On Assign and
Scheduled options.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:59:55 +08:00
Jiayuan Zhang
3baf141265
Merge pull request #192 from multica-ai/forrestchang/runtime-default-name
feat(daemon): include device name in runtime display name
2026-03-30 17:56:43 +08:00
Jiayuan
7aa784ccd3 feat(daemon): include device name in runtime display name
Change runtime naming from "Local Claude" to "Claude (hostname)" so
team members can distinguish runtimes in shared workspaces.
2026-03-30 17:54:29 +08:00
Naiyuan Qing
11954dd7a7
Merge pull request #191 from multica-ai/fix/tiptap-link-navigation
fix(editor): enable link navigation and fix copy artifacts
2026-03-30 17:51:27 +08:00
Naiyuan Qing
81b518d0d1 fix(editor): enable link navigation and fix <url> copy artifacts
- Set openOnClick: true so clicking a link opens it in a new tab
- Add Cmd+Click / Ctrl+Click handler as fallback (skips mention:// links)
- Override prosemirror-markdown link serializer to always use [text](url)
  format instead of <url> autolink syntax, fixing angle brackets appearing
  when copying links from the editor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:45:20 +08:00
Naiyuan Qing
0a38643ef4
Merge pull request #190 from multica-ai/fix/inbox-selection-after-refresh
fix(inbox): fix inbox items unclickable after page refresh
2026-03-30 17:27:23 +08:00
Naiyuan Qing
b4e8dc3769 fix(inbox): use history.replaceState for selection to fix post-refresh clicks
router.replace() triggers a full server navigation cycle in Next.js 15+,
which can stall after a page refresh (no client route cache), preventing
useSearchParams from updating and making inbox items unclickable.

window.history.replaceState() updates the URL synchronously without
triggering server navigation, which is the recommended approach for
URL state management in Next.js 14.1+.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:25:17 +08:00
Naiyuan Qing
1a98cac165
Merge pull request #189 from multica-ai/NevilleQingNY/workspace-isolation-and-agent-parity
feat(api): workspace isolation + agent parity + timeline UI fixes
2026-03-30 17:11:10 +08:00
Naiyuan Qing
0c4cef0ff1 fix(issues): improve timeline activity entry alignment and overflow
- Add items-center for vertical centering between icons and text
- Add truncate on activity text to prevent line wrapping
- Unify icon/avatar sizes to 16px for visual consistency
- Remove connector line (will revisit later)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 17:09:21 +08:00
Naiyuan Qing
9da4f0d68a
Merge pull request #188 from multica-ai/NevilleQingNY/workspace-isolation-and-agent-parity
feat(api): strict workspace isolation + agent parity fixes
2026-03-30 16:51:41 +08:00
Naiyuan Qing
9ede795c5b feat(api): strict workspace isolation + agent parity fixes
Enforce workspace isolation at every layer:

- Router: move RequireWorkspaceMember middleware to group level so ALL
  workspace-scoped routes (issues, agents, skills, runtimes, inbox,
  comments) require workspace context
- SQL: add GetXxxInWorkspace queries that filter by workspace_id,
  eliminating cross-workspace data access at the query level
- Handlers: loadXForUser functions use workspace-scoped queries,
  no fallback to unscoped queries
- Migration 025: add workspace_id column to comment table with backfill
- ListComments: add workspace_id filter for defense-in-depth

Fix daemon workspace mapping:
- Server returns workspace_id in task claim response (from issue)
- Daemon uses task.WorkspaceID directly instead of unreliable
  workspaceIDForRuntime() local map lookup
- Remove workspaceIDForRuntime function

Fix agent/human parity:
- Comment update/delete: use resolveActor for isAuthor check so agents
  can edit/delete their own comments
- Event attribution: replace hardcoded "member" with resolveActor in
  agent, skill, and subscriber publish calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 16:49:13 +08:00
LinYushen
16e0645c75
fix(cli): daemon reads server_url from config file (#187)
* fix(cli): daemon reads server_url from config file

The daemon only checked CLI flags and env vars for server_url, ignoring
the persisted config in ~/.multica/config.json. Now falls back to the
config file when neither flag nor env var is set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(cli): reset workspace data when server_url changes on login

When logging in to a different server, stale workspace_id and
watched_workspaces from the previous server caused 404 errors in the
daemon. Now both browser and token login paths clear workspace data
when the server URL changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(cli): reset workspace data on every login, not just server change

A different user logging in on the same machine would inherit stale
workspace data. Always clear workspace_id and watched_workspaces on
login so autoWatchWorkspaces repopulates them fresh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 16:23:31 +08:00
LinYushen
40aa3f6bd9
feat(cli): support app_url in CLI config (#186)
* feat(cli): support app_url in CLI config for browser login

The login flow opens the frontend URL for browser-based auth, but
previously app_url could only be set via environment variables.
Add app_url to CLIConfig so it can be persisted with `multica config set`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(cli): persist app_url to config during browser login

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 15:51:17 +08:00
yushen
ce43ff014d chore: add Dockerfile for Go backend
Multi-stage build that compiles server, CLI, and migrate binaries,
then produces a minimal Alpine runtime image.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 15:41:42 +08:00
Naiyuan Qing
038dac7fcb
Merge pull request #185 from multica-ai/NevilleQingNY/issue-draft-persist
feat(issues): persist create-issue draft with sidebar indicator
2026-03-30 15:00:09 +08:00
Naiyuan Qing
bf379b2e76 feat(issues): persist create-issue draft with sidebar indicator
- Add zustand draft store with localStorage persistence
- Restore draft fields when reopening create-issue modal
- Clear draft only on successful submission
- Show brand-colored dot on sidebar new-issue button when draft exists

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:57:29 +08:00
Naiyuan Qing
c27715dd5c
Merge pull request #184 from multica-ai/NevilleQingNY/ui-fixes-batch
fix(ui): batch UI fixes — spacing, comments, activity coalescing
2026-03-30 14:31:38 +08:00
Naiyuan Qing
168d9ab5a2 fix(issues): add consistent spacing between list header and items
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:29:29 +08:00
Naiyuan Qing
632ff1f8ae fix(issues): update test mocks and workspace switch ordering
- Add stable issue store mock to prevent infinite effect loop in tests
- Update expected error message in not-found test case
- Clear runtime store on workspace switch and set workspace before hydration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:22:43 +08:00
Naiyuan Qing
cd34b82454 fix(issues): UI polish batch — comment input, card gap, board title, activity coalescing
- CommentInput: remove border-t divider, position submit button inside
  editor area (bottom-right) for cleaner look
- CommentCard: add !gap-0 to override Card's default gap-4
- CommentInput/ReplyInput: strip trailing empty lines from markdown
  before submit to prevent extra blank lines in rendered comments
- BoardCard: use normal text color for title instead of muted+hover
- Timeline: coalesce same actor + same action within 2 min window,
  keeping only the final result (e.g. 5 status changes → 1)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:22:43 +08:00
Naiyuan Qing
9e2cb4040f fix(agents): show error toast on agent creation failure
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:22:43 +08:00
Naiyuan Qing
cc19cfb15a fix(issues): unify activity/comment timeline spacing with flex-col gap
Replace mixed spacing approach (space-y + pb-3) with consistent
flex-col gap-3. Activity connector lines now use absolute positioning
to bridge between icons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:22:43 +08:00
Jiayuan Zhang
f9b1be0e39
Merge pull request #183 from multica-ai/forrestchang/batch-issue-ops
feat(issues): batch operations in list view
2026-03-30 13:57:49 +08:00
Jiayuan
781c3d10e8 merge: resolve conflict with RequireWorkspaceMember middleware
Main added RequireWorkspaceMember middleware to issue list routes.
Applied the same middleware to the new batch-update and batch-delete
routes.
2026-03-30 13:56:07 +08:00
Jiayuan
10f88c5fcd feat(issues): add batch operations for issue list view
Add multi-select with batch update/delete support in the list view.
Users can select issues via checkboxes (per-row or per-status-group)
and apply bulk status, priority, assignee changes or delete via a
floating toolbar.
2026-03-30 13:52:59 +08:00
Jiayuan Zhang
681da9d669
Merge pull request #180 from multica-ai/agent/lambda/6f41715a
refactor(server): consolidate workspace permission checks into middleware
2026-03-30 13:44:11 +08:00
Jiayuan Zhang
3f2b345a1d
Merge pull request #182 from multica-ai/agent/lambda/532f6d3d
fix(handler): set issue_prefix when auto-creating workspace on first login
2026-03-30 13:40:14 +08:00
Jiayuan
f5519e4f64 fix(handler): set issue_prefix when auto-creating workspace on first login
ensureUserWorkspace in auth.go omitted the IssuePrefix field when
creating a default workspace during first login. This caused the
workspace's issue_prefix to be empty, producing identifiers like "-16"
instead of "JIA-16".

- Pass generateIssuePrefix(wsName) when creating the default workspace
- Add fallback in getIssuePrefix to regenerate from workspace name if
  the stored prefix is empty
- Add migration 024 to backfill empty prefixes on existing workspaces
2026-03-30 13:26:42 +08:00
LinYushen
d41b986cb0
feat(server): distinguish agent vs human CLI actions (#181)
* feat(server): distinguish agent vs human CLI actions via X-Agent-ID/X-Task-ID headers

Extract resolveActor helper in handler to centralize agent identity resolution
from X-Agent-ID header with X-Task-ID cross-validation. Fix DeleteComment,
DeleteIssue, and UpdateComment handlers that previously hardcoded "member" as
actor type. Forward MULTICA_TASK_ID as X-Task-ID header from CLI client.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(server): add debug logging and test coverage for resolveActor

Add slog.Debug on agent/task validation failures for easier debugging.
Add TestResolveActor with 5 cases covering member fallback, valid agent,
non-existent agent, valid task, and mismatched task.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:12:59 +08:00