mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
e1745db105
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_
131 lines
6.9 KiB
Markdown
131 lines
6.9 KiB
Markdown
+++
|
||
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"
|
||
}
|
||
}
|
||
```
|