Metadata-Version: 2.4
Name: scriptvault
Version: 0.5.0
Summary: Store and run project commands in a hidden vault directory
Author: Majwt
License-Expression: MIT
Project-URL: Homepage, https://github.com/Majwt/ScriptVault
Project-URL: Repository, https://github.com/Majwt/ScriptVault
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: flake8>=7; extra == "dev"
Dynamic: license-file

# ScriptVault (`sv`)

Store and run project commands in a hidden vault directory.

`sv` keeps scripts, orchestrations, and environment files under a hidden `.sv/` directory so projects do not need a pile of top-level Makefile targets, shell scripts, or ad-hoc commands.

## Install

Requires Python 3.11+.

From PyPI:

```sh
pipx install scriptvault
```

From a checkout:

```sh
pipx install --editable .
```

For maintainers, `sv set-version 0.4.0` sets the version in `pyproject.toml`
and `src/scriptvault/__init__.py`. It uses the project environment created by
`sv build` and rejects invalid versions before changing either file.

## Quick start

Initialize a vault in a project directory:

```sh
sv init
```

Create a script:

```sh
sv add hello
```

Run it:

```sh
sv hello
# or
sv run hello
```

List targets:

```sh
sv list
```

Running `sv` with no arguments prints the usage and every runnable target.

## Vault layout

```text
.project/
  .sv/
    vault.toml
    .env
    GUIDE.md
    scripts/
      hello.sh
      hello.env
  includes/
    c-hello/
      .sv/
        vault.toml
        scripts/
          build.sh
```

