workspace

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: Apache-2.0 Imports: 40 Imported by: 0

Documentation

Overview

Package workspace implements the Workspace interface backed by pkg/sdk.

SeshatWorkspace is the active implementation (Option A — SDK-only path). All LLM traffic flows through pkg/sdk.Client; the Fantasy-based agent package (internal/seshattui/agent/) is NOT used here.

Package workspace defines the Workspace interface used by all seshattui frontends (TUI pages, commands) to interact with a running session.

Architecture — Option A (SDK-only path):

SeshatWorkspace (seshat_workspace.go) is the sole active implementation.
All LLM traffic flows through pkg/sdk: AgentRun → sdk.Session.SubmitMessage.
Streaming is delivered via registered callbacks (OnChunk, OnProgress) which
feed the in-process pubsub brokers that the TUI subscribes to.

The Fantasy-based agent package (internal/seshattui/agent/) is NOT wired into
SeshatWorkspace. It is preserved as a potential future AppWorkspace for
fully-offline / provider-agnostic use, but is currently unused by the TUI.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AgentModel

type AgentModel struct {
	CatwalkCfg catwalk.Model
	ModelCfg   config.SelectedModel
}

AgentModel holds the model information exposed to the UI.

type LSPClientInfo

type LSPClientInfo struct {
	Name            string
	State           lsp.ServerState
	Error           error
	DiagnosticCount int
	ConnectedAt     time.Time
}

LSPClientInfo holds information about an LSP client's state. This is the frontend-facing type; implementations translate from the underlying app or proto representation.

type LSPEvent

type LSPEvent struct {
	Type            LSPEventType
	Name            string
	State           lsp.ServerState
	Error           error
	DiagnosticCount int
}

LSPEvent represents an LSP event forwarded to the TUI.

type LSPEventType

type LSPEventType string

LSPEventType represents the type of LSP event.

const (
	LSPEventStateChanged       LSPEventType = "state_changed"
	LSPEventDiagnosticsChanged LSPEventType = "diagnostics_changed"
)

type MCPResourceContents

type MCPResourceContents struct {
	URI      string `json:"uri"`
	MIMEType string `json:"mime_type,omitempty"`
	Text     string `json:"text,omitempty"`
	Blob     []byte `json:"blob,omitempty"`
}

MCPResourceContents holds the contents of an MCP resource.

type SeshatWorkspace

type SeshatWorkspace struct {
	// contains filtered or unexported fields
}

SeshatWorkspace adapts the Seshat SDK to the Workspace interface. It keeps an in-memory message store and publishes pubsub events that the seshattui UI consumes to render the conversation.

func NewSeshatWorkspace

func NewSeshatWorkspace(client *sdk.Client, workDir, modelStr string) *SeshatWorkspace

NewSeshatWorkspace creates a workspace backed by the given SDK client. modelStr is the "provider:model" string shown in the UI header.

func (*SeshatWorkspace) AgentCancel

func (w *SeshatWorkspace) AgentCancel(sessionID string)

func (*SeshatWorkspace) AgentIsBusy

func (w *SeshatWorkspace) AgentIsBusy() bool

func (*SeshatWorkspace) AgentIsReady

func (w *SeshatWorkspace) AgentIsReady() bool

func (*SeshatWorkspace) AgentIsSessionBusy

func (w *SeshatWorkspace) AgentIsSessionBusy(sessionID string) bool

func (*SeshatWorkspace) AgentModel

func (w *SeshatWorkspace) AgentModel() AgentModel

func (*SeshatWorkspace) AgentRun

func (w *SeshatWorkspace) AgentRun(ctx context.Context, sessionID, prompt string, attachments ...message.Attachment) error

func (*SeshatWorkspace) AgentSummarize

func (w *SeshatWorkspace) AgentSummarize(_ context.Context, _ string) error

func (*SeshatWorkspace) AnswerAskUser

func (w *SeshatWorkspace) AnswerAskUser(id, value string) bool

AnswerAskUser resolves a pending ask_user_question prompt.

func (*SeshatWorkspace) ApprovePlan

func (w *SeshatWorkspace) ApprovePlan(sessionID string) (string, error)

ApprovePlan exits plan mode immediately on behalf of the agent — identical in effect to the agent calling exit_plan_mode — and returns the plan content so the TUI can include it in the approval message. This lets ctrl+y approval skip the agent's verbose "plan approved!" preamble entirely.

func (*SeshatWorkspace) Config

func (w *SeshatWorkspace) Config() *config.Config

