# GreenAsh

A keyboard-driven, green-screen LiveView console — reminiscent of AS/400-style
terminal screens — generated by **introspection** from your Ash resources.
Zero UI code.

## Prerequisites

An existing Phoenix + Ash project. Starting from scratch:

```bash
mix archive.install hex igniter_new
mix archive.install hex phx_new
mix igniter.new my_app --with phx.new --yes
cd my_app
mix igniter.install ash,ash_phoenix,ash_postgres --yes
```

(Two separate steps rather than one combined command: more reliable in
practice.) See Ash's own
[Getting Started guide](https://hexdocs.pm/ash/get-started.html) for details.

## Installation

With [Igniter](https://hexdocs.pm/igniter) (recommended — a single command):

```bash
mix igniter.install green_ash
```

This adds the dependency and patches your router. Nothing else to write.

> If you'd rather run `mix green_ash.install` directly (skipping
> `mix igniter.install`), your project must already have
> `{:igniter, "~> 0.5", only: [:dev, :test]}` in its own dependencies — Mix
> doesn't propagate a library's `only:` dependencies to its consumers.
> `mix igniter.install green_ash` takes care of that for you.

### Manually

If you'd rather not use Igniter, or want to see exactly what the installer does:

1. Add the dependency in `mix.exs`:

   ```elixir
   {:green_ash, "~> 0.3"}
   ```

2. Mount the console in your router, inside a scope going through the
   `:browser` pipeline (session required), and **behind a dev-only guard**:

   ```elixir
   if Application.compile_env(:my_app, :dev_routes) do
     import GreenAsh.Router

     scope "/" do
       pipe_through :browser
       green_ash "/cli"
     end
   end
   ```

> **Gate it. The console has no access control of its own.**
>
> It lists, creates, updates and deletes any record of any exposed resource,
> and its `:actor` command loads any record as the current actor to exercise
> your policies — that impersonation is the whole point of the tool. Reachable
> in production, it is an unauthenticated admin panel over your whole domain.
>
> The Igniter installer wraps the mount in the `:dev_routes` check above, which
> is why it is repeated here: mounting by hand is the one path where nothing
> stops the console shipping. If you need it somewhere other than dev, put it
> behind your own authentication pipeline.

That's it. `/cli` lists your Ash resources, and for each one: create,
list (filter + sort + pagination), business-action update/destroy (with
confirmation), record inspection, and a session-based "actor" for exercising
your policies — all derived by introspecting your actions.

Exposed domains are read **dynamically, on every request**, from
`Application.get_env(:my_app, :ash_domains, [])` — the same config key
`mix ash.setup`/`mix ash.codegen` already rely on. Add a new Ash domain later
(including via Ash's own generators, which maintain that config) and it shows
up immediately — no need to touch the router or re-run the installer.

Need to expose only a subset, or domains not registered under the standard
key? Pass `domains:` explicitly to override the default:

```elixir
green_ash "/cli", domains: [MyApp.Bank, MyApp.Sales]
```

Whichever you pass, keep the route behind the dev-only guard shown under
[Installation](#manually) — the console carries no access control of its own.

## Using the console

- Navigation: digits + Enter on menus, `j`/`k`/`Enter`/`Esc` in lists.
- Vim-style `:` command line: `:list <resource>`, `:new <resource>`,
  `:cols <field...>` (choose and order a list's columns; `:cols all` to
  restore), `:actor <resource> <id>` / `:actor none` (to exercise your
  policies), `:tenant <value>` / `:tenant none` (to browse multitenant
  resources), `:whoami`, `:debug` (raw inspection), `:menu`, `:help`.
- A list's filter, sort, columns and page live in the URL, so a screen can be
  bookmarked or pasted to someone else.

## Adding a resource

Any Ash resource declared in an exposed domain shows up on its own in `/cli`,
with no UI code. A few `description`s on the resource and its actions improve
the labels shown (optional).

## Developing the library

```bash
mix test        # no Postgres required: Ash.DataLayer.Ets harness
```

See `examples/bank/` and `examples/library/` (in the monorepo) for full
Postgres-backed examples.
