Files
Netcatty/application/state/useSessionLogBackend.ts
T
Netcatty-Bot a965a94f0d fix(session-logs): omit alternate-screen TUI paint from logs (#2875)
* fix(#2872): automated Cursor CLI fix

* fix: address Codex review on PR #2875

* fix: address Codex review on PR #2875

* fix(session-logs): sample alternate-screen state after save dialog

Manual session log start previously snapshotted alternate-screen mode
and the initial line before showSaveDialog resolved. Split path selection
from stream start so the renderer re-samples buffer state at activation,
avoiding stale omission/leak if the user enters or leaves a TUI while the
dialog is open.

* fix(session-logs): honor C1 CSI alternate-screen modes in text renderer

8-bit CSI (U+009B) is a valid alternate form of ESC[. Recognize it in
TerminalTextRenderer so DECSET 47/1047/1049 enter/leave still omits TUI
paint from txt/HTML session logs when remotes use the C1 encoding.

* fix(session-logs): apply log-safe RIS reset in text renderer

RIS now leaves alternate-screen mode, resets SGR to defaults, and starts
post-reset shell text on a new log line when needed so mid-line TUI
exits do not glue onto prior output or keep pre-entry colors. History is
preserved because session logs are not live screen wipes.

* fix(session-logs): token-bind dialog path and rebase after RIS

- chooseManualSessionLogPath stores the selected path in main and returns
  an opaque selectionToken; startManualSessionLog redeems that token and
  rejects renderer-supplied filePath so the save dialog cannot be bypassed.
- RIS rebases screenBaseRow onto a fresh log screen (history preserved)
  so post-reset CSI H cannot overwrite pre-RIS text.

* fix(session-logs): seed replay sanitizer on observe attach mid-TUI

When an observe popup restores a snapshot while vim/less is already on
the alternate buffer, re-seed the connection-log sanitizer from the
restored xterm active-buffer type so subsequent TUI redraws are omitted
until leave.

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
2026-08-10 23:35:56 +08:00

63 lines
2.0 KiB
TypeScript

import { useCallback } from "react";
import { netcattyBridge } from "../../infrastructure/services/netcattyBridge";
type ManualChoosePathPayload = {
sessionId: string;
sessionName?: string;
preferredDirectory?: string;
format?: "txt" | "raw" | "html";
};
type ManualStartPayload = {
sessionId: string;
sessionName?: string;
preferredDirectory?: string;
/**
* Opaque token from chooseManualSessionLogPath. Required for the post-dialog
* second phase; raw file paths from the renderer are rejected.
*/
selectionToken?: string;
format?: "txt" | "raw" | "html";
timestampsEnabled?: boolean;
initialLine?: string;
alternateScreenActive?: boolean;
};
type ManualStopPayload = {
sessionId: string;
};
type ManualStatusPayload = {
sessionId: string;
};
export const useSessionLogBackend = () => {
const chooseManualSessionLogPath = useCallback(async (payload: ManualChoosePathPayload) => {
const bridge = netcattyBridge.get();
return bridge?.chooseManualSessionLogPath?.(payload)
?? { success: false, canceled: false, error: "Session log bridge unavailable" };
}, []);
const startManualSessionLog = useCallback(async (payload: ManualStartPayload) => {
const bridge = netcattyBridge.get();
return bridge?.startManualSessionLog?.(payload) ?? { success: false, started: false, error: "Session log bridge unavailable" };
}, []);
const stopManualSessionLog = useCallback(async (payload: ManualStopPayload) => {
const bridge = netcattyBridge.get();
return bridge?.stopManualSessionLog?.(payload) ?? { success: false, stopped: false, error: "Session log bridge unavailable" };
}, []);
const getManualSessionLogStatus = useCallback(async (payload: ManualStatusPayload) => {
const bridge = netcattyBridge.get();
return bridge?.getManualSessionLogStatus?.(payload) ?? { success: false, isLogging: false, error: "Session log bridge unavailable" };
}, []);
return {
chooseManualSessionLogPath,
startManualSessionLog,
stopManualSessionLog,
getManualSessionLogStatus,
};
};