# `Mailglass.Installer.Plan`
[🔗](https://github.com/szTheory/mailglass/blob/v1.0.0/lib/mailglass/installer/plan.ex#L1)

Deterministic installer plan builder.

Resolves the host app's OTP name (e.g. `:my_app`) by reading `mix.exs`
from the current working directory, then substitutes that name into
every Operation path so the installer patches the adopter's actual
files instead of literal `lib/my_app/...` placeholders.

# `build`

```elixir
@spec build(
  keyword(),
  map()
) :: [Mailglass.Installer.Operation.t()]
```

Builds the installer operation list for the current host app context.

The OTP app name is resolved in this order:

1. `opts[:otp_app]` (explicit override; used by tests)
2. `context[:otp_app]` (also for tests)
3. `mix.exs` in `File.cwd!()` (real adopter use)
4. fallback to `:my_app` (preserves prior behavior if mix.exs is absent)

# `detect_otp_app`

```elixir
@spec detect_otp_app() :: atom()
```

Resolves the host OTP app name. Public so the mix task can pass the
result through; tests can also call it directly to assert behaviour.

Reads `mix.exs` in `File.cwd!()` and extracts the `app: :foo` keyword.
Returns the atom (e.g. `:my_app`). Falls back to `:my_app` if the
file is absent or the field can't be parsed — preserves prior
hardcoded-placeholder behaviour rather than crashing.

---

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