refactor(ax): tighten window creation semantics
Some checks failed
Security Scan / security (push) Failing after 29s
Test / test (push) Successful in 1m19s

This commit is contained in:
Virgil 2026-03-31 07:49:58 +00:00
parent 78a2a33ed2
commit 97c9d34f4f
4 changed files with 33 additions and 3 deletions

View file

@ -7,6 +7,7 @@ import (
"forge.lthn.ai/core/go/pkg/core"
"forge.lthn.ai/core/gui/pkg/clipboard"
"forge.lthn.ai/core/gui/pkg/window"
"github.com/modelcontextprotocol/go-sdk/mcp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -53,6 +54,15 @@ func TestMCP_Good_ClipboardRoundTrip(t *testing.T) {
assert.Equal(t, "hello", content.Text)
}
func TestMCP_Bad_WindowCreateRequiresName(t *testing.T) {
c, _ := core.New(core.WithServiceLock())
sub := NewService(c)
_, _, err := sub.windowCreate(context.Background(), nil, window.Window{})
require.Error(t, err)
assert.Contains(t, err.Error(), "window name is required")
}
func TestMCP_Bad_NoServices(t *testing.T) {
c, _ := core.New(core.WithServiceLock())
// Without any services, QUERY should return handled=false

View file

@ -80,6 +80,9 @@ type WindowCreateOutput struct {
}
func (s *Subsystem) windowCreate(_ context.Context, _ *mcp.CallToolRequest, input window.Window) (*mcp.CallToolResult, WindowCreateOutput, error) {
if input.Name == "" {
return nil, WindowCreateOutput{}, coreerr.E("mcp.windowCreate", "window name is required", nil)
}
result, _, err := s.core.PERFORM(window.TaskOpenWindow{
Window: input,
})
@ -363,7 +366,7 @@ func (s *Subsystem) registerWindowTools(server *mcp.Server) {
mcp.AddTool(server, &mcp.Tool{Name: "window_list", Description: "List all application windows"}, s.windowList)
mcp.AddTool(server, &mcp.Tool{Name: "window_get", Description: "Get information about a specific window"}, s.windowGet)
mcp.AddTool(server, &mcp.Tool{Name: "window_focused", Description: "Get the currently focused window"}, s.windowFocused)
mcp.AddTool(server, &mcp.Tool{Name: "window_create", Description: "Create a new application window"}, s.windowCreate)
mcp.AddTool(server, &mcp.Tool{Name: "window_create", Description: "Create a new named application window"}, s.windowCreate)
mcp.AddTool(server, &mcp.Tool{Name: "window_close", Description: "Close an application window"}, s.windowClose)
mcp.AddTool(server, &mcp.Tool{Name: "window_position", Description: "Set the position of a window"}, s.windowPosition)
mcp.AddTool(server, &mcp.Tool{Name: "window_size", Description: "Set the size of a window"}, s.windowSize)

View file

@ -86,6 +86,7 @@ func (m *Manager) SetDefaultHeight(height int) {
// Create opens a window from a declarative spec.
// Example: m.Create(Window{Name: "editor", Title: "Editor", URL: "/"})
// Saved position, size, and maximized state are restored when available.
func (m *Manager) Create(spec Window) (PlatformWindow, error) {
w := spec
if w.Name == "" {
@ -112,10 +113,17 @@ func (m *Manager) Create(spec Window) (PlatformWindow, error) {
w.URL = "/"
}
// Apply saved state if available
m.state.ApplyState(&w)
// Apply saved state if available.
if m.state != nil {
m.state.ApplyState(&w)
}
pw := m.platform.CreateWindow(w.ToPlatformOptions())
if m.state != nil {
if state, ok := m.state.GetState(w.Name); ok && state.Maximized {
pw.Maximise()
}
}
m.mu.Lock()
m.windows[w.Name] = pw

View file

@ -77,6 +77,15 @@ func TestManager_Create_CustomDefaults_Good(t *testing.T) {
assert.Equal(t, 900, h)
}
func TestManager_Create_RestoresMaximizedState_Good(t *testing.T) {
m, _ := newTestManager()
m.state.states["restored"] = WindowState{Maximized: true}
pw, err := m.Create(Window{Name: "restored"})
require.NoError(t, err)
assert.True(t, pw.IsMaximised())
}
func TestManager_Get_Good(t *testing.T) {
m, _ := newTestManager()
_, _ = m.Create(Window{Name: "findme"})