Files
max-sixty__worktrunk/docs/content/claude-code.md
Maximilian Roos e1745db105 feat(list): abbreviate the table's SHA with git, not a fixed slice (#3676)
The Commit cell sliced `&head[..8]` while `--format=json`'s `short_sha`
carried git's `%h`, so one commit read `1b9f1d96` in the table and
`1b9f1d9` in JSON, and `core.abbrev` reached only the JSON. #3675 gave a
detached row's Branch cell the same slice, so the disagreement showed up
twice on one row.

`ListItem::short_sha` becomes the only abbreviation of `head` anywhere:
the Commit cell, a detached row's Branch cell, the statusline, and JSON
all render it. `abbreviated_head()` is gone.

## Column widths

`COMMIT_HASH_WIDTH = 8` is gone. The Commit column and the Branch
column's detached budget both measure the SHAs they will render, so
`core.abbrev = 12` no longer truncates mid-hash and the default 7 stops
reserving a column nothing fills — the freed character goes to Message.

## Latency

`collect()` folds `%h` onto the rows before layout instead of after the
skeleton. The batch carrying it already gates the skeleton for `%ct`
sort order, so this is a map lookup rather than new I/O, and both cells
are identity columns with no placeholder — they still paint in the first
frame.

Measured on a 40-worktree / 400-branch fixture: git subprocess counts
are identical (5 pre-skeleton, 108 for the full run). Pre-skeleton wall
time is unchanged; running both binaries in each order, the sign of the
difference follows run order rather than the binary (+1.5 ms with this
branch second, −0.5 ms with it first), so the residual sits inside
drift.

## Behavior change

Where the commit-details batch fails, the Commit cell is now empty
rather than a slice of a SHA git refused. Age and Message already report
that failure the same way, under the same warning, and two snapshots
show it. `render_text_cell` also stops styling empty text, so a blank
cell no longer emits an escape pair around nothing.

## Reading the diff

160 files, but the hand-written part is +91/−79 in `src/commands/list/`
plus a +71 test. The rest is generated. The docs mirrors and help
snapshots are symmetric. Of the snapshot lines, content is +799/−799 —
every changed line a 1-for-1 hash swap — while +1396 is insta `env:`
metadata refreshing on the 128 snapshots this happens to touch.

`test_list_abbreviated_sha_follows_git` pins the invariant: the table's
hash equals JSON's `short_sha` at git's default and at `core.abbrev =
12`, and a longer prefix is ruled out. It fails against the old fixed
slice.

> _This was written by Claude Code on behalf of max-sixty_
2026-07-30 18:33:30 -07:00

