feat: add project-management web-probe observe

This commit is contained in:
Codex
2026-06-25 11:39:53 +00:00
parent 8d26e6fbc3
commit 80351ce5d2
9 changed files with 1070 additions and 23 deletions
+42
View File
@@ -128,6 +128,7 @@ export interface HwlabRuntimeWebProbeSpec {
readonly browserProxyMode?: "auto" | "direct";
readonly defaultOrigin?: HwlabRuntimeWebProbeOriginSpec;
readonly alertThresholds?: HwlabRuntimeWebProbeAlertThresholdsSpec;
readonly projectManagement?: HwlabRuntimeWebProbeProjectManagementSpec;
}
export interface HwlabRuntimeWebProbeAlertThresholdsSpec {
@@ -143,6 +144,16 @@ export interface HwlabRuntimeWebProbeAlertThresholdsSpec {
readonly sessionRailFallbackRatio: number;
}
export interface HwlabRuntimeWebProbeProjectManagementSpec {
readonly enabled: boolean;
readonly targetPaths: readonly string[];
readonly readinessSelectors: readonly string[];
readonly naturalApiPathPrefixes: readonly string[];
readonly commandAllowlist: readonly string[];
readonly launchRoute: string;
readonly slowApiBudgetMs: number;
}
export interface HwlabRuntimeBuildkitSpec {
readonly sidecarImage: string;
}
@@ -369,6 +380,12 @@ function stringArrayField(obj: Record<string, unknown>, key: string, path: strin
return [...value] as string[];
}
function nonEmptyStringArrayField(obj: Record<string, unknown>, key: string, path: string): string[] {
const values = stringArrayField(obj, key, path);
if (values.length === 0) throw new Error(`${path}.${key} must contain at least one string`);
return values;
}
function optionalStringField(obj: Record<string, unknown>, key: string, path: string): string | undefined {
const value = obj[key];
if (value === undefined) return undefined;
@@ -711,6 +728,31 @@ function webProbeConfig(value: unknown, path: string): HwlabRuntimeWebProbeSpec
...(browserProxyMode === undefined ? {} : { browserProxyMode }),
...(raw.defaultOrigin === undefined ? {} : { defaultOrigin: webProbeOriginConfig(raw.defaultOrigin, `${path}.defaultOrigin`) }),
...(raw.alertThresholds === undefined ? {} : { alertThresholds: webProbeAlertThresholdsConfig(raw.alertThresholds, `${path}.alertThresholds`) }),
...(raw.projectManagement === undefined ? {} : { projectManagement: webProbeProjectManagementConfig(raw.projectManagement, `${path}.projectManagement`) }),
};
}
function webProbeProjectManagementConfig(value: unknown, path: string): HwlabRuntimeWebProbeProjectManagementSpec {
const raw = asRecord(value, path);
const targetPaths = nonEmptyStringArrayField(raw, "targetPaths", path);
const readinessSelectors = nonEmptyStringArrayField(raw, "readinessSelectors", path);
const naturalApiPathPrefixes = nonEmptyStringArrayField(raw, "naturalApiPathPrefixes", path);
const commandAllowlist = nonEmptyStringArrayField(raw, "commandAllowlist", path);
const launchRoute = stringField(raw, "launchRoute", path);
if (!launchRoute.startsWith("/")) throw new Error(`${path}.launchRoute must be an absolute path`);
for (const [field, values] of Object.entries({ targetPaths, naturalApiPathPrefixes })) {
for (const item of values) {
if (!item.startsWith("/")) throw new Error(`${path}.${field} entries must be absolute paths; got ${item}`);
}
}
return {
enabled: booleanField(raw, "enabled", path),
targetPaths,
readinessSelectors,
naturalApiPathPrefixes,
commandAllowlist,
launchRoute,
slowApiBudgetMs: positiveNumberField(raw, "slowApiBudgetMs", path),
};
}