jan-cli 0.7.0

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

Summary of changes made in the development session (June 2026).

## Version

- Bumped to **0.2.0** (`Cargo.toml`, `CHANGELOG.md`)
- `cargo test`, `cargo clippy`, and `cargo package` pass

---

## 1. Script dependencies and external utilities

**Goal:** Let YAML script entries declare other scripts and external binaries required at run time.

**Spec fields** (on any `CommandNode`):

| Field | Purpose |
|-------|---------|
| `path` | Directory prepended to `PATH` when the script or a descendant `run` leaf executes |
| `dependencies` | Other script **names** in the spec whose `path` dirs are prepended first (transitive, cycle-checked) |
| `requires` | External binaries (`fzf`, `jq`, …) that must be on `PATH` before the leaf runs |

**Implementation:**

- New module: `src/deps.rs`
- `run_matched` in `src/lib.rs` resolves dependency dirs, checks `requires`, and sets `PATH` on the child process
- `scripts/generate_scripts_jan_spec.py` emits `path` for every script and copies `dependencies` / `requires` from `script.meta.yaml`
- Example metadata: `trackusage` → depends on `trackusage-impl`; `issue` → requires `gh`, `jq`, `fzf`; `fe` → requires `fzf`, `chafa`, `bat`

---

## 2. Environment variables via YAML

**Goal:** Pass environment variables to child processes from the spec.

**Spec field:** `env` — map of `KEY: value` on command nodes.

**Behavior:**

- Variables from every node along the matched chain are merged; deeper nodes override earlier keys
- Computed `PATH` (from `path` / `dependencies`) is applied after the chain’s `env` map
- Generator reads `env` from `script.meta.yaml`

---

## 3. Removed bundled embedded default spec

**Breaking change:** The binary no longer compiles in `default.spec.yaml` via `include_str!`.

**Removed:**

- `EMBEDDED_*` constants, `load_embedded_default_spec()`, embedded `LoadCtx` in `spec_load.rs`
- `default.spec.yaml` and `default/` from crate root (moved to `examples/`)

**Moved:**

- `default.spec.yaml``examples/default.spec.yaml`
- `default/``examples/default/`

---

## 4. Well-known spec directory

**Goal:** After `cargo install`, `jan` loads specs from disk instead of an embedded tree.

**Resolution priority:**

1. `--spec-dir` / `JAN_SPEC_DIR` + `--spec-root`
2. `--spec` / `JAN_SPEC`
3. `jan.yaml` or `jan.spec.yaml` in `--cwd`
4. Well-known directory: `~/.config/jan/scripts/` (override with `JAN_INSTALL_DIR`), entry `scripts.spec.yaml` or `jan.spec.yaml` (override with `JAN_SPEC_ROOT`)

**Implementation:**

- `well_known_spec_dir()` and `resolve_well_known_spec()` in `src/lib.rs`
- `runner.rs` calls well-known resolver when higher-priority sources miss
- Clear error messages when no spec is found

**State (unchanged):**

- Audit log: `~/.local/share/jan-cli/audit.db` (or `JAN_DB` / `--db`)

---

## 5. Built-ins and aliases

- Removed `jan://embedded` special cases from `bundle` and `alias` in `src/builtins.rs`
- `alias` always emits `--spec-dir` / `--spec-root` on generated aliases

---

## 6. Tests

**Added/updated:**

- `script_dependencies_prepended_to_path` — PATH from dependency scripts
- `requires_blocks_when_utility_missing`
- `env_vars_passed_to_child` — chain merge and override
- `well_known_spec_help_lists_commands``JAN_INSTALL_DIR`
- `well_known_spec_logs_spec_root` — audit log spec identity
- `examples_default_git_r_passthrough` — uses `examples/default.spec.yaml`
- Unit tests in `deps.rs` for transitive deps, cycles, env override

**Removed:** tests that depended on embedded default spec

---

## 7. Documentation

| File | Changes |
|------|---------|
| `README.md` | Full rewrite: installation, spec resolution, CLI reference, env vars, YAML format, script fields, audit log, `bundle`/`alias`, portable workflow, troubleshooting |
| `CHANGELOG.md` | Added 0.2.0 release notes |
| `docs/PORTABLE_SCRIPTS.md` | `JAN_INSTALL_DIR`, well-known dir as default after install |
| `project.meta.yaml` | Removed embedded-default feature; added package/publish scripts |
| `examples/demo.spec.yaml` | Sample `path` / `dependencies` / `requires` / `env` |
| `examples/default.spec.yaml` | Updated description (no longer “bundled”) |

---

## 8. Files touched (high level)

**Rust:** `src/lib.rs`, `src/deps.rs` (new), `src/runner.rs`, `src/spec_load.rs`, `src/builtins.rs`, `tests/cli_smoke.rs`

**Config / docs:** `Cargo.toml`, `CHANGELOG.md`, `README.md`, `project.meta.yaml`, `scripts.spec.yaml`, `docs/PORTABLE_SCRIPTS.md`

**Generator / metadata:** `scripts/generate_scripts_jan_spec.py`, `scripts/source/*/script.meta.yaml` (issue, fe, trackusage)

**Moved:** `default.spec.yaml`, `default/` → `examples/`

**Generated (regenerated):** `generated/scripts/*.yaml`

---

## Release checklist

```bash
cd jan-cli
cargo test
cargo clippy -- -D warnings
cargo package
cargo publish   # when ready
```

Users after `cargo install` must install a spec (bundle via `jan-install.sh`, copy `examples/`, or pass `--spec` / `--spec-dir`).