# `DalaDev.HotPush`
[🔗](https://github.com/manhvu/dala_dev/blob/main/lib/mob_dev/hot_push.ex#L1)

Connects to already-running device nodes and hot-pushes BEAM modules via RPC.

Unlike `DalaDev.Deployer`, this does NOT restart apps — modules are loaded
into the running BEAM in place, just like `nl/1` in IEx.

Requires apps to already be running (start with `mix dala.connect` or
`mix dala.deploy` first).

# `connect`

```elixir
@spec connect(keyword()) :: [node()]
```

Sets up adb tunnels (idempotent) and connects to all running device nodes.

Returns list of connected node atoms.

## Options

- `:cookie` - Erlang cookie (default: `:dala_secret`)
- `:device` - Target specific device by ID (optional)

# `push_all`

```elixir
@spec push_all([node()]) :: {non_neg_integer(), list()}
```

Pushes all compiled BEAM files from `_build/dev/lib/*/ebin/` to `nodes`.

Only pushes BEAMs for runtime dependencies — deps marked `only: :dev` or
`runtime: false` in `mix.exs` (and their transitive deps) are excluded.
This prevents dev tooling (dala_dev, Bandit, Phoenix, etc.) from being pushed
to the device when using `path:` deps during local framework development.

Returns `{pushed_count, failed_list}`.

# `push_all_to_device`

```elixir
@spec push_all_to_device(
  String.t(),
  keyword()
) :: {non_neg_integer(), list()}
```

Pushes all compiled BEAM files to devices specified by ID.

Convenience function that combines `connect/1` and `push_all/1`.

# `push_changed`

```elixir
@spec push_changed([node()], %{required(String.t()) =&gt; non_neg_integer()}) ::
  {non_neg_integer(), list()}
```

Pushes BEAM files that changed since `snapshot` (from `snapshot_beams/0`).
Returns `{pushed_count, failed_list}` — pushed_count is 0 if nothing changed.

# `runtime_beam_dirs`

```elixir
@spec runtime_beam_dirs() :: [String.t()]
```

Returns ebin directories for runtime deps only (no dev-only tooling).
Used by `Deployer` so the filesystem push matches the dist push scope.

# `snapshot_beams`

```elixir
@spec snapshot_beams() :: %{required(String.t()) =&gt; non_neg_integer()}
```

Takes a snapshot of current BEAM mtimes for runtime deps only.
Pass the result to `push_changed/2` before and after compiling to get only
the modules that actually changed.

---

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