fix(#4999): show on-disk memory file paths
This commit is contained in:
1 parent
0585b35739
commit
e2e2182bc0
2 files changed
+117
-2
No files matched your search
+12
-2
@@ -4624,6 +4624,14 @@ function _memorySectionMtime(key) {
|
||||
return _memoryData.memory_mtime || 0;
|
||||
}
|
||||
|
||||
function _memorySectionPath(key) {
|
||||
if (!_memoryData) return '';
|
||||
if (key === 'user') return _memoryData.user_path || '';
|
||||
if (key === 'soul') return _memoryData.soul_path || '';
|
||||
if (key === 'project_context') return _memoryData.project_context_path || '';
|
||||
return _memoryData.memory_path || '';
|
||||
}
|
||||
|
||||
function _setMemoryHeaderButtons(mode) {
|
||||
const header = $('mainMemory') && $('mainMemory').querySelector('.main-view-header');
|
||||
const show = b => b && (b.style.display = '');
|
||||
@@ -4727,8 +4735,10 @@ function _renderMemoryDetail(section) {
|
||||
const mtime = _memorySectionMtime(section);
|
||||
const mtimeStr = mtime ? new Date(mtime * 1000).toLocaleString() : '';
|
||||
const mtimeHtml = mtimeStr ? `<div class="memory-detail-mtime">${esc(mtimeStr)}</div>` : '';
|
||||
const path = section === 'project_context' && _memoryData ? (_memoryData.project_context_path || '') : '';
|
||||
const fileName = section === 'project_context' && _memoryData ? (_memoryData.project_context_name || (path.split(/[\\/]/).pop() || '')) : '';
|
||||
const path = _memorySectionPath(section);
|
||||
const fileName = section === 'project_context' && _memoryData
|
||||
? (_memoryData.project_context_name || (path.split(/[\\/]/).pop() || ''))
|
||||
: (path.split(/[\\/]/).pop() || '');
|
||||
const pathHtml = path ? `<div class="memory-detail-mtime">${esc(fileName)} · ${esc(path)}</div>` : '';
|
||||
const shadowed = section === 'project_context' && _memoryData && Array.isArray(_memoryData.project_context_shadowed)
|
||||
? _memoryData.project_context_shadowed
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import json
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
from types import SimpleNamespace
|
||||
from urllib.parse import urlencode
|
||||
|
||||
@@ -8,6 +10,7 @@ import api.routes as routes
|
||||
|
||||
|
||||
REPO_ROOT = pathlib.Path(__file__).parent.parent.resolve()
|
||||
NODE = shutil.which("node")
|
||||
|
||||
|
||||
def project_context_for(workspace):
|
||||
@@ -129,6 +132,108 @@ def test_memory_panel_defines_read_only_project_context_section():
|
||||
assert "/api/memory?session_id=" in panels
|
||||
|
||||
|
||||
def test_memory_panel_references_all_memory_path_fields():
|
||||
panels = (REPO_ROOT / "static" / "panels.js").read_text(encoding="utf-8")
|
||||
|
||||
assert "function _memorySectionPath(key)" in panels
|
||||
assert "_memoryData.memory_path" in panels
|
||||
assert "_memoryData.user_path" in panels
|
||||
assert "_memoryData.soul_path" in panels
|
||||
assert "_memoryData.project_context_path" in panels
|
||||
|
||||
|
||||
def _memory_render_blocks():
|
||||
panels = (REPO_ROOT / "static" / "panels.js").read_text(encoding="utf-8")
|
||||
helper_start = panels.index("function _memorySectionContent(key)")
|
||||
helper_end = panels.index("function _setMemoryHeaderButtons", helper_start)
|
||||
render_start = panels.index("function _renderMemoryDetail(section)")
|
||||
render_end = panels.index("function _renderMemoryEdit", render_start)
|
||||
return panels[helper_start:helper_end], panels[render_start:render_end]
|
||||
|
||||
|
||||
def _run_memory_render_harness():
|
||||
helper_block, render_block = _memory_render_blocks()
|
||||
script = (
|
||||
"const helperBlock = "
|
||||
+ json.dumps(helper_block)
|
||||
+ ";\nconst renderBlock = "
|
||||
+ json.dumps(render_block)
|
||||
+ ";\n"
|
||||
+ r"""
|
||||
let _memoryData = {
|
||||
memory: 'Primary memory body',
|
||||
memory_path: 'C:/Users/Rod/.hermes/memories/MEMORY.md',
|
||||
memory_mtime: 1712345678,
|
||||
user: 'User memory body',
|
||||
user_path: 'C:/Users/Rod/.hermes/memories/USER.md',
|
||||
user_mtime: 1712345678,
|
||||
soul: 'Soul memory body',
|
||||
soul_path: 'C:/Users/Rod/.hermes/SOUL.md',
|
||||
soul_mtime: 1712345678,
|
||||
project_context: 'Project context body',
|
||||
project_context_path: 'D:/Repos/hermes-webui/AGENTS.md',
|
||||
project_context_name: 'AGENTS.md',
|
||||
project_context_mtime: 1712345678,
|
||||
project_context_shadowed: [{name: 'CLAUDE.md', shadowed_by: 'AGENTS.md'}],
|
||||
};
|
||||
let _memoryMode = '';
|
||||
const nodes = {
|
||||
memoryDetailTitle: {textContent: '', style: {}},
|
||||
memoryDetailBody: {innerHTML: '', style: {}},
|
||||
memoryDetailEmpty: {style: {}},
|
||||
};
|
||||
function $(id) { return nodes[id] || null; }
|
||||
function _memorySectionMeta(section) {
|
||||
return {key: section, label: section, emptyKey: section + '_empty'};
|
||||
}
|
||||
function _memorySectionLabel(meta) { return meta.label; }
|
||||
function _memorySectionEmpty(meta) { return meta.emptyKey; }
|
||||
function _setMemoryHeaderButtons() {}
|
||||
function renderMd(content) { return 'rendered:' + content; }
|
||||
function esc(value) {
|
||||
return String(value)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
eval(helperBlock + "\n" + renderBlock);
|
||||
_renderMemoryDetail('memory');
|
||||
const memoryHtml = nodes.memoryDetailBody.innerHTML;
|
||||
_renderMemoryDetail('project_context');
|
||||
const projectHtml = nodes.memoryDetailBody.innerHTML;
|
||||
console.log(JSON.stringify({memoryHtml, projectHtml, memoryMode: _memoryMode}));
|
||||
"""
|
||||
)
|
||||
completed = subprocess.run(
|
||||
[NODE, "-e", script],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
check=True,
|
||||
)
|
||||
return json.loads(completed.stdout)
|
||||
|
||||
|
||||
def test_memory_detail_renders_path_for_non_project_sections():
|
||||
"""Base-fails/head-passes regression for issue #4999.
|
||||
|
||||
On base, `_renderMemoryDetail('memory')` ignores `memory_path`, so the
|
||||
rendered header omits the path row entirely. On head, the same render must
|
||||
show `MEMORY.md · <path>` using the existing pinned header row pattern.
|
||||
"""
|
||||
if NODE is None:
|
||||
return
|
||||
|
||||
rendered = _run_memory_render_harness()
|
||||
|
||||
assert "MEMORY.md" in rendered["memoryHtml"]
|
||||
assert "C:/Users/Rod/.hermes/memories/MEMORY.md" in rendered["memoryHtml"]
|
||||
assert "AGENTS.md · D:/Repos/hermes-webui/AGENTS.md" in rendered["projectHtml"]
|
||||
assert "CLAUDE.md present, shadowed by AGENTS.md" in rendered["projectHtml"]
|
||||
|
||||
|
||||
def test_blank_session_workspace_does_not_resolve_to_server_cwd(monkeypatch):
|
||||
# Regression for the empty-workspace guard: a session with a blank workspace
|
||||
# (freshly-created/draft sessions) must return None rather than letting
|
||||
|
||||
Reference in new issue
Block a user