Commit graph

1473 commits

Author SHA1 Message Date
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
Jiayuan Zhang
810f2df8be
Merge pull request #179 from multica-ai/forrestchang/daemon-log-readability
fix(daemon): improve agent execution log readability
2026-03-30 03:48:03 +08:00
Jiayuan
f4a6e7c475 refactor(server): consolidate workspace permission checks into middleware
Move workspace membership and role validation from individual handlers
into dedicated Chi middleware. The new middleware resolves workspace ID
(from query param, X-Workspace-ID header, or URL param), validates
membership via DB, and injects the member into request context.

Handlers now read workspace ID and member from context instead of
calling requireWorkspaceMember/requireWorkspaceRole directly. This
eliminates ~17 duplicated permission checks across handlers and makes
it harder to accidentally omit access control on new routes.
2026-03-30 03:40:20 +08:00
Jiayuan
9b2ded6720 fix(daemon): improve agent execution log readability
Use short task IDs (8-char prefix), task-scoped loggers for concurrent
task disambiguation, numbered tool-use at INFO level for progress
tracking, and an agent-finished summary with duration and tool count.
2026-03-30 03:40:02 +08:00
Jiayuan Zhang
c2af66411d
Merge pull request #177 from multica-ai/forrestchang/task-queue-readability
fix(web): improve agent task queue readability
2026-03-30 03:33:48 +08:00
Jiayuan
ed56b85d2a fix(web): improve agent task queue readability
Show issue identifier and title instead of truncated UUIDs, sort active
tasks to top, highlight running/dispatched tasks, and show contextual
timestamps.
2026-03-30 03:29:54 +08:00
Jiayuan Zhang
e1e4079da1
Merge pull request #176 from multica-ai/forrestchang/daemon-stuck-task
fix(daemon): prevent stuck tasks from blocking queue, add concurrency
2026-03-30 03:10:35 +08:00
Jiayuan
67f1f49b09 fix(daemon): prevent stuck tasks from blocking queue and add concurrent execution
- Expand FailAgentTask SQL to accept dispatched OR running status
- Add FailStaleTasks server-side sweeper (dispatched >5min, running >2.5h)
- Fix daemon handleTask to fail tasks on all error paths (StartTask, CompleteTask)
- Make daemon poll loop concurrent with semaphore (default 20 parallel tasks)
- Raise default agent max_concurrent_tasks from 1 to 6 (migration 023)
- Add --max-concurrent-tasks CLI flag and MULTICA_DAEMON_MAX_CONCURRENT_TASKS env
2026-03-30 03:08:52 +08:00
Jiayuan Zhang
00c54232ad
Merge pull request #174 from multica-ai/forrestchang/inbox-hide-sidebar
feat(inbox): hide issue detail sidebar by default
2026-03-30 02:46:51 +08:00
Jiayuan Zhang
cbf8f95d05
Merge pull request #175 from multica-ai/forrestchang/agent-comment-identity
fix(handler): attribute agent CLI actions to agent identity
2026-03-30 02:46:38 +08:00
Jiayuan
a4c8bbb03c fix(handler): attribute agent CLI actions to agent identity
When agents use the multica CLI during task execution, their comments,
issue updates, and issue creations were attributed to the daemon's user
(via JWT) instead of the agent. Pass MULTICA_AGENT_ID env var from the
daemon, send X-Agent-ID header from the CLI client, and use it in
handlers to set the correct author/actor identity.
2026-03-30 02:41:51 +08:00
Jiayuan
63fd7efc95 feat(inbox): hide issue detail sidebar by default
The properties sidebar in the inbox view is not needed by default.
Add defaultSidebarOpen and layoutId props to IssueDetail so inbox
can start with the sidebar collapsed and persist its layout separately.
2026-03-30 02:41:41 +08:00
Jiayuan Zhang
663dec52b8
Merge pull request #173 from multica-ai/forrestchang/fix-cli-login-token
fix(cli): always update server_url on login
2026-03-30 01:51:33 +08:00
Jiayuan
c3a9190016 fix(cli): always update server_url on login
Previously, `multica login` only saved server_url to config when it was
empty. A stale value (e.g. from a prior session pointing at a different
host) was never overwritten, causing subsequent API calls to hit the
wrong server.
2026-03-30 01:49:07 +08:00
Jiayuan Zhang
a10515fa74
Merge pull request #172 from multica-ai/forrestchang/agent-repo-context
feat(daemon): agent-driven repo checkout with bare clone cache
2026-03-29 19:44:27 +08:00
Jiayuan
99ada27925 merge: resolve conflicts with main (workdir reuse)
Main added execenv.Reuse() for workdir reuse across tasks on the same
issue. Our branch removed Type/BranchName/gitRoot from Environment
(repos are now checked out on demand). Resolution: keep Reuse() but
simplify it to work with the new Environment struct (no workspace type
tracking). Keep the "reused" log field from main, drop removed fields.
2026-03-29 19:42:51 +08:00
Jiayuan
cdc1ac708e feat(daemon): agent-driven repo checkout with bare clone cache
Agents now decide which repo to use based on issue context and check out
repos on demand via `multica repo checkout <url>`. Workspace repos are
cached locally as bare clones for fast worktree creation.

Key changes:
- Add repocache package for bare clone management (clone, fetch, worktree)
- Add `multica repo checkout` CLI command that talks to local daemon
- Add POST /repo/checkout endpoint on daemon health server
- Pass workspace repos metadata through register + task claim responses
- Remove pre-created worktrees from execenv (workdir starts empty)
- Update CLAUDE.md template to instruct agents to use `multica repo checkout`
- Pass MULTICA_DAEMON_PORT, WORKSPACE_ID, AGENT_NAME, TASK_ID env vars to agent
2026-03-29 19:37:48 +08:00
Jiayuan Zhang
3b58dff375
Merge pull request #171 from multica-ai/forrestchang/issue-resume-qa
feat(daemon): reuse workdir across tasks on same agent+issue
2026-03-29 18:42:11 +08:00
Jiayuan
ce2b263ea5 feat(daemon): reuse workdir across tasks on same agent+issue pair
Previously each task created a fresh workdir via execenv.Prepare(), even
when resuming work on the same (agent, issue). This caused the agent's
session context to be out of sync with a blank code state.

Now the server returns prior_work_dir in the claim response, and the
daemon tries execenv.Reuse() first — which wraps the existing directory,
detects git worktree state, and refreshes context files. Falls back to
Prepare() if the prior workdir no longer exists. Workdirs are no longer
cleaned up after task completion so they remain available for reuse.
2026-03-29 18:40:29 +08:00
Naiyuan Qing
ab4058b1e4
Merge pull request #170 from multica-ai/NevilleQingNY/ui-polish
fix(ui): restore issue identifier in breadcrumb
2026-03-29 17:59:13 +08:00
Naiyuan Qing
04cba6fc46 fix(ui): restore issue identifier in breadcrumb
Re-add issue.identifier (e.g. MUL-42) to the breadcrumb nav that was
incorrectly removed during merge conflict resolution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:57:12 +08:00