func (*SeshatWorkspace) CreateAgentToolSessionID

func (w *SeshatWorkspace) CreateAgentToolSessionID(messageID, toolCallID string) string

Agent tool session IDs use a simple "msgID:toolID" encoding.

func (*SeshatWorkspace) CreateSession

func (w *SeshatWorkspace) CreateSession(ctx context.Context, title string) (session.Session, error)

func (*SeshatWorkspace) DeleteSession

func (w *SeshatWorkspace) DeleteSession(_ context.Context, sessionID string) error

func (*SeshatWorkspace) DetectProviders

func (w *SeshatWorkspace) DetectProviders()

DetectProviders probes env vars, the credentials DB, and Ollama to populate the workspace's provider key store. Run this in a background goroutine immediately after SetStartupConfig — it blocks on network I/O.

func (*SeshatWorkspace) DisableDockerMCP

func (w *SeshatWorkspace) DisableDockerMCP() error

func (*SeshatWorkspace) DisableMCPServer

func (w *SeshatWorkspace) DisableMCPServer(name string) error

func (*SeshatWorkspace) EnableDockerMCP

func (w *SeshatWorkspace) EnableDockerMCP(ctx context.Context) error

func (*SeshatWorkspace) EnableMCPServer

func (w *SeshatWorkspace) EnableMCPServer(ctx context.Context, name string) error

func (*SeshatWorkspace) ExecutionMode

func (w *SeshatWorkspace) ExecutionMode() string

func (*SeshatWorkspace) FileTrackerLastReadTime

func (w *SeshatWorkspace) FileTrackerLastReadTime(_ context.Context, _, _ string) time.Time

func (*SeshatWorkspace) FileTrackerListReadFiles

func (w *SeshatWorkspace) FileTrackerListReadFiles(_ context.Context, _ string) ([]string, error)

func (*SeshatWorkspace) FileTrackerRecordRead

func (w *SeshatWorkspace) FileTrackerRecordRead(_ context.Context, _, _ string)

func (*SeshatWorkspace) GetDefaultSmallModel

func (w *SeshatWorkspace) GetDefaultSmallModel(_ string) config.SelectedModel

func (*SeshatWorkspace) GetMCPPrompt

func (w *SeshatWorkspace) GetMCPPrompt(clientID, promptID string, args map[string]string) (string, error)

func (*SeshatWorkspace) GetSession

func (w *SeshatWorkspace) GetSession(_ context.Context, sessionID string) (session.Session, error)

func (*SeshatWorkspace) HandleChunk

func (w *SeshatWorkspace) HandleChunk(delta string, isThinking bool)

HandleChunk processes a streaming text delta and updates the in-progress message.

func (*SeshatWorkspace) HandlePermissionRequest

func (w *SeshatWorkspace) HandlePermissionRequest(req permission.PermissionRequest)

HandlePermissionRequest emits a permission request to the seshattui UI.

func (*SeshatWorkspace) HandleToolProgress

func (w *SeshatWorkspace) HandleToolProgress(p sdk.ToolProgress)

HandleToolProgress updates the in-progress tool call within the message. It extracts the full tool input and result content from p.Metadata so that tool renderers receive the correct parameters and output during live streaming.

func (*SeshatWorkspace) ImportCopilot

func (w *SeshatWorkspace) ImportCopilot() (*oauth.Token, bool)

func (*SeshatWorkspace) InitCoderAgent

func (w *SeshatWorkspace) InitCoderAgent(_ context.Context) error

func (*SeshatWorkspace) InitializePrompt

func (w *SeshatWorkspace) InitializePrompt() (string, error)

func (*SeshatWorkspace) LSPGetDiagnosticCounts

func (w *SeshatWorkspace) LSPGetDiagnosticCounts(_ string) lsp.DiagnosticCounts

func (*SeshatWorkspace) LSPGetStates

func (w *SeshatWorkspace) LSPGetStates() map[string]LSPClientInfo

func (*SeshatWorkspace) LSPStart

func (w *SeshatWorkspace) LSPStart(_ context.Context, _ string)

func (*SeshatWorkspace) LSPStopAll

func (w *SeshatWorkspace) LSPStopAll(_ context.Context)

func (*SeshatWorkspace) ListAllUserMessages

func (w *SeshatWorkspace) ListAllUserMessages(_ context.Context) ([]message.Message, error)

func (*SeshatWorkspace) ListMessages

func (w *SeshatWorkspace) ListMessages(_ context.Context, sessionID string) ([]message.Message, error)

