# Portable scripts via jan-cli
Move the incubator `scripts` collection between machines using a YAML spec bundle and the `jan` binary.
## Prerequisites (target machine)
- **`jan`** built or installed (`cargo install --path jan-cli` or copy a release binary).
- **`bash`** (all inlined runners use `bash -lc`).
- Interpreters and tools each script needs (`python3`, `git`, `docker`, `zsh`, `ffmpeg`, etc.) — the bundle does not install these.
- Optional: set `JAN_SPEC_DIR` and use `--spec-root scripts.spec.yaml` (or `JAN_SPEC` pointing at the entry file).
## Layout after import
Recommended install directory:
```text
~/.config/jan/scripts/
scripts.spec.yaml
generated/scripts/
scripts.yaml
git.yaml
…
env.sh # written by `jan bundle` or jan-install.sh
aliases.zsh # optional: from `jan alias -o aliases.zsh`
```
## Export (source machine)
From the monorepo, regenerate when `scripts/source` changes:
```bash
python3 jan-cli/scripts/generate_scripts_jan_spec.py
cd jan-cli
cargo build --release
./target/release/jan --spec-dir . --spec-root scripts.spec.yaml --no-log bundle -o ~/scripts-jan.zip
```
The zip contains all reachable YAML under the spec anchor plus `manifest.json` and `env.sh`.
## Import (target machine)
```bash
mkdir -p ~/.config/jan/scripts
unzip -o ~/scripts-jan.zip -d ~/.config/jan/scripts
# or: bash jan-cli/scripts/jan-install.sh ~/scripts-jan.zip
source ~/.config/jan/scripts/env.sh
jan scripts misc sum help
jan scripts misc sum run -- 1,2,3
```
Generate shell aliases (includes spec flags so `jan` finds the tree without extra env):
```bash
jan alias --spec-dir "$JAN_SPEC_DIR" --spec-root scripts.spec.yaml --shell zsh \
-o ~/.config/jan/scripts/aliases.zsh
source ~/.config/jan/scripts/aliases.zsh
sum 1,2,3
```
## Environment variables
| `JAN_SPEC_DIR` | Directory containing `scripts.spec.yaml` and `generated/` |
| `JAN_SPEC_ROOT` | Entry YAML file name (default `scripts.spec.yaml`) |
| `JAN_SPEC` | Alternative: absolute path to entry YAML (instead of dir + root) |
`env.sh` (shipped in bundles) sets `JAN_SPEC_DIR` and `JAN_SPEC_ROOT`.
## Regeneration
Do **not** hand-edit `jan-cli/generated/scripts/*.yaml`. Regenerate from source:
```bash
python3 jan-cli/scripts/generate_scripts_jan_spec.py
```
## Trust boundary
Bundles contain executable script source inlined in YAML. Only import bundles you trust. `manifest.json` lists file paths and SHA-256 hashes for verification.
## Known limitations
- Cross-script PATH dependencies are resolved only when listed in `script.meta.yaml` `dependencies`.
- Scripts that `source` files outside their directory (e.g. `$LIB_MACHINE_TYPES`) may still fail until metadata or layout is fixed.
- Zsh completions from the legacy `scripts/install.sh` flow are not included.