jan-cli 0.19.0

YAML-defined CLI trees with progressive help, optional exec aliases, merged extra specs, and SQLite audit logging keyed by git branch
Documentation
# `jan config`

Emit shell fragments, symlink (or copy) rc files into `$HOME`, run imperative apply
steps, and check host tools declared as `config:` on command nodes.

```bash
jan config emit --shell zsh -o ~/.config/jan/config.zsh
jan config link
jan config unlink
jan config apply
jan config deps
```

| Subcommand | Description |
|------------|-------------|
| `emit` | Concatenate all `config.shell` fragments (tree walk order) |
| `link` | Place `config.link` files under `$HOME` (write inline bodies; symlink/copy path sources) |
| `unlink` | Remove destinations that still match managed path/inline content |
| `apply` | Run each `config.apply` argv list |
| `deps` | Report `config.deps` tools missing from `PATH` |

## YAML

```yaml
# config.yaml (index)
commands:
  zsh:
    include: config/zsh.yaml
  emacs:
    include: config/emacs.yaml

# config/zsh.yaml — shell fragment inlined on the node
about: zsh history and PATH
config:
  shell: |
    setopt AUTO_CD

# config/emacs.yaml — file body inlined (written by `jan config link`)
about: write init.el into ~/.emacs.d
config:
  link:
    ~/.emacs.d/init.el: |
      (message "hi")
    # or path form: ~/.other: config/other.el
    # or explicit:  ~/.x: { path: config/x } / { content: "…" }
```

| Field | Meaning |
|-------|---------|
| `shell:` (string) | Inline fragment (preferred for short/medium zsh snippets) |
| `shell.path` | File under the preferred jan directory |
| `link` | Map of destination → source. Dest must be absolute or `~/…` under `$HOME` (or `$XDG_CONFIG_HOME`). Value is inline body (`\|` / multiline), a relative path string, `{path: …}`, or `{content: …}`. |
| `apply` | List of argv arrays (no shell interpolation) |
| `deps` | Map of bare command name → optional package/install hint (empty/`~` = name only). Checked by `jan config deps`. |

Nodes may be config-only (no `run`). They appear in `--help` like alias-only nodes; opening a node that declares `config:` shows a **Host configuration (`jan config`)** section (shell path/inline, links, apply count, deps count). Existing `os:` filters still apply.

The node's `about` (or chain) labels each missing group in the `deps` report.

## Relation to `jan alias`

Do not merge schemas. `aliases:` is for typing less (`alias g=git`, extra jan names). `config:` is for host setup (sourced fragments, symlinks, `git config …`, host tool checklists). See [`alias.md`](alias.md).

## Flags

### `emit`

| Flag | Description |
|------|-------------|
| `--shell sh\|bash\|zsh` | Header dialect (default: `zsh`) |
| `-o`, `--output FILE` | Write to a file instead of stdout |

### `link`

| Flag | Description |
|------|-------------|
| `--dry-run` | Print planned links without changing the filesystem |
| `--copy` | Copy instead of symlink |
| `--force` | Replace an existing destination (default: warn and skip) |

If the destination path already exists, `jan config link` prints a warning to
stderr and skips that entry (exit 0). It does not overwrite unless `--force` is
passed. An existing symlink that already points at the intended source is treated
as done (`ok (already linked)`). Each run prints a summary:
`created / updated`, `already ok`, and `skipped (exists)`.

### `unlink`

| Flag | Description |
|------|-------------|
| `--dry-run` | Print planned removals without changing the filesystem |

Removes a destination only when it still matches the managed content (correct
symlink target, or file bytes equal to an inline body). Foreign or modified
files are skipped with a warning. Prints a summary of `removed`,
`already absent`, and `skipped (foreign)`.

### `apply`

| Flag | Description |
|------|-------------|
| `--dry-run` | Print argv lists without running them |

A non-zero child exit fails the whole `apply`.

### `deps`

| Flag | Description |
|------|-------------|
| `--strict` | Exit `1` if any listed tool is missing (default: exit `0` and still print the report) |

## Install pattern

Same idea as `jan alias`:

```bash
jan config emit --shell zsh -o ~/.config/jan/config.zsh
source ~/.config/jan/config.zsh
jan config link
jan config apply
jan config deps
```

`libbeagan_dependencies` (when emitted from the preferred tree) is a thin wrapper around `jan config deps`.

## Relation to Incubator/stow / GNU Stow

For `$HOME` rc placement, prefer `jan config link` / `unlink` (declarative
`config.link` in the preferred tree). The Incubator `stow` tool’s import/export
farm is largely superseded for that use case; keep it only if you need
import-from-live-files or non-home system path farms. GNU Stow’s package folding
is intentionally not mirrored here.