From 8864a36955800df055f0c3680a65d3b10cf460d5 Mon Sep 17 00:00:00 2001 From: tommy0103 Date: Mon, 20 Jul 2026 01:58:22 +0800 Subject: [PATCH] chore(release): prepare Obelisk v0.2.0 --- app/src/renderer/src/views/SessionDetail.vue | 4 +- app/tests/electron-session-virtualization.mjs | 43 +++++++++++++++++++ package-lock.json | 8 ++-- package.json | 2 +- packages/cli/package.json | 2 +- packages/core/package.json | 2 +- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/app/src/renderer/src/views/SessionDetail.vue b/app/src/renderer/src/views/SessionDetail.vue index 169d15f..b25fd12 100644 --- a/app/src/renderer/src/views/SessionDetail.vue +++ b/app/src/renderer/src/views/SessionDetail.vue @@ -293,7 +293,9 @@ async function fetchSessionSnapshot(sessionId, { force = false } = {}) { async function loadLiveSnapshot() { const sessionId = props.id; if (!sessionId) return null; - const revision = ++loadRevision; + // Live reload ordering is owned by the coordinator. Capture the current + // full-load generation so a patch cannot invalidate cold-open layout work. + const revision = loadRevision; const patchRequest = await fetchSessionDetailPatch(sessionId); return { sessionId, revision, patchRequest }; } diff --git a/app/tests/electron-session-virtualization.mjs b/app/tests/electron-session-virtualization.mjs index 064de52..6e880f3 100644 --- a/app/tests/electron-session-virtualization.mjs +++ b/app/tests/electron-session-virtualization.mjs @@ -11,6 +11,7 @@ const here = dirname(fileURLToPath(import.meta.url)); const appRoot = join(here, '..'); const sessionId = 'test-session'; const messageCount = Number(process.env.OBELISK_TIMELINE_MESSAGE_COUNT || 2000); +const coldOpenOnly = process.argv.includes('--cold-open-only'); const focusMessageIndex = Math.floor(messageCount * 0.75); const focusMessageUuid = `message-${focusMessageIndex}`; const stationaryAppendRuns = 3; @@ -645,11 +646,49 @@ async function run() { requestAnimationFrame(sample); window.location.hash = ${JSON.stringify(`/sessions/${sessionId}`)}; })()`, true); + const coldOpenUpdateTimer = setTimeout(() => { + win.webContents.send('obelisk:session-updated', { sessionId }); + }, 10); await waitFor( win.webContents, `document.querySelector('.flap-number')?.getAttribute('aria-label') === '${messageCount}'`, 'the cold-start session snapshot', ); + clearTimeout(coldOpenUpdateTimer); + for (let attempt = 0; attempt < 100 && ipcReads.patches === 0; attempt++) { + await delay(10); + } + const coldOpenPatchReads = ipcReads.patches; + await delay(250); + const coldOpenVisibility = await win.webContents.executeJavaScript(`(() => { + const header = document.querySelector('.session-header'); + const timeline = document.querySelector('.virtual-timeline'); + return { + total: Number(document.querySelector('.flap-number')?.getAttribute('aria-label')), + loading: Boolean(document.querySelector('.first-open-loading')), + headerVisibility: header ? getComputedStyle(header).visibility : null, + timelineVisibility: timeline ? getComputedStyle(timeline).visibility : null, + visibleRows: [...document.querySelectorAll('.virtual-timeline-row')] + .filter(row => getComputedStyle(row).visibility !== 'hidden').length, + patchReads: ${coldOpenPatchReads}, + }; + })()`, true); + const coldOpenRecovered = coldOpenVisibility.total === messageCount + && coldOpenVisibility.patchReads > 0 + && !coldOpenVisibility.loading + && coldOpenVisibility.headerVisibility === 'visible' + && coldOpenVisibility.timelineVisibility === 'visible' + && coldOpenVisibility.visibleRows > 0; + assert( + coldOpenRecovered, + `a live update during cold-open layout cannot strand populated session content hidden (${JSON.stringify(coldOpenVisibility)})`, + ); + if (!coldOpenRecovered) { + win.destroy(); + return; + } + ipcReads.patches = 0; + ipcReads.patchMessageRows.length = 0; await delay(100); const coldOpenOverlap = await win.webContents.executeJavaScript(`(() => { const probe = window.__coldOpenOverlapProbe; @@ -661,6 +700,10 @@ async function run() { coldOpenOverlap.maxOverlaps === 0, `cold-open timeline never paints intersecting message rows (${JSON.stringify(coldOpenOverlap)})`, ); + if (coldOpenOnly) { + win.destroy(); + return; + } const initial = await win.webContents.executeJavaScript(`(() => ({ current: Number(document.querySelector('.msg-nav-current')?.textContent), diff --git a/package-lock.json b/package-lock.json index 04fdf58..6d29140 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "obelisk", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "obelisk", - "version": "0.1.0", + "version": "0.2.0", "license": "AGPL-3.0", "workspaces": [ "packages/*" @@ -1289,7 +1289,7 @@ }, "packages/cli": { "name": "@obelisk-apps/cli", - "version": "0.1.0", + "version": "0.2.0", "license": "AGPL-3.0", "bin": { "obelisk": "dist/cli/src/obelisk.js" @@ -1300,7 +1300,7 @@ }, "packages/core": { "name": "@obelisk/core", - "version": "0.1.0" + "version": "0.2.0" } } } diff --git a/package.json b/package.json index 288fd92..6630a76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obelisk", - "version": "0.1.0", + "version": "0.2.0", "private": true, "type": "module", "description": "Explicit memory infrastructure for coding agents — a queryable SQLite evidence layer over local Claude Code and Codex history, plus human-approved durable memory.", diff --git a/packages/cli/package.json b/packages/cli/package.json index 452d86f..23ee17e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@obelisk-apps/cli", - "version": "0.1.0", + "version": "0.2.0", "description": "Local Obelisk runtime for coding agents.", "license": "AGPL-3.0", "type": "module", diff --git a/packages/core/package.json b/packages/core/package.json index 780e887..2052537 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@obelisk/core", - "version": "0.1.0", + "version": "0.2.0", "private": true, "type": "module", "description": "Shared indexing and query core for Obelisk transports.",