From 5a105fd4a473a5fa179d37fdb1eb55b14db60047 Mon Sep 17 00:00:00 2001 From: Sisyphus Date: Sun, 3 May 2026 14:21:52 +0000 Subject: [PATCH 1/8] fix: disable Luker browser graph mirror Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- index.js | 3 +-- tests/graph-persistence.mjs | 23 +++++++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 34e14b3..0089fd4 100644 --- a/index.js +++ b/index.js @@ -1517,7 +1517,7 @@ function buildPersistenceEnvironment( cacheStorageTier: authorityPrimary ? "none" : hostProfile === "luker" - ? localStoreTier + ? "none" : "none", }; } @@ -24235,4 +24235,3 @@ async function onCompactLukerSidecar() { debugLog("[ST-BME] 初始化完成"); })(); - diff --git a/tests/graph-persistence.mjs b/tests/graph-persistence.mjs index a2db2ee..c86a753 100644 --- a/tests/graph-persistence.mjs +++ b/tests/graph-persistence.mjs @@ -4505,10 +4505,16 @@ result = { assert.equal(legacyStored ?? null, null); await new Promise((resolve) => setTimeout(resolve, 0)); assert.equal( - Number(harness.api.getIndexedDbSnapshot()?.meta?.revision || 0) >= result.revision, - true, - "Luker 主存储成功后应异步补写本地缓存", + Number(harness.api.getIndexedDbSnapshot()?.meta?.revision || 0), + 0, + "Luker 主存储成功后默认不应补写浏览器本地大图谱缓存 revision", ); + assert.equal( + Number(harness.api.getIndexedDbSnapshot()?.nodes?.length || 0), + 0, + "Luker 主存储成功后默认不应补写浏览器本地大图谱缓存 nodes", + ); + assert.equal(result.cacheTier, "none"); assert.equal( harness.api.getGraphPersistenceState().acceptedStorageTier, "luker-chat-state", @@ -4566,9 +4572,14 @@ result = { await new Promise((resolve) => setTimeout(resolve, 0)); assert.equal( - harness.api.getIndexedDbSnapshot()?.nodes?.[0]?.fields?.title, - "事件-luker-detached", - "Luker queued save 的异步本地 mirror 不应被后续 live graph 修改污染", + Number(harness.api.getIndexedDbSnapshot()?.meta?.revision || 0), + 0, + "Luker queued save 默认不应写入浏览器本地大图谱缓存 revision", + ); + assert.equal( + Number(harness.api.getIndexedDbSnapshot()?.nodes?.length || 0), + 0, + "Luker queued save 默认不应写入浏览器本地大图谱缓存 nodes", ); } From 6e4ba0f2264b64c16c215d3f3329eef7bcafb479 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 3 May 2026 15:21:13 +0000 Subject: [PATCH 2/8] chore: bump manifest version [skip ci] --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 4eb3fe2..18df77c 100644 --- a/manifest.json +++ b/manifest.json @@ -6,6 +6,6 @@ "js": "index.js", "css": "style.css", "author": "Youzini", - "version": "6.2.4", + "version": "6.2.5", "homePage": "https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology" } From bb365f172ed571e687553f8acbd4fa34e6164233 Mon Sep 17 00:00:00 2001 From: Sisyphus Date: Sun, 3 May 2026 15:24:34 +0000 Subject: [PATCH 3/8] feat(panel): show Luker browser cache status Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- ui/panel.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/panel.js b/ui/panel.js index 61ede94..b9ee6b0 100644 --- a/ui/panel.js +++ b/ui/panel.js @@ -3326,6 +3326,7 @@ function _refreshTaskPersistence() { ["Journal", journalStateLabel], ["Checkpoint rev", checkpointRevisionLabel], ["缓存落后", cacheLagLabel], + ["浏览器缓存", ps.cacheStorageTier === "none" ? "已关闭(推荐)" : `${cacheTierLabel} · ${mirrorLabel}`], ); } diagnosticRows.push( From 10ec2ded14b477dbe9994e1732bc7c06f11a3707 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 3 May 2026 15:25:50 +0000 Subject: [PATCH 4/8] chore: bump manifest version [skip ci] --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 18df77c..7f0b833 100644 --- a/manifest.json +++ b/manifest.json @@ -6,6 +6,6 @@ "js": "index.js", "css": "style.css", "author": "Youzini", - "version": "6.2.5", + "version": "6.2.6", "homePage": "https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology" } From 03696b786a3260ac22481f0954ccce5acab2f96b Mon Sep 17 00:00:00 2001 From: Sisyphus Date: Sun, 3 May 2026 15:27:16 +0000 Subject: [PATCH 5/8] test: cover Luker persistence without Authority Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- tests/graph-persistence.mjs | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/graph-persistence.mjs b/tests/graph-persistence.mjs index c86a753..e19dd98 100644 --- a/tests/graph-persistence.mjs +++ b/tests/graph-persistence.mjs @@ -4525,6 +4525,74 @@ result = { ); } +{ + const chatId = "chat-luker-no-authority-primary"; + const harness = await createGraphPersistenceHarness({ + chatId, + globalChatId: chatId, + characterId: "char-luker-no-authority", + chatMetadata: { + integrity: "meta-luker-no-authority-primary", + }, + }); + harness.runtimeContext.Luker = { + getContext() { + return harness.runtimeContext.__chatContext; + }, + }; + harness.runtimeContext.extension_settings[MODULE_NAME] = { + authorityEnabled: "on", + authorityPrimaryWhenAvailable: true, + authorityStorageMode: "server-primary", + authoritySqlPrimary: true, + authorityBrowserCacheMode: "minimal", + }; + harness.api.setAuthorityCapabilityState({ + installed: false, + healthy: false, + serverPrimaryReady: false, + storagePrimaryReady: false, + reason: "authority-not-installed", + }); + harness.api.setCurrentGraph( + stampPersistedGraph( + createMeaningfulGraph(chatId, "luker-no-authority"), + { + revision: 7, + integrity: "meta-luker-no-authority-primary", + chatId, + reason: "luker-no-authority-seed", + }, + ), + ); + + const result = await harness.api.persistExtractionBatchResult({ + reason: "luker-no-authority-persist", + lastProcessedAssistantFloor: 5, + }); + + assert.equal(result.accepted, true); + assert.equal(result.storageTier, "luker-chat-state"); + assert.equal(result.acceptedBy, "luker-chat-state"); + assert.equal(result.primaryTier, "luker-chat-state"); + assert.equal(result.cacheTier, "none"); + const manifest = await harness.runtimeContext.__chatContext.getChatState( + LUKER_GRAPH_MANIFEST_NAMESPACE, + ); + assert.equal(manifest?.storageTier, "luker-chat-state"); + assert.equal(manifest?.headRevision, result.revision); + assert.equal( + Number(harness.api.getIndexedDbSnapshot()?.meta?.revision || 0), + 0, + "Authority 不可用时,Luker 主存储不应回退写浏览器大图谱缓存 revision", + ); + assert.equal( + Number(harness.api.getIndexedDbSnapshot()?.nodes?.length || 0), + 0, + "Authority 不可用时,Luker 主存储不应回退写浏览器大图谱缓存 nodes", + ); +} + { const harness = await createGraphPersistenceHarness({ chatId: "chat-luker-queued-save-detached", From 24a4568f707329abed7931aeec3ed800b20db195 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 3 May 2026 15:28:23 +0000 Subject: [PATCH 6/8] chore: bump manifest version [skip ci] --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 7f0b833..c47998e 100644 --- a/manifest.json +++ b/manifest.json @@ -6,6 +6,6 @@ "js": "index.js", "css": "style.css", "author": "Youzini", - "version": "6.2.6", + "version": "6.2.7", "homePage": "https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology" } From fe89c8b2043e6b45e33c042a889c9f43cd51e6f7 Mon Sep 17 00:00:00 2001 From: Sisyphus Date: Sun, 3 May 2026 15:30:22 +0000 Subject: [PATCH 7/8] test: protect manual Luker cache rebuild Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- tests/graph-persistence.mjs | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/graph-persistence.mjs b/tests/graph-persistence.mjs index e19dd98..b94661e 100644 --- a/tests/graph-persistence.mjs +++ b/tests/graph-persistence.mjs @@ -159,6 +159,10 @@ const messageSnippet = extractSnippet( 'function onMessageReceived(messageId = null, type = "") {', "async function onViewGraph() {", ); +const lukerCacheActionSnippet = extractSnippet( + "async function onRebuildLocalCacheFromLukerSidecar() {", + "async function onRepairLukerSidecar() {", +); function createSessionStorage(seed = null) { const store = seed instanceof Map ? seed : new Map(); @@ -1555,6 +1559,7 @@ async function createGraphPersistenceHarness({ persistencePrelude, persistenceCore, messageSnippet, + lukerCacheActionSnippet, ` result = { GRAPH_LOAD_STATES, @@ -1576,6 +1581,7 @@ result = { maybeFlushQueuedGraphPersist, retryPendingGraphPersist, persistExtractionBatchResult, + onRebuildLocalCacheFromLukerSidecar, saveGraphToIndexedDb, cloneGraphForPersistence, assertRecoveryChatStillActive, @@ -4651,6 +4657,60 @@ result = { ); } +{ + const chatId = "chat-luker-manual-cache-rebuild"; + const harness = await createGraphPersistenceHarness({ + chatId, + globalChatId: chatId, + characterId: "char-luker-manual-cache-rebuild", + chatMetadata: { + integrity: "meta-luker-manual-cache-rebuild", + }, + }); + harness.runtimeContext.Luker = { + getContext() { + return harness.runtimeContext.__chatContext; + }, + }; + const graph = stampPersistedGraph( + createMeaningfulGraph(chatId, "luker-manual-cache"), + { + revision: 10, + integrity: "meta-luker-manual-cache-rebuild", + chatId, + reason: "luker-manual-cache-seed", + }, + ); + harness.api.setCurrentGraph(graph); + const persistResult = await harness.api.persistExtractionBatchResult({ + reason: "luker-manual-cache-persist", + lastProcessedAssistantFloor: 6, + }); + await new Promise((resolve) => setTimeout(resolve, 0)); + assert.equal(persistResult.cacheTier, "none"); + assert.equal( + Number(harness.api.getIndexedDbSnapshot()?.meta?.revision || 0), + 0, + "Luker 默认路径不应自动重建浏览器缓存", + ); + + const rebuildResult = await harness.api.onRebuildLocalCacheFromLukerSidecar(); + assert.equal(rebuildResult.handledToast, true); + assert.equal(rebuildResult.result?.loaded, true); + await new Promise((resolve) => setTimeout(resolve, 0)); + await new Promise((resolve) => setTimeout(resolve, 0)); + assert.equal( + Number(harness.api.getIndexedDbSnapshot()?.meta?.revision || 0), + persistResult.revision, + "只有手动重建本地缓存时才应写入浏览器缓存 revision", + ); + assert.equal( + Number(harness.api.getIndexedDbSnapshot()?.nodes?.length || 0), + 1, + "只有手动重建本地缓存时才应写入浏览器缓存 nodes", + ); +} + { const harness = await createGraphPersistenceHarness({ chatId: "chat-luker-v2-load", From 793d3f4d78cb5120244c190f70d10bcc52148caf Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 3 May 2026 15:31:36 +0000 Subject: [PATCH 8/8] chore: bump manifest version [skip ci] --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index c47998e..f653204 100644 --- a/manifest.json +++ b/manifest.json @@ -6,6 +6,6 @@ "js": "index.js", "css": "style.css", "author": "Youzini", - "version": "6.2.7", + "version": "6.2.8", "homePage": "https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology" }