# 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`):
| `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
| `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`).