diff --git a/integrations/codex/plugins/reme/.codex-plugin/plugin.json b/integrations/codex/plugins/reme/.codex-plugin/plugin.json index c18a883e..5924f53f 100644 --- a/integrations/codex/plugins/reme/.codex-plugin/plugin.json +++ b/integrations/codex/plugins/reme/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "reme", - "version": "0.2.4", + "version": "0.2.5", "description": "Automatic memory, focused recall, runtime status, and consolidation through ReMe MCP.", "author": { "name": "EconML team of Alibaba Tongyi Lab", diff --git a/integrations/codex/plugins/reme/ui/status.html b/integrations/codex/plugins/reme/ui/status.html index 7621d342..5aae92d7 100644 --- a/integrations/codex/plugins/reme/ui/status.html +++ b/integrations/codex/plugins/reme/ui/status.html @@ -13,9 +13,11 @@ * { box-sizing: border-box; } body { margin: 0; padding: clamp(16px, 4vw, 32px); background: var(--color-background-primary, var(--bg)); color: var(--color-text-primary, var(--ink)); font: 14px/1.6 system-ui, -apple-system, sans-serif; } main { max-width: 880px; margin: auto; overflow-wrap: anywhere; } - header { display: flex; align-items: start; justify-content: space-between; gap: 24px; margin-bottom: 28px; } + header { display: grid; gap: 12px; margin-bottom: 28px; } header > div { min-width: 0; } - h1 { font-size: 22px; letter-spacing: -.4px; margin: 0; font-weight: 650; } + h1 { font-size: 22px; letter-spacing: -.4px; margin: 0; padding-inline-end: 48px; font-weight: 650; } + .status-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; } + #checked { margin: 0; } h2 { font-size: 15px; line-height: 1.5; margin: 0 0 24px; font-weight: 600; } p { margin: 6px 0; } .muted, small { color: var(--muted); } @@ -82,8 +84,11 @@
-

ReMe status

Waiting for status…

- +

ReMe status

+
+ +

Waiting for status…

+
Opening the connection and memory overview…
@@ -653,7 +658,7 @@ } const host = await transport.request("ui/initialize", { protocolVersion: "2026-01-26", - appInfo: { name: "reme-status", version: "0.2.4" }, + appInfo: { name: "reme-status", version: "0.2.5" }, appCapabilities: { availableDisplayModes: ["fullscreen"] } }); if (host.protocolVersion !== "2026-01-26") throw new Error("Unsupported UI protocol"); diff --git a/integrations/codex/status-app/src/status.html b/integrations/codex/status-app/src/status.html index 18e769b6..1d25ffbd 100644 --- a/integrations/codex/status-app/src/status.html +++ b/integrations/codex/status-app/src/status.html @@ -13,9 +13,11 @@ * { box-sizing: border-box; } body { margin: 0; padding: clamp(16px, 4vw, 32px); background: var(--color-background-primary, var(--bg)); color: var(--color-text-primary, var(--ink)); font: 14px/1.6 system-ui, -apple-system, sans-serif; } main { max-width: 880px; margin: auto; overflow-wrap: anywhere; } - header { display: flex; align-items: start; justify-content: space-between; gap: 24px; margin-bottom: 28px; } + header { display: grid; gap: 12px; margin-bottom: 28px; } header > div { min-width: 0; } - h1 { font-size: 22px; letter-spacing: -.4px; margin: 0; font-weight: 650; } + h1 { font-size: 22px; letter-spacing: -.4px; margin: 0; padding-inline-end: 48px; font-weight: 650; } + .status-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; } + #checked { margin: 0; } h2 { font-size: 15px; line-height: 1.5; margin: 0 0 24px; font-weight: 600; } p { margin: 6px 0; } .muted, small { color: var(--muted); } @@ -82,8 +84,11 @@
-

ReMe status

Waiting for status…

- +

ReMe status

+
+ +

Waiting for status…

