chore(release): prepare Obelisk v0.2.0

This commit is contained in:
tommy0103
2026-07-20 01:58:22 +08:00
parent d399ab154f
commit 8864a36955
6 changed files with 53 additions and 8 deletions
+3 -1
View File
@@ -293,7 +293,9 @@ async function fetchSessionSnapshot(sessionId, { force = false } = {}) {
async function loadLiveSnapshot() { async function loadLiveSnapshot() {
const sessionId = props.id; const sessionId = props.id;
if (!sessionId) return null; 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); const patchRequest = await fetchSessionDetailPatch(sessionId);
return { sessionId, revision, patchRequest }; return { sessionId, revision, patchRequest };
} }
@@ -11,6 +11,7 @@ const here = dirname(fileURLToPath(import.meta.url));
const appRoot = join(here, '..'); const appRoot = join(here, '..');
const sessionId = 'test-session'; const sessionId = 'test-session';
const messageCount = Number(process.env.OBELISK_TIMELINE_MESSAGE_COUNT || 2000); 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 focusMessageIndex = Math.floor(messageCount * 0.75);
const focusMessageUuid = `message-${focusMessageIndex}`; const focusMessageUuid = `message-${focusMessageIndex}`;
const stationaryAppendRuns = 3; const stationaryAppendRuns = 3;
@@ -645,11 +646,49 @@ async function run() {
requestAnimationFrame(sample); requestAnimationFrame(sample);
window.location.hash = ${JSON.stringify(`/sessions/${sessionId}`)}; window.location.hash = ${JSON.stringify(`/sessions/${sessionId}`)};
})()`, true); })()`, true);
const coldOpenUpdateTimer = setTimeout(() => {
win.webContents.send('obelisk:session-updated', { sessionId });
}, 10);
await waitFor( await waitFor(
win.webContents, win.webContents,
`document.querySelector('.flap-number')?.getAttribute('aria-label') === '${messageCount}'`, `document.querySelector('.flap-number')?.getAttribute('aria-label') === '${messageCount}'`,
'the cold-start session snapshot', '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); await delay(100);
const coldOpenOverlap = await win.webContents.executeJavaScript(`(() => { const coldOpenOverlap = await win.webContents.executeJavaScript(`(() => {
const probe = window.__coldOpenOverlapProbe; const probe = window.__coldOpenOverlapProbe;
@@ -661,6 +700,10 @@ async function run() {
coldOpenOverlap.maxOverlaps === 0, coldOpenOverlap.maxOverlaps === 0,
`cold-open timeline never paints intersecting message rows (${JSON.stringify(coldOpenOverlap)})`, `cold-open timeline never paints intersecting message rows (${JSON.stringify(coldOpenOverlap)})`,
); );
if (coldOpenOnly) {
win.destroy();
return;
}
const initial = await win.webContents.executeJavaScript(`(() => ({ const initial = await win.webContents.executeJavaScript(`(() => ({
current: Number(document.querySelector('.msg-nav-current')?.textContent), current: Number(document.querySelector('.msg-nav-current')?.textContent),
+4 -4
View File
@@ -1,12 +1,12 @@
{ {
"name": "obelisk", "name": "obelisk",
"version": "0.1.0", "version": "0.2.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "obelisk", "name": "obelisk",
"version": "0.1.0", "version": "0.2.0",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
@@ -1289,7 +1289,7 @@
}, },
"packages/cli": { "packages/cli": {
"name": "@obelisk-apps/cli", "name": "@obelisk-apps/cli",
"version": "0.1.0", "version": "0.2.0",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"bin": { "bin": {
"obelisk": "dist/cli/src/obelisk.js" "obelisk": "dist/cli/src/obelisk.js"
@@ -1300,7 +1300,7 @@
}, },
"packages/core": { "packages/core": {
"name": "@obelisk/core", "name": "@obelisk/core",
"version": "0.1.0" "version": "0.2.0"
} }
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "obelisk", "name": "obelisk",
"version": "0.1.0", "version": "0.2.0",
"private": true, "private": true,
"type": "module", "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.", "description": "Explicit memory infrastructure for coding agents — a queryable SQLite evidence layer over local Claude Code and Codex history, plus human-approved durable memory.",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@obelisk-apps/cli", "name": "@obelisk-apps/cli",
"version": "0.1.0", "version": "0.2.0",
"description": "Local Obelisk runtime for coding agents.", "description": "Local Obelisk runtime for coding agents.",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"type": "module", "type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@obelisk/core", "name": "@obelisk/core",
"version": "0.1.0", "version": "0.2.0",
"private": true, "private": true,
"type": "module", "type": "module",
"description": "Shared indexing and query core for Obelisk transports.", "description": "Shared indexing and query core for Obelisk transports.",