Skip to main content

README.md

# 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.1"}
   ```

2. Mount the console in your router, inside a scope going through the
   `:browser` pipeline (session required):

   ```elixir
   import GreenAsh.Router

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

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]
```

**Recommended**: keep the route dev-only (as the installer does), guarding it
with `if Application.compile_env(:my_app, :dev_routes) do ... end` — the
console lets you create/update/destroy records without your app's own
authentication, so it isn't a production admin panel.

## Using the console

- Navigation: digits + Enter on menus, `j`/`k`/`Enter`/`Esc` in lists.
- Vim-style `:` command line: `:list <resource>`, `:new <resource>`,
  `:actor <resource> <id>` / `:actor none` (to exercise your policies),
  `:whoami`, `:debug` (raw inspection), `:menu`, `:help`.

## 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.