chore: pin dev frontend auth fix

This commit is contained in:
Codex
2026-05-18 13:06:14 +00:00
parent c09beb0d54
commit 0c0c979a56
12 changed files with 993 additions and 160 deletions
+104 -2
View File
@@ -116,12 +116,12 @@ write_result() {
local ok="$1"
local status="$2"
local detail="$3"
python3 - "$result_json" "$ok" "$status" "$detail" "$run_id" "$repo_url" "$desired_ref" "$manifest_commit" "$environment" "$pipeline_run" "$temporary_namespace" <<'PY'
python3 - "$result_json" "$ok" "$status" "$detail" "$run_id" "$repo_url" "$desired_ref" "$manifest_commit" "$environment" "$pipeline_run" "$temporary_namespace" "$code_queue_image" <<'PY'
import json
import sys
from datetime import datetime, timezone
path, ok, status, detail, run_id, repo, desired_ref, commit, environment, pipeline_run, temporary_namespace = sys.argv[1:]
path, ok, status, detail, run_id, repo, desired_ref, commit, environment, pipeline_run, temporary_namespace, code_queue_image = sys.argv[1:]
record = {
"ok": ok == "true",
"status": status,
@@ -133,6 +133,7 @@ record = {
"environment": environment,
"pipelineRun": pipeline_run or None,
"temporaryNamespace": temporary_namespace or None,
"codeQueueImage": code_queue_image or None,
"finishedAt": datetime.now(timezone.utc).isoformat(),
}
with open(path, "w", encoding="utf-8") as handle:
@@ -144,6 +145,7 @@ PY
pipeline_run=""
temporary_namespace="unidesk-ci-e2e-$run_id"
code_queue_image=""
trap 'code=$?; if [ "$code" -ne 0 ] && [ ! -f "$result_json" ]; then write_result false failed "runner exited with code $code" || true; fi' EXIT
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
@@ -188,8 +190,106 @@ source "$service_env"
backend_commit="${BACKEND_CORE_COMMIT:-unknown}"
frontend_commit="${FRONTEND_COMMIT:-unknown}"
code_queue_commit="${CODE_QUEUE_COMMIT:-unknown}"
if ! [[ "$code_queue_commit" =~ ^[0-9a-f]{40}$ ]]; then
echo "deploy.json environments.$environment.services must include code-queue with a full 40 character commitId; got: $code_queue_commit" >&2
exit 2
fi
deploy_json_b64="$(base64 -w0 "$manifest_file")"
work_dir="$(dirname "$manifest_file")"
repo_dir="$work_dir/repo"
if [ ! -d "$repo_dir/.git" ]; then
echo "launcher repo checkout is missing: $repo_dir" >&2
exit 2
fi
root_exec() {
if [ "$(id -u)" = "0" ]; then
"$@"
return
fi
if sudo -n true >/dev/null 2>&1; then
sudo -n "$@"
return
fi
if [ -x /mnt/c/Windows/System32/wsl.exe ]; then
/mnt/c/Windows/System32/wsl.exe -u root -- "$@"
return
fi
echo "dev_e2e_native_k3s_root_access=missing" >&2
return 1
}
import_image_to_k3s() {
local image="$1"
local archive="/tmp/unidesk-ci-image-${run_id}-${image//[^A-Za-z0-9_.-]/-}.tar"
rm -f "$archive"
docker save "$image" -o "$archive"
root_exec ctr --address /run/k3s/containerd/containerd.sock -n k8s.io images import --digests --all-platforms "$archive"
rm -f "$archive"
echo "dev_e2e_image_imported=$image"
}
ensure_runtime_image() {
local image="$1"
if ! docker image inspect "$image" >/dev/null 2>&1; then
echo "dev_e2e_runtime_image_pull=$image"
docker pull --platform linux/amd64 "$image"
else
echo "dev_e2e_runtime_image_cached=$image"
fi
import_image_to_k3s "$image"
}
build_code_queue_image() {
local short="${code_queue_commit:0:12}"
local commit_image="unidesk-code-queue:ci-$short"
local run_image="unidesk-code-queue:ci-dev-e2e-$run_id"
local source_dir="$work_dir/code-queue-src-$short"
local resolved
git -C "$repo_dir" fetch --no-tags origin "$code_queue_commit" || git -C "$repo_dir" fetch --no-tags origin '+refs/heads/*:refs/remotes/origin/*'
resolved="$(git -C "$repo_dir" rev-parse --verify "$code_queue_commit^{commit}")"
if [ "$resolved" != "$code_queue_commit" ]; then
echo "code_queue_commit_mismatch resolved=$resolved expected=$code_queue_commit" >&2
exit 1
fi
local existing_rev
existing_rev="$(docker image inspect "$commit_image" --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}' 2>/dev/null || true)"
if [ "$existing_rev" != "$resolved" ]; then
rm -rf "$source_dir"
mkdir -p "$source_dir"
git -C "$repo_dir" archive "$resolved" | tar -x -C "$source_dir"
local base_args=()
if docker image inspect unidesk-code-queue:d601-build-base >/dev/null 2>&1; then
base_args=(--build-arg CODE_QUEUE_BASE_IMAGE=unidesk-code-queue:d601-build-base)
elif docker image inspect unidesk-code-queue:d601 >/dev/null 2>&1; then
base_args=(--build-arg CODE_QUEUE_BASE_IMAGE=unidesk-code-queue:d601)
fi
echo "dev_e2e_code_queue_image_build=$commit_image commit=$resolved"
docker build \
"${base_args[@]}" \
--build-arg HTTP_PROXY="${HTTP_PROXY:-}" \
--build-arg HTTPS_PROXY="${HTTPS_PROXY:-}" \
--build-arg ALL_PROXY="${ALL_PROXY:-}" \
--build-arg NO_PROXY="${NO_PROXY:-}" \
--label "org.opencontainers.image.source=$repo_url" \
--label "org.opencontainers.image.revision=$resolved" \
--label "unidesk.ai/ci-run-id=$run_id" \
--label "unidesk.ai/ci-kind=dev-e2e" \
-t "$commit_image" \
-f "$source_dir/src/components/microservices/code-queue/Dockerfile" \
"$source_dir"
else
echo "dev_e2e_code_queue_image_cached=$commit_image commit=$resolved"
fi
docker tag "$commit_image" "$run_image"
import_image_to_k3s "$run_image"
code_queue_image="$run_image"
}
ensure_runtime_image "postgres:16-alpine"
build_code_queue_image
pipeline_manifest="$result_dir/pipelinerun.yaml"
cat >"$pipeline_manifest" <<YAML
apiVersion: tekton.dev/v1
@@ -227,6 +327,8 @@ spec:
value: "$frontend_commit"
- name: code-queue-commit
value: "$code_queue_commit"
- name: app-image
value: "$code_queue_image"
- name: deploy-json-b64
value: "$deploy_json_b64"
workspaces:
+7
View File
@@ -683,6 +683,13 @@ function resolveDeployDevManifest(desiredRef: string): DeployDevManifestSummary
};
}).filter((service) => service.id.length > 0 && service.commitId.length > 0);
if (services.length === 0) throw new Error(`origin/${desiredRef}:deploy.json has no environments.dev services with commitId`);
const codeQueueService = services.find((service) => service.id === "code-queue");
if (codeQueueService === undefined) {
throw new Error(`origin/${desiredRef}:deploy.json environments.dev.services must include code-queue for ci run-dev-e2e`);
}
if (!/^[0-9a-f]{40}$/u.test(codeQueueService.commitId)) {
throw new Error(`origin/${desiredRef}:deploy.json environments.dev.services code-queue commitId must be a full 40-character SHA`);
}
return {
deployCommit: deployCommitResult.stdout.trim(),
desiredRef,
+7 -3
View File
@@ -228,6 +228,8 @@ function compactSummary(summary: unknown, options: CodexTaskOptions, taskId: str
const transcriptCount = asNumber(record.transcriptCount, 0);
const transcriptMaxSeq = transcriptCount > 0 ? record.transcriptMaxSeq ?? null : null;
const initialPrompt = asString(record.initialPrompt ?? record.prompt);
const initialPromptView = textView(initialPrompt, options.full, 3000);
const basePromptView = textView(asString(record.basePrompt), options.full, 2000);
return {
id: record.id ?? taskId,
queueId: record.queueId ?? null,
@@ -256,8 +258,9 @@ function compactSummary(summary: unknown, options: CodexTaskOptions, taskId: str
startedAt: record.startedAt ?? null,
updatedAt: record.updatedAt ?? null,
finishedAt: record.finishedAt ?? null,
initialPrompt: textView(initialPrompt, options.full, 3000),
basePrompt: textView(asString(record.basePrompt), options.full, 2000),
...(options.full
? { initialPrompt: initialPromptView, basePrompt: basePromptView }
: { initialPromptPreview: initialPromptView, basePromptPreview: basePromptView }),
referenceTaskIds: record.referenceTaskIds ?? [],
referenceInjection: record.referenceInjection ?? null,
lastAssistantMessage: compactLastAssistant(record.lastAssistantMessage, options.full),
@@ -808,6 +811,7 @@ function compactTaskMutationResponse(task: unknown, options: CompactTaskMutation
const record = asRecord(task) ?? {};
const taskId = asString(record.id);
const prompt = asString(record.displayPrompt ?? record.basePrompt ?? record.prompt);
const promptView = textView(prompt, options.fullPrompt === true, 1200);
return {
id: taskId || null,
queueId: record.queueId ?? null,
@@ -825,7 +829,7 @@ function compactTaskMutationResponse(task: unknown, options: CompactTaskMutation
startedAt: record.startedAt ?? null,
updatedAt: record.updatedAt ?? null,
finishedAt: record.finishedAt ?? null,
prompt: textView(prompt, options.fullPrompt === true, 1200),
...(options.fullPrompt === true ? { prompt: promptView } : { promptPreview: promptView }),
commands: taskId.length === 0 ? null : {
show: `bun scripts/cli.ts codex task ${taskId}`,
trace: `bun scripts/cli.ts codex task ${taskId} --trace --tail --limit ${defaultTraceLimit}`,
+171 -3
View File
@@ -139,6 +139,7 @@ const FRONTEND_CHECK_NAMES = [
"frontend:code-queue-integrated-visible",
"frontend:code-queue-enqueue-await-smoke",
"frontend:code-queue-summary-mobile-wrap",
"frontend:code-queue-long-prompt-observation",
"frontend:code-queue-initial-prompt-full-expand",
"frontend:code-queue-trace-full-load",
"frontend:code-queue-judge-wrap",
@@ -486,8 +487,10 @@ function wantsPrefix(options: E2ERunOptions, prefix: string): boolean {
}
function publicUrls(config: UniDeskConfig): PublicUrls {
const frontendTarget = String(process.env.UNIDESK_E2E_FRONTEND || "prod").trim().toLowerCase();
const frontendPort = frontendTarget === "dev" ? config.network.devFrontend.port : config.network.frontend.port;
return {
frontendUrl: `http://${config.network.publicHost}:${config.network.frontend.port}`,
frontendUrl: `http://${config.network.publicHost}:${frontendPort}`,
providerIngressHealthUrl: `http://${config.network.publicHost}:${config.network.providerIngress.port}/health`,
providerIngressWsUrl: `ws://${config.network.publicHost}:${config.network.providerIngress.port}/ws/provider`,
blockedCoreUrl: `http://${config.network.publicHost}:${config.network.core.port}`,
@@ -750,6 +753,149 @@ async function runCodeQueueEnqueueAwaitSmoke(page: Page): Promise<any> {
}
}
async function runCodeQueueLongPromptObservation(page: Page): Promise<any> {
const marker = `E2E_LONG_PROMPT_TAIL_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`;
const submitQueueId = "e2e-long-prompt";
const filler = Array.from({ length: 76 }, (_, index) => `long-prompt-line-${String(index + 1).padStart(2, "0")} ${"abcdefghijklmnopqrstuvwxyz0123456789".repeat(2)}`).join("\n");
const prompt = [
"Code Queue long prompt observation regression",
"",
filler,
"",
"验收标准:",
`必须在所有原始 prompt 观察层保留这个唯一 tail marker: ${marker}`,
].join("\n");
const promptChars = prompt.length;
if (promptChars <= 2500) throw new Error(`long prompt fixture too short: ${promptChars}`);
const apiFetch = async (path: string, init: RequestInit = {}): Promise<any> => {
const response = await fetch(path, {
credentials: "same-origin",
headers: { "content-type": "application/json", ...(init.headers || {}) },
...init,
});
const text = await response.text();
let body: any = null;
try { body = text.length > 0 ? JSON.parse(text) : null; } catch { body = { text }; }
return { ok: response.ok, status: response.status, body };
};
await page.getByTestId("code-queue-filter-select").selectOption("__all__").catch(() => undefined);
await page.getByTestId("code-queue-id-select").selectOption(submitQueueId).catch(async () => {
page.once("dialog", (dialog) => { void dialog.accept(submitQueueId); });
await page.getByTestId("codex-create-queue-button").click();
await page.waitForFunction((queueId) => {
const select = document.querySelector('[data-testid="code-queue-id-select"]') as HTMLSelectElement | null;
return Array.from(select?.options || []).some((option) => option.value === queueId);
}, submitQueueId, { timeout: 10000 });
await page.getByTestId("code-queue-id-select").selectOption(submitQueueId);
});
await page.getByTestId("codex-max-attempts-input").fill("1");
await page.getByTestId("codex-repeat-count-input").fill("1");
await page.locator('[data-testid="code-queue-task-form"] textarea').fill(prompt);
await page.waitForFunction(() => {
const button = document.querySelector('[data-testid="codex-enqueue-button"]') as HTMLButtonElement | null;
return button !== null && !button.disabled;
}, undefined, { timeout: 5000 });
const responsePromise = page.waitForResponse((response) => isCodeQueueTaskEnqueueRequest(response.url(), response.request().method()), { timeout: 30000 });
await page.getByTestId("codex-enqueue-button").click();
const response = await responsePromise;
const createBody = await response.json().catch((error: unknown) => ({ parseError: error instanceof Error ? error.message : String(error) }));
const createdTask = Array.isArray(createBody?.tasks) ? createBody.tasks[0] : null;
const taskId = String(createdTask?.id || "");
if (!taskId) return { checked: true, marker, promptChars, createStatus: response.status(), taskId: "", error: "missing task id", createBody };
await page.waitForSelector(`[data-testid="codex-task-${taskId}"]`, { timeout: 30000 }).catch(() => undefined);
const overview = await page.evaluate(async (id) => {
const response = await fetch(`/api/microservices/code-queue/proxy/api/tasks/overview?limit=120&transcriptLimit=0&compact=1&selected=1&includeActive=1&stats=0&afterSeq=0&preferId=${encodeURIComponent(String(id))}`, { credentials: "same-origin" });
const body = await response.json().catch(() => null);
return { ok: response.ok, status: response.status, body };
}, taskId);
const meta = await page.evaluate(async (id) => {
const response = await fetch(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(String(id))}?meta=1`, { credentials: "same-origin" });
const body = await response.json().catch(() => null);
return { ok: response.ok, status: response.status, body };
}, taskId);
const initialPrompt = await page.evaluate(async (id) => {
const response = await fetch(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(String(id))}/prompt?part=initial`, { credentials: "same-origin" });
const body = await response.json().catch(() => null);
return { ok: response.ok, status: response.status, body };
}, taskId);
await page.getByTestId(`codex-task-${taskId}`).click().catch(() => undefined);
await page.waitForSelector('[data-testid="codex-initial-prompt-base"]', { timeout: 15000 }).catch(() => undefined);
const ui = await page.evaluate(() => {
const base = document.querySelector('[data-testid="codex-initial-prompt-base"]') as HTMLElement | null;
return {
baseText: base?.innerText || "",
baseChars: (base?.innerText || "").length,
traceText: document.querySelector('.codex-output-panel')?.textContent || "",
};
});
const overviewTasks = Array.isArray(overview.body?.tasks) ? overview.body.tasks : [];
const overviewTask = overviewTasks.find((task: any) => String(task?.id || "") === taskId) || null;
const selectedTask = overview.body?.selected?.task || null;
const metaTask = meta.body?.task || null;
const createPrompt = String(createdTask?.prompt || "");
const createDisplayPrompt = String(createdTask?.displayPrompt || "");
const createPreview = createdTask?.displayPromptPreview || createdTask?.promptPreview || null;
const overviewPrompt = String(overviewTask?.prompt || "");
const overviewDisplayPrompt = String(overviewTask?.displayPrompt || "");
const overviewPreview = overviewTask?.displayPromptPreview || overviewTask?.promptPreview || null;
const selectedDisplayPrompt = String(selectedTask?.displayPrompt || "");
const selectedPreview = selectedTask?.displayPromptPreview || selectedTask?.promptPreview || null;
const metaPrompt = String(metaTask?.prompt || "");
const metaBasePrompt = String(metaTask?.basePrompt || "");
const metaDisplayPrompt = String(metaTask?.displayPrompt || "");
const promptText = String(initialPrompt.body?.text || "");
const previewHasTruncationMarker = [createPreview?.text, overviewPreview?.text, selectedPreview?.text].some((value) => String(value || "").includes("...<truncated>"));
const originalValues = [createPrompt, createDisplayPrompt, overviewPrompt, overviewDisplayPrompt, selectedDisplayPrompt, metaPrompt, metaBasePrompt, metaDisplayPrompt, promptText];
await apiFetch(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/interrupt`, { method: "POST", body: "{}" }).catch(() => null);
return {
checked: true,
marker,
taskId,
promptChars,
createStatus: response.status(),
createOk: createBody?.ok === true,
createPromptChars: createPrompt.length,
createDisplayPromptChars: createDisplayPrompt.length,
overviewStatus: overview.status,
overviewTaskFound: overviewTask !== null,
overviewPromptChars: overviewPrompt.length,
overviewDisplayPromptChars: overviewDisplayPrompt.length,
selectedTaskFound: selectedTask !== null && String(selectedTask?.id || "") === taskId,
selectedDisplayPromptChars: selectedDisplayPrompt.length,
metaStatus: meta.status,
metaPromptChars: metaPrompt.length,
metaBasePromptChars: metaBasePrompt.length,
metaDisplayPromptChars: metaDisplayPrompt.length,
initialPromptStatus: initialPrompt.status,
initialPromptChars: Number(initialPrompt.body?.chars || promptText.length),
uiBaseChars: ui.baseChars,
preview: {
create: createPreview,
overview: overviewPreview,
selected: selectedPreview,
previewHasTruncationMarker,
createPromptPreviewFieldPresent: createdTask?.promptPreview !== undefined,
overviewPromptPreviewFieldPresent: overviewTask?.promptPreview !== undefined,
selectedPromptPreviewFieldPresent: selectedTask?.promptPreview !== undefined,
},
checks: {
createOriginalHasTail: createPrompt.includes(marker) && createDisplayPrompt.includes(marker),
overviewOriginalHasTail: overviewPrompt.includes(marker) && overviewDisplayPrompt.includes(marker),
selectedOriginalHasTail: selectedDisplayPrompt.includes(marker),
metaOriginalHasTail: metaPrompt.includes(marker) && metaBasePrompt.includes(marker) && metaDisplayPrompt.includes(marker),
initialPromptHasTail: promptText.includes(marker),
uiFullPromptHasTail: String(ui.baseText || "").includes(marker),
originalsHaveNoTruncationMarker: originalValues.every((value) => !value.includes("...<truncated>")),
previewFieldsExplicit: createdTask?.promptPreview !== undefined && overviewTask?.promptPreview !== undefined && selectedTask?.promptPreview !== undefined,
previewCanTruncate: Boolean(createPreview?.truncated || overviewPreview?.truncated || selectedPreview?.truncated),
},
};
}
function runPsql(config: UniDeskConfig, sql: string): { ok: boolean; stdout: string; stderr: string; exitCode: number | null } {
const result = runCommand([
"docker",
@@ -1450,6 +1596,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
"frontend:code-queue-integrated-visible",
"frontend:code-queue-enqueue-await-smoke",
"frontend:code-queue-summary-mobile-wrap",
"frontend:code-queue-long-prompt-observation",
"frontend:code-queue-initial-prompt-full-expand",
"frontend:code-queue-trace-full-load",
"frontend:code-queue-judge-wrap",
@@ -1486,8 +1633,10 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
page.on("dialog", (dialog) => dialog.accept());
await page.goto(urls.frontendUrl, { waitUntil: "domcontentloaded", timeout: 15000 });
await page.waitForSelector('[data-testid="login-screen"]', { timeout: 10000 });
await page.fill('input[name="username"]', config.auth.username);
await page.fill('input[name="password"]', config.auth.password);
const frontendAuthUsername = process.env.UNIDESK_E2E_AUTH_USERNAME || config.auth.username;
const frontendAuthPassword = process.env.UNIDESK_E2E_AUTH_PASSWORD || config.auth.password;
await page.fill('input[name="username"]', frontendAuthUsername);
await page.fill('input[name="password"]', frontendAuthPassword);
await page.click('button[type="submit"]');
await page.waitForSelector('[data-testid="app-shell"]', { timeout: 10000 });
await page.waitForFunction(() => document.querySelector('[data-testid="conn-text"]')?.textContent?.includes("核心在线"), undefined, { timeout: 15000 });
@@ -1547,6 +1696,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
let codeQueueSidebarUpdateMetrics: any = { cardCount: 0, labels: [], hasRecentUpdateLabel: false };
let codeQueueHtmlGuard: any = { rootAttrMissing: false, sourceAttrMissing: false, sourceNoBasePrompt: false };
let codeQueueSummaryMobileMetrics: any = { checked: false, summaryCount: 0, ok: false };
let codeQueueLongPromptMetrics: any = { checked: false };
let codeQueuePromptDefaultEmpty = false;
let codeQueueSubmitGuard: any = { batchRowVisible: false, disabledBeforeConfirm: false, enabledAfterConfirm: false, waitElementMissingBeforeSubmit: false };
let codeQueueEnqueueAwaitSmoke: any = { checked: false };
@@ -1995,6 +2145,9 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
if (wants("frontend:code-queue-enqueue-await-smoke")) {
codeQueueEnqueueAwaitSmoke = await runCodeQueueEnqueueAwaitSmoke(page);
}
if (wants("frontend:code-queue-long-prompt-observation")) {
codeQueueLongPromptMetrics = await runCodeQueueLongPromptObservation(page);
}
codeQueueOptions = await page.locator('[data-testid="code-queue-filter-select"] option').evaluateAll((options) => options.map((option) => (option as HTMLOptionElement).textContent || ""));
codeQueueSwitchMetrics = await page.locator('[data-testid="code-queue-filter-select"] option').evaluateAll((options) => ({
optionCount: options.length,
@@ -3049,6 +3202,21 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2
&& (codeQueueEnqueueAwaitSmoke.interrupt?.ok === true || codeQueueEnqueueAwaitSmoke.interrupt?.status === 409),
{ codeQueueEnqueueAwaitSmoke });
addSelectedCheck(checks, options, "frontend:code-queue-summary-mobile-wrap", codeQueueSummaryMobileMetrics.checked === true && (codeQueueSummaryMobileMetrics.summaryCount === 0 || codeQueueSummaryMobileMetrics.ok === true), { codeQueueSummaryMobileMetrics });
addSelectedCheck(checks, options, "frontend:code-queue-long-prompt-observation",
codeQueueLongPromptMetrics.checked === true
&& codeQueueLongPromptMetrics.createOk === true
&& /^codex_\d+_[A-Za-z0-9_-]+$/u.test(String(codeQueueLongPromptMetrics.taskId || ""))
&& Number(codeQueueLongPromptMetrics.promptChars || 0) > 2500
&& codeQueueLongPromptMetrics.checks?.createOriginalHasTail === true
&& codeQueueLongPromptMetrics.checks?.overviewOriginalHasTail === true
&& codeQueueLongPromptMetrics.checks?.selectedOriginalHasTail === true
&& codeQueueLongPromptMetrics.checks?.metaOriginalHasTail === true
&& codeQueueLongPromptMetrics.checks?.initialPromptHasTail === true
&& codeQueueLongPromptMetrics.checks?.uiFullPromptHasTail === true
&& codeQueueLongPromptMetrics.checks?.originalsHaveNoTruncationMarker === true
&& codeQueueLongPromptMetrics.checks?.previewFieldsExplicit === true
&& codeQueueLongPromptMetrics.checks?.previewCanTruncate === true,
{ codeQueueLongPromptMetrics });
addSelectedCheck(checks, options, "frontend:code-queue-error-red-markers", codeQueueErrorHighlightMetrics.checked === true && codeQueueErrorHighlightMetrics.candidateFound === true && codeQueueErrorHighlightMetrics.ok === true, { codeQueueErrorHighlightMetrics });
addSelectedCheck(checks, options, "frontend:code-queue-initial-prompt-full-expand",
codexInitialPromptFullMetrics.candidateFound === false