From edae8d520c6d84dc32fd9dee35873995d8f03da2 Mon Sep 17 00:00:00 2001 From: WangEn Date: Thu, 17 Sep 2026 19:38:41 +0800 Subject: [PATCH 1/5] fix: search Session tab titles and URLs in New Tab --- apps/extension/public/newtab-ux.js | 38 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/apps/extension/public/newtab-ux.js b/apps/extension/public/newtab-ux.js index 9bc3244..03cf05e 100644 --- a/apps/extension/public/newtab-ux.js +++ b/apps/extension/public/newtab-ux.js @@ -29,14 +29,42 @@ }; } + function queryTerms(value) { + return String(value || "").trim().toLocaleLowerCase().split(/\s+/).filter(Boolean); + } + + function valuesMatchQuery(query, values) { + const terms = queryTerms(query); + if (!terms.length) return true; + const haystack = values.map((value) => String(value || "")).join("\n").toLocaleLowerCase(); + return terms.every((term) => haystack.includes(term)); + } + + function matchingSessionItem(query, items) { + return items.find((item) => valuesMatchQuery(query, [item?.title, item?.url])) || null; + } + function sessionResult(query, session, index) { const items = asArray(session?.items).filter((item) => isHttpUrl(item?.url)); - const source = typeof session?.sourceDevice === "string" && session.sourceDevice.trim() - ? ` · ${session.sourceDevice.trim()}` + const sourceDevice = typeof session?.sourceDevice === "string" ? session.sourceDevice.trim() : ""; + const searchValues = [ + session?.name, + sourceDevice, + ...items.flatMap((item) => [item?.title, item?.url]), + ]; + if (!valuesMatchQuery(query, searchValues)) return null; + + const matchedItem = matchingSessionItem(query, items); + const source = sourceDevice ? ` · ${sourceDevice}` : ""; + const itemMatch = matchedItem + ? ` · ${matchedItem.title || displayHost(matchedItem.url)} · ${matchedItem.url}` : ""; - const subtitle = `${items.length} tab${items.length === 1 ? "" : "s"}${source}`; - const score = searchScore(query, session?.name, subtitle, 390); - if (score < 0) return null; + const subtitle = `${items.length} tab${items.length === 1 ? "" : "s"}${source}${itemMatch}`; + + let score = searchScore(query, session?.name, sourceDevice, 430); + if (score < 0 && matchedItem) score = searchScore(query, matchedItem?.title, matchedItem?.url, 400); + if (score < 0) score = 390; + return { kind: "session", title: session.name || "Session", From e162ba49b02128592bbccd9ef2385f06b698ae41 Mon Sep 17 00:00:00 2001 From: WangEn Date: Thu, 17 Sep 2026 19:39:08 +0800 Subject: [PATCH 2/5] test: cover Session tab title and URL search --- scripts/chromium-newtab-ux-smoke.mjs | 65 ++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/scripts/chromium-newtab-ux-smoke.mjs b/scripts/chromium-newtab-ux-smoke.mjs index 0328500..bf2ca27 100644 --- a/scripts/chromium-newtab-ux-smoke.mjs +++ b/scripts/chromium-newtab-ux-smoke.mjs @@ -171,21 +171,38 @@ try { } if (requestUrl.pathname === "/api/sessions") { return json({ - sessions: [{ - id: "session-ux", - name: "Morning Session", - sourceDevice: "Smoke browser", - createdAt: now, - updatedAt: now, - items: [{ - id: "session-item-ux", - sessionId: "session-ux", - title: "Session target", - url: `${origin}/session`, - pinned: false, - position: 0, - }], - }], + sessions: [ + { + id: "session-ux", + name: "Morning Session", + sourceDevice: "Smoke browser", + createdAt: now, + updatedAt: now, + items: [{ + id: "session-item-ux", + sessionId: "session-ux", + title: "Session target", + url: `${origin}/session`, + pinned: false, + position: 0, + }], + }, + { + id: "session-campus", + name: "Campus Tools", + sourceDevice: "Web", + createdAt: now, + updatedAt: now, + items: [{ + id: "session-item-campus", + sessionId: "session-campus", + title: "学生电子邮箱服务中心 — 北京信息科技大学 BIST", + url: "https://mail.bist.edu.cn/mail/", + pinned: false, + position: 0, + }], + }, + ], }); } return json({}); @@ -219,11 +236,24 @@ try { assert.match(await sessionRow.innerText(), /1 tab/); assert.match(await sessionRow.innerText(), /Smoke browser/); + await search.fill("学生电子"); + const campusByTitle = page.locator("#command-results .result-row").filter({ hasText: "Campus Tools" }).first(); + await campusByTitle.waitFor(); + assert.match(await campusByTitle.innerText(), /学生电子邮箱服务中心/); + + await search.fill("mail.bist"); + const campusByUrl = page.locator("#command-results .result-row").filter({ hasText: "Campus Tools" }).first(); + await campusByUrl.waitFor(); + assert.match(await campusByUrl.innerText(), /mail\.bist\.edu\.cn\/mail/); + + await search.fill("bist.edu.cn/mail"); + await page.locator("#command-results .result-row").filter({ hasText: "Campus Tools" }).first().waitFor(); + const cachedSessionNames = await page.evaluate(async () => { const stored = await chrome.storage.local.get("dockmarkNewTabCacheV1"); return (stored.dockmarkNewTabCacheV1?.sessions ?? []).map((session) => session.name); }); - assert.deepEqual(cachedSessionNames, ["Morning Session"]); + assert.deepEqual(cachedSessionNames, ["Morning Session", "Campus Tools"]); await search.fill("Cached Target"); const foregroundPromise = context.waitForEvent("page"); @@ -254,7 +284,8 @@ try { console.log("✓ New Tab suggests bare ! search-engine shortcuts and Enter accepts them"); console.log("✓ New Tab auto refresh hydrates and caches Sessions on the first real launcher load"); - console.log("✓ New Tab searches and restores a cloud-refreshed Session"); + console.log("✓ New Tab searches Sessions by name, tab title and partial tab URL"); + console.log("✓ New Tab restores a cloud-refreshed Session"); console.log("✓ Shift+Enter opens a selected URL in a foreground tab"); console.log("✓ Ctrl/Command+Enter opens a selected URL in a background tab"); console.log("✓ / focuses the launcher input from the New Tab page"); From e11c03ff9c9d97cb9109bb2d63a8e8780f45eb71 Mon Sep 17 00:00:00 2001 From: WangEn Date: Thu, 17 Sep 2026 19:39:38 +0800 Subject: [PATCH 3/5] chore: bump extension package to 1.5.2 --- apps/extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/extension/package.json b/apps/extension/package.json index 387c09f..5c74033 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -1,6 +1,6 @@ { "name": "@dockmark/extension", - "version": "1.5.1", + "version": "1.5.2", "private": true, "type": "module", "scripts": { From cc369418fab3f348be414375fdf7d8173f2d8ecb Mon Sep 17 00:00:00 2001 From: WangEn Date: Thu, 17 Sep 2026 19:39:46 +0800 Subject: [PATCH 4/5] chore: bump extension manifest to 1.5.2 --- apps/extension/wxt.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/extension/wxt.config.ts b/apps/extension/wxt.config.ts index fcdb2f5..08ea44c 100644 --- a/apps/extension/wxt.config.ts +++ b/apps/extension/wxt.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ modules: ["@wxt-dev/module-react"], manifest: ({ browser }) => ({ name: "Dockmark", - version: "1.5.1", + version: "1.5.2", description: "Browser bridge for Dockmark tabs, reviewed Capture Inbox, sessions, Smart Collection-aware local-first search, reviewed bookmark sync, local health checks and device pairing.", icons: { 16: "icons/dockmark-16.png", From 8dca0f139b7b9d3a2104d2e45fcfdb6ade52145b Mon Sep 17 00:00:00 2001 From: WangEn Date: Thu, 17 Sep 2026 19:39:57 +0800 Subject: [PATCH 5/5] chore: publish extension 1.5.2 to Web distribution --- apps/web/src/extension-distribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/extension-distribution.ts b/apps/web/src/extension-distribution.ts index 15e7146..a6cad1f 100644 --- a/apps/web/src/extension-distribution.ts +++ b/apps/web/src/extension-distribution.ts @@ -1,4 +1,4 @@ -export const EXTENSION_RELEASE_VERSION = "1.5.1"; +export const EXTENSION_RELEASE_VERSION = "1.5.2"; // Fill these when browser-store listings are public. The UI will promote the // store action while keeping manual downloads visible.