func (*SeshatWorkspace) ListSessionHistory

func (w *SeshatWorkspace) ListSessionHistory(_ context.Context, _ string) ([]history.File, error)

func (*SeshatWorkspace) ListSessions

func (w *SeshatWorkspace) ListSessions(_ context.Context) ([]session.Session, error)

func (*SeshatWorkspace) ListSkills

func (w *SeshatWorkspace) ListSkills(_ context.Context) ([]skills.CatalogEntry, error)

func (*SeshatWorkspace) ListTools

func (w *SeshatWorkspace) ListTools(ctx context.Context) ([]ToolInfo, error)

func (*SeshatWorkspace) ListUserMessages

func (w *SeshatWorkspace) ListUserMessages(_ context.Context, sessionID string) ([]message.Message, error)

func (*SeshatWorkspace) LoadSessionMessages

func (w *SeshatWorkspace) LoadSessionMessages(sessionID string, sdkMsgs []sdk.Message)

LoadSessionMessages populates the message store from the SDK session history (call after LoadSession completes).

func (*SeshatWorkspace) MCPGetStates

func (w *SeshatWorkspace) MCPGetStates() map[string]mcptools.ClientInfo

func (*SeshatWorkspace) MCPRefreshPrompts

func (w *SeshatWorkspace) MCPRefreshPrompts(ctx context.Context, name string)

func (*SeshatWorkspace) MCPRefreshResources

func (w *SeshatWorkspace) MCPRefreshResources(ctx context.Context, name string)

func (*SeshatWorkspace) MarkProjectInitialized

func (w *SeshatWorkspace) MarkProjectInitialized() error

func (*SeshatWorkspace) OnChunk

func (w *SeshatWorkspace) OnChunk(chunk sdk.ResponseChunk)

OnChunk is the sdk.ResponseChunk callback — translates to HandleChunk.

func (*SeshatWorkspace) OnProgress

func (w *SeshatWorkspace) OnProgress(p sdk.ToolProgress)

OnProgress is the sdk.ToolProgress callback.

func (*SeshatWorkspace) OnRuntimeEvent

func (w *SeshatWorkspace) OnRuntimeEvent(ev sdk.RuntimeEvent)

OnRuntimeEvent forwards structured runtime events that need dedicated TUI surfaces outside the normal transcript.

func (*SeshatWorkspace) OnSessionTitled

func (w *SeshatWorkspace) OnSessionTitled(id sdk.SessionID, title string)

func (*SeshatWorkspace) ParseAgentToolSessionID

func (w *SeshatWorkspace) ParseAgentToolSessionID(sessionID string) (string, string, bool)

func (*SeshatWorkspace) PermissionDeny

func (w *SeshatWorkspace) PermissionDeny(perm permission.PermissionRequest) bool

func (*SeshatWorkspace) PermissionGrant

func (w *SeshatWorkspace) PermissionGrant(perm permission.PermissionRequest) bool

func (*SeshatWorkspace) PermissionGrantPersistent

func (w *SeshatWorkspace) PermissionGrantPersistent(perm permission.PermissionRequest) bool

func (*SeshatWorkspace) PermissionSetSkipRequests

func (w *SeshatWorkspace) PermissionSetSkipRequests(skip bool)

func (*SeshatWorkspace) PermissionSkipRequests

func (w *SeshatWorkspace) PermissionSkipRequests() bool

func (*SeshatWorkspace) PlanStore

func (w *SeshatWorkspace) PlanStore() sdk.PlanStore

PlanStore returns the workspace's plan persistence backend. Use this to inject the same store into the initial sdk.ClientConfig created outside the workspace (e.g. cmd/cli/tui_seshat.go).

func (*SeshatWorkspace) ProjectNeedsInitialization

func (w *SeshatWorkspace) ProjectNeedsInitialization() (bool, error)

func (*SeshatWorkspace) PromptFn

PromptFn blocks the SDK agent goroutine until the UI resolves the prompt. ask_user_question prompts route to askUserBroker; all others go to permBroker.

func (*SeshatWorkspace) ReadMCPResource

func (w *SeshatWorkspace) ReadMCPResource(ctx context.Context, name, uri string) ([]MCPResourceContents, error)

func (*SeshatWorkspace) ReadSkill

func (*SeshatWorkspace) RefreshMCPTools

func (w *SeshatWorkspace) RefreshMCPTools(ctx context.Context, name string)

func (*SeshatWorkspace) RefreshOAuthToken

