diff --git a/style.css b/style.css
index ba88702..af3a368 100644
--- a/style.css
+++ b/style.css
@@ -1438,6 +1438,101 @@
flex-wrap: wrap;
}
+/* ==================== Memory Popup (Mobile) ==================== */
+
+.bme-memory-popup-scrim {
+ position: fixed;
+ inset: 0;
+ z-index: 999;
+ background: rgba(0, 0, 0, 0.55);
+ backdrop-filter: blur(2px);
+ -webkit-backdrop-filter: blur(2px);
+ cursor: pointer;
+}
+
+.bme-memory-popup-scrim[hidden] {
+ display: none !important;
+}
+
+.bme-memory-popup {
+ display: none;
+ position: fixed;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%) scale(0.92);
+ width: min(460px, calc(100vw - 24px));
+ max-height: min(82vh, 680px);
+ background: var(--bme-surface, #131316);
+ border: 1px solid var(--bme-border);
+ border-radius: 14px;
+ box-shadow: 0 12px 48px rgba(0, 0, 0, 0.65);
+ z-index: 1000;
+ overflow-y: auto;
+ padding: 18px;
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+ transition: transform 0.18s ease, opacity 0.18s ease, visibility 0.18s ease;
+}
+
+.bme-memory-popup.open {
+ display: block;
+ transform: translate(-50%, -50%) scale(1);
+ opacity: 1;
+ visibility: visible;
+ pointer-events: auto;
+}
+
+.bme-memory-popup__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ margin-bottom: 10px;
+}
+
+.bme-memory-popup__title {
+ font-size: 16px;
+ font-weight: 700;
+ color: var(--bme-on-surface);
+ margin: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.bme-memory-popup__actions {
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ flex-shrink: 0;
+}
+
+.bme-memory-popup__badges {
+ display: flex;
+ gap: 6px;
+ flex-wrap: wrap;
+ margin-bottom: 12px;
+}
+
+.bme-memory-popup__body {
+ font-size: 12px;
+ color: var(--bme-on-surface);
+}
+
+.bme-memory-popup::-webkit-scrollbar {
+ width: 4px;
+}
+
+.bme-memory-popup::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+.bme-memory-popup::-webkit-scrollbar-thumb {
+ background: var(--bme-surface-highest);
+ border-radius: 2px;
+}
+
/* ==================== Injection Preview ==================== */
.bme-injection-token-bar {
@@ -7063,11 +7158,11 @@
width: 100%;
max-width: none;
border-right: none;
- border-bottom: 1px solid var(--bme-border);
- max-height: 40vh;
+ border-bottom: none;
+ max-height: none;
}
.bme-memory-detail-panel {
- padding: 14px;
+ display: none;
}
.bme-batch-stages {
flex-wrap: wrap;
diff --git a/ui/panel.html b/ui/panel.html
index 8b99843..04c0d07 100644
--- a/ui/panel.html
+++ b/ui/panel.html
@@ -2986,6 +2986,26 @@
+
+
+
diff --git a/ui/panel.js b/ui/panel.js
index 10f2e57..26cbdb9 100644
--- a/ui/panel.js
+++ b/ui/panel.js
@@ -932,6 +932,7 @@ export async function initPanel({
_bindTabs();
_bindClose();
_bindNodeDetailPanel();
+ _bindMemoryPopup();
_bindResizeHandle();
_bindPanelResize();
_bindGraphControls();
@@ -1186,6 +1187,7 @@ export function openPanel() {
export function closePanel() {
if (!overlayEl) return;
overlayEl.classList.remove("active");
+ _closeMemoryPopup();
_clearScheduledVisibleGraphRefresh();
lastVisibleGraphRefreshToken = "";
}
@@ -1246,6 +1248,7 @@ function _switchTab(tabId) {
}
currentTabId = next;
_closeNodeDetailUi();
+ _closeMemoryPopup();
panelEl?.querySelectorAll(".bme-tab-btn").forEach((btn) => {
btn.classList.toggle("active", btn.dataset.tab === currentTabId);
});
@@ -1352,6 +1355,7 @@ function _bindTaskNavigation() {
function _switchTaskSection(sectionId) {
currentTaskSectionId = sectionId || "pipeline";
+ _closeMemoryPopup();
_syncTaskSectionState();
_refreshTaskMonitor();
}
@@ -1758,7 +1762,12 @@ function _bindTaskMemoryListClick() {
currentSelectedMemoryNodeId = item.dataset.nodeId || "";
list.querySelectorAll(".bme-memory-node-item").forEach((n) => n.classList.toggle("selected", n.dataset.nodeId === currentSelectedMemoryNodeId));
const graph = _getGraph?.();
- _renderTaskMemoryDetailSelection(graph);
+ if (_isMobile()) {
+ const node = (graph?.nodes || []).find((c) => c.id === currentSelectedMemoryNodeId) || null;
+ if (node) _openMemoryPopup(node, graph);
+ } else {
+ _renderTaskMemoryDetailSelection(graph);
+ }
});
}
@@ -1832,20 +1841,31 @@ function _renderTaskMemoryDetailPanel(detailEl, node, graph) {
}
function _saveTaskMemoryDetail() {
- const detailEl = document.getElementById("bme-task-memory-detail");
- const bodyEl = detailEl?.querySelector("#bme-task-memory-editor-body");
+ const popupBody = document.getElementById("bme-memory-popup-body");
+ const popupOpen = document.getElementById("bme-memory-popup")?.classList.contains("open");
+ const detailEl = popupOpen ? null : document.getElementById("bme-task-memory-detail");
+ const bodyEl = popupOpen
+ ? popupBody
+ : detailEl?.querySelector("#bme-task-memory-editor-body");
const nodeId = currentSelectedMemoryNodeId;
if (!nodeId || !bodyEl) return;
- const collected = _collectNodeDetailEditorUpdates(bodyEl, {
- idPrefix: "bme-task-detail",
- });
+ const idPrefix = popupOpen ? "bme-popup-detail" : "bme-task-detail";
+ const collected = _collectNodeDetailEditorUpdates(bodyEl, { idPrefix });
if (!collected.ok) {
toastr.error(collected.errorMessage || "保存失败", "ST-BME");
return;
}
- _persistNodeDetailEdits(nodeId, collected.updates);
+ _persistNodeDetailEdits(nodeId, collected.updates, {
+ afterSuccess: () => {
+ if (popupOpen) {
+ const graph = _getGraph?.();
+ const refreshedNode = (graph?.nodes || []).find((n) => n.id === nodeId);
+ if (refreshedNode) _openMemoryPopup(refreshedNode, graph);
+ }
+ },
+ });
}
function _deleteTaskMemoryDetail() {
@@ -1855,10 +1875,57 @@ function _deleteTaskMemoryDetail() {
_deleteGraphNodeById(nodeId, {
afterSuccess: () => {
currentSelectedMemoryNodeId = "";
+ _closeMemoryPopup();
},
});
}
+function _openMemoryPopup(node, graph) {
+ const popup = document.getElementById("bme-memory-popup");
+ const scrim = document.getElementById("bme-memory-popup-scrim");
+ const titleEl = document.getElementById("bme-memory-popup-title");
+ const badgesEl = document.getElementById("bme-memory-popup-badges");
+ const bodyEl = document.getElementById("bme-memory-popup-body");
+ if (!popup || !bodyEl) return;
+
+ const displayName = getNodeDisplayName(node);
+ const scopeBadge = buildScopeBadgeText(node.scope);
+ const badges = [
+ node.type ? `${_escHtml(_typeLabel(node.type))}` : "",
+ scopeBadge ? `${_escHtml(scopeBadge)}` : "",
+ node.archived ? 'ARCHIVED' : "",
+ ].filter(Boolean).join("");
+
+ if (titleEl) titleEl.textContent = displayName;
+ if (badgesEl) badgesEl.innerHTML = badges;
+
+ bodyEl.replaceChildren(
+ _buildNodeDetailEditorFragment(node, { idPrefix: "bme-popup-detail" }),
+ );
+
+ scrim?.removeAttribute("hidden");
+ popup.classList.add("open");
+}
+
+function _closeMemoryPopup() {
+ const popup = document.getElementById("bme-memory-popup");
+ const scrim = document.getElementById("bme-memory-popup-scrim");
+ popup?.classList.remove("open");
+ scrim?.setAttribute("hidden", "");
+}
+
+function _bindMemoryPopup() {
+ const closeBtn = document.getElementById("bme-memory-popup-close");
+ const scrim = document.getElementById("bme-memory-popup-scrim");
+ const saveBtn = document.getElementById("bme-memory-popup-save");
+ const deleteBtn = document.getElementById("bme-memory-popup-delete");
+
+ closeBtn?.addEventListener("click", () => _closeMemoryPopup());
+ scrim?.addEventListener("click", () => _closeMemoryPopup());
+ saveBtn?.addEventListener("click", () => _saveTaskMemoryDetail());
+ deleteBtn?.addEventListener("click", () => _deleteTaskMemoryDetail());
+}
+
// ---------- Injection Preview ----------
function _refreshTaskInjectionPreview() {