export function mount({ root, state, host }) { state = state || {}; const __cleanup = []; const __setInterval = (...args) => { const id = window.setInterval(...args); __cleanup.push(() => window.clearInterval(id)); return id; }; const __setTimeout = (...args) => { const id = window.setTimeout(...args); __cleanup.push(() => window.clearTimeout(id)); return id; }; if (!(root instanceof HTMLElement)) return; const subtitleEl = root.querySelector('[data-git-subtitle]'); const branchEl = root.querySelector('[data-git-branch]'); const statusEl = root.querySelector('[data-git-status]'); const changedEl = root.querySelector('[data-git-changed]'); const stagingEl = root.querySelector('[data-git-staging]'); const untrackedEl = root.querySelector('[data-git-untracked]'); const upstreamEl = root.querySelector('[data-git-upstream]'); const plusEl = root.querySelector('[data-git-plus]'); const minusEl = root.querySelector('[data-git-minus]'); const updatedEl = root.querySelector('[data-git-updated]'); const filesEl = root.querySelector('[data-git-files]'); if (!(subtitleEl instanceof HTMLElement) || !(branchEl instanceof HTMLElement) || !(statusEl instanceof HTMLElement) || !(changedEl instanceof HTMLElement) || !(stagingEl instanceof HTMLElement) || !(untrackedEl instanceof HTMLElement) || !(upstreamEl instanceof HTMLElement) || !(plusEl instanceof HTMLElement) || !(minusEl instanceof HTMLElement) || !(updatedEl instanceof HTMLElement) || !(filesEl instanceof HTMLElement)) return; const configuredToolName = typeof state.tool_name === 'string' ? state.tool_name.trim() : ''; const rawToolArguments = state && typeof state.tool_arguments === 'object' && state.tool_arguments && !Array.isArray(state.tool_arguments) ? state.tool_arguments : {}; const subtitle = typeof state.subtitle === 'string' ? state.subtitle.trim() : ''; const numberFormatter = new Intl.NumberFormat([], { maximumFractionDigits: 0 }); const setStatus = (label, fg, bg) => { statusEl.textContent = label; statusEl.style.color = fg; statusEl.style.background = bg; statusEl.style.padding = '3px 7px'; statusEl.style.borderRadius = '999px'; }; const statusTone = (value) => { if (value === 'Clean') return { fg: '#6c8b63', bg: '#dfe9d8' }; if (value === 'Dirty') return { fg: '#9a6a2f', bg: '#f4e2b8' }; return { fg: '#a14d43', bg: '#f3d8d2' }; }; const formatBranch = (payload) => { const parts = []; const branch = typeof payload.branch === 'string' ? payload.branch : ''; if (branch) parts.push(branch); if (typeof payload.upstream === 'string' && payload.upstream) { parts.push(payload.upstream); } const ahead = Number(payload.ahead || 0); const behind = Number(payload.behind || 0); if (ahead || behind) { parts.push(`+${ahead} / -${behind}`); } if (!parts.length && typeof payload.head === 'string' && payload.head) { parts.push(payload.head); } return parts.join(' · ') || 'No branch information'; }; const formatUpdated = (raw) => { if (typeof raw !== 'string' || !raw) return '--'; const parsed = new Date(raw); if (Number.isNaN(parsed.getTime())) return raw; return parsed.toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); }; const chipStyle = (status) => { if (status === '??') return { fg: '#6f7582', bg: '#e8edf2' }; if (status.includes('D')) return { fg: '#a45b51', bg: '#f3d7d2' }; if (status.includes('A')) return { fg: '#6d8a5d', bg: '#dce7d6' }; return { fg: '#9a6a2f', bg: '#f3e1ba' }; }; const asLineNumber = (value) => { if (typeof value === 'number' && Number.isFinite(value)) return value; if (typeof value === 'string' && /^\d+$/.test(value)) return Number(value); return null; }; const formatRangePart = (label, start, end) => { if (start === null || end === null) return ''; return start === end ? `${label} ${start}` : `${label} ${start}-${end}`; }; const buildSelectionPayload = (filePath, lines) => { const oldNumbers = lines.map((line) => line.oldNumber).filter((value) => value !== null); const newNumbers = lines.map((line) => line.newNumber).filter((value) => value !== null); const oldStart = oldNumbers.length ? Math.min(...oldNumbers) : null; const oldEnd = oldNumbers.length ? Math.max(...oldNumbers) : null; const newStart = newNumbers.length ? Math.min(...newNumbers) : null; const newEnd = newNumbers.length ? Math.max(...newNumbers) : null; const rangeParts = [ formatRangePart('old', oldStart, oldEnd), formatRangePart('new', newStart, newEnd), ].filter(Boolean); const fileLabel = filePath || 'Selected diff'; const rangeLabel = rangeParts.join(' · ') || 'Selected diff lines'; return { kind: 'git_diff_range', file_path: filePath || fileLabel, file_label: fileLabel, range_label: rangeLabel, label: `${fileLabel} · ${rangeLabel}`, old_start: oldStart, old_end: oldEnd, new_start: newStart, new_end: newEnd, }; }; let activeSelectionController = null; const clearActiveSelection = () => { if (activeSelectionController) { const controller = activeSelectionController; activeSelectionController = null; controller.clear(false); } host.setSelection(null); }; const renderPatchBody = (target, item) => { target.innerHTML = ''; target.dataset.noSwipe = '1'; target.style.marginTop = '10px'; target.style.marginLeft = '-12px'; target.style.marginRight = '-12px'; target.style.width = 'calc(100% + 24px)'; target.style.paddingTop = '10px'; target.style.borderTop = '1px solid rgba(177, 140, 112, 0.16)'; target.style.overflow = 'hidden'; target.style.minWidth = '0'; target.style.maxWidth = 'none'; const viewport = document.createElement('div'); viewport.dataset.noSwipe = '1'; viewport.style.width = '100%'; viewport.style.maxWidth = 'none'; viewport.style.minWidth = '0'; viewport.style.overflowX = 'auto'; viewport.style.overflowY = 'hidden'; viewport.style.touchAction = 'auto'; viewport.style.overscrollBehavior = 'contain'; viewport.style.webkitOverflowScrolling = 'touch'; viewport.style.scrollbarWidth = 'thin'; viewport.style.scrollbarColor = 'rgba(120, 94, 74, 0.28) transparent'; const diffText = typeof item?.diff === 'string' ? item.diff : ''; const diffLines = Array.isArray(item?.diff_lines) ? item.diff_lines : []; if (!diffText && diffLines.length === 0) { const message = document.createElement('div'); message.textContent = 'No line diff available for this path.'; message.style.fontSize = '0.76rem'; message.style.lineHeight = '1.4'; message.style.color = '#9a7b68'; message.style.fontWeight = '600'; target.appendChild(message); return; } const block = document.createElement('div'); block.dataset.noSwipe = '1'; block.style.display = 'grid'; block.style.gap = '0'; block.style.padding = '0'; block.style.borderRadius = '0'; block.style.background = 'rgba(255,255,255,0.58)'; block.style.border = '1px solid rgba(153, 118, 92, 0.14)'; block.style.borderLeft = '0'; block.style.borderRight = '0'; block.style.fontFamily = "var(--card-font, 'Iosevka', 'SF Mono', ui-monospace, Menlo, Consolas, monospace)"; block.style.fontSize = '0.64rem'; block.style.lineHeight = '1.45'; block.style.color = '#5f4a3f'; block.style.width = 'max-content'; block.style.minWidth = '100%'; const selectableLines = []; let localSelection = null; let localAnchorIndex = null; const setSelectedState = (entry, selected) => { if (selected) entry.lineEl.dataset.selected = 'true'; else delete entry.lineEl.dataset.selected; }; const controller = { clear(publish = true) { localSelection = null; localAnchorIndex = null; for (const entry of selectableLines) setSelectedState(entry, false); if (publish) { if (activeSelectionController === controller) activeSelectionController = null; host.setSelection(null); } }, }; const applySelection = (startIndex, endIndex) => { const lower = Math.min(startIndex, endIndex); const upper = Math.max(startIndex, endIndex); localSelection = { startIndex: lower, endIndex: upper }; for (const [index, entry] of selectableLines.entries()) { setSelectedState(entry, index >= lower && index <= upper); } if (activeSelectionController && activeSelectionController !== controller) { activeSelectionController.clear(false); } activeSelectionController = controller; host.setSelection(buildSelectionPayload(String(item?.path || ''), selectableLines.slice(lower, upper + 1)), ); }; const handleSelectableLine = (index) => { if (!localSelection) { localAnchorIndex = index; applySelection(index, index); return; } const singleLine = localSelection.startIndex === localSelection.endIndex; if (singleLine) { const anchorIndex = localAnchorIndex ?? localSelection.startIndex; if (index === anchorIndex) { controller.clear(true); return; } applySelection(anchorIndex, index); localAnchorIndex = null; return; } localAnchorIndex = index; applySelection(index, index); }; const registerSelectableLine = (lineEl, oldNumber, newNumber) => { const entry = { lineEl, oldNumber: asLineNumber(oldNumber), newNumber: asLineNumber(newNumber), }; const index = selectableLines.push(entry) - 1; lineEl.dataset.selectable = 'true'; lineEl.tabIndex = 0; lineEl.setAttribute('role', 'button'); lineEl.addEventListener('click', (event) => { event.preventDefault(); event.stopPropagation(); handleSelectableLine(index); }); lineEl.addEventListener('keydown', (event) => { if (event.key !== 'Enter' && event.key !== ' ') return; event.preventDefault(); handleSelectableLine(index); }); }; if (diffLines.length > 0) { for (const row of diffLines) { const lineEl = document.createElement('div'); lineEl.dataset.gitPatchRow = '1'; lineEl.style.display = 'grid'; lineEl.style.gridTemplateColumns = 'max-content max-content'; lineEl.style.columnGap = '8px'; lineEl.style.alignItems = 'start'; lineEl.style.justifyContent = 'start'; lineEl.style.padding = '0'; lineEl.style.borderRadius = '0'; lineEl.style.width = 'max-content'; lineEl.style.minWidth = '100%'; const numberEl = document.createElement('span'); const lineNumber = typeof row?.line_number === 'number' || typeof row?.line_number === 'string' ? String(row.line_number) : ''; numberEl.textContent = lineNumber; numberEl.style.minWidth = '2.2em'; numberEl.style.textAlign = 'right'; numberEl.style.color = '#8c7464'; numberEl.style.opacity = '0.92'; const textEl = document.createElement('span'); textEl.dataset.gitPatchText = '1'; textEl.textContent = typeof row?.text === 'string' ? row.text : ''; textEl.style.whiteSpace = 'pre'; textEl.style.wordBreak = 'normal'; const kind = typeof row?.kind === 'string' ? row.kind : ''; if (kind === 'added') { lineEl.style.color = '#0c3f12'; lineEl.style.background = 'rgba(158, 232, 147, 0.98)'; } else if (kind === 'removed') { lineEl.style.color = '#6d0d08'; lineEl.style.background = 'rgba(249, 156, 145, 0.98)'; } else { lineEl.style.color = '#5f4a3f'; } lineEl.append(numberEl, textEl); block.appendChild(lineEl); } } else { const makePatchLine = (line, kind, oldNumber = '', newNumber = '') => { const lineEl = document.createElement('div'); lineEl.dataset.gitPatchRow = '1'; lineEl.style.display = 'grid'; lineEl.style.gridTemplateColumns = 'max-content max-content max-content'; lineEl.style.columnGap = '8px'; lineEl.style.alignItems = 'start'; lineEl.style.justifyContent = 'start'; lineEl.style.padding = '0'; lineEl.style.borderRadius = '0'; lineEl.style.width = 'max-content'; lineEl.style.minWidth = '100%'; const oldEl = document.createElement('span'); oldEl.textContent = oldNumber ? String(oldNumber) : ''; oldEl.style.minWidth = '2.4em'; oldEl.style.textAlign = 'right'; oldEl.style.color = '#8c7464'; oldEl.style.opacity = '0.92'; const newEl = document.createElement('span'); newEl.textContent = newNumber ? String(newNumber) : ''; newEl.style.minWidth = '2.4em'; newEl.style.textAlign = 'right'; newEl.style.color = '#8c7464'; newEl.style.opacity = '0.92'; const textEl = document.createElement('span'); textEl.dataset.gitPatchText = '1'; textEl.textContent = line || ' '; textEl.style.whiteSpace = 'pre'; textEl.style.wordBreak = 'normal'; if (kind === 'hunk') { lineEl.style.color = '#6c523f'; lineEl.style.background = 'rgba(224, 204, 184, 0.94)'; lineEl.style.fontWeight = '800'; } else if (kind === 'added') { lineEl.style.color = '#0f4515'; lineEl.style.background = 'rgba(170, 232, 160, 0.98)'; } else if (kind === 'removed') { lineEl.style.color = '#74110a'; lineEl.style.background = 'rgba(247, 170, 160, 0.98)'; } else if (kind === 'context') { lineEl.style.color = '#6f5b4d'; lineEl.style.background = 'rgba(247, 236, 223, 0.72)'; } else if (kind === 'meta') { lineEl.style.color = '#725c4f'; lineEl.style.background = 'rgba(255, 255, 255, 0.42)'; } else if (kind === 'note') { lineEl.style.color = '#8a6f5c'; lineEl.style.background = 'rgba(236, 226, 216, 0.72)'; lineEl.style.fontStyle = 'italic'; } lineEl.append(oldEl, newEl, textEl); if (kind === 'added' || kind === 'removed' || kind === 'context') { registerSelectableLine(lineEl, oldNumber, newNumber); } return lineEl; }; const parseHunkHeader = (line) => { const match = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/.exec(line); if (!match) return null; return { oldLine: Number(match[1] || '0'), newLine: Number(match[3] || '0'), }; }; const prelude = []; const hunks = []; let currentHunk = null; for (const line of diffText.split('\n')) { if (line.startsWith('@@')) { if (currentHunk) hunks.push(currentHunk); currentHunk = { header: line, lines: [] }; continue; } if (currentHunk) { currentHunk.lines.push(line); } else { prelude.push(line); } } if (currentHunk) hunks.push(currentHunk); for (const line of prelude) { let kind = 'meta'; if (line.startsWith('Binary files') || line.startsWith('\\')) kind = 'note'; else if (line.startsWith('+') && !line.startsWith('+++')) kind = 'added'; else if (line.startsWith('-') && !line.startsWith('---')) kind = 'removed'; else if (line.startsWith(' ')) kind = 'context'; block.appendChild(makePatchLine(line, kind)); } for (const hunk of hunks) { const section = document.createElement('section'); section.style.display = 'grid'; section.style.gap = '0'; section.style.marginTop = block.childNodes.length ? '10px' : '0'; section.style.borderTop = '1px solid rgba(177, 140, 112, 0.24)'; section.style.borderBottom = '1px solid rgba(177, 140, 112, 0.24)'; section.appendChild(makePatchLine(hunk.header, 'hunk')); const parsed = parseHunkHeader(hunk.header); let oldLine = parsed ? parsed.oldLine : 0; let newLine = parsed ? parsed.newLine : 0; for (const line of hunk.lines) { if (line.startsWith('+') && !line.startsWith('+++')) { section.appendChild(makePatchLine(line, 'added', '', newLine)); newLine += 1; } else if (line.startsWith('-') && !line.startsWith('---')) { section.appendChild(makePatchLine(line, 'removed', oldLine, '')); oldLine += 1; } else if (line.startsWith('\\')) { section.appendChild(makePatchLine(line, 'note')); } else if (line.startsWith('+++') || line.startsWith('---')) { section.appendChild(makePatchLine(line, 'meta')); } else { const oldNumber = oldLine ? oldLine : ''; const newNumber = newLine ? newLine : ''; section.appendChild(makePatchLine(line, 'context', oldNumber, newNumber)); oldLine += 1; newLine += 1; } } block.appendChild(section); } } viewport.appendChild(block); target.appendChild(viewport); if (item?.diff_truncated) { const note = document.createElement('div'); note.textContent = 'Diff truncated for readability.'; note.style.marginTop = '8px'; note.style.fontSize = '0.72rem'; note.style.lineHeight = '1.35'; note.style.color = '#9a7b68'; note.style.fontWeight = '600'; target.appendChild(note); } }; const renderFiles = (items) => { clearActiveSelection(); filesEl.innerHTML = ''; if (!Array.isArray(items) || items.length === 0) { const empty = document.createElement('div'); empty.textContent = 'Working tree clean.'; empty.style.fontSize = '0.92rem'; empty.style.lineHeight = '1.4'; empty.style.color = '#7d8f73'; empty.style.fontWeight = '700'; empty.style.padding = '12px'; empty.style.borderRadius = '12px'; empty.style.background = 'rgba(223, 233, 216, 0.55)'; empty.style.border = '1px solid rgba(109, 138, 93, 0.12)'; filesEl.appendChild(empty); return; } for (const item of items) { const row = document.createElement('div'); row.style.display = 'block'; row.style.minWidth = '0'; row.style.maxWidth = '100%'; row.style.padding = '0'; row.style.borderRadius = '0'; row.style.background = 'transparent'; row.style.border = '0'; row.style.boxShadow = 'none'; const summaryButton = document.createElement('button'); summaryButton.type = 'button'; summaryButton.style.display = 'flex'; summaryButton.style.alignItems = 'flex-start'; summaryButton.style.justifyContent = 'space-between'; summaryButton.style.gap = '8px'; summaryButton.style.width = '100%'; summaryButton.style.minWidth = '0'; summaryButton.style.padding = '0'; summaryButton.style.margin = '0'; summaryButton.style.border = '0'; summaryButton.style.background = 'transparent'; summaryButton.style.textAlign = 'left'; summaryButton.style.cursor = 'pointer'; const left = document.createElement('div'); left.style.display = 'flex'; left.style.alignItems = 'flex-start'; left.style.gap = '8px'; left.style.minWidth = '0'; left.style.flex = '1 1 auto'; const chip = document.createElement('span'); const chipTone = chipStyle(String(item?.status || 'M')); chip.textContent = String(item?.status || 'M'); chip.style.fontSize = '0.72rem'; chip.style.lineHeight = '1.1'; chip.style.fontWeight = '800'; chip.style.color = chipTone.fg; chip.style.background = chipTone.bg; chip.style.padding = '4px 7px'; chip.style.borderRadius = '999px'; chip.style.flex = '0 0 auto'; const pathWrap = document.createElement('div'); pathWrap.style.minWidth = '0'; const pathEl = document.createElement('div'); pathEl.textContent = String(item?.path || '--'); pathEl.style.fontSize = '0.92rem'; pathEl.style.lineHeight = '1.3'; pathEl.style.fontWeight = '700'; pathEl.style.color = '#65483a'; pathEl.style.wordBreak = 'break-word'; const detailEl = document.createElement('div'); detailEl.style.marginTop = '3px'; detailEl.style.fontSize = '0.77rem'; detailEl.style.lineHeight = '1.35'; detailEl.style.color = '#9a7b68'; const insertions = Number(item?.insertions || 0); const deletions = Number(item?.deletions || 0); detailEl.textContent = insertions || deletions ? `+${numberFormatter.format(insertions)} / -${numberFormatter.format(deletions)}` : 'No line diff'; pathWrap.append(pathEl, detailEl); left.append(chip, pathWrap); const toggle = document.createElement('span'); toggle.setAttribute('aria-hidden', 'true'); toggle.style.fontSize = '0.95rem'; toggle.style.lineHeight = '1'; toggle.style.fontWeight = '800'; toggle.style.color = '#9a7b68'; toggle.style.whiteSpace = 'nowrap'; toggle.style.flex = '0 0 auto'; toggle.style.paddingTop = '1px'; const body = document.createElement('div'); body.hidden = true; body.style.width = '100%'; body.style.maxWidth = '100%'; body.style.minWidth = '0'; renderPatchBody(body, item); const hasDiff = Boolean(item?.diff_available) || Boolean(item?.diff); const setExpanded = (expanded) => { body.hidden = !expanded; summaryButton.setAttribute('aria-expanded', expanded ? 'true' : 'false'); toggle.textContent = expanded ? '▴' : '▾'; }; setExpanded(false); summaryButton.addEventListener('click', () => { setExpanded(body.hidden); }); summaryButton.append(left, toggle); row.append(summaryButton, body); filesEl.appendChild(row); } }; const updateLiveContent = (snapshot) => { host.setLiveContent(snapshot); }; const render = (payload) => { subtitleEl.textContent = subtitle || payload.repo_name || payload.repo_path || 'Git repo'; branchEl.textContent = formatBranch(payload); changedEl.textContent = numberFormatter.format(Number(payload.changed_files || 0)); stagingEl.textContent = `${numberFormatter.format(Number(payload.staged_files || 0))} staged · ${numberFormatter.format(Number(payload.unstaged_files || 0))} unstaged`; untrackedEl.textContent = numberFormatter.format(Number(payload.untracked_files || 0)); upstreamEl.textContent = typeof payload.repo_path === 'string' ? payload.repo_path : '--'; plusEl.textContent = `+${numberFormatter.format(Number(payload.insertions || 0))}`; minusEl.textContent = `-${numberFormatter.format(Number(payload.deletions || 0))}`; updatedEl.textContent = `Updated ${formatUpdated(payload.generated_at)}`; const label = payload.dirty ? 'Dirty' : 'Clean'; const tone = statusTone(label); setStatus(label, tone.fg, tone.bg); renderFiles(payload.files); updateLiveContent({ kind: 'git_repo_diff', repo_name: payload.repo_name || null, repo_path: payload.repo_path || null, branch: payload.branch || null, upstream: payload.upstream || null, ahead: Number(payload.ahead || 0), behind: Number(payload.behind || 0), dirty: Boolean(payload.dirty), changed_files: Number(payload.changed_files || 0), staged_files: Number(payload.staged_files || 0), unstaged_files: Number(payload.unstaged_files || 0), untracked_files: Number(payload.untracked_files || 0), insertions: Number(payload.insertions || 0), deletions: Number(payload.deletions || 0), files: Array.isArray(payload.files) ? payload.files.map((item) => ({ path: item?.path || null, status: item?.status || null, insertions: Number(item?.insertions || 0), deletions: Number(item?.deletions || 0), diff_available: Boolean(item?.diff_available), diff_truncated: Boolean(item?.diff_truncated), })) : [], generated_at: payload.generated_at || null, }); }; const renderError = (message) => { clearActiveSelection(); subtitleEl.textContent = subtitle || 'Git repo'; branchEl.textContent = 'Unable to load repo diff'; changedEl.textContent = '--'; stagingEl.textContent = '--'; untrackedEl.textContent = '--'; upstreamEl.textContent = '--'; plusEl.textContent = '+--'; minusEl.textContent = '- --'; updatedEl.textContent = message; const tone = statusTone('Unavailable'); setStatus('Unavailable', tone.fg, tone.bg); filesEl.innerHTML = ''; const error = document.createElement('div'); error.textContent = message; error.style.fontSize = '0.88rem'; error.style.lineHeight = '1.4'; error.style.color = '#a45b51'; error.style.fontWeight = '700'; error.style.padding = '12px'; error.style.borderRadius = '12px'; error.style.background = 'rgba(243, 216, 210, 0.55)'; error.style.border = '1px solid rgba(164, 91, 81, 0.14)'; filesEl.appendChild(error); updateLiveContent({ kind: 'git_repo_diff', repo_name: null, repo_path: null, dirty: null, error: message, }); }; const loadPayload = async () => { if (!configuredToolName) throw new Error('Missing template_state.tool_name'); if (!host.callToolAsync) throw new Error('Async tool helper unavailable'); const toolResult = await host.callToolAsync( configuredToolName, rawToolArguments, { timeoutMs: 180000 }, ); if (toolResult && toolResult.parsed && typeof toolResult.parsed === 'object' && !Array.isArray(toolResult.parsed)) { return toolResult.parsed; } const rawContent = typeof toolResult?.content === 'string' ? toolResult.content.trim() : ''; if (rawContent) { if (rawContent.includes('(truncated,')) { throw new Error('Tool output was truncated. Increase exec max_output_chars for this card.'); } const normalizedContent = rawContent.replace(/\n+Exit code:\s*-?\d+\s*$/i, '').trim(); if (!normalizedContent.startsWith('{')) { throw new Error(rawContent); } try { const parsed = JSON.parse(normalizedContent); if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) { return parsed; } } catch (error) { const detail = error instanceof Error ? error.message : String(error); throw new Error(`Tool returned invalid JSON: ${detail}`); } } throw new Error('Tool returned invalid JSON'); }; const refresh = async () => { const loadingTone = { fg: '#9a7b68', bg: '#efe3d6' }; setStatus('Refreshing', loadingTone.fg, loadingTone.bg); try { const payload = await loadPayload(); render(payload); } catch (error) { renderError(String(error)); } }; host.setRefreshHandler(() => { void refresh(); }); void refresh(); return { destroy() { host.setRefreshHandler(null); host.setLiveContent(null); host.clearSelection(); for (const cleanup of __cleanup.splice(0)) cleanup(); }, }; }