Commit graph

158 commits

Author SHA1 Message Date
Bohan Jiang
a8a8ff6eca
feat(issues): add sub-issue support (#483)
* feat(issues): add sub-issue support

- Backend: Add ListChildIssues SQL query, add parent_issue_id to UpdateIssue,
  add GET /api/issues/{id}/children endpoint
- Frontend: Display parent issue breadcrumb and link in issue detail sidebar,
  show child issues list with status icons, add "Create sub-issue" action in
  dropdown menu and sidebar, pass parent_issue_id through create issue modal
- Update test mocks for new API method

* fix(issues): add parent validation, cycle detection, and improve child refresh

- CreateIssue: validate parent issue exists in the same workspace
- UpdateIssue: validate parent exists, prevent self-referencing, detect
  circular parent chains (up to 10 levels deep)
- Frontend: derive child issues from store when available instead of
  refetching on every global issue count change
2026-04-08 15:57:13 +08:00
Bohan Jiang
8403c97688
Merge pull request #482 from multica-ai/agent/j/674c6839
feat(usage): add per-task token usage tracking
2026-04-08 14:16:59 +08:00
Jiang Bohan
fa0c0fe747 fix(usage): address review feedback — independent usage reporting + all providers
1. Separate ReportTaskUsage endpoint (POST /api/daemon/tasks/{id}/usage)
   so usage is captured independently of complete/fail — fixes usage loss
   for failed/blocked tasks.

2. Add usage tracking for all four providers:
   - Claude: already done (stream-json message.usage)
   - OpenCode: extract from step_finish.part.tokens
   - OpenClaw: extract from step_end.data token fields
   - Codex: extract from turn/completed and task_complete usage fields

3. Remove usage from CompleteTask payload — all usage goes through the
   dedicated endpoint now.
2026-04-08 13:23:54 +08:00
Jiang Bohan
8a8d3ea20e feat(usage): add per-task token usage tracking
Extract token usage from Claude Code's stream-json output in real-time
during task execution, replacing the inaccurate global JSONL log scanner.

- New `task_usage` table: tracks (task_id, provider, model) level usage
- Agent SDK: parse `message.usage` from assistant messages, accumulate
  per-model and return in Result
- Daemon: convert agent usage to entries, send with CompleteTask
- Server: store usage on task completion, expose workspace-level
  aggregation APIs (GET /api/usage/daily, GET /api/usage/summary)
2026-04-08 13:08:15 +08:00
devv-eve
7c79611309
refactor: remove agent triggers config field (#469)
* refactor: remove agent triggers config field

Remove the triggers field from agent configuration. The on_assign,
on_comment, and on_mention behaviors are now always enabled (hardcoded),
as decided in the Agentflow design discussion (MUL-372).

Changes:
- Database: migration 032 drops triggers column from agent table
- Backend: remove triggers from create/update agent APIs and response
- Backend: simplify trigger-checking logic to always-enabled
- Frontend: remove TriggersTab UI and AgentTrigger types
- Tests: remove trigger config unit tests (no longer configurable)

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

* refactor: also remove agent tools config field

Remove the tools field from agent configuration alongside triggers.
The tools field was a placeholder — stored in the DB and shown in the
UI but never passed to the daemon or used at runtime.

- Database: migration 032 now also drops tools column
- Backend: remove tools from create/update agent APIs and response
- Frontend: remove ToolsTab UI, AgentTool type, and tools tab
- Update landing page copy

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

* fix(test): remove tools/triggers columns from test fixtures

The test fixtures still referenced the dropped tools and triggers
columns when inserting agent rows, causing CI failures.

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

---------

Co-authored-by: Devv <devv@Devvs-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 22:02:28 +08:00
Jiang Bohan
14fe8e9df9 feat(auth): add Google OAuth login
Support Google login that links to existing accounts by email.
When a user who registered via email OTP signs in with Google using
the same email, they are linked to the same account.

Backend:
- Add POST /auth/google endpoint that exchanges Google auth code for
  tokens, fetches user profile, and calls findOrCreateUser()
- Updates user name and avatar from Google profile on first Google login

Frontend:
- Add "Continue with Google" button on login page (shown when
  NEXT_PUBLIC_GOOGLE_CLIENT_ID is configured)
- Add /auth/callback page to handle Google OAuth redirect
- Add loginWithGoogle to auth store and API client
2026-04-07 15:25:26 +08:00
Bohan Jiang
4cf18e122d
Merge pull request #413 from cocovs/codex/fix-daemon-pid-minus1
fix(cli): preserve daemon pid before releasing child process
2026-04-07 14:18:12 +08:00
yushen
0d9d4e6b69 merge: resolve conflicts with origin/main in help.go
Keep branch additions (errSilent, exactArgs, examples template blocks)
that were added in the CLI help UX improvement.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 07:03:03 +08:00
yushen
4c0dbbf1c8 refactor(cli): improve help UX — add examples support, show help on arg errors
- Add EXAMPLES section to leaf and sub help templates (gh CLI style)
- Add example to attachment download command
- Simplify attachment download description
- Show help output when required args are missing (error first, then help)
- Replace cobra.ExactArgs with custom exactArgs that prints help on failure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 07:00:19 +08:00
devv-eve
52a9a6ae5f
refactor(cli): overhaul help output to match gh CLI style (#423)
* refactor(cli): overhaul help output to match gh CLI style

- Add gh-style grouped help with CORE/RUNTIME/ADDITIONAL COMMANDS sections
- Use UPPERCASE section headers (USAGE, FLAGS, EXAMPLES, LEARN MORE)
- Format commands as "name:  description" with automatic alignment
- Add ENVIRONMENT VARIABLES and EXAMPLES sections to root help
- Apply consistent templates to root, subcommand, and leaf commands
- Update descriptions from "Manage X" to "Work with X" for gh parity

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

* fix(execenv): add explicit instruction for agents to always use multica CLI

Agents were using curl/wget to access Multica attachment URLs directly,
which fails due to authentication. Add a prominent "Important" section
to the generated CLAUDE.md template that explicitly prohibits direct
HTTP access and instructs agents to escalate missing CLI functionality
to their workspace owner.

---------

Co-authored-by: Devv <devv@Devvs-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 15:30:40 -07:00
Devv
4afef09a03 refactor(cli): overhaul help output to match gh CLI style
- Add gh-style grouped help with CORE/RUNTIME/ADDITIONAL COMMANDS sections
- Use UPPERCASE section headers (USAGE, FLAGS, EXAMPLES, LEARN MORE)
- Format commands as "name:  description" with automatic alignment
- Add ENVIRONMENT VARIABLES and EXAMPLES sections to root help
- Apply consistent templates to root, subcommand, and leaf commands
- Update descriptions from "Manage X" to "Work with X" for gh parity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 15:10:59 -07:00
Jiayuan Zhang
0771c15a59
fix(trigger): skip parent mention inheritance when reply @mentions only members (#421)
When a reply in a thread explicitly mentions only non-agent entities
(members or issues), do not inherit agent mentions from the parent
comment. This prevents false agent triggers when a user is directing
their reply at other people (e.g. "cc @Someone") rather than requesting
work from agents mentioned in the thread root.

Fixes MUL-324
2026-04-05 04:44:24 +08:00
周阳
5f2ac17129 fix(cli): preserve daemon pid before releasing child process 2026-04-04 21:37:40 +08:00
Jiayuan Zhang
9aee403ff9
Merge pull request #405 from multica-ai/agent/lambda/8bf9407f
fix(comment): allow @mention of assigned agent on done/cancelled issues
2026-04-04 13:31:07 +08:00
Jiayuan
2832a06fe3 fix(comment): allow @mention of assigned agent on done/cancelled issues
The assignee was unconditionally skipped in the mention path, assuming
on_comment would handle it. But on_comment is suppressed for terminal
statuses (done/cancelled), so an explicit @mention of the assignee had
no effect. Now only skip the assignee dedup when on_comment will
actually fire (non-terminal status).
2026-04-04 13:14:09 +08:00
Jiayuan Zhang
fdf594155c
Merge pull request #396 from multica-ai/feat/comment-list-pagination
feat(comments): add pagination to comment list API and CLI
2026-04-04 01:07:22 +08:00
Jiayuan
c39470a53f fix(comments): address code review feedback on pagination
1. Update CLAUDE.md template to document --limit, --offset, --since
   params and guide agents to use pagination when comments are large
2. Add GetJSONWithHeaders to API client; CLI now prints "Showing X of Y
   comments" to stderr when paginating
3. Cap --since without --limit at 500 server-side to prevent unbounded
   result sets
2026-04-04 01:01:48 +08:00
Jiayuan
0bbc6bc1c5 feat(comments): add pagination support to comment list API and CLI
Add --limit, --offset, and --since flags to `multica issue comment list`
to prevent context window overflow when issues have many comments.

The API endpoint now accepts limit, offset, and since (RFC3339) query
parameters. When paginating, the response includes an X-Total-Count
header with the total number of comments.
2026-04-03 23:53:00 +08:00
Jiayuan
91cbf32fd1 fix(cli): address code review feedback for agent/skill/runtime commands
- Add --config flag to skill create/update (accepts JSON string)
- Add --runtime-config flag to agent create/update (accepts JSON string)
- Add --yes flag to skill delete with confirmation prompt
- Improve agent skills set error message (guide users to --skill-ids '')
- Validate --days range (1-365) in runtime usage
- Include last known status in ping/update timeout errors
2026-04-03 16:00:12 +08:00
Jiayuan
10b482fac2 feat(cli): add agent, skill, and runtime management commands
Expand CLI coverage for agent/skill/runtime APIs that previously had no
CLI wrappers despite having fully implemented backend endpoints.

Agent commands (was: only list):
- agent get/create/update/archive/restore/tasks
- agent skills list/set
- agent list --include-archived

Skill commands (new, was: 0% coverage):
- skill list/get/create/update/delete/import
- skill files list/upsert/delete

Runtime commands (new, was: 0% coverage):
- runtime list/usage/activity/ping/update
- ping and update support --wait for polling
2026-04-03 15:41:17 +08:00
Bohan Jiang
fc6405e4be
fix(trigger): allow on_comment when thread root @mentions assignee agent (#382)
When a member-started thread root @mentions the assignee agent, replies
in that thread should trigger on_comment — the thread is a conversation
with the agent, not a member-to-member chat.

Previously isReplyToMemberThread only checked the reply content for
assignee mentions. Now it also checks the parent (thread root) content.
This fixes a gap where path 1 (on_comment) suppressed the trigger and
path 2 (on_mention) skipped the assignee, leaving no trigger path.
2026-04-03 15:07:39 +08:00
Bohan Jiang
c9c8230271
feat(trigger): inherit thread-root mentions for reply-triggered agent tasks (#375)
When a top-level comment @mentions an agent (non-assignee), subsequent
replies in the same thread now also trigger that agent via on_mention.
Previously only the current comment's mentions were checked, so replies
without an explicit re-mention would silently skip the agent.

Extends enqueueMentionedAgentTasks to accept the parent comment and
merge its parsed mentions (deduplicated) into the trigger set, reusing
all existing guards (self-trigger, assignee skip, visibility, dedup).

Closes MUL-177
2026-04-03 13:46:07 +08:00
devv-eve
8eb1caa72b
fix(agent): instruct agents to use download_url for attachments (#356)
* fix(agent): instruct agents to use download_url for attachments

Agents were not aware of the signed vs unsigned URL distinction in
attachments, causing failures when trying to read images. Added an
Attachments section to the generated CLAUDE.md/AGENTS.md template that
tells agents to always use `download_url`. Also increased signed URL
expiry from 5 to 30 minutes to better accommodate agent processing time.

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

* feat(cli): add `multica attachment download` command

Adds a dedicated CLI command for downloading attachments by ID. The
command fetches attachment metadata from the API (which returns a fresh
signed URL), downloads the file, and saves it locally. This eliminates
the need for agents to understand signed vs unsigned URLs.

Changes:
- New `multica attachment download <id>` CLI command
- New `GET /api/attachments/{id}` backend endpoint
- `DownloadFile` helper on APIClient
- Updated CLAUDE.md template to document the command

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

* fix(cli): sanitize filename and add download size limit

- Use filepath.Base on attachment filename to prevent path traversal
- Add 100MB size limit to DownloadFile (matches upload limit)
- Include response body in download error messages for debugging

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

---------

Co-authored-by: Devv <devv@Devvs-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 07:45:42 -07:00
LinYushen
36ba23b3cd
fix(test): use auth.JWTSecret() in integration tests instead of hardcoded secret (#349)
The integration tests hardcoded the old default JWT secret while .env
sets a different JWT_SECRET, causing all authenticated requests to fail
with 401. Use auth.JWTSecret() so tests stay in sync with the server.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:21:21 +08:00
LinYushen
09764c5f51
feat(agent): replace hard delete with archive/restore (#346)
* feat(agent): replace hard delete with archive/restore

Replace agent deletion with soft archive pattern. Archived agents
are preserved in the database with all historical references intact
but cannot be assigned, mentioned, or trigger tasks.

Backend:
- Add archived_at/archived_by columns to agent table (migration 031)
- Replace DELETE /api/agents/{id} with POST /api/agents/{id}/archive
- Add POST /api/agents/{id}/restore endpoint
- ListAgents excludes archived by default (?include_archived=true to include)
- Skip archived agents in task triggers (on_assign, on_comment, on_mention)
- Block assignment to archived agents
- Cancel pending tasks on archive
- New events: agent:archived, agent:restored (replacing agent:deleted)

Frontend:
- Agent type includes archived_at/archived_by fields
- Mention autocomplete and assignee picker filter out archived agents
- Agent list shows archived agents with muted styling
- Agent detail shows archive banner with restore button
- Delete button replaced with Archive button and updated confirmation dialog
- API client: archiveAgent/restoreAgent replace deleteAgent

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

* fix(agent): self-review fixes for archive feature

- Fix: workspace store now fetches agents with include_archived=true
  so archived agents are actually visible in the frontend (the archived
  UI was dead code before — ListAgents excludes archived by default)
- Fix: add error logging for CancelAgentTasksByAgent in ArchiveAgent
- Fix: add idempotency guards — return 409 Conflict when archiving
  an already-archived agent or restoring a non-archived agent
- Fix: revert unnecessary extra GetAgent query in ReconcileAgentStatus
  (archived agents won't have running tasks after CancelAgentTasksByAgent)

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-04-02 17:33:52 +08:00
LinYushen
606930725a
feat(daemon): support direct download update for non-Homebrew installs (#334)
* feat(daemon): support direct download update for non-Homebrew installs

Previously, CLI auto-update only worked for Homebrew installations. Non-brew
binaries would fail with "not installed via Homebrew". Now the daemon and
`multica update` fall back to downloading the release binary directly from
GitHub Releases when Homebrew is not detected.

Also fixes:
- Daemon restart now uses the current executable's absolute path instead of
  searching PATH, ensuring the updated binary is used
- Brew installs preserve the symlink path so the new Cellar version is picked up
- Daemon startup logs now include the CLI version
- Update UI auto-clears "restarting" status after 5s to show the new version

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

* fix(cli): remove dead DetectNewBinaryPath and guard against nil latest version

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-04-02 15:38:06 +08:00
LinYushen
682dc20ba9
fix(runtime): display multica CLI version instead of agent CLI version (#332)
The runtime detail page was showing the agent CLI version (claude/codex)
as "CLI Version" because metadata.version stored the agent version from
agent.DetectVersion(). The multica CLI version was never sent.

Fix: daemon now sends cli_version in the registration request, server
stores it as metadata.cli_version alongside the existing agent version,
and frontend reads metadata.cli_version.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:40:35 +08:00
LinYushen
eba2e7eacf
Merge pull request #327 from multica-ai/agent/j/53c0348f
feat(inbox): auto-scroll to comment and jump-to-bottom button
2026-04-02 14:28:26 +08:00
LinYushen
fdba410f11
feat(runtime): support CLI update from web runtime page (#331)
* 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>
2026-04-02 14:12:49 +08:00
Bohan Jiang
f353e8db59
feat(mentions): support @mentioning issues + server-side auto-expansion (#242)
* 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)
2026-04-02 13:48:53 +08:00
Jiang Bohan
575bbd7f60 feat(inbox): auto-scroll to comment from notification and add jump-to-bottom button
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.
2026-04-02 13:43:05 +08:00
Jiayuan Zhang
0659865645
Merge pull request #314 from multica-ai/agent/lambda/0fa89561
feat(cli): add issue runs and run-messages commands
2026-04-02 03:37:16 +08:00
Jiayuan
6b0c9bba9e feat(cli): add issue runs and run-messages commands
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.
2026-04-02 03:30:33 +08:00
Jiayuan
60e66f32b3 test(server): add integration tests for sweeper event broadcasting fix
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
2026-04-02 03:30:32 +08:00
Jiayuan
eb35bc5dc9 fix(server): broadcast sweeper task:failed events to correct workspace
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"
2026-04-02 03:20:59 +08:00
Jiayuan
02c9d9f0b0 fix(server): @all mentions should not trigger agent execution
@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.
2026-04-02 00:33:21 +08:00
Jiayuan Zhang
8f1526d2bb
Merge pull request #306 from multica-ai/agent/lambda/832eb090
fix(server): improve comment trigger logic for agent execution
2026-04-01 22:28:52 +08:00
Jiayuan
b41536467d test(server): add integration tests for comment trigger logic
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)
2026-04-01 22:11:46 +08:00
Jiayuan
095b7f8185 feat(mentions): support @all to mention all workspace members
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.
2026-04-01 20:58:33 +08:00
yushen
9c249f0770 feat(server,cli): improve attachment support across issue and comment APIs
- Add --attachment flag to `multica issue create` CLI command
- Fix CreateComment response to include linked attachments instead of empty array
- Include attachments inline in GetIssue API response (matching Jira/ClickUp pattern)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:10:43 +08:00
LinYushen
98e7d27acc
feat(cli): add --attachment flag to issue comment add (#260)
Add file attachment support to `multica issue comment add`. The CLI
uploads files via multipart form to /api/upload-file, collects the
returned attachment IDs, and passes them when creating the comment.

Usage: multica issue comment add <issue-id> --content "..." --attachment file1.png --attachment file2.pdf

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:57:23 +08:00
Bohan Jiang
daaa4deaf7
Merge pull request #255 from multica-ai/agent/j/7fc3e0e2
Agent/j/7fc3e0e2
2026-04-01 14:58:54 +08:00
yushen
1a0d8c282a feat(cli): default to production URLs (api.multica.ai, multica.ai)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:27:58 +08:00
Jiang Bohan
4780540bd2 merge: resolve conflicts with main 2026-04-01 13:12:23 +08:00
Bohan Jiang
62eafe5f99
Merge pull request #237 from multica-ai/agent/j/f5e0099c
fix(server): subscribe @mentioned users in issue descriptions
2026-03-31 19:00:07 +08:00
Jiang Bohan
365b5b5f0e feat(agent): add task cancellation with stop button
Users can now interrupt running agents via a "Stop" button on the live
card. The daemon polls task status every 5 seconds and kills the agent
process when cancellation is detected.

Changes:
- New CancelAgentTask SQL query and CancelTask service method
- POST /api/issues/{id}/tasks/{taskId}/cancel endpoint
- Daemon polls GetTaskStatus during execution, cancels context on match
- Frontend: Stop button on AgentLiveCard, task:cancelled WS event
2026-03-31 18:43:37 +08:00
Jiayuan
38cad92e7e fix(inbox): remove hardcoded 50-item limit from inbox list query
The ListInbox endpoint defaulted to LIMIT 50 while the frontend fetched
all items without pagination, causing items beyond the first 50 to be
silently dropped.
2026-03-31 18:36:41 +08:00
Jiang Bohan
c8ab2e8642 fix(server): subscribe @mentioned users in issue descriptions
When a user @mentions someone in an issue description (create or update),
the mentioned users were notified via inbox but not added as subscribers.
This adds subscriber registration for mentioned users in both the
issue:created and issue:updated event listeners, mirroring the existing
notification logic.
2026-03-31 18:36:15 +08:00
LinYushen
b5674869ed
fix(auth): enforce auth on daemon API routes (#224)
* fix(auth): enforce auth middleware and workspace membership on daemon API routes

Daemon routes were registered without the Auth middleware, meaning the
server accepted unauthenticated requests to register runtimes, claim
tasks, etc. The daemon client already sends a Bearer token — the server
just wasn't validating it.

- Split /api/daemon routes: pairing-session endpoints stay public (used
  before the daemon has a token), all others now require Auth middleware
- Add workspace membership check in DaemonRegister so only workspace
  members can register runtimes
- Update test to include X-User-ID header matching the new auth requirement

Closes MUL-90

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

* refactor(daemon): remove dead pairing-session feature

The daemon pairing flow was never completed — the daemon authenticates
via CLI config token, not pairing sessions. Remove all related code:

- Delete daemon_pairing.go handler (4 unused handlers)
- Remove pairing routes from router.go (3 public + 1 protected)
- Delete /pair/local page + test from frontend
- Remove DaemonPairingSession types and API client methods
- Add migration 029 to drop daemon_pairing_session table
- Update LOCAL_DEVELOPMENT.md to reflect actual auth flow

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-31 16:13:58 +08:00
yushen
1e22633301 Merge remote-tracking branch 'origin/main' into feature/file-upload-cloudfront
# Conflicts:
#	apps/web/components/common/rich-text-editor.tsx
#	apps/web/features/issues/components/comment-card.tsx
#	apps/web/package.json
#	pnpm-lock.yaml
2026-03-31 15:59:46 +08:00