# Sidecar protocol

tratto's interface never runs Git itself. Every Git operation goes through **`tratto-sidecar`**, a separate Rust
program that the app starts and talks to over its standard input and output. The AI tools (`tratto-ai`) and the agent
view (`tratto-fleet`) are separate programs that speak the same line protocol.

This page is for the curious and for contributors; you never need it to use tratto.

## Lines

Every message is one JSON object on one line. The first line the sidecar writes says which protocol it speaks and
which Git it found:

```json
{"id":0,"ok":{"protocol":40,"git":"…","floor":true}}
```

## Requests and replies

A request carries a positive `id`, a `method` and its `params`; any other field is refused.

```json
{"id":1,"method":"open","params":{"path":"/home/me/src/tratto"}}
```

The reply has the same `id` and either `ok` or `error`. A long operation can send `event` lines (progress) before its
reply.

```json
{"id":1,"ok":{"repo":1,"worktree":"/home/me/src/tratto","git_dir":"/home/me/src/tratto/.git","bare":false,"object_format":"sha1","ref_storage":"files"}}
{"id":8,"error":{"code":"not_found","kind":"unknown_repository","detail":"no repository 1 is open"}}
```

## Who may ask for what

Every method is classed as a **read**, a **write**, a **destructive** write or a **human** one. A human method — changing
the Git configuration, trusting a directory, adding or editing a remote, creating a pull request, applying an image
compression — is accepted only as the answer to a person's click, never from an automated caller such as the copilot.

## Methods

| Methods | What they do |
|---|---|
| `open`, `close` | open or close a repository and get its handle |
| `log`, `count`, `find`, `merged` | a page of history, a count, a search, the commits a merge brought |
| `commit`, `patch`, `signature`, `changes`, `diff`, `sides` | a commit, its patch, its signature, its files, a diff, the two sides of an image |
| `status`, `stage`, `unstage`, `record` | the working copy, staging, committing (and amending) |
| `refs`, `switch`, `switch_detach`, `track`, `branch_create`, `branch_delete` | branches |
| `tag_create`, `tag_delete`, `tag_states`, `tag_push` | tags |
| `undo_commit`, `reset` | undo the last commit, reset a branch |
| `fetch`, `pull`, `push` | the network; `fetch` takes one `repo`, or `paths` and a `trigger` for a round over several |
| `merge`, `merge_abort`, `pick`, `pick_continue`, `pick_abort` | merge, cherry-pick, revert |
| `flow_state`, `flow_init`, `flow_start`, `flow_finish`, `flow_push` | Git Flow |
| `stash_list`, `stash_push`, `stash_apply`, `stash_pop`, `stash_drop` | stashes |
| `worktrees`, `worktree_add`, `worktree_lock`, `worktree_unlock`, `worktree_remove`, `worktree_prune` | worktrees |
| `submodules`, `submodule_update`, `submodule_sync`, `subtrees`, `subtree_add`, `subtree_pull`, `subtree_push` | submodules and subtrees |
| `remotes`, `remote_add`, `remote_set_url`, `remote_remove` | remotes |
| `review_plan`, `review_context`, `review_create` | pull and merge requests |
| `discard`, `trash_list`, `trash_restore` | discard into the Trash, and restore |
| `clone`, `init`, `predict`, `trust_directory` | clone, create, check a remote before cloning, `safe.directory` |
| `dir`, `file`, `paths`, `grep` | browse and search a working copy (the IDE module) |
| `cancel` | cancel a running request |

The contract is pinned by recorded transcripts in the repository, `crates/tratto-sidecar/tests/transcripts/`.
