# `MingaEditor.State.Workspace`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/state/workspace.ex#L1)

Domain model for an editor workspace.

A workspace owns a task context. The manual workspace represents project-owned file work, while agent workspaces attach one optional agent session and later become the home for workspace files, agent UI, ProjectView, and review state.

# `agent_status`

```elixir
@type agent_status() ::
  :idle
  | :plan
  | :thinking
  | :tool_executing
  | :error
  | :stopped
  | :needs_review
  | :done
  | nil
```

Agent status for workspace display.

# `connection_status`

```elixir
@type connection_status() ::
  MingaEditor.State.Workspace.RemoteSession.connection_status()
```

Remote connection status for workspace-owned remote sessions.

# `icon`

```elixir
@type icon() :: String.t()
```

Workspace icon identifier.

# `kind`

```elixir
@type kind() :: :manual | :agent
```

Workspace kind.

# `t`

```elixir
@type t() :: %MingaEditor.State.Workspace{
  active_file: Minga.Project.FileRef.t() | nil,
  agent_status: agent_status(),
  agent_ui: MingaEditor.Agent.UIState.t() | nil,
  color: non_neg_integer(),
  custom_name: String.t() | nil,
  files: [Minga.Project.FileRef.t()],
  icon: icon(),
  id: non_neg_integer(),
  kind: kind(),
  label: String.t(),
  pending_catchup_events: [MingaAgent.EventLog.EventRecord.t()],
  project_root: String.t() | nil,
  project_view: MingaAgent.ProjectView.t() | nil,
  remote_session: MingaEditor.State.Workspace.RemoteSession.t() | nil,
  review: MingaEditor.State.WorkspaceReview.t(),
  session: pid() | nil
}
```

A workspace domain object.

# `add_file`

```elixir
@spec add_file(t(), Minga.Project.FileRef.t()) :: t()
```

Adds a file membership to the workspace, preserving existing membership order.

# `auto_name`

```elixir
@spec auto_name(t(), String.t()) :: t()
```

Auto-names an agent workspace from an agent prompt unless the user renamed it.

# `clear_pending_catchup_events`

```elixir
@spec clear_pending_catchup_events(t()) :: t()
```

Clears queued remote catch-up events after they have been replayed.

# `clear_remote_session`

```elixir
@spec clear_remote_session(t()) :: t()
```

Clears durable remote metadata. Use only when the workspace no longer represents a remote session.

# `clear_session`

```elixir
@spec clear_session(t()) :: t()
```

Clears the live agent session pid and returns the workspace to idle lifecycle status. Durable remote identity is preserved.

# `close_project_view`

```elixir
@spec close_project_view(t()) :: :ok | {:error, term()}
```

Releases the workspace's owned ProjectView resources, if any.

# `from_persisted_map`

```elixir
@spec from_persisted_map(map(), String.t()) :: {:ok, t()} | {:error, term()}
```

Restores a workspace from persisted JSON data, ignoring unknown fields and using defaults for missing fields.

# `has_file?`

```elixir
@spec has_file?(t(), Minga.Project.FileRef.t()) :: boolean()
```

Returns true when the workspace already contains the file membership.

# `matches_remote_session?`

```elixir
@spec matches_remote_session?(t(), String.t(), String.t()) :: boolean()
```

Returns true when the workspace represents the remote server/session pair.

# `new_agent`

```elixir
@spec new_agent(pos_integer(), String.t(), pid() | nil, String.t() | nil) :: t()
```

Creates a new agent workspace with a unique id.

# `new_manual`

```elixir
@spec new_manual(String.t() | nil) :: t()
```

Creates the manual project workspace.

# `project_view_active?`

```elixir
@spec project_view_active?(t()) :: boolean()
```

Returns true when the workspace still has a live ProjectView.

# `put_remote_session`

```elixir
@spec put_remote_session(
  t(),
  String.t(),
  String.t(),
  connection_status(),
  non_neg_integer()
) :: t()
```

Sets durable remote metadata from its fields.

# `rebind_file`

```elixir
@spec rebind_file(t(), Minga.Project.FileRef.t() | nil, Minga.Project.FileRef.t()) ::
  t()
```

Rebinds the active file membership from one logical file ref to another.

# `refresh_session_pid`

```elixir
@spec refresh_session_pid(t(), pid(), pid()) :: t()
```

Refreshes the workspace session pid after a managed restart.

# `remote?`

```elixir
@spec remote?(t()) :: boolean()
```

Returns true when the workspace has durable remote metadata.

# `remote_server?`

```elixir
@spec remote_server?(t(), String.t()) :: boolean()
```

Returns true when the workspace belongs to the named remote server.

# `remove_file`

```elixir
@spec remove_file(t(), Minga.Project.FileRef.t()) :: t()
```

Removes a file membership from the workspace.

# `rename`

```elixir
@spec rename(t(), String.t()) :: t()
```

Renames the workspace and protects it from future auto-naming.

# `retarget_file`

```elixir
@spec retarget_file(
  t(),
  Minga.Project.FileRef.t() | nil,
  Minga.Project.FileRef.t(),
  boolean()
) :: t()
```

Retargets a file membership for a tab, preserving unrelated active file state.

# `review_pending?`

```elixir
@spec review_pending?(t()) :: boolean()
```

Returns true when drafts or conflicts require user action before close.

# `set_active_file`

```elixir
@spec set_active_file(t(), Minga.Project.FileRef.t() | nil) :: t()
```

Sets the active file membership for the workspace.

# `set_agent_status`

```elixir
@spec set_agent_status(t(), agent_status()) :: t()
```

Sets the agent status on the workspace.

# `set_agent_ui`

```elixir
@spec set_agent_ui(t(), MingaEditor.Agent.UIState.t() | nil) :: t()
```

Sets the workspace-owned agent UI projection.

# `set_icon`

```elixir
@spec set_icon(t(), String.t()) :: t()
```

Sets the workspace icon.

# `set_pending_catchup_events`

```elixir
@spec set_pending_catchup_events(t(), [MingaAgent.EventLog.EventRecord.t()]) :: t()
```

Sets queued remote catch-up events waiting for the workspace to become active.

# `set_project_view`

```elixir
@spec set_project_view(t(), MingaAgent.ProjectView.t() | nil) :: t()
```

Sets the ProjectView owned by the workspace.

# `set_remote_connection_status`

```elixir
@spec set_remote_connection_status(t(), connection_status()) :: t()
```

Updates durable remote connection status when the workspace has remote metadata.

# `set_remote_session`

```elixir
@spec set_remote_session(t(), MingaEditor.State.Workspace.RemoteSession.t() | nil) ::
  t()
```

Sets durable remote metadata on the workspace.

# `set_review`

```elixir
@spec set_review(t(), MingaEditor.State.WorkspaceReview.t()) :: t()
```

Sets review state through the owning workspace module.

# `set_session`

```elixir
@spec set_session(t(), pid() | nil) :: t()
```

Sets the session owned by the workspace.

# `to_persisted_map`

```elixir
@spec to_persisted_map(t()) :: map()
```

Serializes the persisted workspace fields to a JSON-ready map.

# `transition_review`

```elixir
@spec transition_review(t(), atom(), [Minga.Project.FileRef.t()] | nil | term()) ::
  {:ok, t()} | {:error, term()}
```

Moves review state through a legal transition.

# `with_project_root`

```elixir
@spec with_project_root(t(), String.t() | nil) :: t()
```

Returns a copy scoped to a project root for persistence.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
