fix: collapse workbench trace by default

This commit is contained in:
lyon
2026-06-15 17:46:43 +08:00
parent 4fd1410a45
commit e864740d86
3 changed files with 32 additions and 10 deletions
+18 -5
View File
@@ -263,14 +263,27 @@ async function probeStatus(args) {
async function maybeLogin(page, args, actions) {
const username = page.locator("#login-username");
if (!(await username.isVisible({ timeout: Math.min(args.timeoutMs, 12000) }).catch(() => false))) {
if (await username.isVisible({ timeout: Math.min(args.timeoutMs, 12000) }).catch(() => false)) {
await username.fill(args.user);
await page.locator("#login-password").fill(args.pass);
await page.locator("#login-submit").click();
actions.push({ action: "login", user: args.user, selectorMode: "legacy-id" });
await page.locator("#command-input").waitFor({ state: "visible", timeout: args.timeoutMs });
const finalUrl = new URL(page.url());
if (finalUrl.searchParams.has("username") || finalUrl.searchParams.has("password")) {
throw new Error("login credentials leaked into URL query");
}
return;
}
const cardInputs = page.locator(".login-card input");
if ((await cardInputs.count().catch(() => 0)) < 2) {
actions.push({ action: "login", skipped: "login-form-not-visible", authState: await page.locator("body").getAttribute("data-auth-state").catch(() => null) });
return;
}
await username.fill(args.user);
await page.locator("#login-password").fill(args.pass);
await page.locator("#login-submit").click();
actions.push({ action: "login", user: args.user });
await cardInputs.nth(0).fill(args.user);
await cardInputs.nth(1).fill(args.pass);
await page.locator(".login-card button[type=submit]").click();
actions.push({ action: "login", user: args.user, selectorMode: "login-card" });
await page.locator("#command-input").waitFor({ state: "visible", timeout: args.timeoutMs });
const finalUrl = new URL(page.url());
if (finalUrl.searchParams.has("username") || finalUrl.searchParams.has("password")) {
@@ -1,7 +1,6 @@
<script setup lang="ts">
import { computed, nextTick, ref, watch } from "vue";
import type { RunnerTrace, TraceEvent } from "@/types";
import { isTerminalStatus } from "@/composables/useTraceSubscription";
import { firstNonEmptyString } from "@/utils";
import MessageMarkdown from "@/components/workbench/MessageMarkdown.vue";
import { traceEventBody, traceEventLabel, traceEventMeta } from "@/components/workbench/message-rendering";
@@ -40,8 +39,8 @@ watch(() => [eventCount.value, props.trace?.status, following.value, expanded.va
jumpToBottom();
});
watch(() => [props.trace?.traceId, props.trace?.status, props.defaultExpanded] as const, () => {
expanded.value = props.defaultExpanded ?? !isTerminalStatus(props.trace?.status);
watch(() => [props.trace?.traceId, props.storageKey, props.defaultExpanded] as const, () => {
expanded.value = readStoredExpanded() ?? props.defaultExpanded ?? false;
}, { immediate: true });
watch(expanded, (value) => {
@@ -74,6 +73,16 @@ function onDisclosureToggle(event: Event): void {
if (target instanceof HTMLDetailsElement) expanded.value = target.open;
}
function readStoredExpanded(): boolean | null {
if (!props.storageKey) return null;
try {
const value = window.localStorage.getItem(props.storageKey);
if (value === "1") return true;
if (value === "0") return false;
} catch { /* ignore */ }
return null;
}
function rowIsTool(row: TraceEventRow): boolean {
return row.rowId.startsWith("tool:") || /commandExecution/u.test(row.header);
}
@@ -6,7 +6,6 @@ import TraceTimeline from "@/components/agent/TraceTimeline.vue";
import CodeAgentStatusSummary from "@/components/workbench/CodeAgentStatusSummary.vue";
import MessageActions from "@/components/workbench/MessageActions.vue";
import MessageMarkdown from "@/components/workbench/MessageMarkdown.vue";
import { isTerminalStatus } from "@/composables/useTraceSubscription";
import { useClipboard } from "@/composables/useClipboard";
import { useWorkbenchStore } from "@/stores/workbench";
import { traceIdentityText } from "./message-rendering";
@@ -62,7 +61,8 @@ function scrollToBottom(): void {
}
function traceDefaultExpanded(message: ChatMessage): boolean {
return !isTerminalStatus(message.runnerTrace?.status ?? message.status);
void message;
return false;
}
function traceStorageKey(message: ChatMessage): string {