+
Opening the connection and memory overview…
diff --git a/integrations/codex/status-app/src/status.js b/integrations/codex/status-app/src/status.js index 8a7c0665..33612e9d 100644 --- a/integrations/codex/status-app/src/status.js +++ b/integrations/codex/status-app/src/status.js @@ -235,7 +235,7 @@ $("refresh").addEventListener("click", async () => { async function connect() { if (window.parent === window) { text("loading", t("noHost")); return; } const host = await transport.request("ui/initialize", { - protocolVersion: "2026-01-26", appInfo: { name: "reme-status", version: "0.2.4" }, + protocolVersion: "2026-01-26", appInfo: { name: "reme-status", version: "0.2.5" }, appCapabilities: { availableDisplayModes: ["fullscreen"] }, }); if (host.protocolVersion !== "2026-01-26") throw new Error("Unsupported UI protocol"); diff --git a/tests/integration/test_codex_plugin_status_ui.py b/tests/integration/test_codex_plugin_status_ui.py index 87120b05..c34e4b95 100644 --- a/tests/integration/test_codex_plugin_status_ui.py +++ b/tests/integration/test_codex_plugin_status_ui.py @@ -22,7 +22,7 @@ def snapshot(language): return { "checked_at": 1790757300, "language": language, - "plugin_version": "0.2.4", + "plugin_version": "0.2.5", "mcpUrl": "http://localhost:2333/mcp", "service": { "health_check": {"reachable": True, "answer": "ReMe v0.4.1.13 - healthy"}, @@ -57,6 +57,17 @@ def snapshot(language): } +def check_host_close_clearance(page, frame): + refresh = frame.locator("#refresh").bounding_box() + close = page.locator("#host-close").bounding_box() + assert ( + refresh["x"] + refresh["width"] <= close["x"] + or close["x"] + close["width"] <= refresh["x"] + or refresh["y"] + refresh["height"] <= close["y"] + or close["y"] + close["height"] <= refresh["y"] + ), "Refresh must remain outside the host's close control" + + def check_activity_history(page, frame, language, theme, tmp_path): playwright = pytest.importorskip("playwright.sync_api") dense = snapshot(language) @@ -84,7 +95,8 @@ def check_activity_history(page, frame, language, theme, tmp_path): assert "GMT-3" in frame.locator("#activity time").first.get_attribute("title") for width in (320, 480, 768, 940): page.set_viewport_size({"width": width + 16, "height": 1250}) - page.evaluate("width => document.querySelector('iframe').style.width = `${width}px`", width) + page.evaluate("width => document.querySelector('#status-shell').style.width = `${width}px`", width) + check_host_close_clearance(page, frame) assert frame.locator("body").evaluate("node => node.scrollWidth <= window.innerWidth") assert frame.locator("#activity-details").evaluate("node => node.scrollWidth <= node.clientWidth") page.screenshot(path=str(tmp_path / f"status-test-host-{theme}-activity-{width}.png"), full_page=True) @@ -119,7 +131,12 @@ def test_initial_result_refresh_offline_failure_theme_and_untrusted_text(languag errors, external = [], [] page.on("pageerror", lambda error: errors.append(str(error))) page.route("**/*", lambda route: (external.append(route.request.url), route.abort())) - page.set_content('') + page.set_content( + '
' + '' + '
', + ) page.evaluate( """({html, initial, theme}) => { window.calls = []; @@ -175,7 +192,8 @@ def test_initial_result_refresh_offline_failure_theme_and_untrusted_text(languag assert frame.locator("#panel-overview").is_visible() for width in (320, 480, 640, 768, 940): page.set_viewport_size({"width": width + 16, "height": 1250}) - page.evaluate("width => document.querySelector('iframe').style.width = `${width}px`", width) + page.evaluate("width => document.querySelector('#status-shell').style.width = `${width}px`", width) + check_host_close_clearance(page, frame) for name in ("overview", "memory", "dream", "components"): frame.locator(f"#tab-{name}").click() assert frame.locator("body").evaluate("node => node.scrollWidth <= window.innerWidth")