fix(frontend,application): lot utilisateur #315 — détachement Paramètres projet, couleurs projet fiables, restauration conversation custom CLI, images post-aller-retour projet, retrait menus Projects/Project Context (QA verte)

- détachement: le panneau Paramètres du projet devient détachable (mapping historique panel=context → projectSettings dans parseViewWindowParams, DETACHABLE/ViewPanelBody alignés, ProjectsView ne court-circuitant plus le refus); Retry d'échec de détachement préservé
- couleurs projet: projectTheme publie idea:project-theme-changed localement + BroadcastChannel inter-webviews (fenêtres OS détachées), garde de révision par projet dans ProjectsView/ViewWindow contre les lectures settings en course — plus de flash/retour au bleu par défaut
- conversation custom CLI: transcript_restore_expected ne considère plus l'absence de scrollback volatile comme une restauration échouée quand la session rouvre en SessionPlan::None (continuation vide valide); CustomAgentChatView n'affiche plus le faux « conversation liée n'a pas pu être restaurée »
- images: conservation des images de conversation après changement de projet puis retour
- menus Panneaux: retrait des entrées Projects et Project Context (panelOrder WebWorkspace, création/switch via tab-bar +, contexte projet fusionné dans Paramètres du projet)
- QA verte: tests frontend ciblés window/ViewWindow/ProjectSettingsPanel/ProjectsView.detach/projects/CustomAgentChatView/WebDesktopWorkspace + cargo test -p application lifecycle transcript_restore_expected; fichiers .ideai/* (tickets 308-315, index/counter, agents/test, chat-drafts, system-permissions, project-settings.json, attachments/) et scripts/ hors périmètre préservés en worktree; aucun push
This commit is contained in:
2026-09-11 11:27:09 +02:00
parent 352ec2d8b7
commit 45f819e1e8
15 changed files with 434 additions and 82 deletions

View File

@ -2752,7 +2752,7 @@ impl LaunchAgent {
&input.project.root,
input.node_id,
size,
launch_conversation_id.is_some(),
transcript_restore_expected(&session_plan),
&spec.env,
None,
structured_policy.as_ref(),
@ -3651,6 +3651,14 @@ pub(crate) enum ReattachDecision {
Refuse { node_id: NodeId },
}
/// A missing volatile scrollback is only a failed restoration when the provider
/// was actually asked to resume an engine session. A logical conversation id can
/// also reopen with [`SessionPlan::None`] when no provider resumable was persisted;
/// that is a valid empty continuation, notably for custom structured CLIs.
fn transcript_restore_expected(session_plan: &SessionPlan) -> bool {
matches!(session_plan, SessionPlan::Resume { .. })
}
impl ReattachDecision {
/// Decides reattach vs refuse for an already-live agent. See [`reattach_decision`].
#[must_use]
@ -4712,6 +4720,17 @@ mod tests {
}
}
#[test]
fn transcript_restoration_is_expected_only_for_an_effective_provider_resume() {
assert!(transcript_restore_expected(&SessionPlan::Resume {
conversation_id: "engine-session".to_owned(),
}));
assert!(!transcript_restore_expected(&SessionPlan::None));
assert!(!transcript_restore_expected(&SessionPlan::Assign {
conversation_id: "new-session".to_owned(),
}));
}
#[test]
fn codex_pty_first_launch_pairs_workspace_mode_with_project_and_temp_roots() {
let mut spec = spawn_spec(Vec::new());