fix(palette): the project you are in answers to its own name (#170)

The palette's placeholder and empty state both promise project search, but
the switcher loop rightly excludes the project you are already inside — so
typing `wiki` from inside `wiki` matched nothing at all. The destination was
there the whole time, as the unconditional row labelled "Go to project root"
and tagged ACTION, which no project name will ever match.

Relabel that one row with the project's name and tag it `project`. One row,
not two; still first and unconditional, so the BEA-52 dead-route escape
hatch is literally the same row it always was.

Closes BEA-105

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Snow Lee (Sungwon)
2026-08-19 10:58:33 -07:00
committed by GitHub
co-authored by Claude Opus 5
parent a3408bb198
commit 6f8eb99606
4 changed files with 30 additions and 4 deletions
+22 -1
View File
@@ -177,6 +177,27 @@ test("palette (⌘K) fuzzy-jumps to a file", async ({ page }) => {
await expect(page.locator("#content h1")).toHaveText("Topic");
});
// BEA-105: the switcher excludes the project you're in, so typing its own name
// used to match nothing while the palette copy promised project search. The
// root row carries the name now — one row, kind `project`, same destination.
test("palette finds the project you are inside by name", async ({ page }) => {
await login(page);
const pid = await wikiId(page);
await page.goto(`/${pid}`);
await page.waitForSelector("#sidebar");
await page.keyboard.press("ControlOrMeta+k");
await expect(page.locator("#palette")).toBeVisible();
// with no query typed, at least one PROJECT row is on screen
expect(await page.locator("#palette [cmdk-item] .pkind", { hasText: "project" }).count()).toBeGreaterThan(0);
await page.fill("#palette input", "wiki");
const rows = page.locator("#palette [cmdk-item]", { hasText: "wiki" });
await expect(rows).toHaveCount(1); // exactly one, no duplicate root action
await expect(rows.first().locator(".pkind")).toHaveText("project");
await page.keyboard.press("Enter");
await page.waitForURL(`/${pid}`);
});
// BEA-52: on a path that doesn't resolve the tree entries are gone and the
// switcher lists only other projects, so the palette used to offer no way
// back. cmdk owns the list's id (it overwrites ours), hence [cmdk-list].
@@ -187,7 +208,7 @@ test("palette on a dead route still offers the way back", async ({ page }) => {
await expect(page.locator(".notfound")).toBeVisible();
await page.keyboard.press("ControlOrMeta+k");
await expect(page.locator("#palette")).toBeVisible();
for (const label of ["Go to project root", "Dashboard", "Installation", "Settings"]) {
for (const label of ["project root", "Dashboard", "Installation", "Settings"]) {
await expect(page.locator("#palette [cmdk-list]")).toContainText(label);
}
// exactly one whole-project history entry, no duplicate
@@ -467,7 +467,12 @@ export default function Browser(props: {
props.onClosePanel?.();
navigate(to);
};
add("folder", "Go to project root", "action", go("/" + pid));
// Labelled with the project's name and tagged `project`, so typing the
// name of the project you are IN finds it: the switcher loop below
// rightly excludes the current project, which left nothing carrying its
// name while the palette copy promised project search (BEA-105). One row,
// not two — still the first, still unconditional, so BEA-52 holds.
add("folder", project.name + " — project root", "project", go("/" + pid));
add("dashboard", "Dashboard", "action", go(urlForView("dashboard", pid)));
add("terminal", "Installation", "action", go(urlForView("install", pid)));
add("gear", "Settings", "action", go(urlForView("settings", pid)));
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BearDrive</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='%23f5a623'><rect x='4' y='4' width='5.6' height='24'/><rect x='11.2' y='4' width='14.4' height='11.2'/><rect x='11.2' y='16.8' width='16.8' height='11.2'/></svg>">
<script type="module" crossorigin src="/assets/index-CYEvhG3F.js"></script>
<script type="module" crossorigin src="/assets/index-D8UAHgrJ.js"></script>
<link rel="modulepreload" crossorigin href="/assets/_commonjsHelpers-CqkleIqs.js">
<link rel="modulepreload" crossorigin href="/assets/mermaid-DQuCJ8Gi.js">
<link rel="stylesheet" crossorigin href="/assets/index-C20TgXSV.css">