# slash

An AI agent tool orchestration language. Commands are compact slash-expressions embedded in configuration files
(e.g., `settings.json`) and dispatched to self-contained Rust builtins by a `CommandRegistry`.

## Crates

| Crate | Description |
|-------|-------------|
| [`slash-lang`](crates/lang) | Lexer, parser, and AST |
| [`slash-lib`](crates/lib) | Executor, `CommandRegistry`, `SlashCommand` trait, and builtins |
| [`slash-cmd`](crates/cmd) | CLI binary (`slash`) |
| [`slash-testing`](crates/testing) | Proptest strategies and harness |

## Language Overview

Commands are whitespace-tokenized with no quoting, escaping, or variable expansion. Priority is inferred from
the **shape** of the command token. Urgency is a trailing suffix.

### Primary argument

```text
/read($FILE)
/exec(cargo build)
/write(out.txt).append(hello world)
```

### Builder-chain methods

```text
/deploy.env(prod).region(us-east-1)
/write(out.txt).append(line one)
```

### Priority (inferred from casing)

| Token shape | Priority |
|-------------|----------|
| `ALL_CAPS` | Max |
| `TitleCase` | High |
| `camelCase` | Medium |
| `kebab-case` / plain lowercase | Low |
| `snake_case` | Lowest |

### Urgency (trailing `!` suffix)

```text
/build!    # Low urgency
/build!!   # Medium urgency
/build!!!  # High urgency
```

### Optional commands and pipe context

`/cmd?` marks a command optional. When optional commands are piped together, their outputs accumulate into a
`Context` object (key = command name, value = `Option<String>`) passed as JSON to the first non-optional command.

```text
/fetch? | /validate? | /deploy
```

### Operators

```text
/build && /test          # run /test only if /build succeeds
/build || /fallback      # run /fallback only if /build fails
/generate | /format      # pipe stdout
/build |& /log           # pipe stdout + stderr
/build > out.txt         # redirect output (overwrite)
/build >> out.txt        # redirect output (append)
```

## Builtins

| Command | Description |
|---------|-------------|
| `/echo(text)` | Print text; `.text(val)` appends words |
| `/read($PATH)` | Read a file; resolves `$KEY` env vars |
| `/write(path).append(text)` | Write or append to a file |
| `/exec(shell cmd)` | Run a shell command, capture stdout |
| `/find(dir).name(pattern)` | Find files by name glob |
| `/obfsck(text)` | Redact secrets from text |

All commands are registered via the `SlashCommand` trait. Builder-chain methods are validated against each
command's declared `MethodDef` table before dispatch — unknown methods produce a clear error.

## Environment Variables

`$KEY` tokens in primary args are resolved at runtime. The registry loads `.slenv` (then `.env`) via
[dotenvy](https://crates.io/crates/dotenvy) on first use. If a key is not found in the env files,
[dotenvx](https://dotenvx.com/) is tried as a fallback for encrypted secrets.

```text
/read($CONFIG_PATH)
/exec($BUILD_CMD)
```

## CLI

```bash
# Execute a slash expression
slash '/echo.text(hello world)'

# Execute with automatic secret redaction
slash --redact '/exec(cat secrets.txt)'
```

## Usage (library)

```rust
use slash_lib::{parse, CommandRegistry};

let registry = CommandRegistry::default();
let output = registry.run("/echo.text(hello world)", None)?;
println!("{}", output.stdout);
```

## Building

```bash
cargo build --all-targets
cargo nextest run
cargo clippy --all-targets -- -D warnings
```

## License

Licensed under either of [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE) at your option.