func (w *SeshatWorkspace) RefreshOAuthToken(_ context.Context, _ config.Scope, _ string) error

func (*SeshatWorkspace) RemoveConfigField

func (w *SeshatWorkspace) RemoveConfigField(_ config.Scope, _ string) error

func (*SeshatWorkspace) Resolver

func (w *SeshatWorkspace) Resolver() config.VariableResolver

func (*SeshatWorkspace) SaveSession

func (w *SeshatWorkspace) SaveSession(_ context.Context, sess session.Session) (session.Session, error)

func (*SeshatWorkspace) SetCompactMode

func (w *SeshatWorkspace) SetCompactMode(_ config.Scope, _ bool) error

func (*SeshatWorkspace) SetConfigField

func (w *SeshatWorkspace) SetConfigField(scope config.Scope, key string, value any) error

func (*SeshatWorkspace) SetCurrentSession

func (w *SeshatWorkspace) SetCurrentSession(ctx context.Context, sessionID string) error

func (*SeshatWorkspace) SetMCPConfig

func (w *SeshatWorkspace) SetMCPConfig(mcps config.MCPs)

SetMCPConfig stores the MCP configuration loaded from seshat.json so it is included in the config returned by Config() and shown in the Settings panel.

func (*SeshatWorkspace) SetMCPStore

func (w *SeshatWorkspace) SetMCPStore(store *config.ConfigStore)

SetMCPStore stores the full config store used for MCP operations (resource reads, prompt fetches, tool refresh, Docker MCP, enable/disable).

func (*SeshatWorkspace) SetProviderAPIKey

func (w *SeshatWorkspace) SetProviderAPIKey(_ config.Scope, providerID string, value any) error

SetProviderAPIKey persists the API key for a provider and marks it as configured in the TUI's in-memory config (so isConfigured() returns true).

func (*SeshatWorkspace) SetSDKClient

func (w *SeshatWorkspace) SetSDKClient(client *sdk.Client)

SetSDKClient wires the SDK client and registers unique TUI tools.

func (*SeshatWorkspace) SetStartupConfig

func (w *SeshatWorkspace) SetStartupConfig(sqlitePath string, permMode sdk.PermissionMode, monitoring *sdk.MonitoringSystem)

SetStartupConfig stores the options needed to rebuild the SDK client when the user switches provider or model from within the TUI. Must be called before the Bubble Tea program starts.

func (*SeshatWorkspace) Shutdown

func (w *SeshatWorkspace) Shutdown()

func (*SeshatWorkspace) Subscribe

func (w *SeshatWorkspace) Subscribe(p *tea.Program)

func (*SeshatWorkspace) UpdateAgentModel

func (w *SeshatWorkspace) UpdateAgentModel(ctx context.Context) error

UpdateAgentModel rebuilds the SDK client with the current w.model string. Called by the TUI after the user selects a new model.

func (*SeshatWorkspace) UpdatePreferredModel

func (w *SeshatWorkspace) UpdatePreferredModel(_ config.Scope, _ config.SelectedModelType, m config.SelectedModel) error

func (*SeshatWorkspace) WorkingDir

func (w *SeshatWorkspace) WorkingDir() string

func (*SeshatWorkspace) WorktreePath

func (w *SeshatWorkspace) WorktreePath() string

type ToolInfo

type ToolInfo struct {
	Name        string
	Description string
	Category    string
}

ToolInfo holds tool metadata exposed to the TUI.

type Workspace

