vibe-action 0.2.2

Command router — execute shell commands and LLM prompts via simple YAML actions.
# Tag System

Tags connect pipeline steps. When you write `{tag_name}` in an action, the engine replaces it with the output of the step that has `tag: tag_name`.

## The `{query}` Tag

There is one special, built-in tag: `{query}`. It does not require a corresponding `tag: query` step in your pipeline. Instead, the engine automatically resolves it from user input (CLI argument, clipboard, or IDE context).

```yaml
actions:
  - tag: tag_translate
    run: small
    expect: string
    action: |
      Translate to Russian:
      {query}
```

You can also use modifiers with `{query}`, such as `{query|file_path}` to validate it as a file path, or `{query|image}` to read an image. See [Query Tag](./query-tag.md) for details.

## Basic Example

```yaml
actions:
  - tag: tag_files
    run: cmd
    expect: list
    action: ls *.rs
  - tag: tag_summary
    run: small
    expect: string
    action: Summarize these files - {tag_files|join}
```

Step `tag_summary` depends on `tag_files`. The engine runs `tag_files` first, then passes its output to `tag_summary`.

The `|join` modifier collapses the list result into a single string — without it, `tag_summary` would execute once for each file in the list.

## Automatic Dependency Ordering

You don't need to write steps in execution order. The engine:

1. Scans all actions for `{tag}` references
2. Builds a directed acyclic graph (DAG)
3. Sorts topologically using Kahn's algorithm
4. Detects circular dependencies and reports errors

```yaml
actions:
  # These can be in any order — the engine sorts them:
  - tag: tag_commit
    run: cmd
    action: git commit -m '{tag_message}'
  - tag: tag_files
    run: cmd
    action: git diff --name-only
  - tag: tag_message
    run: small
    action: Write a commit message for: {tag_files}
```

Execution order: `tag_files` → `tag_message` → `tag_commit`

## List Expansion

When a step expects `string` or runs `cmd` but receives a list from a tag, the engine runs the action for each element:

```yaml
actions:
  - tag: tag_files
    run: cmd
    expect: list
    action: git diff --name-only
    # Returns: ["main.rs", "lib.rs"]
  - tag: tag_diff
    run: cmd
    expect: list
    action: git diff {tag_files}
    # Runs twice: git diff main.rs, git diff lib.rs
    # Returns: ["diff for main", "diff for lib"]
```

## Multiple Dependencies

A step can reference multiple tags:

```yaml
- tag: tag_report
  run: small
  expect: string
  action: |
    Compare these two files:
    File A: {tag_file_a}
    File B: {tag_file_b}
```

The engine waits for both `tag_file_a` and `tag_file_b` before running `tag_report`.

## Escaping Literals

Use `{{...}}` to include literal braces that should not be parsed as tags:

```yaml
- tag: tag_example
  run: value
  expect: string
  action: |
    To reference a tag, use {{tag_name}} syntax in your action.
    The modifier {{tag|upper}} transforms text to UPPERCASE.
```

## Circular Dependencies

Circular references are detected at startup and reported as errors:

```yaml
# ❌ This will fail validation:
- tag: tag_a
  action: echo {tag_b}
- tag: tag_b
  action: echo {tag_a}
```

```text
Error: Circular dependency detected involving tag: 'tag_a'
```

## Invalid Modifiers

Using a pipe `|` without specifying a modifier name (e.g., `{tag|}`) will cause a fatal validation error, and the pipeline will halt immediately.

Always ensure modifiers are properly named (e.g., `{tag|upper}`) or remove the pipe.