131 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
+++
title = "Agent Integration"
description = "Worktrunk plugins for Claude Code, Codex, OpenCode, and Gemini CLI: a configuration skill, wt list activity tracking, and Claude-only worktree isolation."
weight = 23
[extra]
group = "Reference"
+++
Worktrunk ships a plugin for each supported agent CLI. What a plugin provides depends on the hooks that CLI exposes:
| Capability | Claude Code | Codex | OpenCode | Gemini CLI |
|---|:-:|:-:|:-:|:-:|
| Configuration skill | ✓ | ✓ | | ✓ |
| Activity tracking (🤖/💬 in `wt list`) | ✓ | ✓ | ✓ | ✓ |
| Worktree isolation | ✓ | | | |
| `/wt-switch-create` command | ✓ | | | |
The configuration skill is documentation the agent reads to help set up LLM commits, hooks, and troubleshooting. Activity tracking shows which worktrees have running sessions. Worktree isolation needs worktree-lifecycle hooks and `/wt-switch-create` needs session working-directory switching — both Claude Code-only, so Codex, OpenCode, and Gemini users invoke `wt switch --create` and `wt remove` directly. Codex tracks activity through its own `Stop` and `SessionEnd` hooks.
## Installation
### Claude Code
{{ terminal(cmd="wt config plugins claude install") }}
Manual equivalent:
{{ terminal(cmd="claude plugin marketplace add max-sixty/worktrunk|||claude plugin install worktrunk@worktrunk") }}
### Codex
{{ terminal(cmd="wt config plugins codex install") }}
This configures the Worktrunk marketplace in Codex. Then run `/plugins` in Codex and install Worktrunk from the marketplace. Manual equivalent:
{{ terminal(cmd="codex plugin marketplace add max-sixty/worktrunk") }}
To remove the marketplace entry, run `wt config plugins codex uninstall`. Already-installed plugins are left unchanged.
### OpenCode
{{ terminal(cmd="wt config plugins opencode install") }}
This writes the activity-tracking plugin to OpenCode's global plugins directory, `~/.config/opencode/plugins/worktrunk.ts` (honoring `$OPENCODE_CONFIG_DIR` and `$XDG_CONFIG_HOME`). `wt config plugins opencode uninstall` removes it.
### Gemini CLI
{{ terminal(cmd="gemini extensions install https://github.com/max-sixty/worktrunk") }}
Gemini loads the extension natively from the repository, so there is no `wt` wrapper. `gemini extensions uninstall worktrunk` removes it.
## Configuration skill
With the `/worktrunk` skill, the agent can help with:
- Setting up LLM-generated commit messages
- Adding project hooks (pre-start, pre-merge, pre-commit)
- Configuring worktree path templates
- Fixing shell integration issues
Claude Code is designed to load the skill automatically when it detects worktrunk-related questions.
## Activity tracking
The Claude Code, Codex, OpenCode, and Gemini plugins track agent sessions with status markers in `wt list`:
<!-- ⚠️ AUTO-GENERATED from tests/snapshots/integration__integration_tests__list__list_with_user_marker.snap — edit source to update -->
{% terminal(cmd="wt list") %}
<span class="cmd">wt list</span>
<b>Branch</b> <b>Status</b> <b>HEAD±</b> <b>main↕</b> <b>main…±</b> <b>Remote⇅</b> <b>Path</b> <b>Commit</b> <b>Age</b> <b>Message</b>
@ main <span class=d>^</span><span class=d>⇡</span> <span class=g>⇡1</span> . <span class=d>33323bc</span> <span class=d>1d</span> <span class=d>Initial commit</span>
+ feature-api <span class=d>↑</span> 🤖 <span class=g>↑1</span> <span class=g>+1</span> ../repo.feature-api <span class=d>70343f0</span> <span class=d>1d</span> <span class=d>Add REST API endpoints</span>
+ review-ui <span class=c>?</span> <span class=d>↑</span> 💬 <span class=g>↑1</span> <span class=g>+1</span> ../repo.review-ui <span class=d>a585d6e</span> <span class=d>1d</span> <span class=d>Add dashboard component</span>
+ wip-docs <span class=c>?</span> <span class=d>–</span> ../repo.wip-docs <span class=d>33323bc</span> <span class=d>1d</span> <span class=d>Initial commit</span>
<span class=d>○</span> <span class=d>Showing 4 worktrees, 2 with changes, 2 ahead</span>
{% end %}
<!-- END AUTO-GENERATED -->
- 🤖 — agent is working
- 💬 — agent is waiting or idle
All four plugins clear the marker when a session ends. A stale marker can remain if the agent process is killed before its session-end hook runs. In every case, `wt config state marker clear` removes a marker manually.
### Manual status markers
Set status markers manually for any workflow:
{% terminal() %}
<span class="cmd">wt config state marker set "🚧" # Current branch</span>
<span class="cmd">wt config state marker set "✅" --branch feature # Specific branch</span>
<span class="cmd">git config worktrunk.state.feature.marker '{"marker":"💬","set_at":0}' # Direct</span>
{% end %}
## Worktree isolation (Claude Code only)
Claude Code agents can run in isolated worktrees (`isolation: "worktree"`). By default, Claude Code creates these with `git worktree add`. The plugin's `WorktreeCreate` and `WorktreeRemove` hooks route this through `wt switch --create` and `wt remove` instead, so worktrees created by agents get worktrunk's naming conventions, hooks, and lifecycle management.
## `/wt-switch-create` command (Claude Code only)
`/wt-switch-create [<branch>] [<repo>] [-- <task>]` starts a task in a fresh worktree without leaving the session: it creates the worktree, switches into it, and runs the task (all arguments optional). The worktree shows up in `wt list`; merge or remove it with `wt merge` / `wt remove`.
## Statusline (Claude Code only)
`wt list statusline --format=claude-code` outputs a single-line status for the Claude Code statusline. Claude Code runs it in the background, which is what makes the occasional 1–2 second CI fetch invisible.
<code>~/w/myproject.feature-auth !🤖 @<span style='color:#0a0'>+42</span> <span style='color:#a00'>-8</span> <span style='color:#0a0'>↑3</span> <span style='color:#0a0'>⇡1</span> <span style='color:#0a0'>#3035</span> Opus 🌔 65% <span style='color:#a70'>1.4×(10am–3pm)</span></code>
Worktree state comes from the same cells [`wt list`](@/list.md) renders; Claude Code's stdin JSON adds the model, the `🌔 65%` context gauge, and the rate-limit pace notice. [`wt list statusline`](@/list.md#wt-list-statusline) documents every segment, how the links behave, and the JSON fields behind them.
<figure class="demo">
<picture>
<source srcset="/assets/docs/dark/wt-statusline.gif" media="(prefers-color-scheme: dark)">
<img src="/assets/docs/light/wt-statusline.gif" alt="Claude Code statusline demo" width="1600" height="900">
</picture>
</figure>
Add to `~/.claude/settings.json`:
```json
{
"statusLine": {
"type": "command",
"command": "wt list statusline --format=claude-code"
}
}
```