feat(FN-3708): restore narrow logs/system mouse auto-toggle policy and docu

The merge delivers three feature themes: FN-3708 restores and tests a narrow logs/system mouse auto-toggle policy in the TUI app with documentation, FN-3087 adds immediate wake controls for the agent inbox and messaging API routes, and FN-3704 separates plugin lifecycle management from setup probe s

Fusion-Task-Id: FN-3708
This commit is contained in:
Fusion
2026-05-07 10:57:58 -07:00
committed by gsxdsm
parent 514e5f3b94
commit bbfa5f7b45
5 changed files with 51 additions and 4 deletions

View File

@@ -0,0 +1,5 @@
---
"@runfusion/fusion": patch
---
Fix narrow main-screen TUI mouse behavior so selecting **Logs** enables wheel scrolling and selecting **System** switches back to native text selection mode.

View File

@@ -187,6 +187,10 @@ QR hand-off behavior in TUI:
On startup, the TUI opens on the **System** section by default so you can On startup, the TUI opens on the **System** section by default so you can
immediately see host/port and access-token details. immediately see host/port and access-token details.
Mouse reporting auto-toggles with focus on the main screen: selecting
**Logs** enables wheel scrolling, while selecting **System** turns mouse
reporting back off so native click-drag text selection works.
**Keyboard Navigation:** **Keyboard Navigation:**
| Key | Action | | Key | Action |

View File

@@ -728,6 +728,38 @@ describe("StatsPanel memory row", () => {
}); });
}); });
describe("Narrow status-mode mouse policy", () => {
it("enables mouse mode on Logs and disables it again on System", async () => {
const controller = newController();
controller.setSystemInfo(makeSystemInfo());
controller.log("entry", "scope");
const rendered = render(renderDashboardAppNode(controller));
setTerminalSize(rendered, 60, 24);
rendered.rerender(renderDashboardAppNode(controller));
await vi.waitFor(() => {
expect(controller.getSnapshot().mouseEnabled).toBe(false);
});
rendered.stdin.write("2");
await vi.waitFor(() => {
const snapshot = controller.getSnapshot();
expect(snapshot.activeSection).toBe("logs");
expect(snapshot.mouseEnabled).toBe(true);
});
rendered.stdin.write("1");
await vi.waitFor(() => {
const snapshot = controller.getSnapshot();
expect(snapshot.activeSection).toBe("system");
expect(snapshot.mouseEnabled).toBe(false);
});
rendered.unmount();
});
});
describe("LogsPanel narrow formatting", () => { describe("LogsPanel narrow formatting", () => {
it("shows a compact index instead of full timestamp in narrow terminals", async () => { it("shows a compact index instead of full timestamp in narrow terminals", async () => {
const controller = newController(); const controller = newController();

View File

@@ -4141,13 +4141,15 @@ export function DashboardApp({ controller }: DashboardAppProps) {
// When a log entry is expanded, disable mouse reporting so the user can // When a log entry is expanded, disable mouse reporting so the user can
// click-drag to select the message text natively. Esc/Enter closes the // click-drag to select the message text natively. Esc/Enter closes the
// expanded view and the policy reapplies, restoring wheel scrolling. // expanded view and the policy reapplies, restoring wheel scrolling.
const statusLogsFocused = state.activeSection === "logs"
// Narrow-mode split keeps wheel scrolling for the bottom log strip,
// except when System is selected (preserve native text selection).
|| (state.narrowLogSplitFocused && state.activeSection !== "system");
const wantsMouse = state.mode === "interactive" const wantsMouse = state.mode === "interactive"
? (state.interactiveView === "files" ? (state.interactiveView === "files"
|| state.interactiveView === "git" || state.interactiveView === "git"
|| state.interactiveView === "board") || state.interactiveView === "board")
: ((state.activeSection === "logs" : (statusLogsFocused && !state.logsExpandedMode);
|| (state.narrowLogSplitFocused && state.activeSection !== "system"))
&& !state.logsExpandedMode);
useEffect(() => { useEffect(() => {
if (state.mouseEnabled !== wantsMouse) { if (state.mouseEnabled !== wantsMouse) {
controller.setMouseEnabled(wantsMouse); controller.setMouseEnabled(wantsMouse);

View File

@@ -3184,7 +3184,11 @@ describe("Messaging Routes", () => {
"project-1", "project-1",
{ {
getWorkingDirectory: () => rootDir, getWorkingDirectory: () => rootDir,
getHeartbeatMonitor: () => ({ executeHeartbeat: projectExecuteHeartbeat }), getHeartbeatMonitor: () => ({
executeHeartbeat: projectExecuteHeartbeat,
startRun: vi.fn(),
stopRun: vi.fn(),
}),
}, },
], ],
])), ])),