diff --git a/packages/shared/src/types/issue.ts b/packages/shared/src/types/issue.ts
index 9ef7f2d4..d55f8e15 100644
--- a/packages/shared/src/types/issue.ts
+++ b/packages/shared/src/types/issue.ts
@@ -143,7 +143,6 @@ export interface Issue {
mentionedProjects?: Project[];
myLastTouchAt?: Date | null;
lastExternalCommentAt?: Date | null;
- lastActivityAt?: Date | null;
isUnreadForMe?: boolean;
createdAt: Date;
updatedAt: Date;
diff --git a/server/src/routes/agents.ts b/server/src/routes/agents.ts
index c2ed8ee2..8ec5ffb1 100644
--- a/server/src/routes/agents.ts
+++ b/server/src/routes/agents.ts
@@ -1075,7 +1075,6 @@ export function agentRoutes(db: Db) {
projectId: issue.projectId,
goalId: issue.goalId,
parentId: issue.parentId,
- lastActivityAt: (issue as typeof issue & { lastActivityAt?: Date | null }).lastActivityAt ?? issue.updatedAt,
updatedAt: issue.updatedAt,
activeRun: issue.activeRun,
})),
diff --git a/ui/src/components/Layout.tsx b/ui/src/components/Layout.tsx
index 69457356..be39adb7 100644
--- a/ui/src/components/Layout.tsx
+++ b/ui/src/components/Layout.tsx
@@ -17,6 +17,7 @@ import { MobileBottomNav } from "./MobileBottomNav";
import { WorktreeBanner } from "./WorktreeBanner";
import { DevRestartBanner } from "./DevRestartBanner";
import { useDialog } from "../context/DialogContext";
+import { GeneralSettingsProvider } from "../context/GeneralSettingsContext";
import { usePanel } from "../context/PanelContext";
import { useCompany } from "../context/CompanyContext";
import { useSidebar } from "../context/SidebarContext";
@@ -265,12 +266,13 @@ export function Layout() {
}, [location.hash, location.pathname, location.search]);
return (
-
+
);
}
diff --git a/ui/src/context/GeneralSettingsContext.tsx b/ui/src/context/GeneralSettingsContext.tsx
new file mode 100644
index 00000000..a3917ed6
--- /dev/null
+++ b/ui/src/context/GeneralSettingsContext.tsx
@@ -0,0 +1,28 @@
+import type { ReactNode } from "react";
+import { createContext, useContext } from "react";
+
+export interface GeneralSettingsContextValue {
+ keyboardShortcutsEnabled: boolean;
+}
+
+const GeneralSettingsContext = createContext({
+ keyboardShortcutsEnabled: false,
+});
+
+export function GeneralSettingsProvider({
+ value,
+ children,
+}: {
+ value: GeneralSettingsContextValue;
+ children: ReactNode;
+}) {
+ return (
+
+ {children}
+
+ );
+}
+
+export function useGeneralSettings() {
+ return useContext(GeneralSettingsContext);
+}
diff --git a/ui/src/lib/inbox.test.ts b/ui/src/lib/inbox.test.ts
index 784e38cb..2cdd8721 100644
--- a/ui/src/lib/inbox.test.ts
+++ b/ui/src/lib/inbox.test.ts
@@ -180,7 +180,6 @@ function makeIssue(id: string, isUnreadForMe: boolean): Issue {
labelIds: [],
myLastTouchAt: new Date("2026-03-11T00:00:00.000Z"),
lastExternalCommentAt: new Date("2026-03-11T01:00:00.000Z"),
- lastActivityAt: new Date("2026-03-11T01:00:00.000Z"),
isUnreadForMe,
};
}
@@ -358,10 +357,10 @@ describe("inbox helpers", () => {
it("mixes approvals into the inbox feed by most recent activity", () => {
const newerIssue = makeIssue("1", true);
- newerIssue.lastActivityAt = new Date("2026-03-11T04:00:00.000Z");
+ newerIssue.lastExternalCommentAt = new Date("2026-03-11T04:00:00.000Z");
const olderIssue = makeIssue("2", false);
- olderIssue.lastActivityAt = new Date("2026-03-11T02:00:00.000Z");
+ olderIssue.lastExternalCommentAt = new Date("2026-03-11T02:00:00.000Z");
const approval = makeApprovalWithTimestamps(
"approval-between",
@@ -386,21 +385,19 @@ describe("inbox helpers", () => {
]);
});
- it("prefers canonical lastActivityAt over comment-only timestamps", () => {
- const activityIssue = makeIssue("1", true);
- activityIssue.lastExternalCommentAt = new Date("2026-03-11T01:00:00.000Z");
- activityIssue.lastActivityAt = new Date("2026-03-11T05:00:00.000Z");
+ it("sorts touched issues by latest external comment timestamp", () => {
+ const newerIssue = makeIssue("1", true);
+ newerIssue.lastExternalCommentAt = new Date("2026-03-11T05:00:00.000Z");
- const commentIssue = makeIssue("2", true);
- commentIssue.lastExternalCommentAt = new Date("2026-03-11T04:00:00.000Z");
- commentIssue.lastActivityAt = new Date("2026-03-11T04:00:00.000Z");
+ const olderIssue = makeIssue("2", true);
+ olderIssue.lastExternalCommentAt = new Date("2026-03-11T04:00:00.000Z");
- expect(getRecentTouchedIssues([commentIssue, activityIssue]).map((issue) => issue.id)).toEqual(["1", "2"]);
+ expect(getRecentTouchedIssues([olderIssue, newerIssue]).map((issue) => issue.id)).toEqual(["1", "2"]);
});
it("mixes join requests into the inbox feed by most recent activity", () => {
const issue = makeIssue("1", true);
- issue.lastActivityAt = new Date("2026-03-11T04:00:00.000Z");
+ issue.lastExternalCommentAt = new Date("2026-03-11T04:00:00.000Z");
const joinRequest = makeJoinRequest("join-1");
joinRequest.createdAt = new Date("2026-03-11T03:00:00.000Z");
@@ -485,7 +482,7 @@ describe("inbox helpers", () => {
it("limits recent touched issues before unread badge counting", () => {
const issues = Array.from({ length: RECENT_ISSUES_LIMIT + 5 }, (_, index) => {
const issue = makeIssue(String(index + 1), index < 3);
- issue.lastActivityAt = new Date(Date.UTC(2026, 2, 31, 0, 0, 0, 0) - index * 60_000);
+ issue.lastExternalCommentAt = new Date(Date.UTC(2026, 2, 31, 0, 0, 0, 0) - index * 60_000);
return issue;
});
diff --git a/ui/src/lib/inbox.ts b/ui/src/lib/inbox.ts
index 9f26e998..647b6bea 100644
--- a/ui/src/lib/inbox.ts
+++ b/ui/src/lib/inbox.ts
@@ -217,9 +217,6 @@ export function normalizeTimestamp(value: string | Date | null | undefined): num
}
export function issueLastActivityTimestamp(issue: Issue): number {
- const lastActivityAt = normalizeTimestamp(issue.lastActivityAt);
- if (lastActivityAt > 0) return lastActivityAt;
-
const lastExternalCommentAt = normalizeTimestamp(issue.lastExternalCommentAt);
if (lastExternalCommentAt > 0) return lastExternalCommentAt;
diff --git a/ui/src/pages/Inbox.test.tsx b/ui/src/pages/Inbox.test.tsx
index adb161c2..10ac47d7 100644
--- a/ui/src/pages/Inbox.test.tsx
+++ b/ui/src/pages/Inbox.test.tsx
@@ -56,7 +56,6 @@ function createIssue(overrides: Partial = {}): Issue {
labelIds: [],
myLastTouchAt: null,
lastExternalCommentAt: null,
- lastActivityAt: new Date("2026-03-11T00:00:00.000Z"),
isUnreadForMe: false,
...overrides,
};
diff --git a/ui/src/pages/Inbox.tsx b/ui/src/pages/Inbox.tsx
index 1a356580..d8bbccfa 100644
--- a/ui/src/pages/Inbox.tsx
+++ b/ui/src/pages/Inbox.tsx
@@ -15,6 +15,7 @@ import { instanceSettingsApi } from "../api/instanceSettings";
import { projectsApi } from "../api/projects";
import { useCompany } from "../context/CompanyContext";
import { useBreadcrumbs } from "../context/BreadcrumbContext";
+import { useGeneralSettings } from "../context/GeneralSettingsContext";
import { queryKeys } from "../lib/queryKeys";
import {
armIssueDetailInboxQuickArchive,
@@ -213,7 +214,7 @@ export function InboxIssueMetaLeading({
}
function issueActivityText(issue: Issue): string {
- return `Updated ${timeAgo(issue.lastActivityAt ?? issue.lastExternalCommentAt ?? issue.updatedAt)}`;
+ return `Updated ${timeAgo(issue.lastExternalCommentAt ?? issue.updatedAt)}`;
}
function issueTrailingGridTemplate(columns: InboxIssueColumn[]): string {
@@ -245,7 +246,7 @@ export function InboxIssueTrailingColumns({
assigneeName: string | null;
currentUserId: string | null;
}) {
- const activityText = timeAgo(issue.lastActivityAt ?? issue.lastExternalCommentAt ?? issue.updatedAt);
+ const activityText = timeAgo(issue.lastExternalCommentAt ?? issue.updatedAt);
const userLabel = formatAssigneeUserLabel(issue.assigneeUserId, currentUserId) ?? "User";
return (
@@ -791,10 +792,7 @@ export function Inbox() {
const location = useLocation();
const queryClient = useQueryClient();
const [actionError, setActionError] = useState(null);
- const keyboardShortcutsEnabled = useQuery({
- queryKey: queryKeys.instance.generalSettings,
- queryFn: () => instanceSettingsApi.getGeneral(),
- }).data?.keyboardShortcuts === true;
+ const { keyboardShortcutsEnabled } = useGeneralSettings();
const { data: experimentalSettings } = useQuery({
queryKey: queryKeys.instance.experimentalSettings,
queryFn: () => instanceSettingsApi.getExperimental(),
@@ -1778,7 +1776,7 @@ export function Inbox() {
,
);