type Workspace interface {
	// Sessions
	CreateSession(ctx context.Context, title string) (session.Session, error)
	GetSession(ctx context.Context, sessionID string) (session.Session, error)
	ListSessions(ctx context.Context) ([]session.Session, error)
	SaveSession(ctx context.Context, sess session.Session) (session.Session, error)
	DeleteSession(ctx context.Context, sessionID string) error
	CreateAgentToolSessionID(messageID, toolCallID string) string
	ParseAgentToolSessionID(sessionID string) (messageID string, toolCallID string, ok bool)
	// SetCurrentSession reports the session this client is currently
	// viewing. Empty sessionID clears the entry (e.g. landing screen).
	// In single-client local mode this is a no-op. In client/server
	// mode it informs the server's per-client presence map so other
	// observers can compute attached-client counts per session.
	SetCurrentSession(ctx context.Context, sessionID string) error

	// Messages
	ListMessages(ctx context.Context, sessionID string) ([]message.Message, error)
	ListUserMessages(ctx context.Context, sessionID string) ([]message.Message, error)
	ListAllUserMessages(ctx context.Context) ([]message.Message, error)

	// Agent
	AgentRun(ctx context.Context, sessionID, prompt string, attachments ...message.Attachment) error
	AgentCancel(sessionID string)
	AgentIsBusy() bool
	AgentIsSessionBusy(sessionID string) bool
	AgentModel() AgentModel
	AgentIsReady() bool
	ExecutionMode() string
	// WorktreePath returns the active git worktree path for the current session,
	// or empty string if no worktree is active.
	WorktreePath() string
	AgentSummarize(ctx context.Context, sessionID string) error
	// ApprovePlan exits plan mode immediately (as if exit_plan_mode was called)
	// and returns the plan content from disk. The caller should send this content
	// to the agent so it can start implementation without needing to call
	// exit_plan_mode itself.
	ApprovePlan(sessionID string) (planContent string, err error)
	UpdateAgentModel(ctx context.Context) error
	InitCoderAgent(ctx context.Context) error
	GetDefaultSmallModel(providerID string) config.SelectedModel

	// Permissions
	//
	// PermissionGrant, PermissionGrantPersistent, and PermissionDeny
	// return true if the call resolved the pending request and false if
	// it had already been resolved by another subscriber (or is no
	// longer pending). A false return is not an error; the modal can
	// still close locally because the resolution will arrive via the
	// PermissionNotification event stream regardless of which client
	// won the race.
	PermissionGrant(perm permission.PermissionRequest) bool
	PermissionGrantPersistent(perm permission.PermissionRequest) bool
	PermissionDeny(perm permission.PermissionRequest) bool
	PermissionSkipRequests() bool
	PermissionSetSkipRequests(skip bool)

	// AnswerAskUser resolves a pending ask_user_question prompt.
	// Returns true if the ID was found and the response delivered.
	AnswerAskUser(id, value string) bool

	// FileTracker
	FileTrackerRecordRead(ctx context.Context, sessionID, path string)
	FileTrackerLastReadTime(ctx context.Context, sessionID, path string) time.Time
	FileTrackerListReadFiles(ctx context.Context, sessionID string) ([]string, error)

	// History
	ListSessionHistory(ctx context.Context, sessionID string) ([]history.File, error)

	// LSP
	LSPStart(ctx context.Context, path string)
	LSPStopAll(ctx context.Context)
	LSPGetStates() map[string]LSPClientInfo
	LSPGetDiagnosticCounts(name string) lsp.DiagnosticCounts

	// Config (read-only data)
	Config() *config.Config
	WorkingDir() string
	Resolver() config.VariableResolver

	// Config mutations (proxied to server in client mode)
	UpdatePreferredModel(scope config.Scope, modelType config.SelectedModelType, model config.SelectedModel) error
	SetCompactMode(scope config.Scope, enabled bool) error
	SetProviderAPIKey(scope config.Scope, providerID string, apiKey any) error
	SetConfigField(scope config.Scope, key string, value any) error
	RemoveConfigField(scope config.Scope, key string) error
	ImportCopilot() (*oauth.Token, bool)
	RefreshOAuthToken(ctx context.Context, scope config.Scope, providerID string) error

	// Project lifecycle
	ProjectNeedsInitialization() (bool, error)
	MarkProjectInitialized() error
	InitializePrompt() (string, error)
	ListTools(ctx context.Context) ([]ToolInfo, error)
	ListSkills(ctx context.Context) ([]skills.CatalogEntry, error)
	ReadSkill(ctx context.Context, skillID string) ([]byte, skills.SkillReadResult, error)

	// MCP operations (server-side in client mode)
	MCPGetStates() map[string]mcptools.ClientInfo
	MCPRefreshPrompts(ctx context.Context, name string)
	MCPRefreshResources(ctx context.Context, name string)
	RefreshMCPTools(ctx context.Context, name string)
	ReadMCPResource(ctx context.Context, name, uri string) ([]MCPResourceContents, error)
	GetMCPPrompt(clientID, promptID string, args map[string]string) (string, error)
	EnableDockerMCP(ctx context.Context) error
	DisableDockerMCP() error
	EnableMCPServer(ctx context.Context, name string) error
	DisableMCPServer(name string) error

	// Events
	Subscribe(program *tea.Program)
	Shutdown()
}

Workspace is the main abstraction consumed by the TUI and CLI. It groups every operation a frontend needs to perform against a running workspace, regardless of whether the workspace is in-process or remote.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL