From e582f858ff7e3d0ee4cae12a70fa14374004171e Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 17 Jul 2026 18:40:25 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=A3=B0=E6=98=8E=20Workbench=20L1=20We?= =?UTF-8?q?b=20=E8=BF=90=E8=A1=8C=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/hwlab-node-lanes.yaml | 19 +++++++ scripts/src/hwlab-native-development.test.ts | 1 + scripts/src/hwlab-native-development.ts | 1 + scripts/src/hwlab-node-lanes.ts | 56 +++++++++++++++++++- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/config/hwlab-node-lanes.yaml b/config/hwlab-node-lanes.yaml index 22ad092f..70bc15e6 100644 --- a/config/hwlab-node-lanes.yaml +++ b/config/hwlab-node-lanes.yaml @@ -127,6 +127,25 @@ lanes: bindHost: 0.0.0.0 probeHost: 127.0.0.1 port: 5173 + runtimeConfig: + displayTime: + timeZone: Asia/Shanghai + locale: zh-CN + label: 北京时间 + workbench: + realtimeFeatures: + liveKafkaSse: false + kafkaRefreshReplay: false + projectionRealtime: true + debugCapabilities: + isolatedKafka: false + rawHwlabEventWindow: + enabled: false + maxEntries: 1 + maxRetainedBytes: 1 + traceTimeline: + autoExpandRunning: false + autoCollapseTerminal: false sourceAuthority: extends: templates.hwlabV03.sourceAuthorityGiteaSnapshot giteaMirrorRepoKey: hwlab-nc01-v03 diff --git a/scripts/src/hwlab-native-development.test.ts b/scripts/src/hwlab-native-development.test.ts index b3eecb5e..08cb231c 100644 --- a/scripts/src/hwlab-native-development.test.ts +++ b/scripts/src/hwlab-native-development.test.ts @@ -12,5 +12,6 @@ test("L1 Workbench exposure uses YAML public IP and separate bind/probe addresse expect(env.WORKBENCH_API_PROBE_HOST).toBe(native!.api.probeHost); expect(env.WORKBENCH_API_PUBLIC_HOST).toBe(native!.publicHost); expect(env.WORKBENCH_WEB_PUBLIC_HOST).toBe(native!.publicHost); + expect(JSON.parse(env.WORKBENCH_WEB_RUNTIME_CONFIG!)).toEqual(native!.web.runtimeConfig); expect(hwlabNativeDevelopmentHelp()).toMatchObject({ ok: true, command: "hwlab nodes native-development workbench" }); }); diff --git a/scripts/src/hwlab-native-development.ts b/scripts/src/hwlab-native-development.ts index 0b3ce5f5..4426c3c5 100644 --- a/scripts/src/hwlab-native-development.ts +++ b/scripts/src/hwlab-native-development.ts @@ -67,6 +67,7 @@ export function hwlabNativeDevelopmentEnvironment(native: HwlabRuntimeNativeDeve WORKBENCH_WEB_PUBLIC_HOST: native.publicHost, WORKBENCH_WEB_PORT: String(native.web.port), WORKBENCH_NATIVE_API_URL: `http://${native.api.probeHost}:${native.api.port}`, + WORKBENCH_WEB_RUNTIME_CONFIG: JSON.stringify(native.web.runtimeConfig), }; } diff --git a/scripts/src/hwlab-node-lanes.ts b/scripts/src/hwlab-node-lanes.ts index ba66df49..789b3214 100644 --- a/scripts/src/hwlab-node-lanes.ts +++ b/scripts/src/hwlab-node-lanes.ts @@ -669,7 +669,22 @@ export interface HwlabRuntimeNativeDevelopmentSpec { readonly stateDir: string; readonly api: { readonly bindHost: string; readonly probeHost: string; readonly port: number }; readonly worker: { readonly bindHost: string; readonly probeHost: string; readonly healthPort: number }; - readonly web: { readonly bindHost: string; readonly probeHost: string; readonly port: number }; + readonly web: { + readonly bindHost: string; + readonly probeHost: string; + readonly port: number; + readonly runtimeConfig: { + readonly displayTime: { readonly timeZone: string; readonly locale: string; readonly label: string }; + readonly workbench: { + readonly realtimeFeatures: { readonly liveKafkaSse: boolean; readonly kafkaRefreshReplay: boolean; readonly projectionRealtime: boolean }; + readonly debugCapabilities: { + readonly isolatedKafka: boolean; + readonly rawHwlabEventWindow: { readonly enabled: boolean; readonly maxEntries: number; readonly maxRetainedBytes: number }; + }; + readonly traceTimeline: { readonly autoExpandRunning: boolean; readonly autoCollapseTerminal: boolean }; + }; + }; + }; }; } @@ -1421,6 +1436,13 @@ function nativeDevelopmentConfig(value: unknown, path: string): HwlabRuntimeNati const api = asRecord(workbench.api, `${path}.workbench.api`); const worker = asRecord(workbench.worker, `${path}.workbench.worker`); const web = asRecord(workbench.web, `${path}.workbench.web`); + const runtimeConfig = asRecord(web.runtimeConfig, `${path}.workbench.web.runtimeConfig`); + const displayTime = asRecord(runtimeConfig.displayTime, `${path}.workbench.web.runtimeConfig.displayTime`); + const workbenchRuntime = asRecord(runtimeConfig.workbench, `${path}.workbench.web.runtimeConfig.workbench`); + const realtimeFeatures = asRecord(workbenchRuntime.realtimeFeatures, `${path}.workbench.web.runtimeConfig.workbench.realtimeFeatures`); + const debugCapabilities = asRecord(workbenchRuntime.debugCapabilities, `${path}.workbench.web.runtimeConfig.workbench.debugCapabilities`); + const rawHwlabEventWindow = asRecord(debugCapabilities.rawHwlabEventWindow, `${path}.workbench.web.runtimeConfig.workbench.debugCapabilities.rawHwlabEventWindow`); + const traceTimeline = asRecord(workbenchRuntime.traceTimeline, `${path}.workbench.web.runtimeConfig.workbench.traceTimeline`); return { workbench: { publicHostRef, @@ -1428,7 +1450,37 @@ function nativeDevelopmentConfig(value: unknown, path: string): HwlabRuntimeNati stateDir: relativeWorkspacePathField(stringField(workbench, "stateDir", `${path}.workbench`), `${path}.workbench.stateDir`), api: { bindHost: stringField(api, "bindHost", `${path}.workbench.api`), probeHost: stringField(api, "probeHost", `${path}.workbench.api`), port: numberField(api, "port", `${path}.workbench.api`) }, worker: { bindHost: stringField(worker, "bindHost", `${path}.workbench.worker`), probeHost: stringField(worker, "probeHost", `${path}.workbench.worker`), healthPort: numberField(worker, "healthPort", `${path}.workbench.worker`) }, - web: { bindHost: stringField(web, "bindHost", `${path}.workbench.web`), probeHost: stringField(web, "probeHost", `${path}.workbench.web`), port: numberField(web, "port", `${path}.workbench.web`) }, + web: { + bindHost: stringField(web, "bindHost", `${path}.workbench.web`), + probeHost: stringField(web, "probeHost", `${path}.workbench.web`), + port: numberField(web, "port", `${path}.workbench.web`), + runtimeConfig: { + displayTime: { + timeZone: stringField(displayTime, "timeZone", `${path}.workbench.web.runtimeConfig.displayTime`), + locale: stringField(displayTime, "locale", `${path}.workbench.web.runtimeConfig.displayTime`), + label: stringField(displayTime, "label", `${path}.workbench.web.runtimeConfig.displayTime`), + }, + workbench: { + realtimeFeatures: { + liveKafkaSse: booleanField(realtimeFeatures, "liveKafkaSse", `${path}.workbench.web.runtimeConfig.workbench.realtimeFeatures`), + kafkaRefreshReplay: booleanField(realtimeFeatures, "kafkaRefreshReplay", `${path}.workbench.web.runtimeConfig.workbench.realtimeFeatures`), + projectionRealtime: booleanField(realtimeFeatures, "projectionRealtime", `${path}.workbench.web.runtimeConfig.workbench.realtimeFeatures`), + }, + debugCapabilities: { + isolatedKafka: booleanField(debugCapabilities, "isolatedKafka", `${path}.workbench.web.runtimeConfig.workbench.debugCapabilities`), + rawHwlabEventWindow: { + enabled: booleanField(rawHwlabEventWindow, "enabled", `${path}.workbench.web.runtimeConfig.workbench.debugCapabilities.rawHwlabEventWindow`), + maxEntries: numberField(rawHwlabEventWindow, "maxEntries", `${path}.workbench.web.runtimeConfig.workbench.debugCapabilities.rawHwlabEventWindow`), + maxRetainedBytes: numberField(rawHwlabEventWindow, "maxRetainedBytes", `${path}.workbench.web.runtimeConfig.workbench.debugCapabilities.rawHwlabEventWindow`), + }, + }, + traceTimeline: { + autoExpandRunning: booleanField(traceTimeline, "autoExpandRunning", `${path}.workbench.web.runtimeConfig.workbench.traceTimeline`), + autoCollapseTerminal: booleanField(traceTimeline, "autoCollapseTerminal", `${path}.workbench.web.runtimeConfig.workbench.traceTimeline`), + }, + }, + }, + }, }, }; }