Skip to content

Commit 84ec0c2

Browse files
authored
[codex] Add Control UI sidebar session shortcuts (#82810)
* feat(control-ui): add sidebar session shortcuts * fix(control-ui): simplify cron job creation * style(control-ui): pad settings config chrome * fix(control-ui): fold cron advanced creation into dialog * fix(control-ui): filter sidebar recent sessions * fix(control-ui): clean up chat loading state * fix(control-ui): add settings nav content gutter * fix(control-ui): inherit settings nav icon color * fix(control-ui): polish sidebar new session button * fix(control-ui): speed up communications settings load * fix(control-ui): add cron strings to locale maps * fix(control-ui): refresh i18n metadata for sidebar strings * fix(control-ui): refresh chat raw-copy baseline
1 parent f2d8f38 commit 84ec0c2

72 files changed

Lines changed: 2355 additions & 1145 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ Docs: https://docs.openclaw.ai
2626

2727
### Changes
2828

29+
- Control UI: move settings-only destinations into the Settings workspace and add sidebar recent-session shortcuts plus a one-click new-session action.
30+
- Control UI: speed up scoped settings pages by loading required config before schema refreshes, caching burst schema responses, and opening Communications on lighter message settings first.
31+
- Control UI: simplify the Cron Jobs workspace with modal job creation, collapsed filters, and an empty state aimed at first-time setup.
2932
- Security/audit: add `security.audit.suppressions` for intentionally accepted audit findings, keeping suppressed matches out of the active summary while preserving them in JSON output with an active suppression notice. (#76949) Thanks @100menotu001.
3033
- Agents/subagents: label delegated task and subagent completion handoffs as ready for parent review, and tell requester agents to review/verify results before calling them done. (#78985) Thanks @100menotu001.
3134
- Providers/media: add fal and OpenRouter music-generation providers for the shared `music_generate` tool, including fal MiniMax/ACE/Stable Audio endpoints and OpenRouter Lyria audio output.

src/gateway/server-methods/config.test.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
import { afterEach, describe, expect, it, vi } from "vitest";
2-
import { configHandlers, resolveConfigOpenCommand } from "./config.js";
2+
import {
3+
clearConfigSchemaResponseCacheForTests,
4+
configHandlers,
5+
loadConfigSchemaResponseForTests,
6+
resolveConfigOpenCommand,
7+
} from "./config.js";
38
import { createConfigHandlerHarness } from "./config.test-helpers.js";
49

5-
const execFileMock = vi.hoisted(() => vi.fn());
10+
const { execFileMock, loadGatewayRuntimeConfigSchemaMock } = vi.hoisted(() => ({
11+
execFileMock: vi.fn(),
12+
loadGatewayRuntimeConfigSchemaMock: vi.fn(() => ({
13+
schema: { type: "object" },
14+
uiHints: undefined,
15+
version: "test-schema",
16+
})),
17+
}));
618

719
vi.mock("node:child_process", async () => {
820
const { mockNodeBuiltinModule } = await import("openclaw/plugin-sdk/test-node-mocks");
@@ -16,6 +28,10 @@ vi.mock("node:child_process", async () => {
1628
);
1729
});
1830

31+
vi.mock("../../config/runtime-schema.js", () => ({
32+
loadGatewayRuntimeConfigSchema: loadGatewayRuntimeConfigSchemaMock,
33+
}));
34+
1935
function invokeExecFileCallback(args: unknown[], error: Error | null) {
2036
const callback = args.at(-1);
2137
if (typeof callback !== "function") {
@@ -24,6 +40,11 @@ function invokeExecFileCallback(args: unknown[], error: Error | null) {
2440
callback(error);
2541
}
2642

43+
afterEach(() => {
44+
clearConfigSchemaResponseCacheForTests();
45+
vi.clearAllMocks();
46+
});
47+
2748
describe("resolveConfigOpenCommand", () => {
2849
it("uses open on macOS", () => {
2950
expect(resolveConfigOpenCommand("/tmp/openclaw.json", "darwin")).toEqual({
@@ -55,7 +76,6 @@ describe("resolveConfigOpenCommand", () => {
5576
describe("config.openFile", () => {
5677
afterEach(() => {
5778
delete process.env.OPENCLAW_CONFIG_PATH;
58-
vi.clearAllMocks();
5979
});
6080

6181
it("opens the configured file without shell interpolation", async () => {
@@ -109,3 +129,20 @@ describe("config.openFile", () => {
109129
);
110130
});
111131
});
132+
133+
describe("config schema response cache", () => {
134+
it("reuses a recent schema build across burst config requests", () => {
135+
loadConfigSchemaResponseForTests();
136+
loadConfigSchemaResponseForTests();
137+
138+
expect(loadGatewayRuntimeConfigSchemaMock).toHaveBeenCalledTimes(1);
139+
});
140+
141+
it("can be cleared when config writes change schema inputs", () => {
142+
loadConfigSchemaResponseForTests();
143+
clearConfigSchemaResponseCacheForTests();
144+
loadConfigSchemaResponseForTests();
145+
146+
expect(loadGatewayRuntimeConfigSchemaMock).toHaveBeenCalledTimes(2);
147+
});
148+
});

src/gateway/server-methods/config.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ import type { GatewayRequestHandlers, RespondFn } from "./types.js";
5252
import { assertValidParams } from "./validation.js";
5353

5454
const MAX_CONFIG_ISSUES_IN_ERROR_MESSAGE = 3;
55+
const CONFIG_SCHEMA_RESPONSE_CACHE_TTL_MS = 5_000;
56+
57+
let configSchemaResponseCache: {
58+
expiresAtMs: number;
59+
response: ConfigSchemaResponse;
60+
} | null = null;
5561

5662
type ConfigOpenCommand = {
5763
command: string;
@@ -258,12 +264,30 @@ async function ensureResolvableSecretRefsOrRespond(params: {
258264
}
259265
}
260266

267+
export function clearConfigSchemaResponseCacheForTests() {
268+
configSchemaResponseCache = null;
269+
}
270+
271+
export function loadConfigSchemaResponseForTests(): ConfigSchemaResponse {
272+
return loadSchemaWithPlugins();
273+
}
274+
275+
function clearConfigSchemaResponseCache() {
276+
configSchemaResponseCache = null;
277+
}
278+
261279
function loadSchemaWithPlugins(): ConfigSchemaResponse {
262-
// Note: We can't easily cache this, as there are no callback that can invalidate
263-
// our cache. However, getRuntimeConfig() and loadOpenClawPlugins() (called inside
264-
// loadGatewayRuntimeConfigSchema) already cache their results, and buildConfigSchema()
265-
// is just a cheap transformation.
266-
return loadGatewayRuntimeConfigSchema();
280+
const now = Date.now();
281+
if (configSchemaResponseCache && configSchemaResponseCache.expiresAtMs > now) {
282+
return configSchemaResponseCache.response;
283+
}
284+
285+
const response = loadGatewayRuntimeConfigSchema();
286+
configSchemaResponseCache = {
287+
expiresAtMs: Date.now() + CONFIG_SCHEMA_RESPONSE_CACHE_TTL_MS,
288+
response,
289+
};
290+
return response;
267291
}
268292

269293
export const configHandlers: GatewayRequestHandlers = {
@@ -335,6 +359,7 @@ export const configHandlers: GatewayRequestHandlers = {
335359
nextConfig: parsed.config,
336360
context,
337361
});
362+
clearConfigSchemaResponseCache();
338363
respond(
339364
true,
340365
{
@@ -467,6 +492,7 @@ export const configHandlers: GatewayRequestHandlers = {
467492
context,
468493
disconnectSharedAuthClients,
469494
});
495+
clearConfigSchemaResponseCache();
470496

471497
const { payload, sentinelPath, restart } = await resolveGatewayConfigRestartWriteResult({
472498
requestParams: params,
@@ -533,6 +559,7 @@ export const configHandlers: GatewayRequestHandlers = {
533559
context,
534560
disconnectSharedAuthClients,
535561
});
562+
clearConfigSchemaResponseCache();
536563

537564
const { payload, sentinelPath, restart } = await resolveGatewayConfigRestartWriteResult({
538565
requestParams: params,

ui/src/i18n/.i18n/ar.meta.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"fallbackKeys": [],
3-
"generatedAt": "2026-05-15T06:55:20.574Z",
3+
"generatedAt": "2026-05-17T04:23:07.350Z",
44
"locale": "ar",
5-
"model": "claude-opus-4-6",
6-
"provider": "anthropic",
7-
"sourceHash": "aa10028509a638096a0e2c1d178279d31c1b53df551d0b9aa44d185577311fd2",
8-
"totalKeys": 1113,
9-
"translatedKeys": 1113,
5+
"model": "gpt-5.5",
6+
"provider": "openai",
7+
"sourceHash": "79544002c00e9adfebe5cc0ad3a6ff6393313f6fd7b546e68f0d53110df29914",
8+
"totalKeys": 1117,
9+
"translatedKeys": 1117,
1010
"workflow": 1
1111
}

ui/src/i18n/.i18n/de.meta.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"fallbackKeys": [],
3-
"generatedAt": "2026-05-15T06:53:55.667Z",
3+
"generatedAt": "2026-05-17T04:22:55.626Z",
44
"locale": "de",
5-
"model": "claude-opus-4-6",
6-
"provider": "anthropic",
7-
"sourceHash": "aa10028509a638096a0e2c1d178279d31c1b53df551d0b9aa44d185577311fd2",
8-
"totalKeys": 1113,
9-
"translatedKeys": 1113,
5+
"model": "gpt-5.5",
6+
"provider": "openai",
7+
"sourceHash": "79544002c00e9adfebe5cc0ad3a6ff6393313f6fd7b546e68f0d53110df29914",
8+
"totalKeys": 1117,
9+
"translatedKeys": 1117,
1010
"workflow": 1
1111
}

ui/src/i18n/.i18n/es.meta.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"fallbackKeys": [],
3-
"generatedAt": "2026-05-15T06:54:28.519Z",
3+
"generatedAt": "2026-05-17T04:22:57.470Z",
44
"locale": "es",
5-
"model": "claude-opus-4-6",
6-
"provider": "anthropic",
7-
"sourceHash": "aa10028509a638096a0e2c1d178279d31c1b53df551d0b9aa44d185577311fd2",
8-
"totalKeys": 1113,
9-
"translatedKeys": 1113,
5+
"model": "gpt-5.5",
6+
"provider": "openai",
7+
"sourceHash": "79544002c00e9adfebe5cc0ad3a6ff6393313f6fd7b546e68f0d53110df29914",
8+
"totalKeys": 1117,
9+
"translatedKeys": 1117,
1010
"workflow": 1
1111
}

ui/src/i18n/.i18n/fa.meta.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"fallbackKeys": [],
3-
"generatedAt": "2026-05-15T06:56:25.567Z",
3+
"generatedAt": "2026-05-17T04:23:23.796Z",
44
"locale": "fa",
5-
"model": "claude-opus-4-6",
6-
"provider": "anthropic",
7-
"sourceHash": "aa10028509a638096a0e2c1d178279d31c1b53df551d0b9aa44d185577311fd2",
8-
"totalKeys": 1113,
9-
"translatedKeys": 1113,
5+
"model": "gpt-5.5",
6+
"provider": "openai",
7+
"sourceHash": "79544002c00e9adfebe5cc0ad3a6ff6393313f6fd7b546e68f0d53110df29914",
8+
"totalKeys": 1117,
9+
"translatedKeys": 1117,
1010
"workflow": 1
1111
}

ui/src/i18n/.i18n/fr.meta.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"fallbackKeys": [],
3-
"generatedAt": "2026-05-15T06:54:44.184Z",
3+
"generatedAt": "2026-05-17T04:23:05.794Z",
44
"locale": "fr",
5-
"model": "claude-opus-4-6",
6-
"provider": "anthropic",
7-
"sourceHash": "aa10028509a638096a0e2c1d178279d31c1b53df551d0b9aa44d185577311fd2",
8-
"totalKeys": 1113,
9-
"translatedKeys": 1113,
5+
"model": "gpt-5.5",
6+
"provider": "openai",
7+
"sourceHash": "79544002c00e9adfebe5cc0ad3a6ff6393313f6fd7b546e68f0d53110df29914",
8+
"totalKeys": 1117,
9+
"translatedKeys": 1117,
1010
"workflow": 1
1111
}

ui/src/i18n/.i18n/id.meta.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"fallbackKeys": [],
3-
"generatedAt": "2026-05-15T06:55:42.684Z",
3+
"generatedAt": "2026-05-17T04:23:13.312Z",
44
"locale": "id",
5-
"model": "claude-opus-4-6",
6-
"provider": "anthropic",
7-
"sourceHash": "aa10028509a638096a0e2c1d178279d31c1b53df551d0b9aa44d185577311fd2",
8-
"totalKeys": 1113,
9-
"translatedKeys": 1113,
5+
"model": "gpt-5.5",
6+
"provider": "openai",
7+
"sourceHash": "79544002c00e9adfebe5cc0ad3a6ff6393313f6fd7b546e68f0d53110df29914",
8+
"totalKeys": 1117,
9+
"translatedKeys": 1117,
1010
"workflow": 1
1111
}

ui/src/i18n/.i18n/it.meta.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"fallbackKeys": [],
3-
"generatedAt": "2026-05-15T06:54:58.587Z",
3+
"generatedAt": "2026-05-17T04:23:08.778Z",
44
"locale": "it",
5-
"model": "claude-opus-4-6",
6-
"provider": "anthropic",
7-
"sourceHash": "aa10028509a638096a0e2c1d178279d31c1b53df551d0b9aa44d185577311fd2",
8-
"totalKeys": 1113,
9-
"translatedKeys": 1113,
5+
"model": "gpt-5.5",
6+
"provider": "openai",
7+
"sourceHash": "79544002c00e9adfebe5cc0ad3a6ff6393313f6fd7b546e68f0d53110df29914",
8+
"totalKeys": 1117,
9+
"translatedKeys": 1117,
1010
"workflow": 1
1111
}

0 commit comments

Comments
 (0)