- {filteredCommands.length > 0 ? (
-
- {filteredCommands.map((command, index) => {
- const shortcut = shortcutForCommand(command.id, keybindings);
- return (
-
- );
- })}
+
+
+
);
}
-function filterCommands(
- commands: AppCommand[],
+function resultLimit(
+ selectedCategory: EverythingSearchCategory,
+ resultCategory: EverythingSearchSection["category"],
+): number {
+ return selectedCategory === "all" ? ALL_CATEGORY_LIMITS[resultCategory] : CATEGORY_RESULT_LIMIT;
+}
+
+function commandSearchResult(
+ command: AppCommand,
+ kind: "command" | "action",
+ resolveMessage: (value: string | MessageDescriptor) => string,
+ bindings: readonly { command: string }[],
+): EverythingSearchResult {
+ return {
+ key: `${kind}:${command.id}`,
+ kind,
+ command,
+ title: resolveMessage(command.title),
+ subtitle: resolveMessage(command.subtitle ?? command.group),
+ shortcut: shortcutForCommand(command.id, bindings),
+ };
+}
+
+function resolveSettingMatches(
query: string,
- resolve: (value: string | MessageDescriptor) => string,
-): AppCommand[] {
- const normalized = query.trim().toLowerCase();
- if (!normalized) return commands;
- const terms = normalized.split(/\s+/);
- return commands.filter((command) => {
- const haystack = [
- command.id,
- resolve(command.title),
- resolve(command.group),
- command.subtitle ? resolve(command.subtitle) : "",
- ...(command.keywords ?? []),
- ]
- .join(" ")
- .toLowerCase();
- return terms.every((term) => haystack.includes(term));
- });
+ category: EverythingSearchCategory,
+ t: (descriptor: MessageDescriptor) => string,
+): SettingsSearchResult[] {
+ const options = { devMode: isDevApp(), remoteSession: isRemoteSession() };
+ if (query.trim()) return searchSettings(query, t, options);
+ if (category !== "settings") return [];
+ return SETTINGS_SEARCH_INDEX.filter(
+ (entry) =>
+ (!entry.devOnly || options.devMode) && (!entry.desktopOnly || !options.remoteSession),
+ ).map((entry) => ({
+ section: entry.section,
+ anchor: entry.anchor,
+ title: t(entry.title),
+ snippet: entry.description ? t(entry.description) : null,
+ }));
}
function shortcutForCommand(
diff --git a/src/renderer/commands/EverythingSearchResultRow.tsx b/src/renderer/commands/EverythingSearchResultRow.tsx
new file mode 100644
index 000000000..4e931be42
--- /dev/null
+++ b/src/renderer/commands/EverythingSearchResultRow.tsx
@@ -0,0 +1,141 @@
+import { useRef, type ReactNode } from "react";
+import { Button } from "@heroui/react";
+import { useLingui } from "@lingui/react/macro";
+import { useDraggable } from "@dnd-kit/react";
+import { GripVertical } from "lucide-react";
+import type { Project, Thread } from "@/shared/contracts";
+import type { DragSourceData } from "@/renderer/dnd";
+import { ThreadProviderIcon } from "@/renderer/components/providers/ThreadProviderIcon";
+
+interface ResultRowProps {
+ icon: ReactNode;
+ title: string;
+ subtitle?: string | undefined;
+ shortcut?: string | undefined;
+ index: number;
+ isSelected: boolean;
+ onActivate: () => void;
+ onHover: () => void;
+}
+
+export function EverythingSearchResultRow(props: ResultRowProps) {
+ const stateClass = props.isSelected
+ ? "bg-[var(--row-active)] text-foreground"
+ : "text-foreground/85 hover:bg-[var(--row-hover)] hover:text-foreground";
+
+ return (
+
+ );
+}
+
+export function EverythingSearchThreadRow(props: {
+ thread: Thread;
+ project: Project | undefined;
+ index: number;
+ isSelected: boolean;
+ onActivate: () => void;
+ onHover: () => void;
+}) {
+ const { t } = useLingui();
+ const rowRef = useRef
(null);
+
+ const { handleRef } = useDraggable({
+ id: `everything-search:${props.thread.id}`,
+ type: "thread",
+ data: {
+ type: "thread",
+ threadId: props.thread.id,
+ projectId: props.thread.projectId,
+ ...(props.thread.worktreePath != null ? { worktreePath: props.thread.worktreePath } : {}),
+ } satisfies DragSourceData,
+ element: rowRef,
+ });
+
+ const stateClass = props.isSelected
+ ? "bg-[var(--row-active)] text-foreground"
+ : "text-foreground/85 hover:bg-[var(--row-hover)] hover:text-foreground";
+
+ const context = [
+ props.project?.name,
+ props.thread.worktreeBranch ?? props.thread.worktreePath,
+ ].filter((value): value is string => Boolean(value));
+
+ return (
+
+ (
+
+ )}
+ variant="ghost"
+ fullWidth
+ className="h-10 min-w-0 flex-1 justify-start gap-2 rounded-xl bg-transparent px-3 font-normal hover:bg-transparent"
+ onPress={props.onActivate}
+ onPointerMove={props.onHover}
+ >
+
+
+
+ {props.thread.title}
+
+ {context.length > 0 ? (
+
+ {context.join(" · ")}
+
+ ) : null}
+
+
+
+
+
+
+ );
+}
diff --git a/src/renderer/commands/EverythingSearchResults.tsx b/src/renderer/commands/EverythingSearchResults.tsx
new file mode 100644
index 000000000..d0dc08579
--- /dev/null
+++ b/src/renderer/commands/EverythingSearchResults.tsx
@@ -0,0 +1,143 @@
+import { useEffect, useRef, type ReactNode } from "react";
+import { Trans, useLingui } from "@lingui/react/macro";
+import { Command, File as FileIcon, LoaderCircle, Settings, Zap } from "lucide-react";
+import type { Project, ProjectTreeEntry, Thread } from "@/shared/contracts";
+import type { SettingsSearchResult } from "@/renderer/views/SettingsOverlay/parts/settingsSearchIndex";
+import type { AppCommand } from "./registry";
+import type { EverythingSearchCategory } from "./everythingSearch";
+import { EverythingSearchResultRow, EverythingSearchThreadRow } from "./EverythingSearchResultRow";
+
+export type EverythingSearchResult =
+ | { key: string; kind: "thread"; thread: Thread; project: Project | undefined }
+ | {
+ key: string;
+ kind: "command" | "action";
+ command: AppCommand;
+ title: string;
+ subtitle: string;
+ shortcut: string;
+ }
+ | { key: string; kind: "setting"; setting: SettingsSearchResult }
+ | { key: string; kind: "file"; entry: ProjectTreeEntry };
+
+export interface EverythingSearchSection {
+ category: Exclude;
+ label: string;
+ results: EverythingSearchResult[];
+}
+
+export function EverythingSearchResults(props: {
+ sections: EverythingSearchSection[];
+ activeIndex: number;
+ loading: boolean;
+ emptyMessage?: string | undefined;
+ onActivate: (result: EverythingSearchResult) => void;
+ onHover: (index: number) => void;
+}) {
+ const { t } = useLingui();
+ const listRef = useRef(null);
+ const results = props.sections.flatMap((section) => section.results);
+ const activeResultKey = results[props.activeIndex]?.key;
+
+ useEffect(() => {
+ const row = listRef.current?.querySelector(
+ `[data-search-index="${props.activeIndex}"]`,
+ );
+ row?.scrollIntoView({ block: "nearest" });
+ }, [props.activeIndex, activeResultKey]);
+
+ let nextSectionStart = 0;
+ const sectionsWithStart = props.sections.map((section) => {
+ const start = nextSectionStart;
+ nextSectionStart += section.results.length;
+ return { section, start };
+ });
+
+ return (
+
+ {results.length > 0 ? (
+ sectionsWithStart.map(({ section, start }) => {
+ if (section.results.length === 0) return null;
+ return (
+
+
+ {section.label}
+
+ {section.results.map((result, sectionIndex) => {
+ const index = start + sectionIndex;
+ if (result.kind === "thread") {
+ return (
+
props.onActivate(result)}
+ onHover={() => props.onHover(index)}
+ />
+ );
+ }
+ return (
+ props.onActivate(result)}
+ onHover={() => props.onHover(index)}
+ />
+ );
+ })}
+
+ );
+ })
+ ) : props.loading ? (
+
+
+
+ ) : (
+
+ {props.emptyMessage ?? No results}
+
+ )}
+
+ );
+}
+
+function resultIcon(result: Exclude): ReactNode {
+ if (result.kind === "command") return ;
+ if (result.kind === "action") return ;
+ if (result.kind === "setting") return ;
+ return ;
+}
+
+function resultTitle(result: Exclude): string {
+ if (result.kind === "command" || result.kind === "action") return result.title;
+ if (result.kind === "setting") return result.setting.title;
+ if (result.kind !== "file") return "";
+ return result.entry.name;
+}
+
+function resultSubtitle(
+ result: Exclude,
+ settingsLabel: string,
+): string {
+ if (result.kind === "command" || result.kind === "action") return result.subtitle;
+ if (result.kind === "setting") return result.setting.snippet ?? settingsLabel;
+ if (result.kind !== "file") return "";
+ return result.entry.path;
+}
diff --git a/src/renderer/commands/commandPaletteStore.test.ts b/src/renderer/commands/commandPaletteStore.test.ts
new file mode 100644
index 000000000..02ce40964
--- /dev/null
+++ b/src/renderer/commands/commandPaletteStore.test.ts
@@ -0,0 +1,32 @@
+import { afterEach, describe, expect, it } from "vitest";
+import { useCommandPaletteStore } from "./commandPaletteStore";
+
+describe("useCommandPaletteStore", () => {
+ afterEach(() => {
+ document.body.innerHTML = "";
+ useCommandPaletteStore.setState({ isOpen: false, originTarget: null });
+ });
+
+ it("captures the element that owned focus when search opens", () => {
+ document.body.innerHTML = 'Search';
+ const origin = document.getElementById("origin");
+ origin?.focus();
+
+ useCommandPaletteStore.getState().open();
+ document.getElementById("palette")?.focus();
+
+ expect(useCommandPaletteStore.getState().originTarget).toBe(origin);
+ });
+
+ it("does not replace the origin when an open palette is opened again", () => {
+ document.body.innerHTML = 'Search';
+ const origin = document.getElementById("origin");
+ origin?.focus();
+ useCommandPaletteStore.getState().open();
+
+ document.getElementById("palette")?.focus();
+ useCommandPaletteStore.getState().open();
+
+ expect(useCommandPaletteStore.getState().originTarget).toBe(origin);
+ });
+});
diff --git a/src/renderer/commands/commandPaletteStore.ts b/src/renderer/commands/commandPaletteStore.ts
index c02fbb621..df50e7c6a 100644
--- a/src/renderer/commands/commandPaletteStore.ts
+++ b/src/renderer/commands/commandPaletteStore.ts
@@ -1,7 +1,9 @@
import { create } from "zustand";
+import { resolveFocusElement } from "./focusedSurface";
interface CommandPaletteState {
isOpen: boolean;
+ originTarget: Element | null;
open: () => void;
close: () => void;
toggle: () => void;
@@ -9,7 +11,12 @@ interface CommandPaletteState {
export const useCommandPaletteStore = create((set) => ({
isOpen: false,
- open: () => set({ isOpen: true }),
+ originTarget: null,
+ open: () =>
+ set((state) => (state.isOpen ? {} : { isOpen: true, originTarget: resolveFocusElement() })),
close: () => set({ isOpen: false }),
- toggle: () => set((state) => ({ isOpen: !state.isOpen })),
+ toggle: () =>
+ set((state) =>
+ state.isOpen ? { isOpen: false } : { isOpen: true, originTarget: resolveFocusElement() },
+ ),
}));
diff --git a/src/renderer/commands/defaultKeybindings.test.ts b/src/renderer/commands/defaultKeybindings.test.ts
index e2cf2f862..fa95b7507 100644
--- a/src/renderer/commands/defaultKeybindings.test.ts
+++ b/src/renderer/commands/defaultKeybindings.test.ts
@@ -1,4 +1,4 @@
-import { beforeEach, describe, expect, it } from "vitest";
+import { afterEach, beforeEach, describe, expect, it } from "vitest";
import {
COMPOSER_CONTROL_COMMAND_IDS,
DEFAULT_KEYBINDINGS,
@@ -6,6 +6,9 @@ import {
} from "@/shared/keybindings";
import { getCurrentProjectId } from "@/renderer/actions/currentProject";
import { useAppStore } from "@/renderer/state/appStore";
+import { useDevTerminalStore } from "@/renderer/state/devTerminalStore";
+import { useFileEditorStore } from "@/renderer/state/fileEditorStore";
+import { useFindFocusStore } from "@/renderer/state/findFocusStore";
import { bindingForPlatform, canonicalizeKeybinding, type PlatformName } from "./keybindingMatcher";
import { buildCommandRegistry, buildWhenContext } from "./registry";
import { evaluateWhenClause } from "./when";
@@ -112,21 +115,21 @@ describe("default keybindings", () => {
composerFocus: true,
}),
).toBe(false);
- expect(evaluateWhenClause(bindings["thread.search.open"]?.when, idleThreadContext)).toBe(true);
+ expect(evaluateWhenClause(bindings["palette.open"]?.when, idleThreadContext)).toBe(true);
expect(
- evaluateWhenClause(bindings["thread.search.open"]?.when, {
+ evaluateWhenClause(bindings["palette.open"]?.when, {
...idleThreadContext,
panelFocus: true,
}),
).toBe(false);
expect(
- evaluateWhenClause(bindings["thread.search.open"]?.when, {
+ evaluateWhenClause(bindings["palette.open"]?.when, {
...idleThreadContext,
browserFocus: true,
}),
).toBe(false);
expect(
- evaluateWhenClause(bindings["thread.search.open"]?.when, {
+ evaluateWhenClause(bindings["palette.open"]?.when, {
...idleThreadContext,
composerFocus: true,
}),
@@ -235,3 +238,89 @@ describe("default keybindings", () => {
expect(evaluateWhenClause(starCommand?.when, context)).toBe(true);
});
});
+
+describe("command execution context", () => {
+ afterEach(() => {
+ document.body.innerHTML = "";
+ useFileEditorStore.setState({ tabs: [], activePath: null });
+ useFindFocusStore.setState({ settingsFocusToken: 0, treeFocusToken: 0 });
+ useDevTerminalStore.setState({
+ activeProjectId: null,
+ activeWorktreePath: null,
+ tabs: [],
+ activeTabId: null,
+ });
+ });
+
+ it("cycles editor tabs from the originating target after focus moves", () => {
+ document.body.innerHTML = `
+ Editor
+
+ `;
+ const origin = document.getElementById("origin");
+ document.getElementById("palette")?.focus();
+ useFileEditorStore.setState({ tabs: ["one.ts", "two.ts"], activePath: "one.ts" });
+
+ const command = buildCommandRegistry().find((item) => item.id === "tab.next");
+ void command?.run(undefined, { target: origin });
+
+ expect(useFileEditorStore.getState().activePath).toBe("two.ts");
+ });
+
+ it("opens Find on the originating surface after focus moves", () => {
+ document.body.innerHTML = `
+ Settings
+
+ `;
+ const origin = document.getElementById("origin");
+ document.getElementById("palette")?.focus();
+
+ const command = buildCommandRegistry().find((item) => item.id === "find.open");
+ void command?.run(undefined, { target: origin });
+
+ expect(useFindFocusStore.getState().settingsFocusToken).toBe(1);
+ });
+
+ it("cycles terminal tabs from the originating target after focus moves", () => {
+ document.body.innerHTML = `
+ Terminal
+
+ `;
+ const origin = document.getElementById("origin");
+ document.getElementById("palette")?.focus();
+ useDevTerminalStore.setState({
+ activeProjectId: "project-1",
+ activeWorktreePath: null,
+ tabs: [
+ { id: "one", projectId: "project-1", title: "One", createdAt: "2026-01-01" },
+ { id: "two", projectId: "project-1", title: "Two", createdAt: "2026-01-02" },
+ ],
+ activeTabId: "two",
+ });
+
+ const command = buildCommandRegistry().find((item) => item.id === "tab.previous");
+ void command?.run(undefined, { target: origin });
+
+ expect(useDevTerminalStore.getState().activeTabId).toBe("one");
+ });
+
+ it("focuses the address bar in the originating browser instance", () => {
+ document.body.innerHTML = `
+
+ Browser
+
+
+
+ `;
+ const origin = document.getElementById("origin");
+ const address = document.querySelector("[data-poracode-browser-address]");
+ document.getElementById("palette")?.focus();
+
+ const command = buildCommandRegistry().find((item) => item.id === "browser.focus-address-bar");
+ void command?.run(undefined, { target: origin });
+
+ expect(document.activeElement).toBe(address);
+ expect(address?.selectionStart).toBe(0);
+ expect(address?.selectionEnd).toBe(address?.value.length);
+ });
+});
diff --git a/src/renderer/commands/everythingSearch.test.ts b/src/renderer/commands/everythingSearch.test.ts
new file mode 100644
index 000000000..a256f858c
--- /dev/null
+++ b/src/renderer/commands/everythingSearch.test.ts
@@ -0,0 +1,101 @@
+import { describe, expect, it, vi } from "vitest";
+import type { Project, Thread } from "@/shared/contracts";
+import type { AppCommand } from "./registry";
+import { filterCommandsForSearch, filterThreadsForSearch } from "./everythingSearch";
+
+describe("filterThreadsForSearch", () => {
+ const project: Project = {
+ id: "project-1",
+ name: "Poracode",
+ location: { kind: "windows", path: "C:\\repo" },
+ createdAt: "2026-07-15T00:00:00.000Z",
+ };
+ const projects = new Map([[project.id, project]]);
+
+ it("matches thread and project/worktree metadata with AND semantics", () => {
+ const threads = [
+ makeThread({
+ id: "match",
+ title: "Fix file search",
+ worktreeBranch: "feature/everything",
+ }),
+ makeThread({ id: "miss", title: "Fix file search" }),
+ ];
+
+ expect(
+ filterThreadsForSearch(threads, projects, "poracode everything").map((t) => t.id),
+ ).toEqual(["match"]);
+ });
+
+ it("excludes archived threads and keeps starred threads ahead of newer threads", () => {
+ const threads = [
+ makeThread({ id: "new", updatedAt: "2026-07-15T03:00:00.000Z" }),
+ makeThread({ id: "starred", starred: true, updatedAt: "2026-07-14T03:00:00.000Z" }),
+ makeThread({ id: "archived", archived: true, starred: true }),
+ ];
+
+ expect(filterThreadsForSearch(threads, projects, "").map((t) => t.id)).toEqual([
+ "starred",
+ "new",
+ ]);
+ });
+});
+
+describe("filterCommandsForSearch", () => {
+ const resolve = (value: AppCommand["title"]): string =>
+ typeof value === "string" ? value : String(value.message ?? value.id);
+
+ it("keeps project actions out of command results and actions out of command results", () => {
+ const commands = [
+ makeCommand("files.open", "Open Files", "Project"),
+ makeCommand("script.test.run", "Run tests", "Scripts"),
+ ];
+
+ expect(filterCommandsForSearch(commands, "", resolve, "command").map((c) => c.id)).toEqual([
+ "files.open",
+ ]);
+ expect(filterCommandsForSearch(commands, "", resolve, "action").map((c) => c.id)).toEqual([
+ "script.test.run",
+ ]);
+ });
+
+ it("matches every query term across command metadata and hides non-runnable results", () => {
+ const commands = [
+ {
+ ...makeCommand("git.open", "Open review", "Project"),
+ keywords: ["changes"],
+ },
+ { ...makeCommand("palette.open", "Open palette", "Poracode"), showInPalette: false },
+ ];
+
+ expect(
+ filterCommandsForSearch(commands, "project changes", resolve, "command").map(
+ (command) => command.id,
+ ),
+ ).toEqual(["git.open"]);
+ expect(filterCommandsForSearch(commands, "palette", resolve, "command")).toEqual([]);
+ });
+});
+
+function makeThread(overrides: Partial): Thread {
+ return {
+ id: "thread-1",
+ projectId: "project-1",
+ title: "Thread",
+ agentKind: "codex",
+ config: { model: "gpt-5" },
+ status: "idle",
+ attention: "none",
+ canResumeWithConfig: false,
+ archived: false,
+ done: false,
+ starred: false,
+ createdAt: "2026-07-15T00:00:00.000Z",
+ updatedAt: "2026-07-15T00:00:00.000Z",
+ ...overrides,
+ };
+}
+
+function makeCommand(id: string, title: string, group: string): AppCommand {
+ return { id, title, group, run: vi.fn<() => void>() };
+}
diff --git a/src/renderer/commands/everythingSearch.ts b/src/renderer/commands/everythingSearch.ts
new file mode 100644
index 000000000..d96fa7a47
--- /dev/null
+++ b/src/renderer/commands/everythingSearch.ts
@@ -0,0 +1,77 @@
+import type { MessageDescriptor } from "@lingui/core";
+import type { Project, Thread } from "@/shared/contracts";
+import type { AppCommand } from "./registry";
+
+export type EverythingSearchCategory =
+ | "all"
+ | "threads"
+ | "commands"
+ | "settings"
+ | "files"
+ | "actions";
+
+type ResolveMessage = (value: string | MessageDescriptor) => string;
+
+export function filterThreadsForSearch(
+ threads: readonly Thread[],
+ projectsById: ReadonlyMap,
+ query: string,
+): Thread[] {
+ const terms = searchTerms(query);
+ return threads
+ .filter((thread) => {
+ if (thread.archived) return false;
+ const project = projectsById.get(thread.projectId);
+ return matchesTerms(
+ [
+ thread.title,
+ project?.name ?? "",
+ thread.worktreeBranch ?? "",
+ thread.worktreePath ?? "",
+ thread.agentKind,
+ ],
+ terms,
+ );
+ })
+ .toSorted((a, b) => {
+ if (a.starred !== b.starred) return a.starred ? -1 : 1;
+ return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
+ });
+}
+
+export function filterCommandsForSearch(
+ commands: readonly AppCommand[],
+ query: string,
+ resolve: ResolveMessage,
+ kind: "command" | "action",
+): AppCommand[] {
+ const terms = searchTerms(query);
+ return commands.filter((command) => {
+ if (command.showInPalette === false) return false;
+ if (isProjectActionCommand(command) !== (kind === "action")) return false;
+ return matchesTerms(
+ [
+ command.id,
+ resolve(command.title),
+ resolve(command.group),
+ command.subtitle ? resolve(command.subtitle) : "",
+ ...(command.keywords ?? []),
+ ],
+ terms,
+ );
+ });
+}
+
+export function isProjectActionCommand(command: Pick): boolean {
+ return command.id.startsWith("script.") && command.id.endsWith(".run");
+}
+
+function searchTerms(query: string): string[] {
+ return query.trim().toLocaleLowerCase().split(/\s+/u).filter(Boolean);
+}
+
+function matchesTerms(values: readonly string[], terms: readonly string[]): boolean {
+ if (terms.length === 0) return true;
+ const haystack = values.join(" ").toLocaleLowerCase();
+ return terms.every((term) => haystack.includes(term));
+}
diff --git a/src/renderer/commands/focusedSurface.ts b/src/renderer/commands/focusedSurface.ts
index 9819d3b39..b6499c39d 100644
--- a/src/renderer/commands/focusedSurface.ts
+++ b/src/renderer/commands/focusedSurface.ts
@@ -7,6 +7,11 @@
const EDITOR_FOCUS_SELECTOR = ".monaco-editor";
const TERMINAL_FOCUS_SELECTOR = ".xterm";
+export function resolveFocusElement(target?: EventTarget | null): Element | null {
+ const element = target instanceof Element ? target : document.activeElement;
+ return element instanceof Element ? element : null;
+}
+
/** True when `element` is inside a Monaco editor surface. */
export function isEditorFocusElement(element: Element | null | undefined): boolean {
return Boolean(element?.closest(EDITOR_FOCUS_SELECTOR));
diff --git a/src/renderer/commands/registry.ts b/src/renderer/commands/registry.ts
index 4ede8de0e..da8dc1fca 100644
--- a/src/renderer/commands/registry.ts
+++ b/src/renderer/commands/registry.ts
@@ -33,13 +33,16 @@ import { cycleRecentThread } from "@/renderer/actions/recentThreadCycle";
import { useAppStore } from "@/renderer/state/appStore";
import { useDevTerminalStore } from "@/renderer/state/devTerminalStore";
import { useFileEditorStore } from "@/renderer/state/fileEditorStore";
-import { usePanelStore } from "@/renderer/state/panelStore";
import { useSharedSettings } from "@/renderer/state/sharedSettingsStore";
import { toggleSidebar } from "@/renderer/state/sidebarOverlayStore";
import { useSidebarUiStore } from "@/renderer/state/sidebarUiStore";
import { startShellWithToast, writeScriptToShell } from "@/renderer/utils/shellUtils";
import { openFindForActiveSurface } from "@/renderer/components/find/findController";
-import { isEditorFocusElement, isTerminalFocusElement } from "./focusedSurface";
+import {
+ isEditorFocusElement,
+ isTerminalFocusElement,
+ resolveFocusElement,
+} from "./focusedSurface";
import { useCommandPaletteStore } from "./commandPaletteStore";
import type { CommandWhenContext } from "./when";
import { evaluateWhenClause } from "./when";
@@ -60,7 +63,14 @@ export interface AppCommand {
*/
keys?: string[];
showInShortcuts?: boolean;
- run: (args?: unknown) => void | Promise;
+ /** Hide commands that should not be offered as executable palette results. */
+ showInPalette?: boolean;
+ run: (args?: unknown, context?: AppCommandExecutionContext) => void | Promise;
+}
+
+export interface AppCommandExecutionContext {
+ /** The element that owned focus before a command surface took it. */
+ target: EventTarget | null;
}
interface ActiveContext {
@@ -78,7 +88,7 @@ export function buildWhenContext(
const terminal = useDevTerminalStore.getState();
const paletteOpen = useCommandPaletteStore.getState().isOpen;
const active = resolveActiveContext();
- const element = target instanceof Element ? target : document.activeElement;
+ const element = resolveFocusElement(target);
const inputFocus = isTextInputElement(element);
const editorFocus = isEditorFocusElement(element);
const terminalFocus = isTerminalFocusElement(element);
@@ -124,8 +134,9 @@ function baseCommands(): AppCommand[] {
return [
{
id: "palette.open",
- title: msg`Open Command Palette`,
+ title: msg`Search`,
group: "Poracode",
+ showInPalette: false,
run: () => useCommandPaletteStore.getState().open(),
},
{
@@ -148,7 +159,7 @@ function baseCommands(): AppCommand[] {
subtitle: msg`Search the current view`,
group: "Poracode",
keywords: ["find", "search", "filter"],
- run: openFindForActiveSurface,
+ run: (_args, context) => openFindForActiveSurface(context?.target),
},
{
id: "sidebar.toggle",
@@ -196,9 +207,11 @@ function baseCommands(): AppCommand[] {
},
{
id: "thread.search.open",
- title: msg`Search Threads`,
- group: msg`Thread`,
- run: () => usePanelStore.getState().openThreadSearch(),
+ title: msg`Search`,
+ group: "Poracode",
+ showInPalette: false,
+ showInShortcuts: false,
+ run: () => useCommandPaletteStore.getState().open(),
},
{
id: "thread.archive",
@@ -303,6 +316,7 @@ function baseCommands(): AppCommand[] {
title: msg`Run Terminal Command`,
group: msg`Terminal`,
when: "hasProject",
+ showInPalette: false,
run: (args) => runTerminalCommand(args),
},
{
@@ -388,7 +402,7 @@ function baseCommands(): AppCommand[] {
// same chords elsewhere but stand down inside the editor/terminal (see
// their `when`), leaving them free here.
when: "editorFocus || terminalFocus",
- run: () => switchFocusedSurfaceTab("next"),
+ run: (_args, context) => switchFocusedSurfaceTab("next", context?.target),
},
{
id: "tab.previous",
@@ -396,7 +410,7 @@ function baseCommands(): AppCommand[] {
subtitle: msg`Switch to the previous tab`,
group: "Poracode",
when: "editorFocus || terminalFocus",
- run: () => switchFocusedSurfaceTab("previous"),
+ run: (_args, context) => switchFocusedSurfaceTab("previous", context?.target),
},
{
id: "browser.focus-address-bar",
@@ -406,7 +420,7 @@ function baseCommands(): AppCommand[] {
// Only while the in-app browser holds focus — same scope as the other
// browser shortcuts, and avoids swallowing Ctrl+L elsewhere in the app.
when: "browserFocus",
- run: focusBrowserAddressBar,
+ run: (_args, context) => focusBrowserAddressBar(context?.target),
},
{
id: "browser.toggle",
@@ -504,24 +518,26 @@ function openNewBrowserTab(): void {
.catch(() => {});
}
-function focusBrowserAddressBar(): void {
+function focusBrowserAddressBar(target?: EventTarget | null): void {
// The browser panel can be mounted twice (right panel + overlay), so target
- // the address bar inside the browser that currently holds focus, falling back
- // to the first mounted instance.
- const active = document.activeElement;
+ // the address bar inside the browser where the command originated, falling
+ // back to the active or first mounted instance.
+ const active = resolveFocusElement(target);
const container =
- (active instanceof Element ? active.closest("[data-poracode-browser]") : null) ??
- document.querySelector("[data-poracode-browser]");
+ active?.closest("[data-poracode-browser]") ?? document.querySelector("[data-poracode-browser]");
const input = container?.querySelector("[data-poracode-browser-address]");
if (!input) return;
input.focus();
input.select();
}
-function switchFocusedSurfaceTab(direction: "next" | "previous"): void {
- // The binding's `when` (editorFocus || terminalFocus) guarantees one of these
- // surfaces holds focus when this runs; cycle that surface's own tab strip.
- const element = document.activeElement;
+function switchFocusedSurfaceTab(
+ direction: "next" | "previous",
+ target?: EventTarget | null,
+): void {
+ // The command's availability context guarantees one of these surfaces owned
+ // focus when invoked; cycle that originating surface's own tab strip.
+ const element = resolveFocusElement(target);
if (isTerminalFocusElement(element)) {
useDevTerminalStore.getState().cycleTab(direction);
return;
diff --git a/src/renderer/commands/shortcutCatalog.test.ts b/src/renderer/commands/shortcutCatalog.test.ts
index 68059e999..9176e409a 100644
--- a/src/renderer/commands/shortcutCatalog.test.ts
+++ b/src/renderer/commands/shortcutCatalog.test.ts
@@ -361,10 +361,11 @@ describe("shortcut catalog", () => {
translate,
);
- // `terminal.toggle` (group "Terminal") and `thread.search.open` (group
- // "Thread", no `when`) categorize purely off their group token.
+ // `terminal.toggle` is terminal-scoped by its group, while the unified
+ // search command is global and the legacy thread-search alias stays hidden.
expect(rows.find((row) => row.id === "terminal.toggle")?.contexts).toContain("terminal");
- expect(rows.find((row) => row.id === "thread.search.open")?.contexts).toContain("thread");
+ expect(rows.find((row) => row.id === "palette.open")?.contexts).toContain("global");
+ expect(rows.find((row) => row.id === "thread.search.open")).toBeUndefined();
});
it("does not show conflicting shortcuts inside a context", () => {
diff --git a/src/renderer/commands/useEverythingFileSearch.ts b/src/renderer/commands/useEverythingFileSearch.ts
new file mode 100644
index 000000000..4435b1fdd
--- /dev/null
+++ b/src/renderer/commands/useEverythingFileSearch.ts
@@ -0,0 +1,88 @@
+import { useEffect, useState } from "react";
+import type { Project, ProjectTreeEntry } from "@/shared/contracts";
+import { resolveSearchConfig } from "@/shared/searchExclude";
+import { readBridge } from "@/renderer/bridge";
+import { useSharedSettings } from "@/renderer/state/sharedSettingsStore";
+import { buildFileEditorContext, resolveWorktreeBranch } from "@/renderer/utils/gitHelpers";
+
+interface FileSearchState {
+ entries: ProjectTreeEntry[];
+ loading: boolean;
+ failed: boolean;
+}
+
+const EMPTY_STATE: FileSearchState = { entries: [], loading: false, failed: false };
+
+export function useEverythingFileSearch(input: {
+ project: Project | undefined;
+ worktreePath: string | undefined;
+ worktreeBranch: string | undefined;
+ query: string;
+ enabled: boolean;
+}): FileSearchState {
+ const globalUseIgnoreFiles = useSharedSettings((state) => state.searchUseIgnoreFiles);
+ const globalExclude = useSharedSettings((state) => state.searchExclude);
+ const [state, setState] = useState(EMPTY_STATE);
+
+ useEffect(() => {
+ const trimmed = input.query.trim();
+ if (!input.enabled || !input.project || !trimmed) {
+ setState(EMPTY_STATE);
+ return;
+ }
+
+ const project = input.project;
+ const context = buildFileEditorContext(
+ project,
+ input.worktreePath,
+ input.worktreePath
+ ? resolveWorktreeBranch(project.id, input.worktreePath, input.worktreeBranch)
+ : undefined,
+ );
+ const searchConfig = resolveSearchConfig({
+ globalUseIgnoreFiles,
+ globalExclude,
+ projectUseIgnoreFiles: project.searchSettings?.useIgnoreFiles,
+ projectExclude: project.searchSettings?.exclude,
+ });
+ let cancelled = false;
+ setState({ entries: [], loading: true, failed: false });
+
+ const handle = window.setTimeout(() => {
+ void readBridge()
+ .searchProjectTree({
+ projectLocation: context.projectLocation,
+ query: trimmed,
+ limit: 80,
+ entryType: "file",
+ searchConfig,
+ })
+ .then((result) => {
+ if (cancelled) return;
+ setState({
+ entries: result.entries,
+ loading: false,
+ failed: false,
+ });
+ })
+ .catch(() => {
+ if (!cancelled) setState({ entries: [], loading: false, failed: true });
+ });
+ }, 120);
+
+ return () => {
+ cancelled = true;
+ window.clearTimeout(handle);
+ };
+ }, [
+ input.enabled,
+ input.project,
+ input.query,
+ input.worktreeBranch,
+ input.worktreePath,
+ globalExclude,
+ globalUseIgnoreFiles,
+ ]);
+
+ return state;
+}
diff --git a/src/renderer/components/find/findController.test.ts b/src/renderer/components/find/findController.test.ts
index bf1287b4c..573f53460 100644
--- a/src/renderer/components/find/findController.test.ts
+++ b/src/renderer/components/find/findController.test.ts
@@ -1,8 +1,9 @@
import { afterEach, describe, expect, it } from "vitest";
import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
import { useAppStore } from "@/renderer/state/appStore";
+import { useFindFocusStore } from "@/renderer/state/findFocusStore";
import { usePanelStore } from "@/renderer/state/panelStore";
-import { resolveFindTarget } from "./findController";
+import { openFindForActiveSurface, resolveFindTarget } from "./findController";
function resetFindRoutingState(): void {
document.body.innerHTML = "";
@@ -12,11 +13,11 @@ function resetFindRoutingState(): void {
projectSettingsId: null,
gitOverlayOpen: false,
prReviewContext: null,
- threadSearchOpen: false,
createProjectModalOpen: false,
cloneProjectModalOpen: false,
});
useAppStore.setState({ view: { kind: "home" } });
+ useFindFocusStore.setState({ settingsFocusToken: 0, treeFocusToken: 0 });
}
describe("resolveFindTarget", () => {
@@ -44,4 +45,20 @@ describe("resolveFindTarget", () => {
expect(resolveFindTarget()).toBeNull();
});
+
+ it("routes from a provided originating target after focus moves", () => {
+ document.body.innerHTML = `
+ Setting
+
+ `;
+ const origin = document.getElementById("origin");
+ document.getElementById("palette")?.focus();
+ useCommandPaletteStore.setState({ isOpen: true });
+
+ expect(resolveFindTarget()).toBeNull();
+ expect(resolveFindTarget(origin)).toBe("settings");
+
+ openFindForActiveSurface(origin);
+ expect(useFindFocusStore.getState().settingsFocusToken).toBe(1);
+ });
});
diff --git a/src/renderer/components/find/findController.ts b/src/renderer/components/find/findController.ts
index b9b3ff259..5e29d2c14 100644
--- a/src/renderer/components/find/findController.ts
+++ b/src/renderer/components/find/findController.ts
@@ -5,7 +5,11 @@ import { useFindFocusStore } from "@/renderer/state/findFocusStore";
import { useGitFindStore } from "@/renderer/state/gitFindStore";
import { usePanelStore } from "@/renderer/state/panelStore";
import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
-import { isEditorFocusElement, isTerminalFocusElement } from "@/renderer/commands/focusedSurface";
+import {
+ isEditorFocusElement,
+ isTerminalFocusElement,
+ resolveFocusElement,
+} from "@/renderer/commands/focusedSurface";
import { openEditorFind } from "./editorFindBridge";
import { openTerminalFind } from "./terminalFindBridge";
@@ -18,8 +22,8 @@ export type FindTarget = "editor" | "terminal" | "settings" | "git" | "tree" | "
* fallback. Returns null when nothing is searchable (e.g. a blocking modal owns
* its own input, or the home view).
*/
-export function resolveFindTarget(): FindTarget | null {
- const element = document.activeElement instanceof Element ? document.activeElement : null;
+export function resolveFindTarget(target?: EventTarget | null): FindTarget | null {
+ const element = resolveFocusElement(target);
if (isEditorFocusElement(element)) return "editor";
if (isTerminalFocusElement(element)) return "terminal";
const scope = element
@@ -34,7 +38,6 @@ export function resolveFindTarget(): FindTarget | null {
// Blocking modals trap their own input — leave Ctrl+F to them.
if (
useCommandPaletteStore.getState().isOpen ||
- panel.threadSearchOpen ||
panel.createProjectModalOpen ||
panel.cloneProjectModalOpen
) {
@@ -48,8 +51,8 @@ export function resolveFindTarget(): FindTarget | null {
}
/** Entry point for the `find.open` command: open Find on the active surface. */
-export function openFindForActiveSurface(): void {
- const target = resolveFindTarget();
+export function openFindForActiveSurface(originTarget?: EventTarget | null): void {
+ const target = resolveFindTarget(originTarget);
if (!target) return;
switch (target) {
case "editor":
diff --git a/src/renderer/devBridge.ts b/src/renderer/devBridge.ts
index f0cfe9c09..d88e81ab7 100644
--- a/src/renderer/devBridge.ts
+++ b/src/renderer/devBridge.ts
@@ -12,6 +12,7 @@
*/
import { useAppStore } from "@/renderer/state/appStore";
import { useAgentStatusesStore } from "@/renderer/state/agentStatusesStore";
+import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
import { usePanelStore } from "@/renderer/state/panelStore";
import { useSharedSettings } from "@/renderer/state/sharedSettingsStore";
import { useSidebarUiStore } from "@/renderer/state/sidebarUiStore";
@@ -31,6 +32,7 @@ export function installDevBridge(): void {
update: useUpdateStore,
app: useAppStore,
agentStatuses: useAgentStatusesStore,
+ commandPalette: useCommandPaletteStore,
panel: usePanelStore,
sidebarUi: useSidebarUiStore,
sharedSettings: useSharedSettings,
diff --git a/src/renderer/locales/de/messages.po b/src/renderer/locales/de/messages.po
index 7cd1b4439..e8bd14dab 100644
--- a/src/renderer/locales/de/messages.po
+++ b/src/renderer/locales/de/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Aktionsname"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "KI-Anbieter"
msgid "Alerts when threads need you"
msgstr "Benachrichtigungen, wenn Threads dich brauchen"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Scanner schließen"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Suche schließen"
@@ -2048,8 +2049,6 @@ msgstr "Terminal-Composer einklappen"
msgid "Collapse todo dock"
msgstr "Aufgaben-Dock einklappen"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Befehl"
@@ -3648,6 +3647,10 @@ msgstr "Die Datei ist zu groß für die Vorschau."
msgid "File no longer exists on disk."
msgstr "Die Datei ist nicht mehr auf der Festplatte vorhanden."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "Die Dateisuche ist nicht verfügbar"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "Die Datei verwendet eine nicht unterstützte Codierung."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Dateien"
@@ -5243,6 +5247,11 @@ msgstr "Browser in Fenster verschieben"
msgid "Move changes to a new worktree"
msgstr "Änderungen in einen neuen Arbeitsbaum verschieben"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Thread {0} verschieben"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Verschieben Sie das ToDo-Dock in den rechten Bereich"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "Für diese PR wurden keine Checks gemeldet."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Keine Befehle gefunden"
+#~ msgid "No commands found"
+#~ msgstr "Keine Befehle gefunden"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "Keine passenden Zeitpläne."
#~ msgstr "Keine passenden Aufgaben."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Keine passenden Threads"
@@ -5757,6 +5765,7 @@ msgstr "Noch keine Remote-Umgebungen verbunden."
msgid "No repositories found."
msgstr "Keine Repositorys gefunden."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "Kein Thread ausgewählt"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Keine Threads"
+#~ msgid "No threads"
+#~ msgstr "Keine Threads"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Offene Prüfung"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Öffnen Sie die Befehlspalette"
+#~ msgid "Open Command Palette"
+#~ msgstr "Öffnen Sie die Befehlspalette"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Scrollgeschwindigkeitsmultiplikator für den Terminal-Scrollback-Puffer.
msgid "Scroll to bottom"
msgstr "Nach unten scrollen"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Die aktuelle Ansicht durchsuchen"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Threads durchsuchen"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Threads durchsuchen"
+#~ msgid "Search Threads"
+#~ msgstr "Threads durchsuchen"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Suchen…"
@@ -7914,6 +7925,7 @@ msgstr "Gerät auswählen"
msgid "Select model"
msgstr "Modell auswählen"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Projekt auswählen"
@@ -7970,6 +7982,8 @@ msgstr "Tastenkürzel festlegen"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Sortierreihenfolge der Threads"
msgid "Thread todo dock"
msgstr "Thread-Aufgaben-Dock"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Threads"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Typ"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Geben Sie einen Befehl ein"
+#~ msgid "Type a command"
+#~ msgstr "Geben Sie einen Befehl ein"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "In die Seite tippen"
msgid "Type into the page (tap a field first)"
msgstr "In die Seite tippen (zuerst ein Feld antippen)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Zum Suchen von Dateien Text eingeben"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/en/messages.po b/src/renderer/locales/en/messages.po
index f6bd67292..7bc0703dd 100644
--- a/src/renderer/locales/en/messages.po
+++ b/src/renderer/locales/en/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Action name"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "AI providers"
msgid "Alerts when threads need you"
msgstr "Alerts when threads need you"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Close scanner"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Close search"
@@ -2048,8 +2049,6 @@ msgstr "Collapse terminal composer"
msgid "Collapse todo dock"
msgstr "Collapse todo dock"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Command"
@@ -3648,6 +3647,10 @@ msgstr "File is too large to preview."
msgid "File no longer exists on disk."
msgstr "File no longer exists on disk."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "File search unavailable"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "File uses an unsupported encoding."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Files"
@@ -5243,6 +5247,11 @@ msgstr "Move browser to window"
msgid "Move changes to a new worktree"
msgstr "Move changes to a new worktree"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Move thread {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Move todo dock to right panel"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "No checks reported for this PR."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "No commands found"
+#~ msgid "No commands found"
+#~ msgstr "No commands found"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "No matching schedules."
#~ msgstr "No matching tasks."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "No matching threads"
@@ -5757,6 +5765,7 @@ msgstr "No remote environments connected yet."
msgid "No repositories found."
msgstr "No repositories found."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "No thread selected"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "No threads"
+#~ msgid "No threads"
+#~ msgstr "No threads"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Open check"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Open Command Palette"
+#~ msgid "Open Command Palette"
+#~ msgstr "Open Command Palette"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Scroll speed multiplier for the terminal scrollback buffer."
msgid "Scroll to bottom"
msgstr "Scroll to bottom"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Search the current view"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Search threads"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Search Threads"
+#~ msgid "Search Threads"
+#~ msgstr "Search Threads"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Search…"
@@ -7914,6 +7925,7 @@ msgstr "Select device"
msgid "Select model"
msgstr "Select model"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Select project"
@@ -7970,6 +7982,8 @@ msgstr "Set shortcut"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Thread sort order"
msgid "Thread todo dock"
msgstr "Thread todo dock"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Threads"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Type"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Type a command"
+#~ msgid "Type a command"
+#~ msgstr "Type a command"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Type into the page"
msgid "Type into the page (tap a field first)"
msgstr "Type into the page (tap a field first)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Type to search files"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/es/messages.po b/src/renderer/locales/es/messages.po
index 8738a1f3a..738649a2c 100644
--- a/src/renderer/locales/es/messages.po
+++ b/src/renderer/locales/es/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Nombre de la acción"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Proveedores de IA"
msgid "Alerts when threads need you"
msgstr "Alertas cuando los hilos necesitan tu atención"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Cerrar escáner"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Cerrar búsqueda"
@@ -2048,8 +2049,6 @@ msgstr "Contraer el redactor del terminal"
msgid "Collapse todo dock"
msgstr "Contraer panel de tareas"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Comando"
@@ -3648,6 +3647,10 @@ msgstr "El archivo es demasiado grande para previsualizar."
msgid "File no longer exists on disk."
msgstr "El archivo ya no existe en el disco."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "La búsqueda de archivos no está disponible"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "El archivo usa una codificación no compatible."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Archivos"
@@ -5243,6 +5247,11 @@ msgstr "Mover navegador a una ventana"
msgid "Move changes to a new worktree"
msgstr "Mover cambios a un nuevo worktree"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Mover hilo {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Mover el dock de tareas al panel derecho"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "No se reportaron comprobaciones para este PR."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "No se encontraron comandos"
+#~ msgid "No commands found"
+#~ msgstr "No se encontraron comandos"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "No hay programaciones coincidentes."
#~ msgstr "No hay tareas coincidentes."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "No hay hilos coincidentes"
@@ -5757,6 +5765,7 @@ msgstr "Todavía no hay entornos remotos conectados."
msgid "No repositories found."
msgstr "No se encontraron repositorios."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "No hay hilo seleccionado"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Sin hilos"
+#~ msgid "No threads"
+#~ msgstr "Sin hilos"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Abrir comprobación"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Abrir paleta de comandos"
+#~ msgid "Open Command Palette"
+#~ msgstr "Abrir paleta de comandos"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Multiplicador de la velocidad de desplazamiento del búfer de historial
msgid "Scroll to bottom"
msgstr "Desplazar al final"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Buscar en la vista actual"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Buscar hilos"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Buscar hilos"
+#~ msgid "Search Threads"
+#~ msgstr "Buscar hilos"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Buscar…"
@@ -7914,6 +7925,7 @@ msgstr "Seleccionar dispositivo"
msgid "Select model"
msgstr "Seleccionar modelo"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Seleccionar proyecto"
@@ -7970,6 +7982,8 @@ msgstr "Asignar atajo"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Orden de los hilos"
msgid "Thread todo dock"
msgstr "Panel de tareas del hilo"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Hilos"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Tipo"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Escribe un comando"
+#~ msgid "Type a command"
+#~ msgstr "Escribe un comando"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Escribir en la página"
msgid "Type into the page (tap a field first)"
msgstr "Escribe en la página (toca primero un campo)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Escribe para buscar archivos"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/fr/messages.po b/src/renderer/locales/fr/messages.po
index e0202ca50..dc3fc1923 100644
--- a/src/renderer/locales/fr/messages.po
+++ b/src/renderer/locales/fr/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Nom de l'action"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Fournisseurs d'IA"
msgid "Alerts when threads need you"
msgstr "Alertes lorsque les fils ont besoin de vous"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Fermer le scanner"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Fermer la recherche"
@@ -2048,8 +2049,6 @@ msgstr "Réduire le compositeur du terminal"
msgid "Collapse todo dock"
msgstr "Réduire le dock des tâches"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Commande"
@@ -3648,6 +3647,10 @@ msgstr "Le fichier est trop volumineux pour être prévisualisé."
msgid "File no longer exists on disk."
msgstr "Le fichier n'existe plus sur le disque."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "La recherche de fichiers est indisponible"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "Le fichier utilise un encodage non pris en charge."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Fichiers"
@@ -5242,6 +5246,11 @@ msgstr "Déplacer le navigateur vers une fenêtre"
msgid "Move changes to a new worktree"
msgstr "Déplacer les modifications vers un nouvel arbre de travail"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Déplacer le fil de discussion {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Déplacer le dock Todo vers le panneau de droite"
@@ -5551,8 +5560,8 @@ msgid "No checks reported for this PR."
msgstr "Aucun contrôle signalé pour cette PR."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Aucune commande trouvée"
+#~ msgid "No commands found"
+#~ msgstr "Aucune commande trouvée"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5665,7 +5674,6 @@ msgstr "Aucune planification correspondante."
#~ msgstr "Aucune tâche correspondante."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Aucun fil correspondant"
@@ -5756,6 +5764,7 @@ msgstr "Aucun environnement distant n’est encore connecté."
msgid "No repositories found."
msgstr "Aucun dépôt trouvé."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5811,8 +5820,8 @@ msgid "No thread selected"
msgstr "Aucun fil sélectionné"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Aucun fil de discussion"
+#~ msgid "No threads"
+#~ msgstr "Aucun fil de discussion"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6030,8 +6039,8 @@ msgid "Open check"
msgstr "Ouvrir la vérification"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Ouvrir la palette de commandes"
+#~ msgid "Open Command Palette"
+#~ msgstr "Ouvrir la palette de commandes"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7708,6 +7717,9 @@ msgstr "Multiplicateur de vitesse de défilement pour le tampon de défilement d
msgid "Scroll to bottom"
msgstr "Faire défiler vers le bas"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7810,15 +7822,14 @@ msgstr "Rechercher dans la vue actuelle"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Rechercher des fils"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Rechercher des fils"
+#~ msgid "Search Threads"
+#~ msgstr "Rechercher des fils"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Rechercher…"
@@ -7913,6 +7924,7 @@ msgstr "Sélectionner un appareil"
msgid "Select model"
msgstr "Sélectionnez le modèle"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Sélectionnez un projet"
@@ -7969,6 +7981,8 @@ msgstr "Définir un raccourci"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9211,9 +9225,9 @@ msgstr "Ordre de tri des fils de discussion"
msgid "Thread todo dock"
msgstr "Dock des tâches du fil"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Fils de discussion"
@@ -9376,8 +9390,8 @@ msgid "Type"
msgstr "Type"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Tapez une commande"
+#~ msgid "Type a command"
+#~ msgstr "Tapez une commande"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9387,6 +9401,10 @@ msgstr "Saisir dans la page"
msgid "Type into the page (tap a field first)"
msgstr "Saisir dans la page (touchez d'abord un champ)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Saisissez du texte pour rechercher des fichiers"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/ja/messages.po b/src/renderer/locales/ja/messages.po
index f3a43bac8..c094efa22 100644
--- a/src/renderer/locales/ja/messages.po
+++ b/src/renderer/locales/ja/messages.po
@@ -567,6 +567,7 @@ msgid "Action name"
msgstr "アクション名"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -847,6 +848,7 @@ msgstr "AI プロバイダー"
msgid "Alerts when threads need you"
msgstr "スレッドが対応を必要としたら通知"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1945,7 +1947,6 @@ msgid "Close scanner"
msgstr "スキャナーを閉じる"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "検索を閉じる"
@@ -2047,8 +2048,6 @@ msgstr "ターミナルコンポーザーを折りたたむ"
msgid "Collapse todo dock"
msgstr "todo ドックを折りたたむ"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "コマンド"
@@ -3647,6 +3646,10 @@ msgstr "ファイルが大きすぎてプレビューできません。"
msgid "File no longer exists on disk."
msgstr "ファイルはディスク上に存在しません。"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "ファイル検索を利用できません"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3660,6 +3663,7 @@ msgid "File uses an unsupported encoding."
msgstr "ファイルはサポートされていないエンコーディングを使用しています。"
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "ファイル"
@@ -5241,6 +5245,11 @@ msgstr "ブラウザーをウィンドウに移動"
msgid "Move changes to a new worktree"
msgstr "変更を新しいワークツリーに移動する"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "スレッド「{0}」を移動"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Todo ドックを右側のパネルに移動します"
@@ -5550,8 +5559,8 @@ msgid "No checks reported for this PR."
msgstr "この PR についてはチェックが報告されていません。"
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "コマンドが見つかりません"
+#~ msgid "No commands found"
+#~ msgstr "コマンドが見つかりません"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5664,7 +5673,6 @@ msgstr "一致するスケジュールはありません。"
#~ msgstr "一致するタスクはありません。"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "一致するスレッドがありません"
@@ -5755,6 +5763,7 @@ msgstr "接続済みのリモート環境はまだありません。"
msgid "No repositories found."
msgstr "リポジトリが見つかりません。"
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5810,8 +5819,8 @@ msgid "No thread selected"
msgstr "スレッドが選択されていません"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "スレッドがありません"
+#~ msgid "No threads"
+#~ msgstr "スレッドがありません"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6029,8 +6038,8 @@ msgid "Open check"
msgstr "チェックを開く"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "コマンドパレットを開く"
+#~ msgid "Open Command Palette"
+#~ msgstr "コマンドパレットを開く"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7707,6 +7716,9 @@ msgstr "端末のスクロールバック バッファのスクロール速度
msgid "Scroll to bottom"
msgstr "一番下までスクロール"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7809,15 +7821,14 @@ msgstr "現在のビューを検索"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "スレッドを検索する"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "スレッドの検索"
+#~ msgid "Search Threads"
+#~ msgstr "スレッドの検索"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "検索…"
@@ -7912,6 +7923,7 @@ msgstr "デバイスを選択"
msgid "Select model"
msgstr "モデルを選択してください"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "プロジェクトの選択"
@@ -7968,6 +7980,8 @@ msgstr "ショートカットを設定"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9210,9 +9224,9 @@ msgstr "スレッドのソート順"
msgid "Thread todo dock"
msgstr "スレッドのやることドック"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "スレッド"
@@ -9375,8 +9389,8 @@ msgid "Type"
msgstr "タイプ"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "コマンドを入力してください"
+#~ msgid "Type a command"
+#~ msgstr "コマンドを入力してください"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9386,6 +9400,10 @@ msgstr "ページに入力"
msgid "Type into the page (tap a field first)"
msgstr "ページに入力(先にフィールドをタップ)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "入力してファイルを検索"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/ko/messages.po b/src/renderer/locales/ko/messages.po
index b0cec78ae..3331770d8 100644
--- a/src/renderer/locales/ko/messages.po
+++ b/src/renderer/locales/ko/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "액션 이름"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "AI 공급자"
msgid "Alerts when threads need you"
msgstr "스레드에 응답이 필요할 때 알림"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "스캐너 닫기"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "검색 닫기"
@@ -2048,8 +2049,6 @@ msgstr "터미널 작성기 접기"
msgid "Collapse todo dock"
msgstr "할 일 도크 접기"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "명령"
@@ -3648,6 +3647,10 @@ msgstr "파일이 너무 커서 미리 볼 수 없습니다."
msgid "File no longer exists on disk."
msgstr "파일이 더 이상 디스크에 존재하지 않습니다."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "파일 검색을 사용할 수 없습니다"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "파일이 지원되지 않는 인코딩을 사용합니다."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "파일"
@@ -5243,6 +5247,11 @@ msgstr "브라우저를 창으로 이동"
msgid "Move changes to a new worktree"
msgstr "변경 사항을 새 작업 트리로 이동"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "스레드 {0} 이동"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "할 일 도크를 오른쪽 패널로 이동"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "이 PR에 대해 보고된 검사가 없습니다."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "명령을 찾을 수 없습니다."
+#~ msgid "No commands found"
+#~ msgstr "명령을 찾을 수 없습니다."
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "일치하는 일정이 없습니다."
#~ msgstr "일치하는 작업이 없습니다."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "일치하는 스레드 없음"
@@ -5757,6 +5765,7 @@ msgstr "아직 연결된 원격 환경이 없습니다."
msgid "No repositories found."
msgstr "저장소를 찾을 수 없습니다."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "선택된 스레드 없음"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "스레드 없음"
+#~ msgid "No threads"
+#~ msgstr "스레드 없음"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "체크 열기"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "명령 팔레트 열기"
+#~ msgid "Open Command Palette"
+#~ msgstr "명령 팔레트 열기"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "터미널 스크롤백 버퍼의 스크롤 속도 승수입니다."
msgid "Scroll to bottom"
msgstr "맨 아래로 스크롤"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "현재 보기에서 검색"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "스레드 검색"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "스레드 검색"
+#~ msgid "Search Threads"
+#~ msgstr "스레드 검색"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "검색…"
@@ -7914,6 +7925,7 @@ msgstr "기기 선택"
msgid "Select model"
msgstr "모델 선택"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "프로젝트 선택"
@@ -7970,6 +7982,8 @@ msgstr "단축키 설정"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "스레드 정렬 순서"
msgid "Thread todo dock"
msgstr "스레드 할 일 도크"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "스레드"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "유형"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "명령을 입력하세요"
+#~ msgid "Type a command"
+#~ msgstr "명령을 입력하세요"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "페이지에 입력"
msgid "Type into the page (tap a field first)"
msgstr "페이지에 입력(먼저 필드를 탭하세요)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "파일을 검색하려면 입력하세요"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/pl/messages.po b/src/renderer/locales/pl/messages.po
index a86673edd..dccfe340f 100644
--- a/src/renderer/locales/pl/messages.po
+++ b/src/renderer/locales/pl/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Nazwa akcji"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Dostawcy AI"
msgid "Alerts when threads need you"
msgstr "Alerty, gdy wątki wymagają Twojej uwagi"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Zamknij skaner"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Zamknij wyszukiwanie"
@@ -2048,8 +2049,6 @@ msgstr "Zwiń kompozytor terminala"
msgid "Collapse todo dock"
msgstr "Zwiń dok zadań do wykonania"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Polecenie"
@@ -3648,6 +3647,10 @@ msgstr "Plik jest zbyt duży, aby wyświetlić podgląd."
msgid "File no longer exists on disk."
msgstr "Plik nie istnieje już na dysku."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "Wyszukiwanie plików jest niedostępne"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "Plik używa nieobsługiwanego kodowania."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Pliki"
@@ -5243,6 +5247,11 @@ msgstr "Przenieś przeglądarkę do okna"
msgid "Move changes to a new worktree"
msgstr "Przenieś zmiany do nowego drzewa roboczego"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Przenieś wątek {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Przenieś dok zadań do prawego panelu"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "Dla tego PR nie zgłoszono żadnych kontroli."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Nie znaleziono żadnych poleceń"
+#~ msgid "No commands found"
+#~ msgstr "Nie znaleziono żadnych poleceń"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "Brak pasujących harmonogramów."
#~ msgstr "Brak pasujących zadań."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Brak pasujących wątków"
@@ -5757,6 +5765,7 @@ msgstr "Nie połączono jeszcze żadnych środowisk zdalnych."
msgid "No repositories found."
msgstr "Nie znaleziono repozytoriów."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "Nie wybrano wątku"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Brak wątków"
+#~ msgid "No threads"
+#~ msgstr "Brak wątków"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Otwórz kontrolę"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Otwórz paletę poleceń"
+#~ msgid "Open Command Palette"
+#~ msgstr "Otwórz paletę poleceń"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Mnożnik prędkości przewijania dla bufora przewijania terminala."
msgid "Scroll to bottom"
msgstr "Przewiń w dół"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Przeszukaj bieżący widok"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Przeszukaj wątki"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Przeszukaj wątki"
+#~ msgid "Search Threads"
+#~ msgstr "Przeszukaj wątki"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Szukaj…"
@@ -7914,6 +7925,7 @@ msgstr "Wybierz urządzenie"
msgid "Select model"
msgstr "Wybierz model"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Wybierz projekt"
@@ -7970,6 +7982,8 @@ msgstr "Ustaw skrót"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Kolejność sortowania wątków"
msgid "Thread todo dock"
msgstr "Dok zadań wątku"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Wątki"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Typ"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Wpisz polecenie"
+#~ msgid "Type a command"
+#~ msgstr "Wpisz polecenie"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Pisz na stronie"
msgid "Type into the page (tap a field first)"
msgstr "Pisz na stronie (najpierw stuknij pole)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Wpisz, aby wyszukać pliki"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/pt-BR/messages.po b/src/renderer/locales/pt-BR/messages.po
index 001bc8cd7..2389288bd 100644
--- a/src/renderer/locales/pt-BR/messages.po
+++ b/src/renderer/locales/pt-BR/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Nome da ação"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Provedores de IA"
msgid "Alerts when threads need you"
msgstr "Alertas quando threads precisam de você"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Fechar scanner"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Fechar pesquisa"
@@ -2048,8 +2049,6 @@ msgstr "Recolher o compositor do terminal"
msgid "Collapse todo dock"
msgstr "Recolher dock de tarefas"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Comando"
@@ -3648,6 +3647,10 @@ msgstr "O arquivo é muito grande para ser visualizado."
msgid "File no longer exists on disk."
msgstr "O arquivo não existe mais no disco."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "A pesquisa de arquivos não está disponível"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "O arquivo usa uma codificação não suportada."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Arquivos"
@@ -5243,6 +5247,11 @@ msgstr "Mover navegador para uma janela"
msgid "Move changes to a new worktree"
msgstr "Mover alterações para uma nova árvore de trabalho"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Mover tópico {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Mover dock de tarefas para o painel direito"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "Nenhuma verificação relatada para este PR."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Nenhum comando encontrado"
+#~ msgid "No commands found"
+#~ msgstr "Nenhum comando encontrado"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "Nenhum agendamento correspondente."
#~ msgstr "Nenhuma tarefa correspondente."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Não há tópicos correspondentes"
@@ -5757,6 +5765,7 @@ msgstr "Ainda não há ambientes remotos conectados."
msgid "No repositories found."
msgstr "Nenhum repositório encontrado."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "Nenhuma thread selecionada"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Sem tópicos"
+#~ msgid "No threads"
+#~ msgstr "Sem tópicos"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Abrir verificação"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Abrir paleta de comandos"
+#~ msgid "Open Command Palette"
+#~ msgstr "Abrir paleta de comandos"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Multiplicador de velocidade de rolagem para o buffer de rolagem do termi
msgid "Scroll to bottom"
msgstr "Rolar até o fim"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Pesquisar na visualização atual"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Pesquisar tópicos"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Pesquisar tópicos"
+#~ msgid "Search Threads"
+#~ msgstr "Pesquisar tópicos"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Pesquisar…"
@@ -7914,6 +7925,7 @@ msgstr "Selecionar dispositivo"
msgid "Select model"
msgstr "Selecione o modelo"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Selecione o projeto"
@@ -7970,6 +7982,8 @@ msgstr "Definir atalho"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Ordem de classificação de tópicos"
msgid "Thread todo dock"
msgstr "Doca de tarefas do tópico"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Tópicos"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Tipo"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Digite um comando"
+#~ msgid "Type a command"
+#~ msgstr "Digite um comando"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Digitar na página"
msgid "Type into the page (tap a field first)"
msgstr "Digite na página (toque primeiro em um campo)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Digite para pesquisar arquivos"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/ru/messages.po b/src/renderer/locales/ru/messages.po
index d91f436c6..a7ab40ed5 100644
--- a/src/renderer/locales/ru/messages.po
+++ b/src/renderer/locales/ru/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Имя действия"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Провайдеры ИИ"
msgid "Alerts when threads need you"
msgstr "Оповещения, когда потокам нужно ваше внимание"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Закрыть сканер"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Закрыть поиск"
@@ -2048,8 +2049,6 @@ msgstr "Сворачивать поле ввода терминала"
msgid "Collapse todo dock"
msgstr "Свернуть панель задач"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Команда"
@@ -3648,6 +3647,10 @@ msgstr "Файл слишком большой для предпросмотра
msgid "File no longer exists on disk."
msgstr "Файл больше не существует на диске."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "Поиск файлов недоступен"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "Файл использует неподдерживаемую кодировку."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Файлы"
@@ -5243,6 +5247,11 @@ msgstr "Переместить браузер в окно"
msgid "Move changes to a new worktree"
msgstr "Переместить изменения в новый worktree"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Переместить тред {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Переместить панель задач в правую панель"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "Для этого PR не сообщено о проверках."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Команды не найдены"
+#~ msgid "No commands found"
+#~ msgstr "Команды не найдены"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "Подходящих расписаний нет."
#~ msgstr "Нет подходящих задач."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Подходящих тредов нет"
@@ -5757,6 +5765,7 @@ msgstr "Удалённые среды ещё не подключены."
msgid "No repositories found."
msgstr "Репозитории не найдены."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "Поток не выбран"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Нет тредов"
+#~ msgid "No threads"
+#~ msgstr "Нет тредов"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Открыть проверку"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Открыть палитру команд"
+#~ msgid "Open Command Palette"
+#~ msgstr "Открыть палитру команд"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Множитель скорости прокрутки для буфер
msgid "Scroll to bottom"
msgstr "Прокрутить вниз"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Поиск в текущем виде"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Поиск тредов"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Поиск тредов"
+#~ msgid "Search Threads"
+#~ msgstr "Поиск тредов"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Поиск…"
@@ -7914,6 +7925,7 @@ msgstr "Выбрать устройство"
msgid "Select model"
msgstr "Выбрать модель"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Выбрать проект"
@@ -7970,6 +7982,8 @@ msgstr "Назначить сочетание клавиш"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Порядок сортировки тредов"
msgid "Thread todo dock"
msgstr "Панель задач треда"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Треды"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Тип"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Введите команду"
+#~ msgid "Type a command"
+#~ msgstr "Введите команду"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Вводить на странице"
msgid "Type into the page (tap a field first)"
msgstr "Вводите на странице (сначала коснитесь поля)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Введите запрос для поиска файлов"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/tr/messages.po b/src/renderer/locales/tr/messages.po
index a786d5715..ca34eea57 100644
--- a/src/renderer/locales/tr/messages.po
+++ b/src/renderer/locales/tr/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "İşlem adı"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Yapay zeka sağlayıcıları"
msgid "Alerts when threads need you"
msgstr "İş parçacıkları size ihtiyaç duyduğunda uyarılar"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Tarayıcıyı kapat"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Aramayı kapat"
@@ -2048,8 +2049,6 @@ msgstr "Terminal yazma alanını daralt"
msgid "Collapse todo dock"
msgstr "Yapılacaklar panelini daralt"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Komut"
@@ -3648,6 +3647,10 @@ msgstr "Dosya önizlenemeyecek kadar büyük."
msgid "File no longer exists on disk."
msgstr "Dosya artık diskte mevcut değil."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "Dosya arama kullanılamıyor"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "Dosya desteklenmeyen bir kodlama kullanıyor."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Dosyalar"
@@ -5243,6 +5247,11 @@ msgstr "Tarayıcıyı pencereye taşı"
msgid "Move changes to a new worktree"
msgstr "Değişiklikleri yeni bir çalışma ağacına taşı"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Konuyu taşı: {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Yapılacaklar panelini sağ panele taşı"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "Bu PR için herhangi bir kontrol raporlanmadı."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Hiçbir komut bulunamadı"
+#~ msgid "No commands found"
+#~ msgstr "Hiçbir komut bulunamadı"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "Eşleşen zamanlama yok."
#~ msgstr "Eşleşen görev yok."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Eşleşen konu yok"
@@ -5757,6 +5765,7 @@ msgstr "Henüz bağlı uzak ortam yok."
msgid "No repositories found."
msgstr "Hiçbir depo bulunamadı."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "İş parçacığı seçilmedi"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Konu yok"
+#~ msgid "No threads"
+#~ msgstr "Konu yok"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Kontrolü aç"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Komut Paletini Aç"
+#~ msgid "Open Command Palette"
+#~ msgstr "Komut Paletini Aç"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Terminal geri kaydırma arabelleği için kaydırma hızı çarpanı."
msgid "Scroll to bottom"
msgstr "Aşağıya doğru kaydır"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Geçerli görünümde ara"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Konuları ara"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Konuları Ara"
+#~ msgid "Search Threads"
+#~ msgstr "Konuları Ara"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Ara…"
@@ -7914,6 +7925,7 @@ msgstr "Cihaz seç"
msgid "Select model"
msgstr "Modeli seçin"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Proje seçin"
@@ -7970,6 +7982,8 @@ msgstr "Kısayol belirle"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Konu sıralama düzeni"
msgid "Thread todo dock"
msgstr "Konu yapılacaklar yuvası"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Konular"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Tür"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Bir komut yazın"
+#~ msgid "Type a command"
+#~ msgstr "Bir komut yazın"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Sayfaya yaz"
msgid "Type into the page (tap a field first)"
msgstr "Sayfaya yazın (önce bir alana dokunun)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Dosya aramak için yazın"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/uk/messages.po b/src/renderer/locales/uk/messages.po
index f89153719..8e1db0975 100644
--- a/src/renderer/locales/uk/messages.po
+++ b/src/renderer/locales/uk/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Назва дії"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Постачальники AI"
msgid "Alerts when threads need you"
msgstr "Сповіщення, коли потокам потрібна ваша увага"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Закрити сканер"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Закрити пошук"
@@ -2048,8 +2049,6 @@ msgstr "Згорнути поле вводу термінала"
msgid "Collapse todo dock"
msgstr "Згорнути панель завдань"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Команда"
@@ -3648,6 +3647,10 @@ msgstr "Файл занадто великий для попереднього
msgid "File no longer exists on disk."
msgstr "Файл більше не існує на диску."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "Пошук файлів недоступний"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "Файл використовує непідтримуване кодування."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Файли"
@@ -5243,6 +5247,11 @@ msgstr "Перемістити браузер у вікно"
msgid "Move changes to a new worktree"
msgstr "Перемістити зміни в новий worktree"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Перемістити тред {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Перемістити панель завдань у праву панель"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "Для цього PR не повідомлено про перевірки."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Команд не знайдено"
+#~ msgid "No commands found"
+#~ msgstr "Команд не знайдено"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "Відповідних розкладів немає."
#~ msgstr "Немає відповідних завдань."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Відповідних тредів немає"
@@ -5757,6 +5765,7 @@ msgstr "Віддалені середовища ще не підключено."
msgid "No repositories found."
msgstr "Репозиторії не знайдено."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "Потік не вибрано"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Немає тредів"
+#~ msgid "No threads"
+#~ msgstr "Немає тредів"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Відкрити перевірку"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Відкрити палітру команд"
+#~ msgid "Open Command Palette"
+#~ msgstr "Відкрити палітру команд"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Множник швидкості прокручування буфер
msgid "Scroll to bottom"
msgstr "Прокрутити вниз"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Пошук у поточному поданні"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Пошук тредів"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Пошук тредів"
+#~ msgid "Search Threads"
+#~ msgstr "Пошук тредів"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Пошук…"
@@ -7914,6 +7925,7 @@ msgstr "Вибрати пристрій"
msgid "Select model"
msgstr "Вибрати модель"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Вибрати проєкт"
@@ -7970,6 +7982,8 @@ msgstr "Призначити комбінацію клавіш"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Порядок сортування тредів"
msgid "Thread todo dock"
msgstr "Панель завдань треда"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "Треди"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Тип"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Введіть команду"
+#~ msgid "Type a command"
+#~ msgstr "Введіть команду"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Вводить на странице"
msgid "Type into the page (tap a field first)"
msgstr "Вводите на странице (сначала коснитесь поля)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Введіть запит для пошуку файлів"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/vi/messages.po b/src/renderer/locales/vi/messages.po
index 8f8afbaee..f0a8e49d9 100644
--- a/src/renderer/locales/vi/messages.po
+++ b/src/renderer/locales/vi/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "Tên hành động"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "Nhà cung cấp AI"
msgid "Alerts when threads need you"
msgstr "Cảnh báo khi luồng cần bạn"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "Đóng trình quét"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "Đóng tìm kiếm"
@@ -2048,8 +2049,6 @@ msgstr "Thu gọn trình soạn thảo thiết bị đầu cuối"
msgid "Collapse todo dock"
msgstr "Thu gọn thanh việc cần làm"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "Lệnh"
@@ -3648,6 +3647,10 @@ msgstr "Tệp quá lớn để xem trước."
msgid "File no longer exists on disk."
msgstr "Tệp không còn tồn tại trên đĩa."
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "Tính năng tìm kiếm tệp không khả dụng"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "Tệp sử dụng mã hóa không được hỗ trợ."
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "Tập tin"
@@ -5243,6 +5247,11 @@ msgstr "Chuyển trình duyệt sang cửa sổ"
msgid "Move changes to a new worktree"
msgstr "Di chuyển các thay đổi sang một cây làm việc mới"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "Di chuyển luồng {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "Di chuyển khay việc cần làm sang bảng bên phải"
@@ -5552,8 +5561,8 @@ msgid "No checks reported for this PR."
msgstr "Không có kiểm tra nào được báo cáo cho PR này."
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "Không tìm thấy lệnh nào"
+#~ msgid "No commands found"
+#~ msgstr "Không tìm thấy lệnh nào"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5666,7 +5675,6 @@ msgstr "Không có lịch phù hợp."
#~ msgstr "Không có tác vụ phù hợp."
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "Không có luồng nào phù hợp"
@@ -5757,6 +5765,7 @@ msgstr "Chưa có môi trường từ xa nào được kết nối."
msgid "No repositories found."
msgstr "Không tìm thấy kho lưu trữ nào."
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5812,8 +5821,8 @@ msgid "No thread selected"
msgstr "Chưa chọn luồng"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "Không có luồng nào"
+#~ msgid "No threads"
+#~ msgstr "Không có luồng nào"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6031,8 +6040,8 @@ msgid "Open check"
msgstr "Mở kiểm tra"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "Mở bảng lệnh"
+#~ msgid "Open Command Palette"
+#~ msgstr "Mở bảng lệnh"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7709,6 +7718,9 @@ msgstr "Hệ số nhân tốc độ cuộn cho bộ đệm cuộn ngược đầ
msgid "Scroll to bottom"
msgstr "Cuộn xuống dưới cùng"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7811,15 +7823,14 @@ msgstr "Tìm kiếm trong chế độ xem hiện tại"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "Tìm kiếm luồng"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "Tìm kiếm luồng"
+#~ msgid "Search Threads"
+#~ msgstr "Tìm kiếm luồng"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "Tìm kiếm…"
@@ -7914,6 +7925,7 @@ msgstr "Chọn thiết bị"
msgid "Select model"
msgstr "Chọn mô hình"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "Chọn dự án"
@@ -7970,6 +7982,8 @@ msgstr "Đặt phím tắt"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9212,9 +9226,9 @@ msgstr "Thứ tự sắp xếp luồng"
msgid "Thread todo dock"
msgstr "Dock việc cần làm của luồng"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "luồng"
@@ -9377,8 +9391,8 @@ msgid "Type"
msgstr "Loại"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "Nhập lệnh"
+#~ msgid "Type a command"
+#~ msgstr "Nhập lệnh"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9388,6 +9402,10 @@ msgstr "Nhập vào trang"
msgid "Type into the page (tap a field first)"
msgstr "Nhập vào trang (chạm vào trường trước)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "Nhập để tìm kiếm tệp"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/locales/zh-CN/messages.po b/src/renderer/locales/zh-CN/messages.po
index 50dd3bfaf..bf41e4c49 100644
--- a/src/renderer/locales/zh-CN/messages.po
+++ b/src/renderer/locales/zh-CN/messages.po
@@ -568,6 +568,7 @@ msgid "Action name"
msgstr "操作名称"
#: src/mobile/views/pr/PrOverviewPage.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/common/BranchSelector/parts/BranchFooterActions.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/ActionsSection.tsx
#: src/renderer/views/ProjectSettingsOverlay/parts/SettingsSidebar.tsx
@@ -848,6 +849,7 @@ msgstr "AI 提供商"
msgid "Alerts when threads need you"
msgstr "线程需要你时提醒"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/commands/shortcutCatalog.ts
#: src/renderer/components/skills/SkillsManager.tsx
#: src/renderer/views/PullRequestsView/PullRequestsView.tsx
@@ -1946,7 +1948,6 @@ msgid "Close scanner"
msgstr "关闭扫描器"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Close search"
msgstr "关闭搜索"
@@ -2048,8 +2049,6 @@ msgstr "折叠终端输入框"
msgid "Collapse todo dock"
msgstr "折叠待办事项面板"
-#. Accessible label for the command palette search input
-#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/mcp/McpServerEditor.tsx
msgid "Command"
msgstr "命令"
@@ -3648,6 +3647,10 @@ msgstr "文件太大,无法预览。"
msgid "File no longer exists on disk."
msgstr "文件不再存在于磁盘上。"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "File search unavailable"
+msgstr "文件搜索不可用"
+
#. placeholder {0}: entry.insertions + entry.deletions
#. placeholder {0}: file.insertions + file.deletions
#: src/renderer/views/GitReviewOverlay/parts/GitDiffContent/parts/DiffSection.tsx
@@ -3661,6 +3664,7 @@ msgid "File uses an unsupported encoding."
msgstr "文件使用不受支持的编码。"
#: src/mobile/views/WorkspaceView.tsx
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/layout/UnifiedRightPanel.tsx
msgid "Files"
msgstr "文件"
@@ -5242,6 +5246,11 @@ msgstr "将浏览器移到窗口"
msgid "Move changes to a new worktree"
msgstr "将更改移至新工作树"
+#. placeholder {0}: props.thread.title
+#: src/renderer/commands/EverythingSearchResultRow.tsx
+msgid "Move thread {0}"
+msgstr "移动线程 {0}"
+
#: src/renderer/components/thread/ThreadTodoDock.tsx
msgid "Move todo dock to right panel"
msgstr "将待办事项停靠栏移至右侧面板"
@@ -5551,8 +5560,8 @@ msgid "No checks reported for this PR."
msgstr "没有为此 PR 报告检查。"
#: src/renderer/commands/CommandPalette.tsx
-msgid "No commands found"
-msgstr "没有找到命令"
+#~ msgid "No commands found"
+#~ msgstr "没有找到命令"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "No commits found."
@@ -5665,7 +5674,6 @@ msgstr "没有匹配的计划。"
#~ msgstr "没有匹配的任务。"
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "No matching threads"
msgstr "没有匹配的线程"
@@ -5756,6 +5764,7 @@ msgstr "尚未连接远程环境。"
msgid "No repositories found."
msgstr "未找到存储库。"
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/find/FindBar.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
msgid "No results"
@@ -5811,8 +5820,8 @@ msgid "No thread selected"
msgstr "未选择线程"
#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
-msgid "No threads"
-msgstr "没有线程"
+#~ msgid "No threads"
+#~ msgstr "没有线程"
#: src/mobile/views/ThreadsView.tsx
msgid "No threads in this project"
@@ -6030,8 +6039,8 @@ msgid "Open check"
msgstr "打开检查"
#: src/renderer/commands/registry.ts
-msgid "Open Command Palette"
-msgstr "打开命令面板"
+#~ msgid "Open Command Palette"
+#~ msgstr "打开命令面板"
#: src/renderer/views/PrReviewOverlay/parts/PrCommitsTab.tsx
msgid "Open commit on GitHub"
@@ -7708,6 +7717,9 @@ msgstr "终端回滚缓冲区的滚动速度倍增器。"
msgid "Scroll to bottom"
msgstr "滚动到底部"
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
+#: src/renderer/commands/registry.ts
#: src/renderer/components/thread/ChatPane/parts/items/commandSummary.ts
#: src/renderer/components/thread/ChatPane/parts/items/toolDisplay.ts
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -7810,15 +7822,14 @@ msgstr "搜索当前视图"
#: src/mobile/NarrowShell.tsx
#: src/mobile/views/ThreadsView.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Search threads"
msgstr "搜索线程"
#: src/renderer/commands/registry.ts
-msgid "Search Threads"
-msgstr "搜索线程"
+#~ msgid "Search Threads"
+#~ msgstr "搜索线程"
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+#: src/renderer/commands/CommandPalette.tsx
msgid "Search…"
msgstr "搜索..."
@@ -7913,6 +7924,7 @@ msgstr "选择设备"
msgid "Select model"
msgstr "选择模型"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/components/thread/ProjectSwitchMenu.tsx
msgid "Select project"
msgstr "选择项目"
@@ -7969,6 +7981,8 @@ msgstr "设置快捷键"
#: src/mobile/chrome.ts
#: src/mobile/NarrowShell.tsx
+#: src/renderer/commands/CommandPalette.tsx
+#: src/renderer/commands/EverythingSearchResults.tsx
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
#: src/renderer/views/MainView/parts/RightPanel/parts/BrowserPanel/parts/BrowserToolbar.tsx
#: src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -9211,9 +9225,9 @@ msgstr "线程排序顺序"
msgid "Thread todo dock"
msgstr "线程待办事项停靠栏"
+#: src/renderer/commands/CommandPalette.tsx
#: src/renderer/views/SettingsOverlay/parts/SettingsSidebar.tsx
#: src/renderer/views/SettingsOverlay/parts/ThreadSettings.tsx
-#: src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
msgid "Threads"
msgstr "线程"
@@ -9376,8 +9390,8 @@ msgid "Type"
msgstr "类型"
#: src/renderer/commands/CommandPalette.tsx
-msgid "Type a command"
-msgstr "输入命令"
+#~ msgid "Type a command"
+#~ msgstr "输入命令"
#: src/mobile/views/BrowserView.tsx
msgid "Type into the page"
@@ -9387,6 +9401,10 @@ msgstr "在页面中输入"
msgid "Type into the page (tap a field first)"
msgstr "在页面中输入(请先点按一个字段)"
+#: src/renderer/commands/CommandPalette.tsx
+msgid "Type to search files"
+msgstr "输入内容以搜索文件"
+
#. placeholder {0}: agent.label
#. placeholder {0}: agentStatus.label
#: src/renderer/components/thread/ThreadAuthRequiredDock.tsx
diff --git a/src/renderer/state/panelStore.test.ts b/src/renderer/state/panelStore.test.ts
index 53babc77b..12bad82b5 100644
--- a/src/renderer/state/panelStore.test.ts
+++ b/src/renderer/state/panelStore.test.ts
@@ -1,6 +1,7 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { selectAnyObstructingOverlayOpen, usePanelStore } from "./panelStore";
import { useFileEditorStore } from "./fileEditorStore";
+import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
const initialPanelState = usePanelStore.getState();
const initialFileEditorState = useFileEditorStore.getState();
@@ -17,8 +18,8 @@ function resetPanelStore() {
browserOverlayOpen: false,
settingsOpen: false,
projectSettingsId: null,
- threadSearchOpen: false,
});
+ useCommandPaletteStore.setState({ isOpen: false });
}
function resetFileEditorStore() {
@@ -64,8 +65,8 @@ describe("selectAnyObstructingOverlayOpen", () => {
expect(selectAnyObstructingOverlayOpen()).toBe(true);
});
- it("returns true when the thread search overlay is open", () => {
- usePanelStore.setState({ threadSearchOpen: true });
+ it("returns true when everything search is open", () => {
+ useCommandPaletteStore.setState({ isOpen: true });
expect(selectAnyObstructingOverlayOpen()).toBe(true);
});
diff --git a/src/renderer/state/panelStore.ts b/src/renderer/state/panelStore.ts
index 192df1594..247426889 100644
--- a/src/renderer/state/panelStore.ts
+++ b/src/renderer/state/panelStore.ts
@@ -1,6 +1,7 @@
import { create } from "zustand";
import { persistStoreSlice, readPersistedSlice } from "@/renderer/utils/persistStoreSlice";
import type { ThreadSortMode } from "@/renderer/views/MainView/parts/Sidebar/parts/sortMode";
+import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
import { useFileEditorStore } from "./fileEditorStore";
export interface GitReviewContext {
@@ -48,9 +49,10 @@ interface PanelState {
settingsOpen: boolean;
/** When the overlay is opened deep-linked to a section (e.g. "usage"); else null. */
settingsSection: string | null;
+ /** Optional setting row to scroll to after opening a deep-linked section. */
+ settingsAnchor: string | null;
projectSettingsId: string | null;
threadSortMode: ThreadSortMode;
- threadSearchOpen: boolean;
/** Whether the "Start from scratch" create-project modal is open. */
createProjectModalOpen: boolean;
/** Whether the "Clone a repository" modal is open. */
@@ -72,13 +74,11 @@ interface PanelState {
setBrowserOverlayDrawerWidth: (v: number) => void;
openBrowserPanel: () => void;
openSettings: () => void;
- openSettingsSection: (section: string) => void;
+ openSettingsSection: (section: string, anchor?: string) => void;
clearSettingsSection: () => void;
closeSettings: () => void;
openProjectSettings: (projectId: string) => void;
closeProjectSettings: () => void;
- openThreadSearch: () => void;
- closeThreadSearch: () => void;
openCreateProjectModal: () => void;
closeCreateProjectModal: () => void;
openCloneProjectModal: () => void;
@@ -147,9 +147,9 @@ export const usePanelStore = create()((set) => ({
),
settingsOpen: false,
settingsSection: null,
+ settingsAnchor: null,
projectSettingsId: null,
threadSortMode: "updated",
- threadSearchOpen: false,
createProjectModalOpen: false,
cloneProjectModalOpen: false,
@@ -260,22 +260,23 @@ export const usePanelStore = create()((set) => ({
set((state) => (state.threadSortMode === mode ? {} : { threadSortMode: mode })),
openSettings: () =>
set((state) =>
- state.settingsOpen && state.settingsSection === null
+ state.settingsOpen && state.settingsSection === null && state.settingsAnchor === null
? {}
- : { settingsOpen: true, settingsSection: null },
+ : { settingsOpen: true, settingsSection: null, settingsAnchor: null },
),
- openSettingsSection: (section) => set({ settingsOpen: true, settingsSection: section }),
+ openSettingsSection: (section, anchor) =>
+ set({ settingsOpen: true, settingsSection: section, settingsAnchor: anchor ?? null }),
clearSettingsSection: () =>
- set((state) => (state.settingsSection === null ? {} : { settingsSection: null })),
+ set((state) =>
+ state.settingsSection === null && state.settingsAnchor === null
+ ? {}
+ : { settingsSection: null, settingsAnchor: null },
+ ),
closeSettings: () => set((state) => (state.settingsOpen ? { settingsOpen: false } : {})),
openProjectSettings: (projectId) =>
set((state) => (state.projectSettingsId === projectId ? {} : { projectSettingsId: projectId })),
closeProjectSettings: () =>
set((state) => (state.projectSettingsId === null ? {} : { projectSettingsId: null })),
- openThreadSearch: () =>
- set((state) => (state.threadSearchOpen ? {} : { threadSearchOpen: true })),
- closeThreadSearch: () =>
- set((state) => (state.threadSearchOpen ? { threadSearchOpen: false } : {})),
openCreateProjectModal: () =>
set((state) => (state.createProjectModalOpen ? {} : { createProjectModalOpen: true })),
closeCreateProjectModal: () =>
@@ -335,7 +336,7 @@ export function selectAnyObstructingOverlayOpen(): boolean {
p.projectSettingsId !== null ||
p.gitOverlayOpen ||
p.prReviewContext !== null ||
- p.threadSearchOpen
+ useCommandPaletteStore.getState().isOpen
) {
return true;
}
diff --git a/src/renderer/views/MainView/MainView.tsx b/src/renderer/views/MainView/MainView.tsx
index af0f8b858..96e426c4a 100644
--- a/src/renderer/views/MainView/MainView.tsx
+++ b/src/renderer/views/MainView/MainView.tsx
@@ -1,4 +1,4 @@
-import { startTransition, useEffect } from "react";
+import { Suspense, startTransition, useEffect, useState } from "react";
import type { AgentStatus } from "@/shared/contracts";
import { buildPaneLayoutFromLegacy } from "@/shared/paneLayout";
import { readBridge } from "@/renderer/bridge";
@@ -10,6 +10,8 @@ import { useWelcomeGateStore } from "@/renderer/state/welcomeGateStore";
import { buildWslProjectDistrosKey, parseWslProjectDistrosKey } from "@/renderer/state/projectKeys";
import { useSharedSettings } from "@/renderer/state/sharedSettingsStore";
import { AppDndProvider } from "@/renderer/dnd";
+import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
+import { DeferredCommandPalette as PrewarmedCommandPalette } from "@/renderer/deferredFeatures";
import { useKeyboardShortcuts } from "@/renderer/hooks/useKeyboardShortcuts";
import { useGitRefresh } from "@/renderer/hooks/useGitRefresh";
@@ -21,7 +23,6 @@ import { AppOverlays } from "@/renderer/views/MainView/parts/AppOverlays";
import { WorktreeDeleteDialogs } from "@/renderer/views/MainView/parts/WorktreeDeleteDialogs";
import { PullFromSourceDialog } from "@/renderer/views/MainView/parts/PullFromSourceDialog";
import { MainPageLayout, StalePanelCleanup } from "@/renderer/views/MainView/parts/MainPageLayout";
-import { ThreadSearchOverlayHost } from "@/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay";
function findMissingWslDistro(distros: readonly string[], statuses: readonly AgentStatus[]) {
const cachedDistros = new Set(
@@ -111,7 +112,7 @@ export function MainView(props: { storeHydrated: boolean; loadT0: number }) {
}
>
startTransition(() => openHome())} />
-
+
@@ -120,3 +121,18 @@ export function MainView(props: { storeHydrated: boolean; loadT0: number }) {
>
);
}
+
+function DeferredCommandPaletteHost() {
+ const open = useCommandPaletteStore((state) => state.isOpen);
+ const [enabled, setEnabled] = useState(open);
+
+ useEffect(() => {
+ if (open) setEnabled(true);
+ }, [open]);
+
+ return enabled ? (
+
+
+
+ ) : null;
+}
diff --git a/src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx b/src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
index 0c90804aa..ad4696053 100644
--- a/src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
+++ b/src/renderer/views/MainView/parts/Sidebar/Sidebar.tsx
@@ -49,6 +49,7 @@ import {
import { useScrollFade } from "@/renderer/hooks/useScrollFade";
import { useAppStore } from "@/renderer/state/appStore";
import { usePanelStore } from "@/renderer/state/panelStore";
+import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
import { useSidebarUiStore } from "@/renderer/state/sidebarUiStore";
import { useSharedSettings } from "@/renderer/state/sharedSettingsStore";
import { useUpdateStore } from "@/renderer/state/updateStore";
@@ -233,8 +234,8 @@ export function Sidebar() {
// lights up for every other section.
const remoteAccessSettingsActive = settingsOpen && settingsSection === "remoteAccess";
const otherSettingsActive = settingsOpen && !remoteAccessSettingsActive;
- const threadSearchOpen = usePanelStore((s) => s.threadSearchOpen);
- const openThreadSearch = usePanelStore((s) => s.openThreadSearch);
+ const searchOpen = useCommandPaletteStore((state) => state.isOpen);
+ const openSearch = useCommandPaletteStore((state) => state.open);
const isHomeProjectCollapsed = useSidebarUiStore((s) =>
homeProject ? (s.collapsedProjects[homeProject.id] ?? false) : false,
);
@@ -336,8 +337,8 @@ export function Sidebar() {
iconOnly
icon={}
label={t`Search`}
- isActive={threadSearchOpen}
- onPress={openThreadSearch}
+ isActive={searchOpen}
+ onPress={openSearch}
/>
diff --git a/src/renderer/views/MainView/parts/SidebarHeaderControls.tsx b/src/renderer/views/MainView/parts/SidebarHeaderControls.tsx
index d5c0410ba..8a16b7e58 100644
--- a/src/renderer/views/MainView/parts/SidebarHeaderControls.tsx
+++ b/src/renderer/views/MainView/parts/SidebarHeaderControls.tsx
@@ -2,6 +2,7 @@ import { FolderPlus, Globe, Search } from "lucide-react";
import { Button, Dropdown, Label, Tooltip } from "@heroui/react";
import { Trans, useLingui } from "@lingui/react/macro";
import { usePanelStore } from "@/renderer/state/panelStore";
+import { useCommandPaletteStore } from "@/renderer/commands/commandPaletteStore";
import { toggleBrowserPanel } from "@/renderer/actions/panelActions";
import {
type ThreadSortMode,
@@ -28,7 +29,7 @@ export function SidebarHeaderControls() {
size="sm"
variant="ghost"
className="size-6 min-w-0 text-muted hover:text-foreground"
- onPress={() => usePanelStore.getState().openThreadSearch()}
+ onPress={() => useCommandPaletteStore.getState().open()}
>
diff --git a/src/renderer/views/SettingsOverlay/SettingsOverlay.test.tsx b/src/renderer/views/SettingsOverlay/SettingsOverlay.test.tsx
index 31b40f498..0e5605468 100644
--- a/src/renderer/views/SettingsOverlay/SettingsOverlay.test.tsx
+++ b/src/renderer/views/SettingsOverlay/SettingsOverlay.test.tsx
@@ -1,4 +1,4 @@
-import { act, fireEvent, screen, within } from "@testing-library/react";
+import { act, fireEvent, screen, waitFor, within } from "@testing-library/react";
import { renderWithI18n as render } from "@/renderer/testUtils/i18n";
import type { ReactNode } from "react";
import { beforeEach, describe, expect, it, vi } from "vitest";
@@ -109,11 +109,11 @@ vi.mock("@/renderer/components/thread/AgentDiscoveryScreen", () => ({
}));
vi.mock("./parts/GeneralSettings", () => ({
- GeneralSettings: () =>
General
,
+ GeneralSettings: () =>
General
,
}));
vi.mock("./parts/AppearanceSettings", () => ({
- AppearanceSettings: () =>
Appearance
,
+ AppearanceSettings: () =>
Appearance
,
}));
vi.mock("./parts/TerminalSettings", () => ({
@@ -174,6 +174,7 @@ vi.mock("./parts/SingleAgentSettings", () => ({
}));
import { SettingsOverlay } from "./SettingsOverlay";
+import { usePanelStore } from "@/renderer/state/panelStore";
const baseCapabilities = {
models: [],
@@ -209,6 +210,11 @@ describe("SettingsOverlay", () => {
resetDiscoveredAgentsMock.mockReset();
refreshAgentStatusesMock.mockReset();
refreshAgentStatusesMock.mockResolvedValue(undefined);
+ usePanelStore.setState({
+ settingsOpen: false,
+ settingsSection: null,
+ settingsAnchor: null,
+ });
});
it("keeps WSL-only installed agents reachable from the sidebar", () => {
@@ -339,6 +345,41 @@ describe("SettingsOverlay", () => {
expect(within(screen.getByRole("main")).getByText("Usage")).toBeInTheDocument();
});
+ it("scrolls to an initially requested setting anchor", async () => {
+ const scrollIntoView = vi.fn<(options?: ScrollIntoViewOptions | boolean) => void>();
+ HTMLElement.prototype.scrollIntoView = scrollIntoView;
+ usePanelStore.getState().openSettingsSection("general", "general.language");
+
+ render(
undefined} />);
+
+ await waitFor(() =>
+ expect(scrollIntoView).toHaveBeenCalledWith({ behavior: "smooth", block: "start" }),
+ );
+ expect(within(screen.getByRole("main")).getByText("General")).toHaveClass(
+ "poracode-setting-highlight",
+ );
+ expect(usePanelStore.getState().settingsSection).toBeNull();
+ expect(usePanelStore.getState().settingsAnchor).toBeNull();
+ });
+
+ it("scrolls to a setting anchor requested while the overlay is open", async () => {
+ const scrollIntoView = vi.fn<(options?: ScrollIntoViewOptions | boolean) => void>();
+ HTMLElement.prototype.scrollIntoView = scrollIntoView;
+ render( undefined} />);
+
+ act(() => {
+ usePanelStore.getState().openSettingsSection("appearance", "appearance.mode");
+ });
+
+ expect(within(screen.getByRole("main")).getByText("Appearance")).toBeInTheDocument();
+ await waitFor(() =>
+ expect(scrollIntoView).toHaveBeenCalledWith({ behavior: "smooth", block: "start" }),
+ );
+ expect(within(screen.getByRole("main")).getByText("Appearance")).toHaveClass(
+ "poracode-setting-highlight",
+ );
+ });
+
it("marks agents that need attention in the sidebar", () => {
statusesState.agentStatuses = [
makeStatus("acp-generic:factory-droid", {
diff --git a/src/renderer/views/SettingsOverlay/SettingsOverlay.tsx b/src/renderer/views/SettingsOverlay/SettingsOverlay.tsx
index b4dd4b20d..763bb892a 100644
--- a/src/renderer/views/SettingsOverlay/SettingsOverlay.tsx
+++ b/src/renderer/views/SettingsOverlay/SettingsOverlay.tsx
@@ -87,33 +87,33 @@ export function SettingsOverlay(props: { onClose: () => void }) {
const { onClose } = props;
const { t } = useLingui();
const requestedSection = usePanelStore((s) => s.settingsSection);
+ const requestedAnchor = usePanelStore((s) => s.settingsAnchor);
const clearSettingsSection = usePanelStore((s) => s.clearSettingsSection);
const [activeSection, setActiveSection] = useState(
(requestedSection as SettingsSection | null) ?? "general",
);
- // Apply a deep-link request (e.g. clicking a sidebar usage circle) and clear
- // it so it doesn't re-fire on the next open.
- useEffect(() => {
- if (requestedSection) {
- setActiveSection(requestedSection as SettingsSection);
- clearSettingsSection();
- }
- }, [requestedSection, clearSettingsSection]);
-
// Pending scroll-to-setting target, set when a settings search result is
- // clicked. The token re-fires the effect when the same setting is picked
- // twice. Local (not a store): only this overlay coordinates the scroll, and it
- // has to land *after* the section content remounts (`key={activeSection}`).
- const [scrollTarget, setScrollTarget] = useState<{ anchor: string; token: number } | null>(null);
- const scrollTokenRef = useRef(0);
+ // clicked. Local (not a store): only this overlay coordinates the scroll, and
+ // it has to land *after* the section content remounts (`key={activeSection}`).
+ const [scrollTarget, setScrollTarget] = useState<{ anchor: string } | null>(null);
const navigateToSection = useCallback((section: SettingsSection, anchor?: string) => {
setActiveSection(section);
if (anchor) {
- scrollTokenRef.current += 1;
- setScrollTarget({ anchor, token: scrollTokenRef.current });
+ setScrollTarget({ anchor });
+ } else {
+ setScrollTarget(null);
}
}, []);
+ // Apply a deep-link request (e.g. clicking a sidebar usage circle or an
+ // everything-search setting result) and clear it so the same target can be
+ // requested again while this overlay remains open.
+ useEffect(() => {
+ if (!requestedSection) return;
+ navigateToSection(requestedSection as SettingsSection, requestedAnchor ?? undefined);
+ clearSettingsSection();
+ }, [requestedSection, requestedAnchor, clearSettingsSection, navigateToSection]);
+
// After the target section mounts, scroll its anchor into view and flash it.
// Runs on rAF (with a short retry) so the freshly-remounted row is in the DOM.
useEffect(() => {
diff --git a/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.test.ts b/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.test.ts
index 192c74971..3bda96d27 100644
--- a/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.test.ts
+++ b/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.test.ts
@@ -99,6 +99,12 @@ describe("searchSettings", () => {
expect(lower).toContain("browser.allowDataAccess");
});
+ it("matches every query term across title, description, and keywords", () => {
+ const anchors = searchSettings("appearance mode", t).map((result) => result.anchor);
+ expect(anchors).toContain("appearance.mode");
+ expect(searchSettings("appearance missing", t)).toEqual([]);
+ });
+
it("finds the Skills and MCP settings", () => {
expect(searchSettings("skills", t).map((result) => result.anchor)).toContain("skills.manage");
expect(searchSettings("shared", t).map((result) => result.anchor)).toContain("skills.manage");
diff --git a/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.ts b/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.ts
index d219c5da5..65b03a1f1 100644
--- a/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.ts
+++ b/src/renderer/views/SettingsOverlay/parts/settingsSearchIndex.ts
@@ -539,17 +539,17 @@ function truncate(text: string, max = SNIPPET_MAX): string {
}
/**
- * Match `query` against the index. Case-insensitive substring over the localized
- * title, then description, then English `keywords` — same semantics as the
- * sidebar's existing section-label filter. Returns `[]` for a blank query.
+ * Match `query` against the index. Every whitespace-delimited term must match
+ * the localized title, description, or English `keywords`. Returns `[]` for a
+ * blank query.
*/
export function searchSettings(
query: string,
t: Translate,
opts?: { devMode?: boolean; remoteSession?: boolean; index?: readonly SettingsSearchEntry[] },
): SettingsSearchResult[] {
- const needle = query.trim().toLowerCase();
- if (needle === "") return [];
+ const terms = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
+ if (terms.length === 0) return [];
const index = opts?.index ?? SETTINGS_SEARCH_INDEX;
const results: SettingsSearchResult[] = [];
for (const entry of index) {
@@ -557,11 +557,17 @@ export function searchSettings(
if (entry.desktopOnly && opts?.remoteSession) continue;
const title = t(entry.title);
const description = entry.description ? t(entry.description) : "";
- const titleMatch = title.toLowerCase().includes(needle);
- const descMatch = description !== "" && description.toLowerCase().includes(needle);
- const keywordMatch =
- entry.keywords !== undefined && entry.keywords.toLowerCase().includes(needle);
- if (!titleMatch && !descMatch && !keywordMatch) continue;
+ const normalizedTitle = title.toLowerCase();
+ const normalizedDescription = description.toLowerCase();
+ const normalizedKeywords = entry.keywords?.toLowerCase() ?? "";
+ const titleMatch = terms.every((term) => normalizedTitle.includes(term));
+ const matches = terms.every(
+ (term) =>
+ normalizedTitle.includes(term) ||
+ normalizedDescription.includes(term) ||
+ normalizedKeywords.includes(term),
+ );
+ if (!matches) continue;
results.push({
section: entry.section,
anchor: entry.anchor,
diff --git a/src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx b/src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
deleted file mode 100644
index c196c279e..000000000
--- a/src/renderer/views/ThreadSearchOverlay/ThreadSearchOverlay.tsx
+++ /dev/null
@@ -1,161 +0,0 @@
-import { useEffect, useMemo, useRef, useState } from "react";
-import { Search } from "lucide-react";
-import { Trans, useLingui } from "@lingui/react/macro";
-import { useShallow } from "zustand/shallow";
-import { useAppStore } from "@/renderer/state/appStore";
-import { usePanelStore } from "@/renderer/state/panelStore";
-import { useDragSource } from "@/renderer/dnd";
-import { openThread } from "@/renderer/actions/threadActions";
-import { ThreadSearchResultRow } from "./parts/ThreadSearchResultRow";
-
-const RESULT_LIMIT = 50;
-
-export function ThreadSearchOverlay(props: { onClose: () => void }) {
- const { onClose } = props;
- const { t } = useLingui();
- const [query, setQuery] = useState("");
- const [selectedIndex, setSelectedIndex] = useState(0);
- const inputRef = useRef(null);
- const listRef = useRef(null);
-
- const threads = useAppStore(useShallow((s) => s.threads));
- const projects = useAppStore(useShallow((s) => s.projects));
-
- const dragSource = useDragSource();
- const isDraggingThreadFromSearch =
- dragSource?.type === "thread" && threads.some((thread) => thread.id === dragSource.threadId);
- const wasDraggingRef = useRef(false);
-
- // When a drag started from this overlay ends, close the overlay.
- useEffect(() => {
- if (isDraggingThreadFromSearch) {
- wasDraggingRef.current = true;
- return;
- }
- if (wasDraggingRef.current) {
- wasDraggingRef.current = false;
- onClose();
- }
- }, [isDraggingThreadFromSearch, onClose]);
-
- useEffect(() => {
- inputRef.current?.focus();
- }, []);
-
- const projectsById = useMemo(() => {
- const map = new Map();
- for (const project of projects) map.set(project.id, project);
- return map;
- }, [projects]);
-
- const results = useMemo(() => {
- const q = query.trim().toLowerCase();
- const candidates = threads.filter((thread) => !thread.archived);
- const filtered = q
- ? candidates.filter((thread) => thread.title.toLowerCase().includes(q))
- : candidates;
- return filtered
- .slice()
- .sort((a, b) => {
- if (a.starred !== b.starred) return a.starred ? -1 : 1;
- return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
- })
- .slice(0, RESULT_LIMIT);
- }, [threads, query]);
-
- useEffect(() => {
- setSelectedIndex(0);
- }, [query]);
-
- function activateAt(index: number) {
- const thread = results[index];
- if (!thread) return;
- openThread(thread.id);
- onClose();
- }
-
- function onKeyDown(e: React.KeyboardEvent) {
- if (e.key === "ArrowDown") {
- e.preventDefault();
- setSelectedIndex((i) => Math.min(i + 1, Math.max(0, results.length - 1)));
- } else if (e.key === "ArrowUp") {
- e.preventDefault();
- setSelectedIndex((i) => Math.max(0, i - 1));
- } else if (e.key === "Enter") {
- e.preventDefault();
- activateAt(selectedIndex);
- } else if (e.key === "Escape") {
- e.preventDefault();
- onClose();
- }
- }
-
- // Hide the overlay visually while a drag is alive so the dragged thread can
- // be dropped onto a pane underneath, without unmounting the dnd source.
- const hidden = isDraggingThreadFromSearch;
-
- return (
-
-
-
-
-
- setQuery(e.target.value)}
- placeholder={t`Search…`}
- className="flex-1 bg-transparent text-sm outline-none placeholder:text-muted/70"
- spellCheck={false}
- autoComplete="off"
- />
-
-
- {results.length === 0 ? (
-
- {query.trim() ? No matching threads : No threads}
-
- ) : (
-
-
- Threads
-
- {results.map((thread, index) => (
-
activateAt(index)}
- onHover={() => setSelectedIndex(index)}
- />
- ))}
-
- )}
-
-
-
- );
-}
-
-export function ThreadSearchOverlayHost() {
- const open = usePanelStore((s) => s.threadSearchOpen);
- if (!open) return null;
- return usePanelStore.getState().closeThreadSearch()} />;
-}
diff --git a/src/renderer/views/ThreadSearchOverlay/parts/ThreadSearchResultRow.tsx b/src/renderer/views/ThreadSearchOverlay/parts/ThreadSearchResultRow.tsx
deleted file mode 100644
index 1d4695435..000000000
--- a/src/renderer/views/ThreadSearchOverlay/parts/ThreadSearchResultRow.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { useRef } from "react";
-import type { Project, Thread } from "@/shared/contracts";
-import { ThreadProviderIcon } from "@/renderer/components/providers/ThreadProviderIcon";
-import { useDraggable } from "@dnd-kit/react";
-import type { DragSourceData } from "@/renderer/dnd";
-import { handleKeyActivate } from "@/renderer/utils/a11y";
-
-export function ThreadSearchResultRow(props: {
- thread: Thread;
- project: Project | undefined;
- isSelected: boolean;
- onActivate: () => void;
- onHover: () => void;
-}) {
- const { thread, project, isSelected, onActivate, onHover } = props;
- const rowRef = useRef(null);
-
- useDraggable({
- id: `thread-search:${thread.id}`,
- type: "thread",
- data: {
- type: "thread",
- threadId: thread.id,
- projectId: thread.projectId,
- ...(thread.worktreePath != null ? { worktreePath: thread.worktreePath } : {}),
- } satisfies DragSourceData,
- element: rowRef,
- });
-
- const stateClass = isSelected
- ? "bg-[var(--row-active)] text-foreground"
- : "text-foreground/85 hover:bg-[var(--row-hover)] hover:text-foreground";
-
- return (
- handleKeyActivate(e, onActivate)}
- >
-
-
- {thread.title}
-
- {project ? (
- {project.name}
- ) : null}
-
- );
-}
diff --git a/src/shared/analytics/posthogPrivacy.ts b/src/shared/analytics/posthogPrivacy.ts
index 657584671..f9f96858d 100644
--- a/src/shared/analytics/posthogPrivacy.ts
+++ b/src/shared/analytics/posthogPrivacy.ts
@@ -16,11 +16,11 @@ export const PRODUCT_ANALYTICS_EVENT_NAMES = [
"thread.started",
"thread.turn_completed",
"ui.project_group_toggled",
+ "ui.everything_search_toggled",
"ui.right_panel_toggled",
"ui.right_panel_tab_changed",
"ui.sidebar_toggled",
"ui.thread_list_show_more",
- "ui.thread_search_toggled",
"ui.worktree_group_toggled",
] as const;
diff --git a/src/shared/contracts/projectTree.ts b/src/shared/contracts/projectTree.ts
index d7ca2fafa..fc7da2795 100644
--- a/src/shared/contracts/projectTree.ts
+++ b/src/shared/contracts/projectTree.ts
@@ -92,6 +92,7 @@ export const searchProjectTreePayloadSchema = z.object({
projectLocation: projectLocationSchema,
query: z.string().default(""),
limit: z.number().int().min(1).max(200).default(50),
+ entryType: z.enum(["file", "directory"]).optional(),
searchConfig: searchConfigSchema.optional(),
});
export type SearchProjectTreePayload = z.infer;
diff --git a/src/shared/keybindings.test.ts b/src/shared/keybindings.test.ts
index 3a615dc4b..de9ac0a34 100644
--- a/src/shared/keybindings.test.ts
+++ b/src/shared/keybindings.test.ts
@@ -17,8 +17,11 @@ describe("DEFAULT_KEYBINDINGS", () => {
expect(byCommand["pane.close"]?.when).toContain("!browserFocus");
expect(byCommand["pane.close"]?.when).toContain("!composerFocus");
expect(byCommand["editor.save"]?.when).toBe("editorFocus");
- expect(byCommand["thread.search.open"]?.when).toContain("!inputFocus");
- expect(byCommand["thread.search.open"]?.when).toContain("!panelFocus");
+ const constrainedSearch = DEFAULT_KEYBINDINGS.keybindings.find(
+ (binding) => binding.command === "palette.open" && binding.when,
+ );
+ expect(constrainedSearch?.when).toContain("!inputFocus");
+ expect(constrainedSearch?.when).toContain("!panelFocus");
expect(byCommand["thread.star"]?.when).toContain("draftView");
expect(byCommand["thread.star"]?.when).toContain("!inputFocus");
expect(byCommand["thread.star"]?.when).toContain("!terminalFocus");
diff --git a/src/shared/keybindings.ts b/src/shared/keybindings.ts
index a664f7dbc..8598a8d91 100644
--- a/src/shared/keybindings.ts
+++ b/src/shared/keybindings.ts
@@ -156,7 +156,7 @@ export const DEFAULT_KEYBINDINGS: KeybindingsFile = {
when: "hasProject",
},
{
- command: "thread.search.open",
+ command: "palette.open",
key: "Ctrl+G",
mac: "Meta+G",
when: NOT_TYPING,
diff --git a/src/supervisor/ProjectSearchIndex.test.ts b/src/supervisor/ProjectSearchIndex.test.ts
new file mode 100644
index 000000000..fd36fe211
--- /dev/null
+++ b/src/supervisor/ProjectSearchIndex.test.ts
@@ -0,0 +1,117 @@
+import { beforeEach, describe, expect, it, vi } from "vitest";
+import type { ProjectLocation } from "@/shared/contracts";
+import type { WslBridgeClient } from "./wsl/bridge/client";
+
+const execGitMock = vi.hoisted(() => vi.fn<() => Promise>());
+
+vi.mock("./git", async () => {
+ const actual = await vi.importActual("./git");
+ return {
+ ...actual,
+ execGit: execGitMock,
+ };
+});
+
+import { ProjectSearchIndex } from "./ProjectSearchIndex";
+
+const location: Extract = {
+ kind: "wsl",
+ distro: "Ubuntu",
+ linuxPath: "/home/user/project",
+ uncPath: "\\\\wsl.localhost\\Ubuntu\\home\\user\\project",
+};
+
+describe("ProjectSearchIndex caching", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("uses separate cache entries when useIgnoreFiles changes", async () => {
+ execGitMock.mockResolvedValue("src/tracked.ts\n");
+ const find = vi.fn().mockResolvedValue({
+ entries: [{ path: "ignored/generated.ts", name: "generated.ts", type: "file" }],
+ truncated: false,
+ });
+ const index = new ProjectSearchIndex(() => "");
+ index.setWslClient({ find } as unknown as WslBridgeClient);
+ const excludePatterns = ["**/.git"];
+
+ const respectingIgnoreFiles = await index.searchProjectTree({
+ projectLocation: location,
+ query: "tracked",
+ limit: 10,
+ searchConfig: { useIgnoreFiles: true, excludePatterns },
+ });
+ const includingIgnoredFiles = await index.searchProjectTree({
+ projectLocation: location,
+ query: "generated",
+ limit: 10,
+ searchConfig: { useIgnoreFiles: false, excludePatterns },
+ });
+
+ expect(respectingIgnoreFiles.entries.map((entry) => entry.path)).toEqual(["src/tracked.ts"]);
+ expect(includingIgnoredFiles.entries.map((entry) => entry.path)).toEqual([
+ "ignored/generated.ts",
+ ]);
+ expect(execGitMock).toHaveBeenCalledOnce();
+ expect(find).toHaveBeenCalledOnce();
+ });
+
+ it("uses separate cache entries for comma-separated and distinct exclude patterns", async () => {
+ const find = vi.fn().mockResolvedValue({
+ entries: [{ path: "src/keep.ts", name: "keep.ts", type: "file" }],
+ truncated: false,
+ });
+ const index = new ProjectSearchIndex(() => "");
+ index.setWslClient({ find } as unknown as WslBridgeClient);
+
+ await index.searchProjectTree({
+ projectLocation: location,
+ query: "keep",
+ limit: 10,
+ searchConfig: { useIgnoreFiles: false, excludePatterns: ["a,b"] },
+ });
+ await index.searchProjectTree({
+ projectLocation: location,
+ query: "keep",
+ limit: 10,
+ searchConfig: { useIgnoreFiles: false, excludePatterns: ["a", "b"] },
+ });
+
+ expect(find).toHaveBeenCalledTimes(2);
+ });
+
+ it("filters entry types before applying the result limit", async () => {
+ execGitMock.mockResolvedValue("src/match.ts\n");
+ const index = new ProjectSearchIndex(() => "");
+
+ const result = await index.searchProjectTree({
+ projectLocation: location,
+ query: "src",
+ limit: 1,
+ entryType: "file",
+ searchConfig: { useIgnoreFiles: true, excludePatterns: [] },
+ });
+
+ expect(result.entries.map((entry) => entry.path)).toEqual(["src/match.ts"]);
+ });
+
+ it("matches reordered terms across an entry name and path", async () => {
+ execGitMock.mockResolvedValue(
+ "src/components/search/CommandPalette.tsx\nsrc/components/search/Other.tsx\n",
+ );
+ const index = new ProjectSearchIndex(() => "");
+
+ const result = await index.searchProjectTree({
+ projectLocation: location,
+ query: "palette components",
+ limit: 10,
+ entryType: "file",
+ searchConfig: { useIgnoreFiles: true, excludePatterns: [] },
+ });
+
+ expect(result.entries.map((entry) => entry.path)).toEqual([
+ "src/components/search/CommandPalette.tsx",
+ ]);
+ });
+});
diff --git a/src/supervisor/ProjectSearchIndex.ts b/src/supervisor/ProjectSearchIndex.ts
index e5c0c4560..27464d13b 100644
--- a/src/supervisor/ProjectSearchIndex.ts
+++ b/src/supervisor/ProjectSearchIndex.ts
@@ -25,7 +25,10 @@ function joinRelativePath(parentPath: string, name: string): string {
}
function cacheKeyForSearchConfig(config: SearchConfigPayload): string {
- return [...config.excludePatterns].sort().join(",");
+ return JSON.stringify({
+ useIgnoreFiles: config.useIgnoreFiles,
+ excludePatterns: [...config.excludePatterns].sort(),
+ });
}
/**
@@ -109,7 +112,7 @@ export class ProjectSearchIndex {
const config = payload.searchConfig ?? { useIgnoreFiles: true, excludePatterns: [] };
const { entries } = await this.getOrBuildSearchIndex(payload.projectLocation, config);
return {
- entries: this.rankEntries(entries, query, payload.limit),
+ entries: this.rankEntries(entries, query, payload.limit, payload.entryType),
};
}
@@ -117,7 +120,7 @@ export class ProjectSearchIndex {
location: ProjectLocation,
config: SearchConfigPayload,
): Promise<{ entries: ProjectTreeEntry[] }> {
- const key = `${getLocationIdentity(location)}|${cacheKeyForSearchConfig(config)}`;
+ const key = `${JSON.stringify(getLocationIdentity(location))}:${cacheKeyForSearchConfig(config)}`;
const cached = this.cache.get(key);
if (cached && Date.now() - cached.createdAt < CACHE_TTL_MS) {
this.cache.delete(key);
@@ -251,16 +254,31 @@ export class ProjectSearchIndex {
return results;
}
- rankEntries(entries: ProjectTreeEntry[], query: string, limit: number): ProjectTreeEntry[] {
+ rankEntries(
+ entries: ProjectTreeEntry[],
+ query: string,
+ limit: number,
+ entryType?: ProjectTreeEntry["type"],
+ ): ProjectTreeEntry[] {
+ const terms = query.split(/\s+/).filter(Boolean);
+ if (terms.length === 0) return [];
const scored: { entry: ProjectTreeEntry; score: number }[] = [];
for (const entry of entries) {
+ if (entryType && entry.type !== entryType) continue;
const nameLower = entry.name.toLowerCase();
const pathLower = entry.path.toLowerCase();
let score = 0;
- if (nameLower.startsWith(query)) score = 3;
- else if (nameLower.includes(query)) score = 2;
- else if (pathLower.includes(query)) score = 1;
- if (score > 0) scored.push({ entry, score });
+ let matches = true;
+ for (const term of terms) {
+ if (nameLower.startsWith(term)) score += 3;
+ else if (nameLower.includes(term)) score += 2;
+ else if (pathLower.includes(term)) score += 1;
+ else {
+ matches = false;
+ break;
+ }
+ }
+ if (matches) scored.push({ entry, score });
}
scored.sort((a, b) => {
@@ -279,9 +297,9 @@ export class ProjectSearchIndex {
}
invalidateCaches(location: ProjectLocation): void {
- const prefix = `${getLocationIdentity(location)}|`;
+ const prefix = `${JSON.stringify(getLocationIdentity(location))}:`;
for (const key of this.cache.keys()) {
- if (key === getLocationIdentity(location) || key.startsWith(prefix)) {
+ if (key.startsWith(prefix)) {
this.cache.delete(key);
}
}