@@ -14,10 +14,12 @@ import (
14 "github.com/opencode-ai/opencode/internal/tui/components/dialogs/quit"
14 "github.com/opencode-ai/opencode/internal/tui/components/dialogs/quit"
15 "github.com/opencode-ai/opencode/internal/tui/layout"
15 "github.com/opencode-ai/opencode/internal/tui/layout"
16 "github.com/opencode-ai/opencode/internal/tui/page"
16 "github.com/opencode-ai/opencode/internal/tui/page"
17− "github.com/opencode-ai/opencode/internal/tui/theme"
17+ "github.com/opencode-ai/opencode/internal/tui/page/chat"
18+ "github.com/opencode-ai/opencode/internal/tui/styles"
18 "github.com/opencode-ai/opencode/internal/tui/util"
19 "github.com/opencode-ai/opencode/internal/tui/util"
22+// appModel represents the main application model that manages pages, dialogs, and UI state.
21type appModel struct {
23type appModel struct {
22 width, height int
24 width, height int
23 keyMap KeyMap
25 keyMap KeyMap
@@ -35,6 +37,7 @@ type appModel struct {
35 completions completions.Completions
37 completions completions.Completions
40+// Init initializes the application model and returns initial commands.
38func (a appModel) Init() tea.Cmd {
41func (a appModel) Init() tea.Cmd {
39 var cmds []tea.Cmd
42 var cmds []tea.Cmd
40 cmd := a.pages[a.currentPage].Init()
43 cmd := a.pages[a.currentPage].Init()
@@ -46,6 +49,7 @@ func (a appModel) Init() tea.Cmd {
46 return tea.Batch(cmds...)
49 return tea.Batch(cmds...)
52+// Update handles incoming messages and updates the application state.
49func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
53func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
50 var cmds []tea.Cmd
54 var cmds []tea.Cmd
51 var cmd tea.Cmd
55 var cmd tea.Cmd
@@ -111,6 +115,7 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
111 return a, tea.Batch(cmds...)
115 return a, tea.Batch(cmds...)
118+// handleWindowResize processes window resize events and updates all components.
114func (a *appModel) handleWindowResize(msg tea.WindowSizeMsg) tea.Cmd {
119func (a *appModel) handleWindowResize(msg tea.WindowSizeMsg) tea.Cmd {
115 var cmds []tea.Cmd
120 var cmds []tea.Cmd
116 msg.Height -= 1 // Make space for the status bar
121 msg.Height -= 1 // Make space for the status bar
@@ -134,6 +139,7 @@ func (a *appModel) handleWindowResize(msg tea.WindowSizeMsg) tea.Cmd {
134 return tea.Batch(cmds...)
139 return tea.Batch(cmds...)
142+// handleKeyPressMsg processes keyboard input and routes to appropriate handlers.
137func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
143func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
139 // completions
145 // completions
@@ -182,11 +188,7 @@ func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
185−// RegisterCommand adds a command to the command dialog
191+// moveToPage handles navigation between different pages in the application.
186−// func (a *appModel) RegisterCommand(cmd dialog.Command) {
187−// a.commands = append(a.commands, cmd)
190func (a *appModel) moveToPage(pageID page.PageID) tea.Cmd {
192func (a *appModel) moveToPage(pageID page.PageID) tea.Cmd {
191 if a.app.CoderAgent.IsBusy() {
193 if a.app.CoderAgent.IsBusy() {
192 // For now we don't move to any page if the agent is busy
194 // For now we don't move to any page if the agent is busy
@@ -209,6 +211,7 @@ func (a *appModel) moveToPage(pageID page.PageID) tea.Cmd {
209 return tea.Batch(cmds...)
211 return tea.Batch(cmds...)
214+// View renders the complete application interface including pages, dialogs, and overlays.
212func (a *appModel) View() tea.View {
215func (a *appModel) View() tea.View {
213 pageView := a.pages[a.currentPage].View()
216 pageView := a.pages[a.currentPage].View()
214 components := []string{
217 components := []string{
@@ -220,7 +223,6 @@ func (a *appModel) View() tea.View {
220 layers := []*lipgloss.Layer{
223 layers := []*lipgloss.Layer{
221 lipgloss.NewLayer(appView),
224 lipgloss.NewLayer(appView),
223− t := theme.CurrentTheme()
224 if a.dialog.HasDialogs() {
226 if a.dialog.HasDialogs() {
225 layers = append(
227 layers = append(
@@ -246,12 +248,15 @@ func (a *appModel) View() tea.View {
246 canvas := lipgloss.NewCanvas(
248 canvas := lipgloss.NewCanvas(
247 layers...,
249 layers...,
252+ t := styles.CurrentTheme()
249 view := tea.NewView(canvas.Render())
253 view := tea.NewView(canvas.Render())
250− view.SetBackgroundColor(t.Background())
254+ view.SetBackgroundColor(t.BgBase)
251 view.SetCursor(cursor)
255 view.SetCursor(cursor)
252 return view
256 return view
259+// New creates and initializes a new TUI application model.
255func New(app *app.App) tea.Model {
260func New(app *app.App) tea.Model {
256 startPage := page.ChatPage
261 startPage := page.ChatPage
257 model := &appModel{
262 model := &appModel{
@@ -262,7 +267,7 @@ func New(app *app.App) tea.Model {
262 keyMap: DefaultKeyMap(),
267 keyMap: DefaultKeyMap(),
264 pages: map[page.PageID]util.Model{
269 pages: map[page.PageID]util.Model{
265− page.ChatPage: page.NewChatPage(app),
270+ page.ChatPage: chat.NewChatPage(app),
266 page.LogsPage: page.NewLogsPage(),
271 page.LogsPage: page.NewLogsPage(),