Skip to content

refactor(tui): centralize terminal session lifecycle - #12

Merged
CnBarrier404 merged 23 commits into
mainfrom
refactor/tui-lifecycle
Aug 30, 2026
Merged

refactor(tui): centralize terminal session lifecycle#12
CnBarrier404 merged 23 commits into
mainfrom
refactor/tui-lifecycle

Conversation

@CnBarrier404

Copy link
Copy Markdown
Owner

Summary

  • introduce a terminal session boundary and semantic lifecycle hooks
  • move repository initialization and update checks out of terminal navigation
  • replace the task runner with direct async event flows and simplify page orchestration
  • update architecture documentation and affected tests

Testing

  • Not run as part of PR creation

- register TerminalLifecycle and UpdateCheckSessionHook
- remove update orchestration from TerminalSession
- redraw the main menu through RenderRequested
Move repository initialization into the Application layer and keep the TUI startup hook as an adapter. Remove the obsolete TUI Modules path and Navigator startup orchestration.
Expose a neutral content host through the terminal lifecycle context so the repository initialization hook owns recovery, retry, and unsupported format handling while the navigator remains focused on normal navigation.
Require the fully configured navigator and remove the unused fallback navigation path, lifecycle compatibility constructor, and empty page code.
Remove the unused synchronous TryRun overload and IsRunning state, and clean obsolete repository initialization test code from Navigator tests.
Move application metadata, paths, and runtime logging settings into Application. Update application consumers and remove obsolete TUI configuration types.
Keep repository startup pending through interactive recovery and defer
MainMenu and session hooks until startup prerequisites complete.
Remove the unused session hook infrastructure and obsolete TUI update tests.
Replace startup hooks with an explicit repository initialization flow.
Move lifecycle task and cancellation ownership to the terminal session.

BREAKING CHANGE: ITerminalStartupHook and RepositoryInitializationStartupHook have been removed.
Move repository startup and main-menu activation into TerminalSession.
Remove the standalone TerminalLifecycle service.

BREAKING CHANGE: TerminalLifecycle has been removed.
Start initialization after the shell is running and track all TUI background
work through TerminalTaskRunner. Propagate shutdown cancellation, drain tasks
before disposal, and dispose views removed during page transitions.

BREAKING CHANGE: remove the public TerminalLifecycleContext API.
Remove the shared task runner and obsolete UI dispatch bridge.

Use direct async/await handlers with local blocking work offloaded.

Own startup cancellation in TerminalSession to avoid shutdown hangs.
Remove redundant Task.Run wrappers around DispatchAsync calls while keeping synchronous repository initialization offloaded.

Copy link
Copy Markdown
Owner Author

Review notes — ChatGPT

I reviewed the current PR, including the TUI lifecycle refactor and the latest follow-up commit. CI is green, including the NativeAOT publish check, and the overall direction of moving startup/recovery concerns out of TerminalNavigator looks cleaner.

There is one behavior regression I would fix before merging:

Blocking application work now runs on the TUI thread

Removing TerminalTaskRunner changed several page operations from “run the whole request off the UI thread, then marshal the result back” to directly awaiting IRequestDispatcher.DispatchAsync(...) from Terminal.Gui event handlers.

That is safe only when the request handler yields quickly. Some handlers do not. For example, InspectAssetsHandler.HandleAsync performs List(...) / Fields(...) synchronously and only then returns Task.FromResult(...). List(...) reads the assets file and may call ReadField for every listed asset. With the new InspectAssetsView.InspectListAsync / InspectFieldsAsync flow, that synchronous work executes on the Terminal.Gui event-loop thread, so sufficiently large files can freeze input and stop the working indicator from updating.

The same pattern exists in other synchronous request handlers such as repository recovery/management and listing installed mods, so I would keep the new async flow structure but introduce a thin offload boundary for application operations whose handlers can do synchronous I/O/CPU work (for example, starting the dispatch from Task.Run with the page lifetime cancellation token), rather than bringing the old callback-oriented TerminalTaskRunner back wholesale.

Update-check lifecycle

The current MainMenuView still ties update checking to each view instance, so returning to the main menu can restart the check and leaving it can cancel an in-flight one. Given the planned page split into view + logic, I would not block this PR on that architectural placement. The newly added TODO is enough to keep the intended session-scoped, once-per-terminal-session behavior visible for the follow-up refactor.

Other than that, I did not find another issue I am confident enough to call a merge blocker in the new TerminalSession stop/cancellation flow, repository initialization flow, or page lifetime cancellation changes.

Document the TUI View and Logic separation, UI-thread marshaling, background operation ownership, and the Flows project structure.
@CnBarrier404
CnBarrier404 merged commit 021648a into main Aug 30, 2026
1 check passed
@CnBarrier404
CnBarrier404 deleted the refactor/tui-lifecycle branch August 30, 2026 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant