mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 17:47:40 +00:00
* [comment audit] Align legacy failure-read counts with cached display * [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci] * [comment audit] Condense shared generation, path and preview comments [skip ci] * [comment audit] Condense host, file and Git contract rationale [skip ci] * [comment audit] Tighten Git lifecycle and provider contract comments [skip ci] * [comment audit] Clarify shared host authority and launch isolation [skip ci] * [comment audit] simplify local access mobile and native chat contracts [skip ci] * [comment audit] simplify native chat presentation and state contracts [skip ci] * [comment audit] simplify native runtime and provider contracts [skip ci] * [comment audit] simplify migration and orchestration contracts [skip ci] * [comment audit] simplify plugin trust and process capture rationale [skip ci] * [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci] * [comment audit] clarify remote recovery and launch wire rationale [skip ci] * [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci] * [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci] * [comment audit] clarify sidebar, skill and SSH invariants [skip ci] * [comment audit] condense structured chat delivery and timing rationale [skip ci] * [comment audit] condense terminal replay and telemetry invariants [skip ci] * [comment audit] clarify launch permission and terminal delivery rationale [skip ci] * [comment audit] clarify workspace ownership and layout contracts [skip ci] * [comment audit] wait for fitted and painted SSH terminal links * [comment audit] clarify layout persistence and session ownership [skip ci] * [comment audit] clarify host routing and workspace lifecycle contracts [skip ci] * [comment audit] clarify startup persistence and app lifetime comments [skip ci] * [comment audit] clarify recovery and activity boundaries [skip ci] * [comment audit] condense activity and artifact invariants [skip ci] * [comment audit] condense automation authority contracts [skip ci] * [comment audit] simplify automation scheduling and history contracts [skip ci] * [comment audit] clarify browser chrome and annotation lifecycles [skip ci] * [comment audit] clarify browser routing and retained guest ownership [skip ci] * [comment audit] clarify browser recovery and document ownership comments [skip ci] * [comment audit] restore hosted runners required by native IME fixtures * [comment audit] shorten preview, palette and dashboard invariants [skip ci] * [comment audit] clarify terminal preview, dashboard and retention comments [skip ci] * [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci] * [comment audit] shorten rich-text and combined-diff ownership comments [skip ci] * [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci] * [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci] * [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci] * [comment audit] clarify rich Markdown source and selection safeguards [skip ci] * [comment audit] clarify editor loading and emulator stream lifetimes [skip ci] * [comment audit] trim emulator and feature tour narration [skip ci] * [comment audit] clarify floating workspace and GitHub cache ownership [skip ci] * [comment audit] trim provider controls and Linear filter explanations [skip ci] * [comment audit] clarify pairing and chat resume lifetimes [skip ci] * [comment audit] clarify chat delivery and transcript lifetimes [skip ci] * [comment audit] clarify session options and host-owned status [skip ci] * [comment audit] clarify draft durability and live-status precedence [skip ci] * [comment audit] Trim chat send and model ownership explanations [skip ci] * [comment audit] Shorten transcript ownership and send recovery comments [skip ci] * [comment audit] Simplify native chat composer and transcript hook comments [skip ci] * [comment audit] Shorten native chat scroll and structured session explanations [skip ci] * [comment audit] Trim workspace picker and onboarding commentary [skip ci] * [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci] * [comment audit] Trim sidebar and session history explanations [skip ci] * [comment audit] Condense session resume and review checks comments [skip ci] * [comment audit] Shorten checks state and file explorer refresh comments [skip ci] * [comment audit] Trim plugin bridge and source-control action rationale [skip ci] * [comment audit] Trim source-control listing and review rationale [skip ci] * [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci] * [comment audit] Condense Settings account and appearance rationale [skip ci] * [comment audit] Trim pairing and repository Settings explanations [skip ci] * [comment audit] Condense Settings search SSH and terminal safeguards [skip ci] * [comment audit] Shorten Settings voice and provider ownership comments [skip ci] * [comment audit] Condense Settings draft persistence and host-state rationale [skip ci] * [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci] * [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci] * [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci] * [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci] * [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci] * [comment audit] Prune focus-read baseline after comment cleanup * [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci] * [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci] * [comment audit] Clarify viewport geometry and skill update safeguards [skip ci] * [comment audit] Tighten skill inventory, usage and host status comments [skip ci] * [comment audit] Clarify usage ownership and resource kill safeguards [skip ci] * [comment audit] Tighten tab selection, rename and search contracts [skip ci] * [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci] * [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci] * [comment audit] Tighten provider loading and terminal recovery comments [skip ci] * [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci] * [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci] * [comment audit] Tighten PTY startup and replay explanations [skip ci] * [comment audit] Clarify PTY identity and delivery ownership [skip ci] * [comment audit] Shorten remote reconnect and input replay rationale [skip ci] * [comment audit] Condense terminal parking clipboard and file link comments [skip ci] * [comment audit] Clarify IME ownership and trim trace history [skip ci] * [comment audit] Shorten pane recovery and parked watcher explanations [skip ci] * [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci] * [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci] * [comment audit] Trim renderer lifecycle and menu rationale [skip ci] * [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci] * [comment audit] Clarify renderer hook evidence and source ownership [skip ci] * [comment audit] Tighten IPC ownership and reconnect explanations [skip ci] * [comment audit] Trim renderer focus, paste and attention comments [skip ci] * [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci] * [comment audit] Trim agent launch, resume and ownership commentary [skip ci] * [comment audit] Shorten account, browser and editor comments [skip ci] * [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci] * [comment audit] Condense launch recovery and editor tokenization comments [skip ci] * [comment audit] Condense workspace selection and terminal pane rationale [skip ci] * [comment audit] Condense terminal fitting and rendering recovery comments [skip ci] * [comment audit] Condense terminal input and host routing explanations [skip ci] * [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci] * [comment audit] Condense structured launch and terminal link explanations [skip ci] * [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci] * [comment audit] Condense session persistence and workspace activation rationale [skip ci] * [comment audit] Condense workspace routing and browser ownership rationale [skip ci] * [comment audit] Condense mirror recovery and layout authority rationale [skip ci] * [comment audit] Condense runtime transport and file safety rationale [skip ci] * [comment audit] Condense runtime graph and structured session rationale [skip ci] * [comment audit] Condense browser creation and remote tab recovery rationale [skip ci] * [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci] * [comment audit] Condense frame, startup and provider cache rationale [skip ci] * [comment audit] Condense host twin and agent lifecycle rationale [skip ci] * [comment audit] Condense browser authority and editor cleanup rationale [skip ci] * [comment audit] Condense editor buffer identity and review cache rationale [skip ci] * [comment audit] Condense provider lifetime and repository ownership rationale [skip ci] * [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci] * [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci] * [comment audit] Condense cleanup ownership and listing admission rationale [skip ci] * [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci] * [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci] * [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci] * [comment audit] Condense cloud rollout and assignment safety rationale [skip ci] * [comment audit] Condense relay session and database recovery rationale [skip ci] * [comment audit] Condense relay placement and protocol compatibility rationale [skip ci] * [comment audit] Condense build and packaging constraints [skip ci] * [comment audit] Condense CI gates and validation isolation rationale [skip ci] * [comment audit] Condense catalog identity and browser validation rationale [skip ci] * [comment audit] Condense mobile browser and frame-budget rationale [skip ci] * [comment audit] Shorten mobile route and browser test explanations [skip ci] * [comment audit] Condense editor and session seam test rationale [skip ci] * [comment audit] Trim session and terminal closure history [skip ci] * [comment audit] Shorten terminal browser and census explanations [skip ci] * [comment audit] Preserve root-only E2E diagnostic baseline * [comment audit] Condense mobile seam and HTML preview test rationale [skip ci] * [comment audit] Condense preview instrumentation and render harness rationale [skip ci] * [comment audit] Condense bundle contracts and native-build constraints [skip ci] * [comment audit] Shorten native packaging and CI routing rationale [skip ci] * [comment audit] Condense release tooling and benchmark constraints [skip ci] * [comment audit] Condense packaging and platform gate rationale [skip ci] * [comment audit] Shorten mobile route and history rationale [skip ci] * [comment audit] Condense mobile browser and component rationale [skip ci] * [comment audit] Shorten drawer and workspace-form rationale [skip ci] * [comment audit] Trim mobile review and editor-document explanations [skip ci] * [comment audit] Condense editor lifecycle and Markdown explanations [skip ci] * [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci] * [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci] * [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci] * [comment audit] Condense bridge stream, native request and audio rationale [skip ci] * [comment audit] Reduce bridge schema and page-client commentary [skip ci] * [comment audit] Tighten mobile page bridge contracts [skip ci] * [comment audit] Clarify mobile cache and session constraints [skip ci] * [comment audit] Condense mobile route and lifecycle rationale [skip ci] * [comment audit] Tighten mobile shell hook timing rationale [skip ci] * [comment audit] Clarify route handoff and notification compatibility [skip ci] * [comment audit] Clarify push registration and dictation cleanup constraints [skip ci] * [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci] * [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci] * [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci] * [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci] * [comment audit] Tighten stream replay and queued session ownership rationale [skip ci] * [comment audit] Condense mobile composer and reply-schema constraints [skip ci] * [comment audit] Clarify mobile transcript recovery and session ownership [skip ci] * [comment audit] Clarify mobile queue and source-control compatibility [skip ci] * [comment audit] Condense storage and task launch constraints [skip ci] * [comment audit] Clarify task schemas and terminal document ownership [skip ci] * [comment audit] Tighten terminal input and viewport rationale [skip ci] * [comment audit] Shorten terminal and RPC recorder contracts [skip ci] * [comment audit] Condense recorder engine and connection contracts [skip ci] * [comment audit] Shorten host credential and relay recovery comments [skip ci] * [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci] * [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci] * [comment audit] Condense catalog and relay entry contracts [skip ci] * [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci] * [comment audit] Condense WSL relay and E2E regression rationale [skip ci] * [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci] * [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci] * [comment audit] Shorten layout oracle and regression explanations [skip ci] * [comment audit] Condense paired recovery and ownership regression contracts [skip ci] * [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci] * [comment audit] Condense terminal rendering and IME regression rationale [skip ci] * [comment audit] Shorten terminal recovery and benchmark contracts [skip ci] * [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci] * [comment audit] Condense workflow routing and release rationale [skip ci] * [comment audit] Condense mobile security and installer contracts [skip ci] * [comment audit] Shorten native rationale and stylesheet workarounds [skip ci] * [comment audit] Shorten Windows visibility probe rationale [skip ci] * [comment audit] Condense embedded release and signing rationale [skip ci] * [comment audit] Retain current main test behavior in final reconciliation [skip ci] * [comment audit] Complete final comment review across current source inventory * [comment audit] Handle consolidated audit reports before final CI * [comment audit] Preserve credential storage census detail [skip ci] * [comment audit] Scale broad changed E2E selections with verified timing shards * [comment audit] Align E2E assertions with browser close and settled session metadata * [comment audit] Match existing E2Es to current resource and windowing contracts * [comment audit] Observe the shared server outage notice in reconnect coverage * [comment audit] Make existing renderer probes measure settled tab and PTY work * [comment audit] Align palette E2E selector with task search * [comment audit] Refresh remaining palette search selectors * [comment audit] Keep selector correction within selected audit specs * [comment audit] Await emoji fixture settings inside renderer evaluation * [comment audit] Cancel fixture fit retries between terminal tests --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
339 lines
11 KiB
JavaScript
339 lines
11 KiB
JavaScript
import { chromium } from '@playwright/test'
|
|
import { spawn } from 'node:child_process'
|
|
import { mkdirSync, mkdtempSync } from 'node:fs'
|
|
import net from 'node:net'
|
|
import os from 'node:os'
|
|
import path from 'node:path'
|
|
import process from 'node:process'
|
|
import { fileURLToPath } from 'node:url'
|
|
import {
|
|
appShutdownTimeoutMs,
|
|
cdpPollTimeoutMs,
|
|
delay,
|
|
pollUntil,
|
|
rendererActionTimeoutMs,
|
|
runWithTimeout
|
|
} from './repro-timing.mjs'
|
|
import { createCompletedOnboardingProfile } from './wsl-workspace-fixture.mjs'
|
|
|
|
const rootDir = path.resolve(fileURLToPath(new URL('../../..', import.meta.url)))
|
|
|
|
function isPortFree(port) {
|
|
return new Promise((resolve) => {
|
|
const server = net.createServer()
|
|
server.once('error', () => {
|
|
try {
|
|
server.close()
|
|
} catch {}
|
|
resolve(false)
|
|
})
|
|
server.once('listening', () => server.close(() => resolve(true)))
|
|
server.listen(port, '127.0.0.1')
|
|
})
|
|
}
|
|
|
|
export async function pickFreePort() {
|
|
for (let port = 9533; port < 9633; port += 1) {
|
|
if (await isPortFree(port)) {
|
|
return port
|
|
}
|
|
}
|
|
throw new Error('Could not find a free CDP port in 9533..9632.')
|
|
}
|
|
|
|
export function createGpuUserDataDirectory(gpuMode) {
|
|
const userDataDir = mkdtempSync(path.join(os.tmpdir(), `orca-apphang-${gpuMode}-userdata-`))
|
|
createCompletedOnboardingProfile(userDataDir)
|
|
return userDataDir
|
|
}
|
|
|
|
export function launchDevApp({ cdpPort, userDataDir }) {
|
|
const env = { ...process.env }
|
|
delete env.ELECTRON_RUN_AS_NODE
|
|
delete env.CODEX_HOME
|
|
delete env.ORCA_CODEX_HOME
|
|
const isolatedHome = path.join(userDataDir, 'home')
|
|
mkdirSync(isolatedHome, { recursive: true })
|
|
Object.assign(env, {
|
|
ELECTRON_ENABLE_LOGGING: '1',
|
|
ELECTRON_ENABLE_STACK_DUMPING: '1',
|
|
NODE_ENV: 'development',
|
|
// Keep disposable app-hang measurements free of real-home Codex work and developer state exposure.
|
|
ORCA_DEV_USER_DATA_PATH: userDataDir,
|
|
HOME: isolatedHome,
|
|
USERPROFILE: isolatedHome,
|
|
ORCA_SKIP_DEV_WEB_PREPARE: '1',
|
|
ORCA_STARTUP_DIAGNOSTICS: '1',
|
|
REMOTE_DEBUGGING_PORT: String(cdpPort),
|
|
VITE_EXPOSE_STORE: 'true'
|
|
})
|
|
const child = spawn(
|
|
process.execPath,
|
|
[path.join('config', 'scripts', 'run-electron-vite-dev.mjs')],
|
|
{
|
|
cwd: rootDir,
|
|
env,
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
windowsHide: true
|
|
}
|
|
)
|
|
const logs = []
|
|
const collect = (source) => (chunk) => {
|
|
const text = chunk.toString()
|
|
for (const line of text.split(/\r?\n/).filter(Boolean)) {
|
|
logs.push({ source, line, at: Date.now() })
|
|
console.log(`[apphang-repro:${source}] ${line}`)
|
|
}
|
|
}
|
|
child.stdout?.on('data', collect('stdout'))
|
|
child.stderr?.on('data', collect('stderr'))
|
|
return { child, logs }
|
|
}
|
|
|
|
export async function stopDevApp(child) {
|
|
if (!child?.pid || child.exitCode !== null || child.signalCode !== null) {
|
|
return
|
|
}
|
|
await new Promise((resolve) => {
|
|
const timer = setTimeout(resolve, appShutdownTimeoutMs)
|
|
child.once('exit', () => {
|
|
clearTimeout(timer)
|
|
resolve()
|
|
})
|
|
if (process.platform === 'win32') {
|
|
const killer = spawn('taskkill', ['/pid', String(child.pid), '/t', '/f'], {
|
|
stdio: 'ignore',
|
|
windowsHide: true
|
|
})
|
|
killer.once('exit', () => undefined)
|
|
return
|
|
}
|
|
child.kill('SIGTERM')
|
|
})
|
|
}
|
|
|
|
async function waitForCdp(port) {
|
|
const url = `http://127.0.0.1:${port}/json`
|
|
const startedAt = Date.now()
|
|
while (Date.now() - startedAt < cdpPollTimeoutMs) {
|
|
try {
|
|
const response = await fetch(url)
|
|
if (response.ok) {
|
|
const targets = await response.json()
|
|
if (Array.isArray(targets) && targets.some((target) => target.type)) {
|
|
return targets
|
|
}
|
|
}
|
|
} catch {}
|
|
await delay(500)
|
|
}
|
|
throw new Error(`Timed out waiting for CDP targets on ${url}`)
|
|
}
|
|
|
|
async function getMainPage(browser) {
|
|
const startedAt = Date.now()
|
|
while (Date.now() - startedAt < cdpPollTimeoutMs) {
|
|
for (const context of browser.contexts()) {
|
|
const pages = context.pages()
|
|
const page =
|
|
pages.find((candidate) =>
|
|
/^https?:\/\/127\.0\.0\.1:|^https?:\/\/localhost:/.test(candidate.url())
|
|
) ?? pages[0]
|
|
if (page) {
|
|
return page
|
|
}
|
|
}
|
|
await delay(250)
|
|
}
|
|
throw new Error('Timed out waiting for the Electron renderer page.')
|
|
}
|
|
|
|
export async function connectToApp(cdpPort) {
|
|
await waitForCdp(cdpPort)
|
|
const browser = await chromium.connectOverCDP(`http://127.0.0.1:${cdpPort}`)
|
|
const page = await getMainPage(browser)
|
|
await page.waitForLoadState('domcontentloaded', { timeout: 30_000 })
|
|
return { browser, page }
|
|
}
|
|
|
|
export async function installRendererProbe(page) {
|
|
await page.evaluate(() => {
|
|
if (globalThis.__orcaApphangProbe) {
|
|
return
|
|
}
|
|
const probe = {
|
|
intervalMs: 50,
|
|
last: performance.now(),
|
|
maxDriftMs: 0,
|
|
samples: 0,
|
|
startedAt: performance.now(),
|
|
lastTickAt: performance.now()
|
|
}
|
|
const timer = setInterval(() => {
|
|
const now = performance.now()
|
|
const drift = Math.max(0, now - probe.last - probe.intervalMs)
|
|
probe.maxDriftMs = Math.max(probe.maxDriftMs, drift)
|
|
probe.last = now
|
|
probe.lastTickAt = now
|
|
probe.samples += 1
|
|
}, probe.intervalMs)
|
|
globalThis.__orcaApphangProbe = { probe, timer }
|
|
})
|
|
}
|
|
|
|
export async function waitForStoreReady(page) {
|
|
await pollUntil(
|
|
'renderer store exposure',
|
|
() => page.evaluate(() => Boolean(window.__store && window.api)),
|
|
Boolean,
|
|
30_000
|
|
)
|
|
await pollUntil(
|
|
'workspace session hydration',
|
|
() =>
|
|
page.evaluate(() => {
|
|
const state = window.__store?.getState?.()
|
|
return Boolean(state?.workspaceSessionReady && state?.hydrationSucceeded)
|
|
}),
|
|
Boolean,
|
|
45_000
|
|
)
|
|
}
|
|
|
|
export async function collectRendererDiagnostics(page) {
|
|
if (!page) {
|
|
return null
|
|
}
|
|
try {
|
|
return await runWithTimeout(
|
|
'renderer diagnostics',
|
|
() =>
|
|
page.evaluate(async () => {
|
|
const timed = (label, promise) =>
|
|
Promise.race([
|
|
Promise.resolve(promise).then(
|
|
(value) => ({ value }),
|
|
(error) => ({ error: error instanceof Error ? error.message : String(error) })
|
|
),
|
|
new Promise((resolve) =>
|
|
setTimeout(() => resolve({ error: `Timed out collecting ${label}` }), 1_000)
|
|
)
|
|
])
|
|
const readWebglIdentity = () => {
|
|
const canvas = document.createElement('canvas')
|
|
let gl = null
|
|
try {
|
|
gl = canvas.getContext('webgl2') ?? canvas.getContext('webgl')
|
|
if (!gl) {
|
|
return { available: false, vendor: null, renderer: null }
|
|
}
|
|
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info')
|
|
if (!debugInfo) {
|
|
return { available: true, vendor: null, renderer: null }
|
|
}
|
|
return {
|
|
available: true,
|
|
vendor: String(gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) ?? '') || null,
|
|
renderer: String(gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) ?? '') || null
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
available: false,
|
|
error: error instanceof Error ? error.message : String(error)
|
|
}
|
|
} finally {
|
|
try {
|
|
gl?.getExtension('WEBGL_lose_context')?.loseContext()
|
|
} catch {}
|
|
canvas.width = 0
|
|
canvas.height = 0
|
|
}
|
|
}
|
|
const allPaneManagersDiagnostics = Array.from(
|
|
window.__paneManagers?.entries?.() ?? []
|
|
).map(([managerTabId, paneManager]) => ({
|
|
tabId: managerTabId,
|
|
diagnostics: paneManager?.getRenderingDiagnostics?.() ?? []
|
|
}))
|
|
const webglContextCounts = allPaneManagersDiagnostics.reduce(
|
|
(acc, entry) => {
|
|
acc.managerCount += 1
|
|
acc.paneCount += entry.diagnostics.length
|
|
for (const diagnostic of entry.diagnostics) {
|
|
if (diagnostic.hasWebgl) {
|
|
acc.attachedWebglCount += 1
|
|
}
|
|
if (diagnostic.webglAttachmentDeferred) {
|
|
acc.deferredWebglCount += 1
|
|
}
|
|
}
|
|
return acc
|
|
},
|
|
{ attachedWebglCount: 0, deferredWebglCount: 0, managerCount: 0, paneCount: 0 }
|
|
)
|
|
const state = window.__store?.getState?.()
|
|
const worktreeId = state?.activeWorktreeId ?? null
|
|
const tabId =
|
|
state?.activeTabType === 'terminal'
|
|
? state.activeTabId
|
|
: worktreeId
|
|
? (state?.activeTabIdByWorktree?.[worktreeId] ?? null)
|
|
: null
|
|
const manager = tabId ? window.__paneManagers?.get(tabId) : null
|
|
const activePane = manager?.getActivePane?.() ?? manager?.getPanes?.()?.[0] ?? null
|
|
const buffer = activePane?.terminal?.buffer?.active ?? null
|
|
return {
|
|
hasStore: Boolean(window.__store),
|
|
workspaceSessionReady: state?.workspaceSessionReady ?? null,
|
|
hydrationSucceeded: state?.hydrationSucceeded ?? null,
|
|
activeView: state?.activeView ?? null,
|
|
activeRepoId: state?.activeRepoId ?? null,
|
|
activeWorktreeId: worktreeId,
|
|
activeTabType: state?.activeTabType ?? null,
|
|
activeTabId: tabId,
|
|
terminalGpuAcceleration: state?.settings?.terminalGpuAcceleration ?? null,
|
|
repoCount: state?.repos?.length ?? null,
|
|
worktreeCountsByRepo: Object.fromEntries(
|
|
Object.entries(state?.worktreesByRepo ?? {}).map(([repoId, worktrees]) => [
|
|
repoId,
|
|
worktrees.length
|
|
])
|
|
),
|
|
ptyIdsByTabId: tabId ? (state?.ptyIdsByTabId?.[tabId] ?? []) : [],
|
|
paneManagerCount: window.__paneManagers?.size ?? null,
|
|
activePane: activePane
|
|
? {
|
|
id: activePane.id ?? null,
|
|
leafId: activePane.leafId ?? null,
|
|
ptyId: activePane.container?.dataset?.ptyId ?? null,
|
|
cols: activePane.terminal?.cols ?? null,
|
|
rows: activePane.terminal?.rows ?? null,
|
|
buffer: buffer
|
|
? {
|
|
baseY: buffer.baseY,
|
|
viewportY: buffer.viewportY,
|
|
cursorY: buffer.cursorY,
|
|
length: buffer.length
|
|
}
|
|
: null
|
|
}
|
|
: null,
|
|
renderingDiagnostics: manager?.getRenderingDiagnostics?.() ?? null,
|
|
allPaneManagersDiagnostics,
|
|
webglContextCounts,
|
|
webglIdentity: readWebglIdentity(),
|
|
rendererProbe: globalThis.__orcaApphangProbe?.probe ?? null,
|
|
ptySessions: await timed('PTY sessions', window.api?.pty?.listSessions?.()),
|
|
rendererDeliveryDebug: await timed(
|
|
'renderer delivery debug',
|
|
window.api?.pty?.getRendererDeliveryDebugSnapshot?.()
|
|
)
|
|
}
|
|
}),
|
|
rendererActionTimeoutMs
|
|
)
|
|
} catch (error) {
|
|
return { error: error instanceof Error ? error.message : String(error) }
|
|
}
|
|
}
|