# `Planck.Headless`
[🔗](https://github.com/alexdesousa/planck/blob/v0.1.0/lib/planck/headless.ex#L1)

The headless core of the Planck coding agent.

`planck_headless` owns configuration, loads resources at startup (tools,
skills, teams, compactor), and manages session lifecycles. UIs depend on
this module; they are rendering surfaces only and never call `planck_agent`
directly.

See `specs/planck-headless.md` for the full design.

# `session_id`

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

# `available_models`

```elixir
@spec available_models() :: [Planck.AI.Model.t()]
```

Return models available for use (providers with API keys configured).

# `close_session`

```elixir
@spec close_session(session_id()) :: :ok | {:error, term()}
```

Close a session. Stops the agent team and the session GenServer.
The SQLite file is retained for later resumption.

# `config`

```elixir
@spec config() :: Planck.Headless.Config.t()
```

Return the resolved configuration.

# `configure_model`

```elixir
@spec configure_model(keyword()) :: :ok | {:error, term()}
```

Persist a model configuration to the JSON config and `.env` files, then
reload resources so the new model is immediately available.

Options:
- `:provider` (required) — e.g. `:anthropic`, `:ollama`
- `:model_id` (required) — model identifier string
- `:scope` — `:local` (default, `.planck/`) or `:global` (`~/.planck/`)
- `:api_key` — written to `<scope>/.env` for cloud providers
- `:base_url` — stored in `models` config entry for local providers
- `:default` — set as `default_provider`/`default_model` (default: `true`)

# `delete_session`

```elixir
@spec delete_session(session_id()) :: :ok
```

Close a session and permanently delete its SQLite file from disk.

Stops all running agents and the Session GenServer if active, then removes
the `.db` file. This operation is irreversible.

# `get_team`

```elixir
@spec get_team(String.t()) :: {:ok, Planck.Agent.Team.t()} | {:error, :not_found}
```

Look up a team by alias.

# `list_sessions`

```elixir
@spec list_sessions() :: [
  %{session_id: String.t(), name: String.t(), active: boolean()}
]
```

List all sessions on disk — active and inactive — with their id, name, and
whether they are currently running.

# `list_teams`

```elixir
@spec list_teams() :: [
  %{alias: String.t(), name: String.t() | nil, description: String.t() | nil}
]
```

List all registered teams with alias, name, and description.

# `nudge`

```elixir
@spec nudge(session_id()) :: :ok | {:error, term()}
```

Nudge the orchestrator to act on its existing message history without adding
a new user message. Used after session resume when a recovery context is
already present and just needs to be acted upon.

Returns `:ok` if the orchestrator was nudged, `{:error, reason}` otherwise.

# `prompt`

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

Send a user prompt to the orchestrator of a session.

# `reload_resources`

```elixir
@spec reload_resources() :: :ok
```

Reload tools, skills, teams, and the compactor from disk.
In-flight sessions keep their original resources.

# `resume_session`

```elixir
@spec resume_session(
  String.t(),
  keyword()
) :: {:ok, session_id()} | {:error, term()}
```

Resume a session by session_id or by name. Reconstructs the team, restores
message history, and injects a recovery context if prior work was in-flight.

# `rewind_to_message`

```elixir
@spec rewind_to_message(session_id(), pos_integer(), String.t()) ::
  :ok | {:error, term()}
```

Edit a previous user message: rewind the orchestrator to strictly before the
given DB row id (truncates both the SQLite session and in-memory history via
`Agent.rewind_to_message/2`), then re-prompt with `new_text`.

# `start_session`

```elixir
@spec start_session(keyword()) :: {:ok, session_id()} | {:error, term()}
```

Start a new session. Returns `{:ok, session_id}`.

## Options

- `template:` — team alias, path to a TEAM.json directory, or `nil` for the
  default dynamic team (lone orchestrator built from config defaults).
- `name:` — session name; auto-generated as `<adjective>-<noun>` if absent.
- `cwd:` — working directory for the session (default: `File.cwd!()`).

---

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