diff --git a/packages/views/inbox/components/inbox-list-item.tsx b/packages/views/inbox/components/inbox-list-item.tsx
index 06e9b4154..0bc7e4c80 100644
--- a/packages/views/inbox/components/inbox-list-item.tsx
+++ b/packages/views/inbox/components/inbox-list-item.tsx
@@ -2,7 +2,7 @@
import { StatusIcon } from "../../issues/components";
import { ActorAvatar } from "../../common/actor-avatar";
-import { Archive } from "lucide-react";
+import { Archive, CircleCheck } from "lucide-react";
import type { InboxItem } from "@multica/core/types";
import { InboxDetailLabel } from "./inbox-detail-label";
import { getInboxDisplayTitle } from "./inbox-display";
@@ -25,11 +25,13 @@ export function InboxListItem({
isSelected,
onClick,
onArchive,
+ onDone,
}: {
item: InboxItem;
isSelected: boolean;
onClick: () => void;
onArchive: () => void;
+ onDone?: () => void;
}) {
const displayTitle = getInboxDisplayTitle(item);
@@ -59,6 +61,26 @@ export function InboxListItem({
+ {onDone && (
+ {
+ e.stopPropagation();
+ onDone();
+ }}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.stopPropagation();
+ onDone();
+ }
+ }}
+ className="hidden rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-info group-hover:inline-flex"
+ >
+
+
+ )}
{
+ if (!item.issue_id) return;
+ setSelectedKey("");
+ updateIssueMutation.mutate(
+ { id: item.issue_id, status: "done" },
+ { onError: () => toast.error("Failed to mark as done") },
+ );
+ archiveMutation.mutate(item.id, {
+ onError: () => toast.error("Failed to archive"),
+ });
+ };
+
// Batch operations
const handleMarkAllRead = () => {
markAllReadMutation.mutate(undefined, {
@@ -235,6 +249,11 @@ export function InboxPage() {
isSelected={(item.issue_id ?? item.id) === selectedKey}
onClick={() => handleSelect(item)}
onArchive={() => handleArchive(item.id)}
+ onDone={
+ item.issue_id && item.issue_status !== "done" && item.issue_status !== "cancelled"
+ ? () => handleDone(item)
+ : undefined
+ }
/>
))}
diff --git a/packages/views/issues/components/issue-detail.tsx b/packages/views/issues/components/issue-detail.tsx
index f0b1c393a..2b35c6239 100644
--- a/packages/views/issues/components/issue-detail.tsx
+++ b/packages/views/issues/components/issue-detail.tsx
@@ -9,6 +9,7 @@ import {
ChevronDown,
ChevronLeft,
ChevronRight,
+ CircleCheck,
MoreHorizontal,
PanelRight,
Pin,
@@ -511,6 +512,23 @@ export function IssueDetail({ issueId, onDelete, defaultSidebarOpen = true, layo
+ {issue.status !== "done" && issue.status !== "cancelled" && (
+
+ handleUpdateField({ status: "done" })}
+ >
+
+
+ }
+ />
+ Mark as done
+
+ )}