Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions packages/app-bundle/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@
"packages/app/e2e/regression/review-line-comment.spec.ts": "953e9c67ed4cee91968369088237cf2288558eaa55e55b61f385571bccad7003",
"packages/app/e2e/regression/session-timeline-lifecycle-state.spec.ts": "00bfd4f6199c1b350d14a9eda5e3a4c546b020df32e3604609326281869d6d4f",
"packages/app/e2e/regression/session-timeline-tool-projection.spec.ts": "c0bb866b113d38ddec084e04027030cf5b7c81f1fe4e6ee88fcd7b1b161296c3",
"packages/app/e2e/regression/tab-dblclick-close.spec.ts": "7bf9490c2f39281c7751c39747bb720ec1b5571d7b7ddc803686071aa8ad55aa",
"packages/app/e2e/regression/tab-close-gestures.spec.ts": "630eb5076fd3555ef80cd2634262194e005e2bfdca5f1b222a169d77a177859d",
"packages/app/e2e/regression/tab-navigate-mousedown.spec.ts": "8521d43183f0df624449edbba8ee4dc646f0ecb84a9c5a04d275613f9da875ae",
"packages/app/e2e/regression/tab-strip-organize.spec.ts": "c96f72c665388e50006a02299252ba73aa551937a09e39aea758d8d8a9bcd221",
"packages/app/e2e/regression/workbench-drops.spec.ts": "0188f4f1ff07a40945a4900bfa85e21a4f578be9f18257a803200a18ce41ac05",
"packages/app/e2e/regression/workbench-panes.spec.ts": "e0dfb84bd1b8be00a89cf48387aeaab5ec75845e8efbc8e4fa8252204fb27e8f",
"packages/app/e2e/smoke/session-timeline.spec.ts": "4006274a5001e36502e16b11ef7b9caee5dfdad2280766380470c72118b7fd90",
Expand Down Expand Up @@ -186,12 +187,17 @@
"packages/app/src/components/titlebar-layout.ts": "f8e1950c75ae0530b96208a8146ad9efe20f8b8d8c2ae8dd3025b9b9809b4831",
"packages/app/src/components/titlebar-portal-dedup.test.ts": "99034b76bf7896247a7eb8d492e7801ac2d67290cce226e70487c008eaff2a1f",
"packages/app/src/components/titlebar-portal-registry.ts": "e6a159c44490125046ddbb249fbda5cef6cef383a604a168cb4018cf49025521",
"packages/app/src/components/titlebar-tab-nav.css": "90930c2f9476fb0eace8692424a029b3510781c88d1ee61f7f2edba559526832",
"packages/app/src/components/titlebar-tab-nav.tsx": "0d5e11f63006e87fc42a4682c481203f50622677b07a8ff87a3348613cdf3674",
"packages/app/src/components/titlebar-tab-arrange.test.ts": "eb249ecb84fcfeabfbf7e1f6653fccd930c39b70008a23b1d5517358c0652088",
"packages/app/src/components/titlebar-tab-arrange.ts": "1888e28edd3c1e45259f2249eaa88af6196150866537282d39bc00337e3ae2f5",
"packages/app/src/components/titlebar-tab-list.tsx": "c5fcf03408a7fb8b958d0db94639f6317adab07547c2f2eb30555af96e3eb34b",
"packages/app/src/components/titlebar-tab-menu.tsx": "aefc11ff78cd0ff369beb9541e2f338a3a4371d10e106397ef82c03b246c47ba",
"packages/app/src/components/titlebar-tab-nav.css": "710e92ab9d9af1d1ef0746018d185c868835fa3fc3bb11d8bf6e11b3a3f53263",
"packages/app/src/components/titlebar-tab-nav.tsx": "fb852c6514b015afd2bdd92a688506ce408dcc71cdc407b28b7c2c08894443be",
"packages/app/src/components/titlebar-tab-popover.css": "d731db2d7d49838004089a3d82ff68c22214b0ca636bf3b8e02498c14dadbf8d",
"packages/app/src/components/titlebar-tab-strip.tsx": "a3c8a8df186a6164494230bec7f302cfe3a1cf658e3ab10f9ef0af4f5d63c038",
"packages/app/src/components/titlebar-tab-popover.tsx": "9cf6fa24c0099b42aa244454666e5d73014dd38e32bb3b2c5c214e9c572b13be",
"packages/app/src/components/titlebar-tab-strip.tsx": "17fcc3ee571e807ec10c41211a06dd8a61f151d1cd262056b86ba5daba982f07",
"packages/app/src/components/titlebar.css": "50c262603ba1140db9e4fefe8f03e9c6ae3bf64dc7a917e55586bfd67a5e3011",
"packages/app/src/components/titlebar.tsx": "51b5fae599e040cacd3f9c0d978d896eb72351f4f592f15dd6b94c759bccf260",
"packages/app/src/components/titlebar.tsx": "02350cb60b47316d2c08cdc0bbf868aa0bf325433733d27ace8033bdd4eeada6",
"packages/app/src/components/vault-browser-model.test.ts": "7ca11eae3574033d58081bc4126b1ec772a5b496573c70159f05497a1365f4cd",
"packages/app/src/components/vault-browser-model.ts": "d9ef6ff588a96ae79b13c3ae0c2a442a42b59021dd501b3a17bd810dda6f7b20",
"packages/app/src/components/vault-browser.tsx": "509efa874d69bcd07ef2495a025bc8de2b2fa582736003ff709b4ca76096274b",
Expand Down Expand Up @@ -257,8 +263,9 @@
"packages/app/src/context/stream-gap.ts": "2fd8eba30a6112cebf38e33c9418ab2b7d9c9d466f76729d828d5ab52d56c5ec",
"packages/app/src/context/stream-liveness.test.ts": "2759eb2233f8ff6ced02957f971e756fe525575b2c8aefcbd7749470dec960f2",
"packages/app/src/context/stream-liveness.ts": "875fe871312ad15f6376b933659c152f2241b8101e70de97ed410a720cbbafaa",
"packages/app/src/context/tab-migration.ts": "569e69cd3425917c7e195f91c3a838abea68b616267ea7511f3ccf01d94ac01e",
"packages/app/src/context/tabs.tsx": "06d6ddb6d50727a4e0a01ac1ca4a70b06bf63a4e5f881526aead54ccde62472b",
"packages/app/src/context/tab-migration.test.ts": "09f8087df7c343653329a233545f6edb77ce01f0f8362051aedd8712c89954a6",
"packages/app/src/context/tab-migration.ts": "197d7063bf48ea0d2868e30252319aac4b57bc85441132e99f9d0d940ea6f877",
"packages/app/src/context/tabs.tsx": "dd2ec1bb13683b3fd2c0348fd735410c2d1203e1456d6a392d09e98e71492b3a",
"packages/app/src/context/vault-panel.ts": "f91cb5fb49a9f0d46bd2a1b131f9a218b30147e2ad3617d2a2dc4f1e14599a53",
"packages/app/src/context/workbench.tsx": "69a44da2b69989bd2c67ebffdb49941841f3f4718d6a70d659c828b57928d9eb",
"packages/app/src/context/zoom-keybind.test.ts": "a1385c93639687a7dac7d21f8f02841d82a55e42465ce3836b97b16c82b52469",
Expand Down Expand Up @@ -1102,11 +1109,11 @@
"packages/ui/src/v2/components/text-shimmer-v2.tsx"
],
"exceptions": [],
"extracted_at": "2026-11-07T23:24:13.583Z",
"extracted_at": "2026-11-08T15:26:48.452Z",
"per_package": {
"packages/app": {
"A": 312,
"M": 166,
"A": 318,
"M": 167,
"D": 0
},
"packages/core": {
Expand Down Expand Up @@ -1151,7 +1158,7 @@
}
},
"counts": {
"overlay_total": 1080,
"overlay_total": 1087,
"deletions": 7,
"server_coupled": 0
},
Expand Down Expand Up @@ -1238,8 +1245,9 @@
"packages/app/e2e/regression/review-line-comment.spec.ts": "M",
"packages/app/e2e/regression/session-timeline-lifecycle-state.spec.ts": "M",
"packages/app/e2e/regression/session-timeline-tool-projection.spec.ts": "M",
"packages/app/e2e/regression/tab-dblclick-close.spec.ts": "A",
"packages/app/e2e/regression/tab-close-gestures.spec.ts": "A",
"packages/app/e2e/regression/tab-navigate-mousedown.spec.ts": "M",
"packages/app/e2e/regression/tab-strip-organize.spec.ts": "A",
"packages/app/e2e/regression/workbench-drops.spec.ts": "A",
"packages/app/e2e/regression/workbench-panes.spec.ts": "A",
"packages/app/e2e/smoke/session-timeline.spec.ts": "M",
Expand Down Expand Up @@ -1334,9 +1342,14 @@
"packages/app/src/components/titlebar-layout.ts": "A",
"packages/app/src/components/titlebar-portal-dedup.test.ts": "A",
"packages/app/src/components/titlebar-portal-registry.ts": "A",
"packages/app/src/components/titlebar-tab-arrange.test.ts": "A",
"packages/app/src/components/titlebar-tab-arrange.ts": "A",
"packages/app/src/components/titlebar-tab-list.tsx": "A",
"packages/app/src/components/titlebar-tab-menu.tsx": "A",
"packages/app/src/components/titlebar-tab-nav.css": "M",
"packages/app/src/components/titlebar-tab-nav.tsx": "M",
"packages/app/src/components/titlebar-tab-popover.css": "M",
"packages/app/src/components/titlebar-tab-popover.tsx": "M",
"packages/app/src/components/titlebar-tab-strip.tsx": "M",
"packages/app/src/components/titlebar.css": "M",
"packages/app/src/components/titlebar.tsx": "M",
Expand Down Expand Up @@ -1405,6 +1418,7 @@
"packages/app/src/context/stream-gap.ts": "A",
"packages/app/src/context/stream-liveness.test.ts": "A",
"packages/app/src/context/stream-liveness.ts": "A",
"packages/app/src/context/tab-migration.test.ts": "A",
"packages/app/src/context/tab-migration.ts": "M",
"packages/app/src/context/tabs.tsx": "M",
"packages/app/src/context/vault-panel.ts": "A",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ const server = "http://127.0.0.1:4096"
const sessionA = session("ses_tab_a", "Tab A session")
const sessionB = session("ses_tab_b", "Tab B session")

