<!-- https://ouijit.com/docs/cli/ · rendered as Markdown for agents and LLMs -->

# CLI

Drive Ouijit from any terminal it spawns: tasks, hooks, scripts, tags, pull request drafts, themes, and panels, all from the shell.

## Where it lives

The `ouijit` command is auto-installed into every terminal Ouijit opens, host and sandboxed alike. It talks to the running app over a localhost API authenticated by a per-session token, so it only works from inside an Ouijit terminal.

## Output format

Every successful command writes a single JSON value to `stdout` and exits 0. Errors write `{"error": "..."}` to `stderr` and exit non-zero. Pipe to `jq` to extract fields:

```
ouijit task list | jq '.[] | select(.status == "in_progress") | .name'
```

## Project detection

The CLI detects the active project from your current directory by walking up to the nearest git root. Inside a worktree it follows the `.git` file back to the main repository. Override with `--project <path>`.

## Tasks

Statuses are `todo`, `in_progress`, `in_review`, and `done`.

```
ouijit task list                              # array of tasks
ouijit task get 5                             # single task
ouijit task current                           # task owning this terminal
ouijit task create "Fix login bug"
ouijit task create "Refactor auth" --prompt "Extract middleware"
ouijit task start 5                           # creates worktree, sets in_progress
ouijit task start 5 --branch custom-name
ouijit task start 5 --run-hook                # run the configured start hook, no dialog
ouijit task start 5 --skip-hook               # spawn the terminal, run no hook
ouijit task start 5 --hook-command "claude"   # one-off command instead of the configured hook
ouijit task create-and-start "Add 2FA"        # create + start in one step
ouijit task create-and-start "Add 2FA" --prompt "..." --branch custom --skip-hook
ouijit task spawn "Add 2FA"                   # alias for create-and-start
ouijit task set-status 5 in_review            # fires the review hook (dialog by default)
ouijit task set-status 5 in_review --run-hook # run the review hook, no dialog
ouijit task set-status 5 in_review --skip-hook
ouijit task set-status 5 done --hook-command "npm run deploy"
ouijit task bulk-set-status done 5 6 7        # set status on many in parallel
ouijit task set-name 5 "Better name"
ouijit task set-description 5 "More detail"
ouijit task set-merge-target 5 develop
ouijit task delete 5
```

`--run-hook`, `--skip-hook`, and `--hook-command` are mutually exclusive. By default, a status change opens that column's hook dialog in the GUI, just like dragging a card; use these flags for headless runs where no one is at the keyboard to dismiss it. They apply to `task start` and `create-and-start` (the start hook) and to `set-status` into `in_progress`, `in_review`, or `done` (the continue, review, and done hooks). `bulk-set-status` takes the same flags. Setting status to `todo` runs no hook and rejects these flags.

`ouijit task current` resolves the task owning the current terminal via the `OUIJIT_PTY_ID` env var that Ouijit sets on every spawn:

```
TASK=$(ouijit task current | jq -r .taskNumber)
ouijit task set-status "$TASK" in_review
```

## Hooks

Manage the [lifecycle hooks](https://ouijit.com/docs/hooks/) and the editor command. Hook types are `start`, `continue`, `run`, `review`, `done`, `editor`.

```
ouijit hook list
ouijit hook get start
ouijit hook set start --name "Install & agent" --command 'npm install && claude "$OUIJIT_TASK_DESCRIPTION"'
ouijit hook set run --name "Dev server" --command "npm run dev" --restart-if-running
ouijit hook delete done
```

`--restart-if-running` applies to the run hook only: relaunch instead of focusing an already-running instance.

## Tags

Tag tasks to [group and filter](https://ouijit.com/docs/terminals/) their terminals.

```
ouijit tag list                               # all tags across projects
ouijit tag list --task 5                      # tags on one task
ouijit tag add 5 bug
ouijit tag remove 5 bug
ouijit tag set 5 bug priority urgent          # replace all tags
```

## Scripts

Scripts are saved shell commands that show up in the [panel menu](https://ouijit.com/docs/panels/) and the CLI. Unlike hooks, they don't fire on lifecycle events.

```
ouijit script list
ouijit script set --name "Lint" --command "npm run lint"
ouijit script set --name "Dev" --command "npm run dev" --restart-if-running
ouijit script run Lint                        # by name
ouijit script run <id>                        # by id
ouijit script run Tests --task 5              # run inside task 5's worktree
ouijit script delete <id>
```

`script run` streams the command's output through your terminal and exits with the command's exit code. `script set` upserts by name, so re-running with the same `--name` updates that script.

## Pull requests

Inspect [pull requests](https://ouijit.com/docs/pull-requests/) and stage review drafts. Drafts stay local until the user sends the review from the app.

```
ouijit pr list                                # open PRs, grouped review/yours/others
ouijit pr view 42                             # one PR with threads, timeline, checks
ouijit pr link 42 --task 5                    # link a PR to a task
ouijit pr draft list 42
ouijit pr draft add 42 --file src/api.ts --line 88 --body "typo" --origin claude
ouijit pr draft add 42 --file src/api.ts --line 88 --body -   # body from stdin
ouijit pr draft add 42 --file src/api.ts --start-line 80 --line 88 --body "range"
ouijit pr draft discard 42 <draft-id>
```

`--body -` reads the body from stdin, the safe path for multi-line text. `--origin` names the author shown beside the draft. `--side` defaults to `RIGHT` (the new file); anchor comments to lines that appear as added lines in the diff.

## Markdown panels

Open markdown files as [panels](https://ouijit.com/docs/panels/) on a terminal. The pty id defaults to the current terminal.

```
ouijit markdown add ./plan.md                 # uses current OUIJIT_PTY_ID
ouijit markdown add ./plan.md pty_abc123      # explicit pty id
ouijit markdown list
ouijit markdown remove ./plan.md
```

## Web preview panels

```
ouijit preview add http://localhost:3000      # uses current OUIJIT_PTY_ID
ouijit preview add http://localhost:3000 pty_abc123
ouijit preview list
ouijit preview remove http://localhost:3000
```

## Themes

[Themes](https://ouijit.com/docs/themes/) are global, not project-scoped.

```
ouijit theme list                             # preference, presets, custom themes
ouijit theme use dracula
ouijit theme use system
ouijit theme save '{"id":"my-theme","name":"My Theme","base":"dark","tokens":{"--color-accent":"#ff2d55"}}'
ouijit theme save --file my-theme.json
ouijit theme delete my-theme
```

## Projects

```
ouijit project list                           # every project registered with the app
```

## Environment variables

Ouijit sets these on every terminal it spawns:

| Variable | What it is |
| --- | --- |
| `OUIJIT_API_URL` | Base URL for the local REST API the CLI talks to. |
| `OUIJIT_API_TOKEN` | Bearer token scoped to this terminal session. |
| `OUIJIT_PTY_ID` | Unique id for this terminal session. Used by `task current` and the panel commands (`markdown`, `preview`). |

Hooks get task context on top of these. See [Hooks → Hook environment](https://ouijit.com/docs/hooks/#hook-environment) for the `OUIJIT_TASK_*` variables.
