feat(mcp,orchestrator,frontend): tool idea_restart_self, redemarrage autonome d'un agent — #288 (tool core self-only via requester MCP handshake, retour immediat {restartId, status: scheduled} puis orchestration detachee: snapshot reprise, stop PTY/structured, liberation Busy/mailbox, relance LaunchAgent meme conversation_id fresh_start=false, injection interne invisible; events domain/wire agentRestartRequested/PhaseChanged/Completed/Failed phases stopping/releasingInput/launching/resuming; CLI custom: separateurs exacts redemarrage de l'agent + etat termine/echoue, deduplication (restartId, event), verrouillage composer; TUI native: overlay AgentRestartOverlay sans injection xterm, progress/annonces projetes jusqu'a idle; QA verte: mcp_server restart_self 1/1, restart-self 3/3, backend self_restart_contract + events wire 2/2, frontend 3 suites 92/92, npm build, cargo check --workspace, fmt --check, diff --check; reserves hors perimetre: web-server 103/110 fixture PTY preexistante, 34 echecs npm test globaux listProjectSettings/web hors #288; scripts/ hors perimetre)
This commit is contained in:
@ -367,4 +367,26 @@ describe("LayoutGrid — ticket #48 cell control layering", () => {
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it("gives the native TUI restart overlay priority over other cell veils", async () => {
|
||||
const setup = await makeSplitAgentGrid();
|
||||
renderGrid(setup.gateways);
|
||||
await flush();
|
||||
|
||||
act(() => {
|
||||
setup.system.emit(busy(setup.agentId, true));
|
||||
setup.system.emit({
|
||||
type: "agentRestartRequested",
|
||||
agentId: setup.agentId,
|
||||
restartId: "restart-1",
|
||||
reason: null,
|
||||
});
|
||||
});
|
||||
|
||||
const overlay = await screen.findByTestId("agent-restart-overlay");
|
||||
expect(overlay.className).toContain("z-[4]");
|
||||
expect(screen.queryByTestId("target-announcements-overlay")).toBeNull();
|
||||
expect(screen.queryByText("------- redemarrage de l'agent -------")).toBeNull();
|
||||
expect(controlsFor(setup.bId).controls.style.zIndex).toBe("5");
|
||||
});
|
||||
});
|
||||
|
||||
@ -30,7 +30,9 @@ import { TerminalView, useWritePortal } from "@/features/terminals";
|
||||
import { useGateways } from "@/app/di";
|
||||
import { useProjectWorkState } from "@/features/workstate/useProjectWorkState";
|
||||
import {
|
||||
AgentRestartOverlay,
|
||||
TargetAnnouncementsOverlay,
|
||||
useAgentRestart,
|
||||
useTargetAnnouncements,
|
||||
} from "@/features/announcements";
|
||||
import { PluginLayoutCellView } from "@/features/plugins";
|
||||
@ -623,6 +625,7 @@ function LeafView({
|
||||
// write-portal veil can be mutually excluded with the F3 overlay (exactly one
|
||||
// full-cell veil at a time, F3 first). Same source the overlay itself reads.
|
||||
const { active: announcementBusyActive } = useTargetAnnouncements(agentId ?? "");
|
||||
const { restart: agentRestart } = useAgentRestart(agentId ?? "");
|
||||
// Ticket #54 — local model-server launch state for this cell's pinned agent.
|
||||
// Correlated `agentId → profileId → opencode.localModelServerId → status` via
|
||||
// the shared hook (same reduction as `useAgents`). While the bound server is
|
||||
@ -1466,7 +1469,8 @@ function LeafView({
|
||||
is being injected into the agent's PTY, a grey veil with a centred
|
||||
message sits above the terminal. Only ever shown for an agent cell —
|
||||
and never together with the F3 overlay (exactly one veil, F3 first). */}
|
||||
{!modelServerOverlay &&
|
||||
{!agentRestart &&
|
||||
!modelServerOverlay &&
|
||||
cellMode !== "custom" &&
|
||||
shouldShowWritePortalVeil(agentId != null, Boolean(overlay), busyActive) && (
|
||||
<div
|
||||
@ -1504,7 +1508,7 @@ function LeafView({
|
||||
an availability veil showing its live réflexions. Native TUI cells
|
||||
need the full-cell guard; custom CLI cells keep the canonical busy
|
||||
badge and composer lock only, matching their normal chat turn flow. */}
|
||||
{!modelServerOverlay && cellMode !== "custom" && agentId != null && (
|
||||
{!agentRestart && !modelServerOverlay && cellMode !== "custom" && agentId != null && (
|
||||
<TargetAnnouncementsOverlay
|
||||
projectId={projectId}
|
||||
agentId={agentId}
|
||||
@ -1517,7 +1521,7 @@ function LeafView({
|
||||
agent's bound local server is downloading its model / starting /
|
||||
probing, the empty terminal is covered rather than left to time out.
|
||||
Retracts at `ready`/`failed` (the predicate returns null then). */}
|
||||
{modelServerOverlay && (
|
||||
{!agentRestart && modelServerOverlay && (
|
||||
<div
|
||||
data-testid="model-server-overlay"
|
||||
role="status"
|
||||
@ -1634,6 +1638,9 @@ function LeafView({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{cellMode !== "custom" && agentId != null && agentRestart && (
|
||||
<AgentRestartOverlay agentId={agentId} />
|
||||
)}
|
||||
</div>
|
||||
{busyNotice && (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user