Changelog
-
Centralized logging module β Moved
sec_gemini/tui2/logging.pytosec_gemini/logging.pyso all components (TUI, MCP server, BYOT CLI) share the same structured JSON logging infrastructure. Fixed_KwargsAdapterto store structured fields safely, avoidingLogRecordattribute collisions (e.g.name=). -
BYOT:
setup_byot_logging()β New convenience function for the standalone BYOT CLI. Writes rotating JSON to~/.config/sec-gemini/logs/byot.logplus colored console output via Rich. Added--verboseCLI flag. -
BYOT: dedicated log file β MCP server now writes BYOT logs to a separate
byot.logvia a namespace handler onsecgemini.byot, in addition tomcp.logvia the root logger. -
MCP: BYOT observability tools β Added 3 new Layer 1 tools:
get_byot_status(state, tools, hub URL, uptime, errors),list_byot_tools(focused tool listing),reload_byot(stop + restart with refreshed config). Added 2 debug tools:byot_logandbyot_log_grepfor inspecting BYOT logs. -
MCP:
mcp_reloadsendsToolListChangedNotificationβ After re-registering tools, the client is notified so it re-fetches the tool list. New tools appear immediately without a server reconnect. -
MCP:
mcp_reloadcovers BYOT and tools modules β Addedsec_gemini.byot.*andsec_gemini.tools.*to the reload list so BYOT code changes take effect without restarting the MCP server. -
BYOT: structured logging β Converted
byot/service.pyandbyot/client.pyto useget_logger()with structured kwargs (tool_count=,hub_url=,job_id=) instead of%sformatting. -
BYOT: better auth error reporting β Hub registration rejection now logs
registration_rejectedwith hub URL and key prefix, and raises a more descriptive error message. -
MCP: TUI lifecycle tools β Added
tui_start,tui_stop,tui_statusdebug tools that launch/manage the TUI as a headless subprocess. Enables autonomous TUI debugging from Claude Code without manual terminal setup. -
TUI: debug socket server β New
DebugServerintui2/debug_server.pyexposes a Unix domain socket (~/.config/sec-gemini/debug.sock) when--debugis passed. Accepts JSON commands for screen inspection, widget queries, clicks, keypresses, and state dumps. -
TUI:
--debugand--headlessCLI flags βsec-gemini run --debugstarts the debug socket server;--headlessruns without a terminal for MCP-managed sessions. -
sec_gemini/backoff.pyβExponentialBackoffutility with full jitter for use in reconnection and retry logic. -
30 new unit tests covering dispatch routing, error handling, reconnection backoff, retry behavior, and session state management.
-
TUI: stream loop stops after terminal state β The message stream loop no longer re-subscribes every 30s after a session reaches COMPLETED, FAILED, CANCELED, or MAX_ATTEMPTS_EXCEEDED. Previously this caused the server to replay the entire message history indefinitely. The session VM now tracks status changes via a callback and sets COMPLETED on AGENT_IS_DONE receipt.
-
BYOT: idempotent start β
start_byot()returns current tools when BYOT is already running instead of raising an error. Fixes the βBYOT already createdβ toast when creating a second session. -
BYOT: hot-reload resilience β MCP status tools (
get_byot_status,list_byot_tools) access raw service attributes to survive Pydantic class identity mismatches aftermcp_reload().ByotService.status()also converts tools to dicts before constructingByotStatus. -
Sessions: sorted newest-first β
list_sessions()now returns sessions sorted bycreated_atdescending in both the Backend and MCP tool layer. -
MCP:
mcp_reloadnow re-registers tools β Previously only reloaded modules without updating the registered tool closures. Now callsregister_all_tools()andregister_debug_tools()after reload so code changes take effect without restarting the MCP server. -
MCP: TUI inspection tools use IPC β
tui_screenshot,tui_get_screen,tui_query,tui_click,tui_type,tui_press,tui_get_statenow communicate via the debug Unix socket instead of requiring an in-process app reference that was never set in standalone mode. -
MCP: stale debug socket cleanup β
tui_stopand MCP lifespan shutdown now remove the debug socket file to prevent stale socket issues. -
Session:
get()reuses cached sessions βClientSessions.get()now returns the existing tracked session instead of always creating a fresh one, which was clobbering accumulated state (status, name, created_at). -
Session: server-assigned names applied from stream β Added
Session.handle_streamed_message()to pick upMESSAGE_TYPE_SESSION_NAMEfrom server.SessionMessagesnow holds a reference to its parentSessionand calls the handler before yielding messages. -
Session: state reconciliation after reconnection β Added reconnect callback mechanism to
RpcClient.ClientSessionsregisters_reconcile_stateat bind time, callinglist()after reconnection to resync all session state from the server. -
Connection: improved message routing reliability β Message routing now uses strict request ID matching, ensuring reliable delivery and preventing misrouting or silent drops.
-
Connection: exponential backoff on reconnection β Replaced fixed 0.2s/1.0s reconnection delays with exponential backoff using full jitter (base=0.5s, max=30s, multiplier=2x). Prevents connection storms and server-side rate limiting during network instability.
-
Session: log warning on invalid status β
update_from_eventnow logs a warning when it receives an unrecognized status string, instead of silently swallowing theValueError. -
Session: handle name and created_at from events β
update_from_eventnow updates_nameand_created_atwhen those fields are present in the event dict. -
ClientSessions: handle session_not_found β
_handle_server_messagenow handlessession_not_foundevents by removing stale sessions from the local cache and logging a warning. -
ClientSessions: log unknown session state changes β State change events for sessions not in the local registry now emit a debug log instead of being silently ignored.