feat(terminals): reprise de conversation par cellule + fix ordre d'écriture
Permet de recharger la conversation CLI précédente de chaque cellule à la
réouverture du projet, de façon universelle (indépendant du modèle/CLI).
- profil AgentRuntime: bloc déclaratif optionnel `session { assignFlag, resumeFlag }`
- LeafCell: `conversationId` (persistant, distinct du SessionId PTY) + `agentWasRunning`
- runtime: SessionPlan (None/Assign/Resume) + composition pure des args
- LaunchAgent: décide Assign vs Resume, génère l'UUID, remonte l'id assigné
(persistance par l'appelant via setCellConversation — découplage SRP)
- close: SnapshotRunningAgents fige `agentWasRunning` avant le kill-all
(statut clot/en cours universel, sans parsing CLI)
- SessionInspector: port optionnel best-effort + adapter ClaudeTranscriptInspector
- popup de reprise par cellule (statut + sujet/tokens si dispo), intercalée
avant le Resume auto, jamais sur le chemin reattach
fix(terminals): sérialise les écritures PTY (file FIFO par handle) — corrige
les caractères mélangés/accents dus au réordonnancement des invoke Tauri concurrents
fix(layout): l'opération `move` préservait mal les champs du leaf (perdait `agent`)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -202,19 +202,41 @@ export function TerminalView({
|
||||
.catch(onOpenError);
|
||||
}
|
||||
|
||||
// Refit + propagate size to the PTY on container resize.
|
||||
const ro = new ResizeObserver(() => {
|
||||
// Refit + propagate size to the PTY on container resize. ResizeObserver can
|
||||
// fire many times per frame, and during layout/tab transitions the container
|
||||
// momentarily reports a zero or transient size — fitting then would size
|
||||
// xterm's grid (and the PTY) to a stale value, leaving the repainted content
|
||||
// shifted/misaligned once the real size settles. So we: (1) coalesce bursts
|
||||
// into a single `requestAnimationFrame` that runs after layout settles,
|
||||
// (2) skip fitting while the container has no real size, and (3) push a PTY
|
||||
// resize only when rows/cols actually change (avoids redundant reflows).
|
||||
let rafId = 0;
|
||||
let lastRows = term.rows;
|
||||
let lastCols = term.cols;
|
||||
const refit = () => {
|
||||
rafId = 0;
|
||||
if (disposed) return;
|
||||
if (container.clientWidth === 0 || container.clientHeight === 0) return;
|
||||
try {
|
||||
fit.fit();
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
if (handle) void handle.resize(term.rows, term.cols);
|
||||
if (handle && (term.rows !== lastRows || term.cols !== lastCols)) {
|
||||
lastRows = term.rows;
|
||||
lastCols = term.cols;
|
||||
void handle.resize(term.rows, term.cols);
|
||||
}
|
||||
};
|
||||
const ro = new ResizeObserver(() => {
|
||||
if (rafId) cancelAnimationFrame(rafId);
|
||||
rafId = requestAnimationFrame(refit);
|
||||
});
|
||||
ro.observe(container);
|
||||
|
||||
return () => {
|
||||
disposed = true;
|
||||
if (rafId) cancelAnimationFrame(rafId);
|
||||
ro.disconnect();
|
||||
onKey.dispose();
|
||||
// DETACH, never close: tearing the view down (navigation / layout change)
|
||||
|
||||
Reference in New Issue
Block a user