From 4ca26ab2ca75c5718fa7a595595677016b57baf6 Mon Sep 17 00:00:00 2001
From: spoukyii <61633921+spoukyii@users.noreply.github.com>
Date: Thu, 5 Nov 2026 23:56:09 -0800
Subject: [PATCH 1/3] test(web): cover opening a project whose newest threads
are settled or snoozed
---
.../components/CommandPalette.browser.test.tsx | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/apps/web/src/components/CommandPalette.browser.test.tsx b/apps/web/src/components/CommandPalette.browser.test.tsx
index 9faeab83c6ffc..b050f1328651c 100644
--- a/apps/web/src/components/CommandPalette.browser.test.tsx
+++ b/apps/web/src/components/CommandPalette.browser.test.tsx
@@ -46,7 +46,7 @@ describe("CommandPalette open intents", () => {
await expect.element(input).toHaveValue("acme");
});
- it("opens a searched project's latest listed thread, not a newer subagent", async () => {
+ it("opens a searched project's latest listed thread, not a newer subagent or parked thread", async () => {
const environmentId = EnvironmentId.make("local");
const projectId = ProjectId.make("acme");
const parentId = ThreadId.make("parent");
@@ -82,6 +82,20 @@ describe("CommandPalette open intents", () => {
relationshipToParent: "subagent",
},
}),
+ makeThreadFixture({
+ id: ThreadId.make("settled"),
+ environmentId,
+ projectId,
+ latestUserMessageAt: "2026-03-04T00:00:00.000Z",
+ settledOverride: "settled",
+ }),
+ makeThreadFixture({
+ id: ThreadId.make("snoozed"),
+ environmentId,
+ projectId,
+ latestUserMessageAt: "2026-03-05T00:00:00.000Z",
+ snoozedUntil: "2999-01-01T00:00:00.000Z",
+ }),
],
});
await using screen = await render({null});
From 5027d3aa18937593c9d33b933561264b0017fd56 Mon Sep 17 00:00:00 2001
From: spoukyii <61633921+spoukyii@users.noreply.github.com>
Date: Fri, 6 Nov 2026 00:00:31 -0800
Subject: [PATCH 2/3] fix(web): opening a project from the command palette
skips settled and snoozed threads
Picking a project in the command palette opens that project's latest
thread. The candidates dropped archived threads, subagents and side
chats, but still counted threads the user had settled or snoozed, so a
project whose newest thread was parked opened straight back onto it.
Deleting the open thread already skips settled and snoozed threads when
it picks the next one (#29643). The palette now filters its candidates
the same way, settledOverride and effectiveSnoozed at the current time,
for single and grouped projects alike. When every thread is parked it
starts a new thread, as it does for an empty project.
Bug: opening a project from the command palette lands on a settled or snoozed thread
---
apps/web/src/components/CommandPalette.tsx | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/apps/web/src/components/CommandPalette.tsx b/apps/web/src/components/CommandPalette.tsx
index 7c0821678e512..f5fd8a434b5c9 100644
--- a/apps/web/src/components/CommandPalette.tsx
+++ b/apps/web/src/components/CommandPalette.tsx
@@ -163,6 +163,7 @@ import {
} from "../commandPaletteStore";
import { PULL_REQUESTS_PANEL_REF, useRightPanelStore } from "../rightPanelStore";
import { getLatestThreadForProject, sortThreads } from "@t3tools/client-runtime/state/thread-sort";
+import { effectiveSnoozed } from "@t3tools/client-runtime/state/thread-settled";
import {
cn,
getLocalFileManagerName,
@@ -784,9 +785,15 @@ function OpenCommandPaletteDialog(props: {
),
)
: null;
+ // oxlint-disable-next-line react/purity -- runs in an event handler (oxc#27309)
+ const now = new Date().toISOString();
+ // Settled and snoozed threads are parked, so opening a project never lands on one.
+ const openableThreads = threads.filter(
+ (thread) => thread.settledOverride !== "settled" && !effectiveSnoozed(thread, { now }),
+ );
const latestThread = groupedProjectKeys
? (sortThreads(
- threads.filter(
+ openableThreads.filter(
(thread) =>
thread.archivedAt === null &&
groupedProjectKeys.has(`${thread.environmentId}:${thread.projectId}`),
@@ -794,7 +801,7 @@ function OpenCommandPaletteDialog(props: {
clientSettings.sidebarThreadSortOrder,
)[0] ?? null)
: getLatestThreadForProject(
- threads.filter((thread) => thread.environmentId === project.environmentId),
+ openableThreads.filter((thread) => thread.environmentId === project.environmentId),
project.id,
clientSettings.sidebarThreadSortOrder,
);
From e5edca9831c770ef60fa52099187289a0a6ea003 Mon Sep 17 00:00:00 2001
From: Julius Marminge
Date: Sun, 15 Nov 2026 03:05:30 +0000
Subject: [PATCH 3/3] refactor(web): drop restating comment in palette project
navigation
Co-Authored-By: Claude Opus 5.5
---
apps/web/src/components/CommandPalette.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/apps/web/src/components/CommandPalette.tsx b/apps/web/src/components/CommandPalette.tsx
index c34f3ea40aa5d..ec7393427b901 100644
--- a/apps/web/src/components/CommandPalette.tsx
+++ b/apps/web/src/components/CommandPalette.tsx
@@ -819,7 +819,6 @@ function OpenCommandPaletteDialog(props: {
: null;
// oxlint-disable-next-line react/purity -- runs in an event handler (oxc#27309)
const now = new Date().toISOString();
- // Settled and snoozed threads are parked, so opening a project never lands on one.
const openableThreads = threads.filter(
(thread) => thread.settledOverride !== "settled" && !effectiveSnoozed(thread, { now }),
);