<!--
Sitemap:
- [Installation](/installation)
- [Upgrading](/upgrading): Version-specific steps for upgrading an existing Bento install.
- [Concepts](/concepts)
- [Build your first pipeline](/tutorials/pipeline-args)
- [Target a specific issue or PR from a URL](/tutorials/url-targeting)
- [Keep state across runs](/tutorials/pipeline-state)
- [Fire a pipeline on a schedule or on demand](/tutorials/schedule-and-fire)
- [Deploy a box to Railway](/tutorials/deploy-to-railway)
- [Operate a hosted daemon](/tutorials/operate-a-hosted-daemon)
- [Configuration](/configuration)
- [Members](/members)
- [Knowledge base](/knowledge-base/)
- [Method and delivery](/knowledge-base/modes)
- [Config](/knowledge-base/config)
- [MCP](/knowledge-base/mcp)
- [Pipeline configuration reference](/pipelines/config)
- [Filters](/pipelines/filters)
- [Triggers](/triggers/)
- [GitHub trigger](/triggers/github)
- [Linear trigger](/triggers/linear)
- [Webhook trigger](/triggers/webhook)
- [Schedule trigger](/triggers/schedule)
- [Manual trigger](/triggers/manual)
- [Traces](/pipelines/traces)
- [Slack](/integrations/slack)
- [Public access](/public-access)
- [Context engineering](/context-engineering)
- [Best practices](/best-practices)
- [Troubleshooting](/troubleshooting)
- [Architecture](/architecture/vision)
- [Workspaces](/workspaces)
- [Authentication](/authentication)
- [Identity](/identity)
- [Security](/security)
- [References](/references)
- [Changelog](/changelog): Bento release history.
- [CLI reference](/cli/)
- [Setup](/cli/setup)
- [Secrets](/cli/secrets)
- [Lifecycle](/cli/lifecycle)
- [Sandbox image](/cli/image)
- [Sandboxes](/cli/sandbox)
- [Observability](/cli/observability)
- [Diagnostics](/cli/diagnostics)
- [Triggers](/cli/triggers)
- [Workbench](/cli/workbench)
- [Auth](/cli/auth)
- [Knowledge](/cli/knowledge)
- [Evals](/cli/evals)
- [Bento](/index)
- [Runtime wrapper](/architecture/runtime-wrapper)
- [Skill evolve](/architecture/skill-evolve)
-->

# Manual trigger

You fire every configured pipeline on demand. There is no key to opt in:

```bash
bento trigger fire <pipeline-name>
```

A pipeline with an event trigger fires on demand too. Manual and event-triggered runs use the same dispatch path:

```yaml
trigger:
  github:
    - pull_request.opened
agent: reviewer
```

A pipeline that only ever runs on demand declares no `trigger` at all.

A fire persists a trigger of kind `manual`, whatever the pipeline declares.

## Example: smoke test on demand

`trigger` here carries only the repo to check out — nothing fires this pipeline automatically:

```yaml
name: smoke-tests
trigger:
  repo: acme/my-project
agent: solver
instructions: |
  Run the smoke tests and report pass/fail.
sandbox:
  backend: docker
```

```bash
bento trigger fire smoke-tests
```

## Typed inputs

A pipeline declares the inputs it accepts under `args:`. Each input has a `type` (`string`, `number`, or `boolean`), an optional `required` flag, and an optional `default`:

```yaml
name: manual-task
trigger:
  repo: acme/my-project
agent: editor
args:
  request:
    type: string
    required: true
  tone:
    type: string
    default: terse
instructions: |
  Process this request in a {{args.tone}} style:

  {{args.request}}
```

Pass inputs with repeatable `--arg key=value` flags:

```bash
bento trigger fire manual-task --arg request="review the latest changes"
```

Validated values substitute into `instructions` as `{{args.<name>}}`, a namespace distinct from the `{{event.*}}` webhook payload. Validation is strict. Bento rejects an undeclared key, a missing required input, and a wrong type, and a declared `default` fills an omitted input. A pipeline with no `args:` accepts no inputs. Targeting flags (`--branch`/`--sha`/`--pr`) are separate from `args` and never collide with a declared input.

You also map an input off the trigger with `from:`, a template rendered against `{{event.*}}` (the parsed payload) or `{{url.*}}` (`host`, `pathname`, `segments.N`, `query.X`). This is how a pasted URL targets a specific item with no daemon-side code — see [URL routing](#url-routing) below:

```yaml
args:
  issue:
    type: string
    default: ""                      # blank → the pipeline self-selects
    from: "{{event.issue.number}}"   # a pasted issue URL fills this
```

An explicit `--arg` overrides `from:`. An empty render falls back to `default`.

## URL routing

You also fire a pipeline by pasting a URL, with no pipeline name and no flags. Add `trigger.patterns`, a list of URL prefixes that route to the pipeline:

```yaml
name: pr-review
trigger:
  github:
    - pull_request.opened
  patterns:
    - https://github.com/acme/backend/pull
    - https://github.com/acme/frontend/pull
agent: reviewer
```

```bash
bento trigger fire https://github.com/acme/backend/pull/42
```

The URL prefix-matches the `patterns` of every pipeline to select one pipeline. The daemon then parses the URL into the same event a real webhook produces, so one pipeline serves every repository in its `patterns` list. The parser supports a GitHub **pull request** URL (`/pull/<n>`) and an **issue** URL (`/issues/<n>`). It builds the event the path describes: a `gh` lookup fills the head ref and the SHA of a pull request URL, and an issue resolves to the default branch of the repository.

Write `patterns` at the path granularity you want to route. A repository-level prefix such as `https://github.com/acme/backend` matches both pull request and issue URLs. That is correct while one pipeline owns the repository. When a pull-request-shaped and an issue-shaped pipeline share a repository, give them `…/pull` and `…/issues` patterns, so each shape routes to the right pipeline. Without that split, a URL matches both and raises the ambiguous error below.

`patterns` selects the pipeline. The URL's host selects the parser. Both extend independently.

A URL matching no pipeline's `patterns` is an error. A URL matching more than one is an error that lists them, not a fan-out across all of them.

To act on the *specific* item a URL names, map its identifier into an arg with `from:`. The url surface exposes both the parsed payload (`{{event.*}}`) and the raw URL parts (`{{url.host}}`, `{{url.pathname}}`, `{{url.segments.N}}`, `{{url.query.X}}`), so a pipeline targets off any URL shape:

```yaml
trigger:
  patterns:
    - https://github.com/acme/backend/issues
args:
  issue:
    type: string
    default: ""                      # blank (schedule/manual) → self-select
    from: "{{event.issue.number}}"   # pasted issue URL → that issue
instructions: |
  Target issue: {{args.issue}}
  If a target is given, solve exactly that issue; otherwise pick one yourself.
```

```bash
bento trigger fire https://github.com/acme/backend/issues/42   # solves #42
```
