From 6fa4b7bdc9d0cb2c0a50ca0e06b32bc51f7a9a83 Mon Sep 17 00:00:00 2001 From: Vatsal Sanjay Date: Mon, 30 Mar 2026 18:02:15 +0100 Subject: [PATCH 1/2] Filter internal search backlog entries Filter search index entries that expose internal blog backlog pages through the public command palette. Add a regression test covering Private-ToDo and 0_ToDo URLs so future search_db refreshes do not resurface those links. --- assets/js/search-manager.js | 32 ++++++++++++++++++++++--- tests/search-manager.test.js | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 tests/search-manager.test.js diff --git a/assets/js/search-manager.js b/assets/js/search-manager.js index 395011f..f4ddcd0 100644 --- a/assets/js/search-manager.js +++ b/assets/js/search-manager.js @@ -26,6 +26,27 @@ threshold: 0.4, }; + const INTERNAL_SEARCH_PATTERNS = [ + /https:\/\/blogs\.comphy-lab\.org\/Private-ToDo/i, + /https:\/\/blogs\.comphy-lab\.org\/0_ToDo/i, + /^Private todo blog public/i, + /^0_todo blog public/i, + ]; + + function isInternalSearchEntry(entry) { + const combinedText = [entry?.title, entry?.url, entry?.content] + .filter(Boolean) + .join(" "); + + return INTERNAL_SEARCH_PATTERNS.some((pattern) => + pattern.test(combinedText) + ); + } + + function sanitizeSearchData(data) { + return data.filter((entry) => !isInternalSearchEntry(entry)); + } + /** * Loads the search database from the server * @returns {Promise} Promise that resolves to search data array @@ -61,9 +82,14 @@ ); } - searchData = data; - console.log(`Search database loaded: ${data.length} items`); - return data; + const sanitizedData = sanitizeSearchData(data); + + searchData = sanitizedData; + console.log( + `Search database loaded: ${sanitizedData.length} items ` + + `(${data.length - sanitizedData.length} internal items filtered)` + ); + return sanitizedData; } catch (error) { console.warn("Could not load search database:", error.message); searchData = []; // Set empty array to prevent further attempts diff --git a/tests/search-manager.test.js b/tests/search-manager.test.js new file mode 100644 index 0000000..7f1b0eb --- /dev/null +++ b/tests/search-manager.test.js @@ -0,0 +1,46 @@ +describe("search-manager sanitization", () => { + beforeEach(() => { + jest.resetModules(); + jest.clearAllMocks(); + document.body.innerHTML = ""; + delete window.SearchManager; + delete window.searchDatabaseForCommandPalette; + }); + + it("filters internal backlog pages from search results", async () => { + global.fetch = jest.fn().mockResolvedValue({ + ok: true, + json: () => + Promise.resolve([ + { + title: "Private todo blog public - Elasticity and viscoelasticity", + url: + "https://blogs.comphy-lab.org/Private-ToDo-Blog-public/" + + "#elasticity-and-viscoelasticity", + content: "internal planning item", + priority: 3, + }, + { + title: "0_todo blog public", + url: "https://blogs.comphy-lab.org/0_ToDo-Blog-public/", + content: "internal backlog page", + priority: 3, + }, + { + title: "Teaching - Teaching: Methods", + url: "https://comphy-lab.org/teaching/#teaching", + content: "public teaching overview", + priority: 3, + }, + ]), + }); + + require("../assets/js/search-manager.js"); + + const data = await window.SearchManager.loadSearchDatabase(); + + expect(data).toHaveLength(1); + expect(data[0].title).toBe("Teaching - Teaching: Methods"); + expect(data[0].url).toBe("https://comphy-lab.org/teaching/#teaching"); + }); +}); From 68fd176728ab254dcbf2cccf43cbc340cef22f95 Mon Sep 17 00:00:00 2001 From: comphy-bot Date: Tue, 31 Mar 2026 23:20:26 +0100 Subject: [PATCH 2/2] Fix search sanitization false positives --- assets/js/search-manager.js | 4 ++-- tests/search-manager.test.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/assets/js/search-manager.js b/assets/js/search-manager.js index f4ddcd0..26e1c4e 100644 --- a/assets/js/search-manager.js +++ b/assets/js/search-manager.js @@ -34,12 +34,12 @@ ]; function isInternalSearchEntry(entry) { - const combinedText = [entry?.title, entry?.url, entry?.content] + const entryIdentityText = [entry?.title, entry?.url] .filter(Boolean) .join(" "); return INTERNAL_SEARCH_PATTERNS.some((pattern) => - pattern.test(combinedText) + pattern.test(entryIdentityText) ); } diff --git a/tests/search-manager.test.js b/tests/search-manager.test.js index 7f1b0eb..6a80385 100644 --- a/tests/search-manager.test.js +++ b/tests/search-manager.test.js @@ -43,4 +43,38 @@ describe("search-manager sanitization", () => { expect(data[0].title).toBe("Teaching - Teaching: Methods"); expect(data[0].url).toBe("https://comphy-lab.org/teaching/#teaching"); }); + + it("keeps public pages whose content references internal backlog URLs", async () => { + global.fetch = jest.fn().mockResolvedValue({ + ok: true, + json: () => + Promise.resolve([ + { + title: "Skill - Badge Shapes", + url: "https://comphy-lab.org/.agents/skills/add-paper/SKILL/#badge-shapes", + content: + "Example badge config referencing https://blogs.comphy-lab.org/0_ToDo-Blog-public/ for documentation only.", + priority: 3, + }, + { + title: "Private todo blog public - Elasticity and viscoelasticity", + url: + "https://blogs.comphy-lab.org/Private-ToDo-Blog-public/" + + "#elasticity-and-viscoelasticity", + content: "internal planning item", + priority: 3, + }, + ]), + }); + + require("../assets/js/search-manager.js"); + + const data = await window.SearchManager.loadSearchDatabase(); + + expect(data).toHaveLength(1); + expect(data[0].title).toBe("Skill - Badge Shapes"); + expect(data[0].url).toBe( + "https://comphy-lab.org/.agents/skills/add-paper/SKILL/#badge-shapes" + ); + }); });