fix(sessions): reprendre/forker une session managée morte par UUID (résout le 404)
Le bouton « Reprendre » envoie l'UUID Arboretum, mais resume/fork ne résolvaient l'id que via la découverte (indexée par claudeSessionId, qui exclut justement les sessions managées) → 404 systématique après fermeture. Ajoute PtyManager.resumeTargetById (cwd d'origine + claudeSessionId + groupe lus en DB par UUID) et un résolveur unifié dans resume ET fork : session managée morte par UUID, sinon session claude externe découverte par claudeSessionId. Garde-fous anti-resume d'une session vivante conservés.
This commit is contained in:
@@ -144,6 +144,37 @@ try {
|
||||
const out = c.state.outputs.get(att?.channel) ?? '';
|
||||
check('resume lance `--resume sid-dead` dans le bon cwd', out.includes('args=[--resume sid-dead]') && out.includes(`cwd=${workDir}`), out.replace(/\s+/g, ' ').slice(0, 120));
|
||||
|
||||
// --- Régression « Reprendre » : reprise d'une session MANAGÉE morte par son UUID Arboretum ---
|
||||
// (le bouton web envoie l'UUID managé, pas le claudeSessionId ; le serveur doit le résoudre en DB).
|
||||
const createManaged = await fetch(`${ORIGIN}/api/v1/sessions`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Origin: ORIGIN, Cookie: cookie },
|
||||
body: JSON.stringify({ cwd: workDir, command: 'claude' }),
|
||||
});
|
||||
const managed = (await createManaged.json()).session;
|
||||
check('création session managée claude → 201 (pid)', createManaged.status === 201 && managed?.pid > 0);
|
||||
|
||||
// Simule la capture du claudeSessionId : entrée registre pour le pid du PTY managé (pollée toutes les 400ms).
|
||||
writeFileSync(
|
||||
join(sessions, `${managed.pid}.json`),
|
||||
JSON.stringify({ pid: managed.pid, sessionId: 'sid-managed', cwd: workDir, status: 'idle' }),
|
||||
);
|
||||
const captured = await c.waitMsg(
|
||||
(m) => m.type === 'session_update' && m.session?.id === managed.id && m.session?.claudeSessionId === 'sid-managed',
|
||||
);
|
||||
check('claudeSessionId capturé depuis le registre (session managée)', !!captured);
|
||||
|
||||
// Fermeture (kill) puis reprise par UUID managé → 201 dans le cwd d'origine (avant le fix : 404).
|
||||
const killManaged = await fetch(`${ORIGIN}/api/v1/sessions/${managed.id}`, { method: 'DELETE', headers: { Origin: ORIGIN, Cookie: cookie } });
|
||||
check('kill session managée → 200', killManaged.status === 200);
|
||||
await sleep(400); // laisse handleExit persister ended_at
|
||||
const resumeManaged = await postJson(`/api/v1/sessions/${managed.id}/resume`, cookie);
|
||||
const resumedManaged = (await resumeManaged.json()).session;
|
||||
check(
|
||||
'resume d’une session MANAGÉE morte par UUID → 201',
|
||||
resumeManaged.status === 201 && resumedManaged?.command === 'claude' && resumedManaged?.source === 'managed' && resumedManaged?.cwd === workDir,
|
||||
);
|
||||
|
||||
// Broadcast : une nouvelle session découverte est poussée via session_update au rafraîchissement périodique.
|
||||
writeJsonl(workDir, 'sid-new');
|
||||
const pushed = await c.waitMsg((m) => m.type === 'session_update' && m.session?.id === 'sid-new', 13000);
|
||||
|
||||
Reference in New Issue
Block a user