- `vault.toml` defines inline scripts, orchestrations, and nested vault includes.
- `.env` is the global dotenv file.
- `GUIDE.md` is the generated reference (see [Guide](#guide)).
- `scripts/*.sh` are executable file scripts.
- `scripts/NAME.env` is the per-script dotenv file.
- `[include.NAME]` sections load scripts from nested vaults (see below).

### Nested Vaults

Include scripts from subdirectories:

```toml
[vault]
name = "myproject"

[include.c-hello]
path = "includes/c-hello/.sv/vault.toml"

[include.shell]
path = "includes/shell/.sv/vault.toml"
```

Run scripts with the include name prefix:

```bash
sv run c-hello build
sv c-hello build
```

or with the qualified `include:target` form, which names one include
explicitly (useful when two includes define the same target):

```bash
sv run c-hello:build
sv c-hello:build
```

Implied run (`sv deploy`) works for plain and qualified target names.

## Scripts

### File scripts

A file at `.sv/scripts/hello.sh` becomes `sv hello`.

```sh
#!/bin/sh
echo "Hello from $SV_NAME"
```

File-script metadata can be defined without `cmd`:

```toml
[scripts.hello]
description = "Print a greeting"
```

This requires a same-name script file in `.sv/scripts/`, such as `hello` or
`hello.sh`, with a shebang. Without a matching file, `cmd` is required.

Scripts and orchestrations accept either `desc` or `description`. If both are
set, `description` takes precedence. Descriptions are shown beside names in
`sv list`.

Listings use colors on supported terminals. Piped output, JSON, `TERM=dumb`,
and environments with `NO_COLOR` set remain plain.

On macOS/Linux, captured orchestration and parallel output uses a
pseudo-terminal (PTY) when the output terminal supports color, so child
commands retain their automatic colors. Stdin and signal handling remain
unchanged. Redirected output, `NO_COLOR`, `TERM=dumb`, Windows and unavailable
PTYs use normal pipes instead. Explicit force-color settings in child commands
still apply.

### Inline scripts

Define a command in `vault.toml`:

```toml
[scripts.hello]
cmd = "echo hello"
```

### Creating scripts

```sh
sv add hello
sv add hello --in < script.sh
```

### Local And Hidden Scripts

```sh
sv add personal --local
sv add personal --local --in < script.sh
sv run personal
sv list --all
```

Local scripts live in `.sv/local/scripts/`. `sv init` and `sv add --local`
ensure `.sv/.gitignore` ignores `/local/`, preserving existing ignore rules.
Local scripts appear in `sv list` by default; use `hidden = true` to hide
them. `.sv/local/scripts/NAME.env` supplies per-script environment variables.
Local and shared names must not
conflict. Gitignore rules do not untrack files already committed.

Shared helpers can also be hidden:

```toml
[scripts.helper]
hidden = true
cmd = "echo helper"
```

`hidden = true` also works for file-script metadata and orchestrations.
`sv list --all` reveals hidden targets, including with `--json` or `--nested`.
Hiding is a listing preference, not access control or secret protection.

### Source-Only Helpers

Put reusable shell helpers in `.sv/lib/`, outside the runnable script directory:

```bash
source "$SV_LIB/helper.sh"
source "$SV_TOP_LIB/git-version.sh"
```

`SV_LIB` points to the owning vault's library directory. `SV_TOP_LIB` points
to the outermost vault's library directory in the current execution chain.
If a nested vault is invoked on its own, both point to that nested vault's
library. These paths are injected even when the directories do not yet exist.
Helpers are not runnable targets and never appear in `sv list`, even with
`--all`. Sourcing keeps their functions and variables in the calling shell.

## Running targets

```sh
sv hello
sv run hello arg1 arg2
sv run hello -- --special-arg
```

Arguments after the target are passed to the script. Use `--` to pass a leading dash safely.

## Orchestrations

An orchestration is a named sequence of steps in `vault.toml`.

```toml
[orchestrate.ci]
steps = [
  { sh = "echo build" },
  { run = "hello" },
  { parallel = ["test", "lint"] },
]
```

Run it like any other target:

```sh
sv ci
```

Orchestrations can call scripts and other orchestrations. `sv` detects cycles and reports them.

## Interrupting runs

Scripts that run until `^C` (servers, watchers, `dotnet` HTTP apps) get the
interrupt directly: `sv` and its children share the terminal's process group,
and `sv` itself ignores the first `^C` so the script can shut down. `sv` then
exits with the script's exit code.

If the script hangs during shutdown, press `^C` a second time: `sv` kills every
child it started and exits with code 130. A `^C` while no script is running
also exits with 130.

```sh
sv serve        # first ^C: the server stops, sv waits and exits with its code
                # second ^C: sv kills the server and exits 130
```

## Environment

Environment files are dotenv-style `KEY=VALUE` files.

Precedence, from lowest to highest:

1. `.sv/.env`
2. `.sv/scripts/NAME.env`, or `.sv/local/scripts/NAME.env` for local scripts
3. The real environment
4. Injected `SV_*` variables

Injected variables:

- `SV_TOP_ROOT`: outermost vault's root directory in the execution chain
- `SV_TOP_LIB`: that outermost vault's `.sv/lib` directory
- `SV_ROOT`: root directory of the vault owning the current script or orchestration
- `SV_DIR`: that owning vault's `.sv` directory
- `SV_LIB`: that owning vault's `.sv/lib` directory
- `SV_CWD`: current working directory at invocation
- `SV_NAME`: target name, when running a named script

## Editing

Open the interactive target picker:

```sh
sv edit
```

`sv edit` uses `fzf` when available and stdin/stdout are a TTY; otherwise it falls back to a numbered prompt.

Edit a specific target:

```sh
sv edit hello
```

Edit a script's environment:

```sh
sv edit hello env
```

Edit a target's configuration in `vault.toml`:

```sh
sv edit hello config
```

Edit the global vault config or global env:

```sh
sv edit config
sv edit env
```

## Shell completion

Print a completion script for your shell:

```sh
sv completion bash
sv completion zsh
sv completion fish
```

Examples:

```sh
# bash
eval "$(sv completion bash)"
```

```sh
# zsh
eval "$(sv completion zsh)"
```

```sh
# fish
sv completion fish | source
```

## Help

```sh
sv            # usage plus every runnable target
sv help       # usage only
sv --version
```

## Guide

`sv init` writes `.sv/GUIDE.md`, a reference for scripts, orchestrations,
nested vaults, and environment injection. The guide is stamped with the sv
version that generated it:

```sh
sv guide          # rewrite it only when that stamp is older than this sv
sv guide --force  # rewrite it either way
```

## Documentation

For detailed guides and documentation:

- [Vault Activation](docs/VAULT_ACTIVATION.md) - How to activate specific vaults
- [Nested Vaults](docs/IMPLEMENTATION_SUMMARY.md) - Working with nested vaults
- [Completion Guide](docs/COMPLETION_REPORT.md) - Shell completion details

---

## Root Vault Activation

When running `sv` from any subdirectory, it automatically uses the root `.sv` directory.

See [Vault Activation](docs/VAULT_ACTIVATION.md) for detailed information.

## Orchestration with Nested Scripts

Orchestrations can reference scripts from included vaults.

See [Nested Vaults](docs/IMPLEMENTATION_SUMMARY.md) for examples.

## Shell Completion

Generate shell completion scripts:

```bash
# Auto-detect from SHELL environment variable
sv completion $shell | source

# Specify shell explicitly
sv completion bash | source
sv completion zsh | source
sv completion fish | source

# Use full path
sv completion /usr/bin/bash | source
```

See [Shell Completion](docs/COMPLETION_REPORT.md) for details.
