jan-cli 0.16.0

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

Move a personal `jan` command tree between machines using a YAML spec bundle and
the `jan` binary. The canonical personal tree lives under `dotfiles/jan` (flat
category YAML files). The `jan-cli` crate is the engine + install helper; it no
longer regenerates scripts from `Incubator/scripts`.

## Prerequisites (target machine)

- **`jan`** built or installed (`cargo install --path jan-cli` or copy a release binary).
- **`bash`** (inlined runners use `bash -lc`).
- **`python3`** for bundle structure, hash, and size verification plus confined extraction.
- Interpreters and tools each script needs (`git`, `docker`, `zsh`, `ffmpeg`, `deno`, etc.).
- After install: explicitly run **`jan use <install-dir>`**.

## Layout after import

Recommended install directory:

```text
~/.config/jan/scripts/
  scripts.spec.yaml
  scripts.yaml
  git.yaml
  …
  env.sh              # written by `jan bundle`
  aliases.zsh         # optional: from `jan alias -o aliases.zsh`
```

## Export (source machine)

Prefer the reviewed personal tree, then bundle:

```bash
jan use /path/to/dotfiles/jan
jan bundle -o ~/scripts-jan.zip
```

The zip contains all reachable YAML under the preferred directory plus
`manifest.json` and `env.sh`.

## Import (target machine)

```bash
bash jan-cli/scripts/jan-install.sh ~/scripts-jan.zip
# Review the extracted YAML before activating it.
jan use ~/.config/jan/scripts
jan --help
jan scripts misc sum help
jan scripts misc sum run -- 1,2,3
```

### Remote bundle prefer (no separate install script)

If the bundle is hosted over HTTPS and you know its SHA256:

```bash
jan use https://example.com/scripts-jan.zip --sha256 <64-hex>
# → downloads to ~/.cache/jan/objects/, verifies zip + manifest members,
#   unpacks under ~/.cache/jan/trees/<sha256>/, then prefers that tree
jan use --show
jan --help
```

Generate shell aliases (requires `jan use` already):

```bash
jan alias --shell zsh -o ~/.config/jan/scripts/aliases.zsh
source ~/.config/jan/scripts/aliases.zsh
sum 1,2,3
```

## Environment variables

| Variable | Purpose |
|----------|---------|
| `JAN_CONFIG_DIR` | Where `jan use` stores preference (default `~/.config/jan-cli`) |
| `JAN_INSTALL_DIR` | Default unpack directory for `jan-install.sh` (default `~/.config/jan/scripts`) |

`jan-install.sh` rejects absolute paths, `..`, symlinks, duplicate or unlisted
members, oversized archives, and manifest hash/size mismatches. It replaces the
target tree atomically and deliberately does **not** run `jan use`.

## Editing the personal tree

Edit YAML under `dotfiles/jan` directly. Do **not** run
`jan-cli/scripts/generate_scripts_jan_spec.py` — that helper has been retired
with the old `Incubator/scripts` project.

Useful built-ins over the preferred tree:

```bash
jan list
jan search --keyword git
jan show sum
jan validate
jan audit recent
```

## Trust boundary

Bundles contain executable script source inlined in YAML. Activating an
extracted tree with `jan use` lets that tree launch arbitrary programs with your
user account's permissions on every later `jan` invocation.

Only activate bundles from publishers you trust, and review the extracted YAML
before running `jan use`. `manifest.json` lets the installer detect corruption,
path tampering, and archive/manifest inconsistency. It is not signed and does
not authenticate the publisher or make malicious content safe. The installer
deliberately does not run `jan use`.

## Known limitations

- Cross-script PATH dependencies are resolved only when listed as `dependencies`
  on script nodes (and/or inlined into the runner).
- Scripts that `source` files outside their materialized temp dir may still fail
  until the missing helper is inlined.
- Legacy zsh completions from the removed `scripts/install.sh` flow are not
  included; prefer `jan alias` for shell convenience.