test("double-clicking a session tab closes it", async ({ page }) => {
// Closing a tab without hunting for it: middle-click closes a background tab;
// the close button closes the active one and moves to its neighbour.
// (Double-click on the title renames — see titlebar_dblclick_close.test.ts in
// the extension; this spec used to assert double-click-to-close, which the
// .18 tab rework replaced.)

test("middle-clicking a background session tab closes it", async ({ page }) => {
await mockServer(page)
await page.addInitScript(
({ server, sessionA, sessionB }) => {
Expand All @@ -26,23 +32,18 @@ test("double-clicking a session tab closes it", async ({ page }) => {
const hrefB = `/server/${base64Encode(server)}/session/${sessionB.id}`
await page.goto(hrefA)
await expect(page.getByText(sessionA.title).first()).toBeVisible()

// Both tabs should be visible
await expect(page.locator("[data-titlebar-tab-slot]:visible")).toHaveCount(2)

// Double-click the B tab container (not the title rename area) to close it
const tabB = page.locator(`[data-titlebar-tab-slot]:has(a[href="${hrefB}"]) [data-titlebar-tab]`)
await expect(tabB).toBeVisible()
await tabB.dblclick()
await tabB.click({ button: "middle" })

// B should be removed — only A remains
await expect(page.locator("[data-titlebar-tab-slot]:visible")).toHaveCount(1)
await expect(page.locator(`a[data-titlebar-tab-link][href="${hrefB}"]`)).toHaveCount(0)
// A stays active
await expect(page).toHaveURL(new RegExp(`${hrefA.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`))
})

test("double-clicking the active session tab closes it and navigates to neighbor", async ({ page }) => {
test("the close button on the active session tab closes it and navigates to its neighbour", async ({ page }) => {
await mockServer(page)
await page.addInitScript(
({ server, sessionA, sessionB }) => {
Expand All @@ -63,11 +64,8 @@ test("double-clicking the active session tab closes it and navigates to neighbor
await page.goto(hrefA)
await expect(page.locator("[data-titlebar-tab-slot]:visible")).toHaveCount(2)

const tabA = page.locator(`[data-titlebar-tab-slot]:has(a[href="${hrefA}"]) [data-titlebar-tab]`)
await expect(tabA).toBeVisible()
await tabA.dblclick()
await page.getByRole("button", { name: `Close ${sessionA.title}` }).click()

// A closed — B should be the remaining tab and active
await expect(page.locator("[data-titlebar-tab-slot]:visible")).toHaveCount(1)
await expect(page.locator(`a[data-titlebar-tab-link][href="${hrefA}"]`)).toHaveCount(0)
await expect(page).toHaveURL(new RegExp(`${hrefB.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`))
Expand Down
Loading
Loading