源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import {
|
||||
evaluate,
|
||||
finishRendererScenario,
|
||||
markRenderer,
|
||||
startRendererScenario,
|
||||
waitForEvaluation
|
||||
} from "./agent-gui-performance-helpers.mjs";
|
||||
import {
|
||||
requiredScenarioData,
|
||||
sqlString,
|
||||
startupWorkspaceID
|
||||
} from "./agent-gui-performance-snapshot-helpers.mjs";
|
||||
import {
|
||||
prepareAgentGUIWindowStressSnapshot,
|
||||
waitForWorkbenchRendererIdle,
|
||||
waitForWorkbenchRendererQuiet
|
||||
} from "./agent-gui-window-performance-scenarios.mjs";
|
||||
|
||||
const dockPopupPreviewWindowCount = 50;
|
||||
const dockPopupPreviewScreenshot = "workbench-dock-popup-preview.png";
|
||||
const dockPopupPreviewMarkers = {
|
||||
start: "tutti-perf:workbench-dock-popup-preview:start",
|
||||
opened: "tutti-perf:workbench-dock-popup-preview:opened-observed",
|
||||
ready: "tutti-perf:workbench-dock-popup-preview:ready-observed",
|
||||
captured: "tutti-perf:workbench-dock-popup-preview:captured-observed",
|
||||
end: "tutti-perf:workbench-dock-popup-preview:end"
|
||||
};
|
||||
|
||||
export const workbenchDockPopupPreviewScenario = {
|
||||
id: "workbench-dock-popup-preview",
|
||||
markers: dockPopupPreviewMarkers,
|
||||
milestones: [
|
||||
{
|
||||
key: "opened",
|
||||
label: "Dock popup opened",
|
||||
marker: dockPopupPreviewMarkers.opened
|
||||
},
|
||||
{
|
||||
key: "ready",
|
||||
label: "all preview images ready",
|
||||
marker: dockPopupPreviewMarkers.ready
|
||||
},
|
||||
{
|
||||
key: "captured",
|
||||
label: "Dock popup pixels captured",
|
||||
marker: dockPopupPreviewMarkers.captured
|
||||
}
|
||||
],
|
||||
prepareSnapshot: prepareWorkbenchDockPopupPreviewDatabaseSnapshot,
|
||||
prepare: prepareWorkbenchDockPopupPreview,
|
||||
execute: executeWorkbenchDockPopupPreview,
|
||||
describe(prepared) {
|
||||
return `${prepared.expectedNodeIDs.length} mounted AgentGUI windows; fresh Dock preview cache`;
|
||||
},
|
||||
summarize(prepared, result) {
|
||||
return scenarioSummary(
|
||||
[
|
||||
{
|
||||
name: `${dockPopupPreviewWindowCount} Dock popup cards rendered`,
|
||||
passed: result.cardCount === dockPopupPreviewWindowCount
|
||||
},
|
||||
{
|
||||
name: "foreground preview rendered",
|
||||
passed: result.foregroundReadyCount === 1
|
||||
},
|
||||
{
|
||||
name: "background previews rendered",
|
||||
passed:
|
||||
result.backgroundReadyCount === dockPopupPreviewWindowCount - 1
|
||||
},
|
||||
{
|
||||
name: "preview PNGs contain visible pixels",
|
||||
passed: result.pixelReadyCount === dockPopupPreviewWindowCount
|
||||
},
|
||||
{
|
||||
name: "preview titles rendered",
|
||||
passed: result.titledCardCount === dockPopupPreviewWindowCount
|
||||
},
|
||||
{
|
||||
name: "no loading or terminal fallback remained",
|
||||
passed: result.unreadyCount === 0
|
||||
},
|
||||
{ name: "pixel screenshot written", passed: result.captured }
|
||||
],
|
||||
[
|
||||
{ label: "Workspace", value: prepared.workspaceID },
|
||||
{ label: "Dock popup cards", value: result.cardCount },
|
||||
{
|
||||
label: "Foreground/background previews",
|
||||
value: `${result.foregroundReadyCount}/${result.backgroundReadyCount}`
|
||||
},
|
||||
{ label: "Pixel-ready previews", value: result.pixelReadyCount },
|
||||
{ label: "Titled cards", value: result.titledCardCount },
|
||||
{ label: "Screenshot", value: dockPopupPreviewScreenshot }
|
||||
],
|
||||
"an isolated empty preview cache forces 49 background AgentGUI cards through the serialized DOM-clone fallback; every resulting PNG must decode with visible, non-uniform pixels"
|
||||
);
|
||||
},
|
||||
assessTrace: assessWorkbenchDockPopupPreviewTrace
|
||||
};
|
||||
|
||||
export function prepareWorkbenchDockPopupPreviewSnapshot(snapshot) {
|
||||
if (
|
||||
!snapshot ||
|
||||
typeof snapshot !== "object" ||
|
||||
!Array.isArray(snapshot.nodes)
|
||||
) {
|
||||
throw new Error("invalid Workbench Dock popup preview snapshot input");
|
||||
}
|
||||
const stressedSnapshot = prepareAgentGUIWindowStressSnapshot(
|
||||
snapshot,
|
||||
dockPopupPreviewWindowCount
|
||||
);
|
||||
const agentGuiNodes = stressedSnapshot.nodes
|
||||
.filter((node) => node?.data?.typeId === "agent-gui")
|
||||
.map((node, index) => ({
|
||||
...node,
|
||||
title: `Dock Preview ${index + 1}`
|
||||
}));
|
||||
const agentGuiNodeByID = new Map(
|
||||
agentGuiNodes.map((node) => [node.id, node])
|
||||
);
|
||||
return {
|
||||
snapshot: {
|
||||
...stressedSnapshot,
|
||||
nodes: stressedSnapshot.nodes.map(
|
||||
(node) => agentGuiNodeByID.get(node.id) ?? node
|
||||
)
|
||||
},
|
||||
expectedNodeIDs: agentGuiNodes.map((node) => node.id),
|
||||
expectedTitles: agentGuiNodes.map((node) => node.title)
|
||||
};
|
||||
}
|
||||
|
||||
export function assessWorkbenchDockPopupPreviewTrace(traceSummary) {
|
||||
const maximumRendererTaskMs = 50;
|
||||
const maximumObservedRendererTaskMs = traceSummary.timing.maxLongTaskMs;
|
||||
return {
|
||||
assertions: [
|
||||
{
|
||||
name: `renderer task <= ${maximumRendererTaskMs} ms`,
|
||||
passed: maximumObservedRendererTaskMs <= maximumRendererTaskMs
|
||||
}
|
||||
],
|
||||
details: [
|
||||
{
|
||||
label: "Maximum renderer task",
|
||||
value: `${maximumObservedRendererTaskMs} ms`
|
||||
},
|
||||
{
|
||||
label: "Renderer task budget",
|
||||
value: `${maximumRendererTaskMs} ms`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
async function prepareWorkbenchDockPopupPreviewDatabaseSnapshot(context) {
|
||||
const workspaceID = await startupWorkspaceID(context);
|
||||
const rows = await context.sqliteJSON(
|
||||
context.databasePath,
|
||||
`
|
||||
SELECT snapshot_json AS snapshotJSON
|
||||
FROM workspace_workbench_snapshots
|
||||
WHERE workspace_id = '${sqlString(workspaceID)}'
|
||||
LIMIT 1;
|
||||
`
|
||||
);
|
||||
const prepared = prepareWorkbenchDockPopupPreviewSnapshot(
|
||||
JSON.parse(rows[0]?.snapshotJSON ?? "null")
|
||||
);
|
||||
await context.sqliteExec(
|
||||
context.databasePath,
|
||||
`
|
||||
UPDATE workspace_workbench_snapshots
|
||||
SET snapshot_json = '${sqlString(JSON.stringify(prepared.snapshot))}'
|
||||
WHERE workspace_id = '${sqlString(workspaceID)}';
|
||||
`
|
||||
);
|
||||
return {
|
||||
data: {
|
||||
expectedNodeIDs: prepared.expectedNodeIDs,
|
||||
workspaceID
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function prepareWorkbenchDockPopupPreview(context, options) {
|
||||
const scenarioData = requiredScenarioData(
|
||||
context,
|
||||
"workbench-dock-popup-preview"
|
||||
);
|
||||
const expectedNodeIDs = scenarioData.expectedNodeIDs;
|
||||
await waitForEvaluation(
|
||||
context.pageClient,
|
||||
`(() => {
|
||||
const expectedNodeIDs = ${JSON.stringify(expectedNodeIDs)};
|
||||
const shells = expectedNodeIDs.map((nodeID) =>
|
||||
document.querySelector('[data-workbench-window-id="' + CSS.escape(nodeID) + '"]')
|
||||
);
|
||||
const mountedShellCount = shells.filter((shell) =>
|
||||
shell instanceof HTMLElement &&
|
||||
shell.dataset.minimizedMount === 'visible' &&
|
||||
shell.dataset.presentationVisibility === 'visible'
|
||||
).length;
|
||||
const pendingHydrationCount = document.querySelectorAll(
|
||||
'[data-agent-gui-workbench-hydration="pending"]'
|
||||
).length;
|
||||
const slot = document.querySelector(
|
||||
'[data-desktop-dock-anchor-key="agent-gui:unified"]'
|
||||
);
|
||||
const button = slot?.querySelector('button');
|
||||
if (!(button instanceof HTMLButtonElement)) {
|
||||
return { ready: false, mountedShellCount, pendingHydrationCount };
|
||||
}
|
||||
const rect = button.getBoundingClientRect();
|
||||
return {
|
||||
ready:
|
||||
mountedShellCount === expectedNodeIDs.length &&
|
||||
pendingHydrationCount === 0 &&
|
||||
rect.width > 0 &&
|
||||
rect.height > 0,
|
||||
mountedShellCount,
|
||||
pendingHydrationCount,
|
||||
expectedWindowCount: expectedNodeIDs.length
|
||||
};
|
||||
})()`,
|
||||
options.timeoutMs,
|
||||
"50 mounted AgentGUI windows and the unified Agent Dock button"
|
||||
);
|
||||
await waitForWorkbenchRendererQuiet(context.pageClient);
|
||||
await waitForWorkbenchRendererIdle(context.pageClient);
|
||||
return {
|
||||
expectedNodeIDs,
|
||||
workspaceID: scenarioData.workspaceID
|
||||
};
|
||||
}
|
||||
|
||||
async function executeWorkbenchDockPopupPreview(context, prepared, options) {
|
||||
const { pageClient } = context;
|
||||
await startRendererScenario(pageClient, dockPopupPreviewMarkers.start);
|
||||
await evaluate(
|
||||
pageClient,
|
||||
`(() => {
|
||||
const slot = document.querySelector(
|
||||
'[data-desktop-dock-anchor-key="agent-gui:unified"]'
|
||||
);
|
||||
const button = slot?.querySelector('button');
|
||||
if (!(button instanceof HTMLButtonElement)) {
|
||||
throw new Error('Agent Dock button is unavailable');
|
||||
}
|
||||
button.click();
|
||||
return true;
|
||||
})()`
|
||||
);
|
||||
await waitForEvaluation(
|
||||
pageClient,
|
||||
`(() => {
|
||||
const popup = document.querySelector(
|
||||
'[data-desktop-dock-popup-root][data-popup-variant="default"]'
|
||||
);
|
||||
const cards = popup?.querySelectorAll('[data-desktop-dock-popup-card]');
|
||||
return { ready: cards?.length === ${dockPopupPreviewWindowCount} };
|
||||
})()`,
|
||||
options.timeoutMs,
|
||||
"Agent Dock popup with 50 cards"
|
||||
);
|
||||
await markRenderer(pageClient, dockPopupPreviewMarkers.opened);
|
||||
await waitForEvaluation(
|
||||
pageClient,
|
||||
`(() => {
|
||||
const cards = [...document.querySelectorAll(
|
||||
'[data-desktop-dock-popup-root][data-popup-variant="default"] [data-desktop-dock-popup-card]'
|
||||
)];
|
||||
const images = cards.map((card) =>
|
||||
card.querySelector('[data-preview-state="ready"][data-preview-kind="image"] img')
|
||||
);
|
||||
return {
|
||||
ready:
|
||||
cards.length === ${dockPopupPreviewWindowCount} &&
|
||||
images.every((image) =>
|
||||
image instanceof HTMLImageElement &&
|
||||
image.complete &&
|
||||
image.naturalWidth > 0 &&
|
||||
image.naturalHeight > 0
|
||||
)
|
||||
};
|
||||
})()`,
|
||||
options.timeoutMs,
|
||||
"decoded foreground and background Dock preview images"
|
||||
);
|
||||
const previewState = await evaluate(
|
||||
pageClient,
|
||||
`Promise.all([...document.querySelectorAll(
|
||||
'[data-desktop-dock-popup-root][data-popup-variant="default"] [data-desktop-dock-popup-card]'
|
||||
)].map(async (card) => {
|
||||
const image = card.querySelector(
|
||||
'[data-preview-state="ready"][data-preview-kind="image"] img'
|
||||
);
|
||||
if (!(image instanceof HTMLImageElement)) {
|
||||
return {
|
||||
active: card.getAttribute('data-active') === 'true',
|
||||
pixelReady: false,
|
||||
ready: false,
|
||||
title: card.querySelector('[role="button"]')?.getAttribute('aria-label') ?? ''
|
||||
};
|
||||
}
|
||||
await image.decode().catch(() => undefined);
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = Math.min(64, image.naturalWidth);
|
||||
canvas.height = Math.min(64, image.naturalHeight);
|
||||
const context = canvas.getContext('2d', { willReadFrequently: true });
|
||||
if (!context) throw new Error('Dock preview pixel canvas unavailable');
|
||||
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
||||
const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
let visiblePixels = 0;
|
||||
const colorBuckets = new Set();
|
||||
for (let index = 0; index < pixels.length; index += 4) {
|
||||
if (pixels[index + 3] <= 8) continue;
|
||||
visiblePixels += 1;
|
||||
colorBuckets.add(
|
||||
(pixels[index] >> 5) + ':' +
|
||||
(pixels[index + 1] >> 5) + ':' +
|
||||
(pixels[index + 2] >> 5)
|
||||
);
|
||||
}
|
||||
const totalPixels = canvas.width * canvas.height;
|
||||
return {
|
||||
active: card.getAttribute('data-active') === 'true',
|
||||
pixelReady:
|
||||
totalPixels > 0 &&
|
||||
visiblePixels / totalPixels >= 0.05 &&
|
||||
colorBuckets.size >= 2,
|
||||
ready: true,
|
||||
title: card.querySelector('[role="button"]')?.getAttribute('aria-label') ?? ''
|
||||
};
|
||||
}))`,
|
||||
true
|
||||
);
|
||||
await markRenderer(pageClient, dockPopupPreviewMarkers.ready);
|
||||
await capturePageScreenshot(
|
||||
context,
|
||||
join(context.outputDirectory, dockPopupPreviewScreenshot)
|
||||
);
|
||||
await markRenderer(pageClient, dockPopupPreviewMarkers.captured);
|
||||
await finishRendererScenario(pageClient, dockPopupPreviewMarkers.end);
|
||||
return {
|
||||
backgroundReadyCount: previewState.filter(
|
||||
(preview) => !preview.active && preview.ready
|
||||
).length,
|
||||
captured: true,
|
||||
cardCount: previewState.length,
|
||||
foregroundReadyCount: previewState.filter(
|
||||
(preview) => preview.active && preview.ready
|
||||
).length,
|
||||
pixelReadyCount: previewState.filter((preview) => preview.pixelReady)
|
||||
.length,
|
||||
titledCardCount: previewState.filter((preview) => preview.title.trim())
|
||||
.length,
|
||||
unreadyCount: previewState.filter((preview) => !preview.ready).length
|
||||
};
|
||||
}
|
||||
|
||||
async function capturePageScreenshot(context, outputPath) {
|
||||
const screenshot = await context.pageClient.send("Page.captureScreenshot", {
|
||||
captureBeyondViewport: false,
|
||||
format: "png",
|
||||
fromSurface: true
|
||||
});
|
||||
await writeFile(outputPath, Buffer.from(screenshot.data, "base64"));
|
||||
}
|
||||
|
||||
function scenarioSummary(assertions, details, stabilityCriterion) {
|
||||
return {
|
||||
outcome: assertions.every((assertion) => assertion.passed)
|
||||
? "passed"
|
||||
: "failed",
|
||||
assertions,
|
||||
details,
|
||||
stabilityCriterion
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user