4652 Commits

Author SHA1 Message Date
Maximilian Roos c1c70a7e39 docs(changelog): fold #3549 and #3539 into the 0.69.0 changelog (#3562)
> _This was written by Claude Code on behalf of max_
v0.69.0
2026-07-23 18:25:30 -07:00
Maximilian Roos 7b2e0705a1 Release v0.69.0 (#3559)
Highlights: clickable CI and dev-server-URL statusline segments in Claude Code (#3550), `wt merge --no-rebase` accepting merge-shaped fast-forward histories (#3509), a faster and lower-CPU `wt switch` picker (#3544, #3534), and SignPath code signing for the Windows release binary (#3553). Full details in CHANGELOG.md.

> _This was written by Claude Code on behalf of max_
2026-07-23 18:08:29 -07:00
Worktrunk Bot 784de4aacb skills(running-tend): nightly defers repo-wide CI breakage to tend-ci-fix (#3320)
## What

Adds a "Repo-Wide CI Breakage" note to the nightly reference
(`.claude/skills/running-tend/references/nightly-cleaner.md`): a failure
that reproduces identically on `main` and every PR belongs to
`tend-ci-fix`, which fires on any `ci`-workflow `failure` on `main`, and
a non-required job failing is enough to trigger it. It does not fire on
runs that end `cancelled`, so the nightly records the breakage in its
summary rather than assuming the handoff lands.

Also updates the `SKILL.md` reference index, which listed only "branch
naming" for a file covering three topics.

## Why

A nightly run shipped its sweep PR, then while polling that PR's CI
diagnosed an unrelated repo-wide `code-coverage` break and started a
second fix it did not finish, stranding the work on a pushed branch with
no PR. Two workflows chasing the same repo-wide break duplicate effort
and can produce conflicting PRs.

Which workflow owns that break is not derivable from the nightly's own
context, and it is documented nowhere else in the repo's skills (the
only other mention of ci-fix is a label description). That is the whole
of what this PR adds.

## What was cut, and why

Earlier revisions carried a session-budget rule as well: the session has
no room for a second deliverable, so ship one thing and stop. That
rested on a 3600s harness cap. The cap has been 10800s since tend 0.1.9
and becomes 21000s once the pending tend release lands, so the claim
does not hold at current durations, and its evidence was a single run.
Removed.

The routing advice also needed a correction rather than a restatement.
`tend-ci-fix` gates on `conclusion == 'failure'`
(`.github/workflows/tend-ci-fix.yaml:18`), so a `ci` run cancelled by
rapid pushes never triggers it. Presenting the handoff as reliable would
send a real breakage nowhere, so the note names the gap.

## Status of the breakage that prompted this

Resolved independently: `cache-apt-pkgs-action` no longer appears
anywhere under `.github/` on `main`, so the pin mismatch the nightly
diagnosed is gone. The orphan branch `fix/ci-cache-apt-pkgs-pin-sha` is
still on the remote and is now moot.

🤖 Generated by the tend review-runs workflow
([run](https://github.com/max-sixty/worktrunk/actions/runs/28361631224)),
revised since.

> _This was written by Claude Code on behalf of max_

---------

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Maximilian Roos <m@maxroos.com>
2026-07-23 16:42:45 -07:00
Maximilian Roos 9ecd7945e0 fix(merge): measure squash/rebase against the target's upstream, not a stale local ref (#3549)
Fixes #3519.

## The bug

`wt merge` resolves its target to the **local** default-branch ref and
squashes/rebases the span `merge-base(local-target, HEAD)..HEAD`. When
the primary checkout's local `main` is behind `origin/main` **and** the
branch descends from the newer `origin/main` tip (e.g. created with
`--base origin/main`), that merge-base falls back at the stale local
tip, so the span sweeps in every commit already on `origin/main`. The
squash folds them into a single commit and the local fast-forward lands
it — corrupting the primary checkout's `main` and, if that ref is later
pushed, duplicating already-upstream content under new SHAs. Reproduced
deterministically before fixing: a 1-commit feature off `origin/main`,
with local `main` two commits behind, squashed "3 commits" into a new
SHA on local `main` — matching the report.

The same mis-measured span reaches every rewrite entry point: a
standalone `wt step squash` folds the upstream commits into the *branch*
(the reporter's 1-commit PR becoming 13), and `wt step rebase` replays
them onto the stale ref when it fires.

## The fix: measure against the upstream; let the merge carry

One local-only predicate (no fetch — worktrunk is local-first),
`Repository::span_upstream`: the target's upstream, returned exactly
when the branch's history extends past the local target ref into it —
i.e. `merge-base(HEAD, upstream)` is not an ancestor of the local
target. The rewrite pipeline responds by *measuring* there instead of
guessing from the stale ref:

- **`wt step squash`** (and the squash inside `wt merge`) computes its
span, commit count, message, and `reset --soft` base against the
upstream — only the branch's own commits fold, and the target ref is
never touched. The `--dry-run`/`--show-prompt` previews use the same
base.
- **`wt step rebase`** (and the rebase inside `wt merge`) rebases *onto*
the upstream, so a non-linear branch replays only its own commits
instead of duplicating upstream ones onto the stale ref. In the plain
stale topology it no-ops, as before.
- **`wt merge`** announces the situation up front, then completes: the
fast-forward carries local `main` through the already-fetched upstream
commits by their real SHAs to the result — the same graph a fresh local
`main` would have produced:

  ```
○ Local main is 2 commits behind origin/main; the merge fast-forwards
through them
  ◎ Squashing 2 commits into a single commit (2 files, +2)...
  ✓ Squashed @ 3f2a91c
  ✓ Merged to main (3 commits, 3 files, +3)
  ```

The one refusal left is forced by topology rather than chosen by policy:
a target that has **diverged** from its upstream (its own commits *and*
behind, with the branch based past it) can never fast-forward in any
mode — reconciling the target's own commits is the user's call, so the
merge stops before any rewrite or approval prompt:

```
✗ Local main has diverged from origin/main — can't fast-forward to a branch based on origin/main
↳ Reconcile main with origin/main (rebase or merge its local commits), or specify a different target
```

This is the reporter's suggested direction ("use `origin/<default>` as
the merge/rebase target"), minus the network: the already-fetched
remote-tracking ref is the measurement base, and `wt merge` still never
touches the wire. It also extends the rule the rest of worktrunk already
applies — `IntegrationTargets` / the preview panes' comparison base
treat the upstream as the truth when the local default lags it; the
merge pipeline was the one mutating surface that didn't.

Quiet on everything that must keep working: a legitimately-diverged
local target with the branch forked from the shared base (the supported
offline workflow — existing regression test unchanged), targets with no
upstream, orphan branches, and explicit non-branch targets like `wt step
squash origin/main`.

## Tests

- `test_merge_carries_stale_local_main_through_upstream` — the #3519
topology end-to-end: merge succeeds, the carry is announced, the squash
folds only the branch's own commits and sits directly on the
`origin/main` tip, and `origin/main` is an ancestor of the merged `main`
(real SHAs, no duplication).
- `test_step_squash_measures_against_upstream_when_local_main_stale` —
the standalone squash folds only the branch's own commits and never
moves the target ref (this scenario previously corrupted `main` through
a squash-then-merge sequence).
- `test_step_rebase_targets_upstream_when_local_main_stale` — a branch
that merged `origin/main` in rebases onto the upstream: linearized, real
upstream SHAs retained, target ref untouched.
- `test_merge_refuses_diverged_target_when_branch_based_on_upstream` —
the forced refusal: nothing mutated, branch survives.
- `test_merge_removes_branch_when_local_main_diverged_from_upstream`
(legitimate divergence, branch from shared base) still passes — no
regression.

Docs: the merge help page (primary source in `src/cli/mod.rs`) describes
the upstream-aware measurement, the carry, and the diverged refusal;
generated mirrors and help snapshots regenerated.

> _This was written by Claude Code on behalf of Maximilian_

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 16:34:16 -07:00
Worktrunk Bot 3554f4979a fix(rebase): surface Ctrl-C during rebase as interrupt, not conflict (#3539)
Surfaced by the nightly code-quality survey; the fix layer was corrected
after review, and the review discussion then drove the `Interrupted`
rendering work (see below).

## Problem

When a `git rebase` child is killed by a signal (SIGINT/SIGTERM) but
leaves the worktree in `REBASING` state, `handle_rebase` classified the
failure by `worktree_state()` alone (now `REBASING`) and returned
`GitError::RebaseConflict`, printing conflict-resolution guidance and a
non-130 exit code instead of a clean interrupt. This violates the
signal-handling policy in `CLAUDE.md`: signal-derived child exits must
be detected via the structured signal channel **before** any other
classification.

The original attempt added an interrupt check to
`classify_rebase_failure`, but it was **inert on the real path**:
`handle_rebase` runs `repo.run_command(["rebase", …])`, which is
`Cmd::run()` capture mode. On failure that returns a `CommandError` (via
`from_failed_output`), never a `WorktrunkError::ChildProcessExited`, and
the interrupt detector only matched `ChildProcessExited`. Worse,
`from_failed_output` stored only `output.status.code()` (which is `None`
for a signal kill) and dropped `output.status.signal()` entirely, so the
signal number wasn't recoverable downstream at all.

A second problem fell out of the review discussion: every interrupt
classification funneled into `AlreadyDisplayed { exit_code: 128 + sig
}`, erasing the signal identity — so a SIGTERM-killed `wt` exited
**silently**. Because wt traps SIGINT/SIGTERM to forward them to
children, the shell never sees wt die and never prints its own
`Terminated` line, so the standard shell convention was suppressed with
nothing in its place. And an interrupt that left the worktree mid-rebase
said nothing about the `REBASING` state it left behind (git ran in
capture mode, so none of its output was ever shown).

## Fix

The capture layer preserves the signal:

- `CommandError` gains a `signal: Option<i32>` field, populated in
`from_failed_output` from `output.status.signal()` on Unix (`None`
elsewhere). A signal-killed child has no exit code, so the display
summary names the signal instead: `git rebase failed (signal 11)`.
- `ErrorExt::interrupt_signal()` (né `interrupt_exit_code()`) walks the
anyhow chain for a `CommandError` carrying SIGINT or SIGTERM, so it
works through `run_command`'s `.context("Failed to execute: git …")`
wrapper.

Only SIGINT/SIGTERM classify as interrupts in capture mode. Capture
children get no signal forwarding or escalation, so a death by any other
signal (SIGSEGV, an OOM SIGKILL) is never wt's own doing, and a silent
exit would discard the captured stderr the user never saw. Those stay on
the visible error path: mid-rebase, the `REBASING` state classifies them
as `RebaseConflict`, whose rendering carries the `--abort` hint;
otherwise `GitError::Other`. Stream mode's `ChildProcessExited` branch
counts any signal: its output already streamed to the terminal, and
user-initiated kills are normalized upstream to the originating
SIGINT/SIGTERM (the `seen_signal` branch in `shell_exec`, the concurrent
runner's originating-signal override).

Interrupt exits are now typed and announced. A new
`WorktrunkError::Interrupted { signal, hint }` replaces
`AlreadyDisplayed { exit_code: 128 + sig }` at every
interrupt-classification site (`handle_command_error`, `for_each`,
`classify_rebase_failure`, `run_custom`'s signal branch). It still exits
`128 + signal`, but renders once, at exit, per shell convention:

- **SIGINT**: silent — the terminal already echoed `^C`, and shells
print nothing for an interrupted job.
- **SIGTERM**: `✗ Terminated` — the line the shell would have printed
had wt not trapped the signal.
- **Any other signal** (reachable from stream mode): `✗ Killed by signal
N`.

`hint` carries an optional recovery line rendered under the message.
`classify_rebase_failure` uses it for the state an interrupt leaves
behind:

```
◎ Rebasing onto main...
✗ Terminated
↳ Rebase onto main left in progress; to abort, run git rebase --abort
```

(For SIGINT the hint stands alone under the user's own `^C`.)

## Reachability caveat

The common terminal Ctrl-C case is subtler than the original description
implied: on paths where wt has not installed its signal handler, a
terminal Ctrl-C is delivered to the whole foreground group and
terminates `wt` itself at 130 before classification runs. The
capture-mode fix is reachable, and correct, when the signal reaches only
the `git` child while `wt` survives (e.g. within `wt merge` after the
handler is installed, a targeted kill, or a supervisor signalling the
child), and it also closes the latent, broader gap where capture-mode
signal deaths were classified without consulting the structured signal
channel at all.

## Tests

- `capture_mode_interrupt_is_not_classified_as_conflict` feeds
`classify_rebase_failure` the real `CommandError`-with-signal shape
(wrapped in the `.context(...)` layer `run_command` adds) and asserts
`Interrupted { signal: 2, hint: Some(…) }` with the `git rebase --abort`
hint, not `RebaseConflict`.
- `capture_mode_crash_signal_stays_a_visible_error` asserts a SIGSEGV
death mid-rebase classifies as `RebaseConflict` and a SIGKILL death
outside `REBASING` as `Other`, never a silent interrupt.
- `interrupt_signal_capture_mode_narrows_to_sigint_sigterm` pins the
capture-mode signal set: 2 and 15 classify, 9 and 11 don't.
- `from_failed_output_preserves_signal_and_interrupt_signal_recovers_it`
pins the capture layer directly: a signal-killed `Output` yields
`signal: Some(2)` / `exit_code: None`, recovered through a
`.context(...)` wrapper.
- `interrupted_renders_by_signal_and_exits_128_plus_signal` pins the
exit-time rendering: silent SIGINT, `✗ Terminated` for SIGTERM, `✗
Killed by signal 9` otherwise, hint placement, and the `128 + signal`
exit codes.
- `test_interrupt_signal` covers the stream-mode channel plus
idempotence (an `Interrupted` error re-checked by an outer loop stays an
interrupt).
- Existing integration tests drive the paths end-to-end:
`test_pre_merge_pipeline_aborts_on_signal_exit` (hook pipeline),
`test_for_each_aborts_on_signal_exit` (worktree loop),
`run_custom_propagates_signal_exit_code` (custom subcommands) — all now
flowing through `Interrupted`.

---------

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
Co-authored-by: Maximilian Roos <m@maxroos.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:16:41 -07:00
Maximilian Roos 8f55d15301 fix(release): preserve signed Windows zip filename, match checksum format (#3556)
## Summary
- The SignPath action's `skip-decompress` defaults to `false`, so it
would have extracted the returned zip's contents as loose files into
`target/distrib/` instead of saving back a signed
`worktrunk-x86_64-pc-windows-msvc.zip`. The checksum step would have
silently hashed the still-unsigned zip, and the release would have
shipped unsigned Windows binaries with no CI failure to flag it.
- `sha256sum` without `-b` omits the `*` binary-mode marker;
cargo-dist's own checksums use `<hash> *<filename>` (confirmed against a
real release asset). Added `-b` to match.

Confirmed via `gh run view` on #3553's own CI run that
`build-local-artifacts` is skipped on PRs in this repo, so this code
path has never actually executed — this is the first real fix before it
runs for real on a tagged release.

## Test plan
- [x] `actionlint .github/workflows/release.yaml` — no new warnings
(same pre-existing shellcheck style notes as before)
- [x] Verified `skip-decompress` behavior against the action's own
`action.yml` input spec
- [x] Verified checksum format against a real downloaded release asset
(`v0.68.0`)

> _This was written by Claude Code on behalf of Max_
2026-07-23 16:13:30 -07:00
Maximilian Roos 14d4d92532 feat(statusline): make the CI and URL segments clickable in Claude Code (#3550)
The statusline suppressed OSC 8 hyperlinks in Claude Code mode, so its
CI segment was colored but not clickable and its dev-server URL printed
in full. Claude Code renders OSC 8, so both segments now link the way
they already do in `wt list`.

```
 ~/w/worktrunk.statusline-osc8-hyperlinks  ↕|🤖  ↑2 ↓1  ^+93 -24  #3550  :17913  Opus 4.8
                                                                   └link┘  └link┘
```

## Why it was off

The gate dated from 2026-01-02, inside Claude Code's OSC 8 regression
window — links worked through 2.0.76, broke around 2.1.3, and got a
partial IDE-terminal-only fix in 2.1.42
([anthropics/claude-code#26356](https://github.com/anthropics/claude-code/issues/26356)).
The premise was correct when written and has since expired; that issue
was auto-closed for inactivity rather than on a fix, so the tracker
understates current support.

## Verification

PTY-captured the raw byte stream from Claude Code 2.1.218, with
`TERM_PROGRAM`/`VSCODE_*` stripped so it exercises the
standalone-terminal path that was reported broken. Claude Code doesn't
strip or blindly pass through — it parses OSC 8 into its frame model,
assigns a hyperlink id, and re-emits canonically (normalizing an ST
terminator to BEL):

```
PRE ESC]8;id=1l7bqdh;https://example.com/ST-PROBE BEL STLINKTEXT ESC]8;; BEL  MID …
```

It holds in both the normal and alt-screen (`CLAUDE_CODE_NO_FLICKER=1`)
render paths, with `FORCE_HYPERLINK` unset. Driving the real `wt` binary
through Claude Code end to end yields both links live:

```
LINK: https://github.com/max-sixty/worktrunk/pull/3550
LINK: http://127.0.0.1:17913
```

Degradation is graceful: a terminal or multiplexer that drops OSC 8
shows the same text, just not clickable (tmux only gained OSC 8 in 3.4;
zellij and Alacritty support it).

## Shape of the change

With links unconditional for the statusline, the plumbed `include_links`
flag had one value, so it collapses into the segment builder.
`format_url_cell` likewise takes the link decision from its caller
rather than probing the terminal, matching `PrStatus::format_cell` — the
statusline's stdout is a pipe, so `supports_hyperlinks` reports false
there even though the consumer renders OSC 8. That left
`hyperlink_stdout` with no callers, so it goes.

`format_cell` keeps its `include_link` parameter: `wt list` passes the
terminal probe, and the picker passes `false` because a `--prs` row
never reaches the strip path.

`format_url_cell` moved next to `estimate_url_width`, which budgets the
column against it — the two have to agree on when a cell collapses to
`:port` and were in separate files.

The URL segment also gets shorter: the URL rides inside the escape
sequence, so `http://127.0.0.1:17913` becomes `:17913`, returning 16
columns on a line that budgets by width.

## Safety of the truncation interaction

`truncate_visible` ends its cut with `\e[0m`, which resets colour but
leaves an OSC 8 link *open* — a severed link would make the rest of the
terminal line clickable, and `ansi_cut` really will sever one if
reached.

It can't be reached, because the two cuts never meet: `fit_to_width`
drops whole segments worst-priority-first and stops at one, so character
truncation only ever lands on a best-priority survivor — Directory (0),
Branch or Model (1) — none of which carry escapes beyond SGR. Every
link-bearing segment is strictly worse (CI 5, URL 9), so each is dropped
entire first.

Reviewing the branch turned up that the numbered comments in
`format_statusline_segments` had drifted from `COLUMN_SPECS` — CI was
labelled 9 (it is 5) and the URL 8 (it is 9), with branch-diff and
upstream also off — and the first version of the test had taken those
stale numbers as its specification. The comments are corrected and the
test now rests on the invariant above, which doesn't depend on where CI
sits. It sweeps widths 1–90 over both links, asserts it spans every drop
stage, and pins that the URL goes before CI.

A second test pins that the hidden URL costs no visible width
(`ansi_strip` drops OSC 8 for both terminators), so priority budgeting
isn't inflated.

## Docs

The Claude Code statusline page now says the segments are clickable —
it's the feature's own page and said nothing about it. The `wt list
--help` JSON field description gains the links but stays short: an
earlier, longer wording shrank the help table's Field column and wrapped
two dozen unrelated rows.

## One judgement call worth flagging

`format_statusline_segments` also feeds plain `wt list statusline`
(shell prompts) and the JSON `statusline` field. The CI link was already
unconditional on both before this change; what's new is that the URL
cell renders as a linked `:3000` rather than the full URL, so a consumer
that strips OSC 8 sees only `:3000`. The structured `url` /
`dev_server.url` field still carries the full URL, and `:3000` still
answers "which port", so this reads as the right trade — but it is the
one place the collapse to a constant reaches a renderer that isn't
Claude Code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

> _This was written by Claude Code on behalf of max_

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 14:20:01 -07:00
Worktrunk Bot 72ae751241 docs: correct stale comments (list layout, repository caching spec, zsh probe trace) (#3540)
Stale code comments surfaced by the nightly code-quality survey.
Documentation-only — no behavior change, no test needed.

Three corrections where a comment no longer matched the code it
describes:

- **`src/commands/list/layout.rs`** (two sites) — the Message column's
width bounds are `MIN_MESSAGE = 10` / `MAX_MESSAGE = 100`, but the
allocation pseudo-code comment said "min 20, preferred 50" and the
`calculate_layout_with_width` docstring said "flexible (20-100 chars)".
Both now read 10–100, matching the constants and the authoritative prose
earlier in the same file ("minimum width 10 … expands up to max 100").

- **`src/git/repository/mod.rs`** — the `# Caching` system spec drifted
from the code in three ways: (1) it listed only four process-wide
statics and claimed all were "keyed by canonicalized filesystem path",
but `GIT_COMMON_DIR_CACHE` is keyed by the *raw* discovery path (its own
doc: "Keys are stored as-is"); (2) it omitted two real process-wide
caches of external state, `GIT_CONFIG_PRELOAD` and
`WORKTRUNK_USER_CONFIG_PRELOAD`, both populated by `prewarm` and
consumed by `at()`; (3) the invariants "a cached value … is never
updated within the same command" and "all cache access is lock-free at
the call site" are contradicted by `all_config` being
`OnceCell<RwLock<..>>` — its contents are mutated via `set_config_value`
and read under an explicit lock in `config_last`. The spec now groups
the statics by their actual keying and carves out the `all_config`
exception.

- **`src/shell/utils.rs`** — the zsh compinit-probe trace logged `$ zsh
-ic '…'`, but the invocation is `zsh +m -ic …` (`ZSH_PROBE_FLAGS`). The
`+m` flag is load-bearing (issue #3322 — it prevents the interactive
probe from grabbing wt's controlling terminal), so omitting it from the
trace would mislead anyone copying the logged command to reproduce.

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
Co-authored-by: Maximilian Roos <m@maxroos.com>
2026-07-23 12:57:15 -07:00
Maximilian Roos 5f8c301dec feat(release): sign Windows binaries via SignPath (#3553)
## Summary
- Signs the Windows release zip (`wt.exe` + `git-wt.exe`) via
[SignPath](https://signpath.io)'s free OSS code-signing program, using
the `test-signing` policy (self-signed test certificate) while the
project's Foundation-program application is under review.
- Non-blocking (`continue-on-error`) so a signing hiccup can't take down
crates.io/homebrew/winget/AUR publishing.
- Recomputes the `.sha256` checksum after signing, since the signed
zip's bytes differ from the unsigned one.
- Uses a dedicated low-privilege `CI builds` SignPath identity
(submitter-only), not an admin account.

## Test plan
- [x] `actionlint` clean (only pre-existing shellcheck style warnings
elsewhere in the file)
- [x] Artifact configuration (zip containing `wt.exe` + `git-wt.exe`)
validated against SignPath's own XML parser and against the real file
layout inside a downloaded `v0.68.0` Windows release zip
- [ ] First real Windows build after merge will be the first live
signing round-trip through GitHub Actions — watch that release's CI run

> _This was written by Claude Code on behalf of Max_

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 12:19:32 -07:00
Maximilian Roos a3de0b0db6 fix: exempt the foreground thread from the command semaphore (#3544)
Accepting a row in the `wt switch` picker could stall for ~10s on a
large repo — and indefinitely under sustained background traffic —
before the switch began. Every `Cmd::run` acquires the global 32-permit
command semaphore, so the accept path's first command queued behind the
picker's per-row preview diffs, which on a 38-worktree rust-lang/rust
fixture each held a permit for ~14s (trace: Enter at t=4.3s, first
switch command spawned at t=14.3s, all of it inside
`semaphore().acquire()`). Since permits go to an arbitrary waiter
(`Condvar::notify_one`), the foreground can also lose every race while
background tasks keep replenishing the queue.

The foreground thread — the one that enters `main()` — now bypasses the
semaphore in `run` and `pipe_into`. It executes commands one at a time,
so it can't contribute to the fan-out the semaphore exists to bound, and
it's what the user is waiting on. `stream`/`delayed_stream` already
followed this rule; background pool tasks keep the full 32-permit cap.
The cap was already approximate (rayon work-stealing can run a capped
closure on the calling thread), so no permits are reserved.

Verified with a PTY driver against a repo whose `git` shim sleeps 15s on
`diff`, with `WORKTRUNK_MAX_CONCURRENT_COMMANDS=2`: accept-to-exit was
>100s before (killed) and 0.08s after; a control run of the unfixed
binary with an unsaturated cap also exits in 0.08s, isolating the
semaphore as the cause. A unit test covers the exemption (initializing
thread exempt, spawned threads capped).

> _This was written by Claude Code on behalf of max_

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 13:46:24 -07:00
Maximilian Roos a7c4a7a120 refactor(wt-perf): place fixtures under target/wt-perf, not the cache dir (#3547)
## What

Move every `wt-perf` on-disk fixture out of the per-user cache dir and
under the cargo target dir at `<target>/wt-perf/`, resolved by a renamed
`wt_perf_fixture_dir()`:

- `setup <config>` fixtures → `<target>/wt-perf/<config>` (was
`~/.cache/wt-perf/<config>`).
- The rust-lang/rust clone and `prune-real` fixtures →
`<target>/wt-perf/bench-repos/` (was `~/.cache/wt-perf/bench-repos/`).
- `wt_perf_cache_dir()` → `wt_perf_fixture_dir()`. The target dir is
derived from the **running executable's own path** (it lives inside
whichever dir cargo built into — `<target>/debug/wt-perf`,
`<target>/release/deps/<bench>`), so it honors `CARGO_TARGET_DIR`, a
config-file `build.target-dir`, and cargo-llvm-cov's
`target/llvm-cov-target/` — none of which a bare `CARGO_TARGET_DIR` env
read covers. Falls back to `<workspace>/target` if the binary isn't
under a recognizable profile dir. The `etcetera` dependency is dropped.
- The `WT_PERF_CACHE_DIR` env override (and the empty-value guard it
required) is removed; the benchmarks workflow now caches the
deterministic `target/wt-perf/bench-repos` path directly.
- In-process throwaway fixtures (`create_repo`) are unchanged — they
keep using `tempfile::TempDir`.

This reverses the location decision from #3542, which had moved these
into `~/.cache/wt-perf`.

## Why

`target/` is the conventional home for build/test-generated artifacts —
gitignored, reaped by `cargo clean`, and already where criterion writes
(`target/criterion`). Keeping every wt-perf fixture there gives one
predictable location under the repo that `cargo clean` fully resets.
Deriving the target dir from the running binary (rather than assuming
`<workspace>/target`) keeps that property intact even when the target
dir is relocated.

## Tradeoff (accepted)

`target/` is **not** shared across git worktrees (worktrees don't share
it) and is wiped by `cargo clean`. So the ~15 GiB `prune-real` rust
clone re-clones per worktree and after every `cargo clean` — the cost
#3542 avoided by using the cache dir. This is deliberate and documented
on `wt_perf_fixture_dir`; it's cheap for the synthetic `setup` fixtures,
which rebuild in seconds.

## Testing

- `cargo build -p wt-perf --all-targets`, `cargo test -p wt-perf` —
clean.
- New unit test `target_dir_from_exe_finds_cargo_target` covers the
resolution logic (relocated `CARGO_TARGET_DIR`, bench binary under
`release/deps/`, cargo-llvm-cov's nested target, closest-profile-wins,
and the outside-any-target fallback).
- `pre-commit run --all-files` (fmt, clippy, yaml, typos, cargo-lock,
custom hooks) — clean.
- Smoke-tested end-to-end: `setup branches-2` lands at
`<worktree>/target/wt-perf/branches-2` and writes nothing to
`~/.cache/`; a copy of the binary run from a fake `<dir>/debug/wt-perf`
correctly resolves fixtures to `<dir>/wt-perf/`, proving a relocated
target dir is honored.

> _This was written by Claude Code on behalf of Maximilian_

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 13:44:50 -07:00
Maximilian Roos f14fa69c0e feat(list): run merge analysis in a read-only object database (#3535)
When the Git object database is read-only, `wt list` and `wt list statusline` redirect their object-writing merge/conflict probes (write-tree, commit-tree, merge-tree --write-tree) into a temporary object database with the real one as a read-only alternate, so the full analysis runs in a managed read-only sandbox. Detection is a one-time writability probe; the writable path is unchanged. Scoped to the two observational list entry points (collect and populate_item); mutating commands keep the persistent database and fail loudly on a read-only store.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 11:14:20 -07:00
Worktrunk Bot dbefb98ed4 fix(plugin): add pipefail to WorktreeCreate hook so wt failures surface (#3546)
## Problem

The Claude plugin's `WorktreeCreate` hook
(`plugins/worktrunk/hooks/hooks.json`) pipes the `wt` result straight
into `jq`:

```
bash -c 'name=$(jq -er .name) || exit 1; cd "${CLAUDE_PROJECT_DIR:-.}" || exit 1; bash "$CLAUDE_PLUGIN_ROOT/hooks/wt.sh" switch --create "$name" --no-cd --format=json | jq -er .path'
```

Without `set -o pipefail`, the pipeline's exit status is `jq`'s, not
`wt`'s. On jq 1.6, `jq -er .path` exits **0** on the empty stdout of a
failed `wt`:

```console
$ printf '' | jq -er .path; echo $?   # jq 1.6
0
```

So when `wt switch --create` dies (e.g. an existing-branch collision
after the branch/worktree were already created by an earlier partial
run), the hook "succeeds" while printing nothing. Claude Code then
reports the misleading `WorktreeCreate hook failed: hook succeeded but
returned no worktree path` instead of `wt`'s real stderr — as reported
in #3545.

The project's own `skills/wt-switch-create/rationale.md` already
documents the `bash -c 'set -o pipefail; …'` wrapper as the intended
design ("The hooks.json pipefail wrapper"), but the command in
`hooks.json` never actually carried it. This PR brings the code in line
with its own documentation.

## Solution

Prefix the existing `bash -c` command with `set -o pipefail;`. The
wrapper is already `bash -c`, so this is safe — dash rejects `set -o
pipefail` fatally, which is precisely why the `bash -c` wrapper (rather
than the login shell) exists per the rationale. With pipefail, the
pipeline surfaces `wt`'s nonzero exit regardless of jq version.

## Testing

Added a reproduction assertion to `test_plugin_layout_is_consolidated`
(`tests/integration_tests/config_show.rs`) that fails when the
`WorktreeCreate` hook command lacks `set -o pipefail` — it fails on the
pre-fix `hooks.json` and passes after. Also verified the pipeline shape
directly:

```console
$ bash -c 'set -o pipefail; (echo "✗ Branch foo already exists" >&2; exit 1) | jq -er .path'; echo $?
✗ Branch foo already exists
4                       # nonzero -> hook correctly fails, wt's stderr shown
$ bash -c 'set -o pipefail; echo "{\"path\":\"/tmp/wt/foo\"}" | jq -er .path'; echo $?
/tmp/wt/foo
0                       # success path unchanged
```

The `bash -c '…'` body stays single-quoted, so
`test_claude_hook_commands_parse_in_all_shells` (login-shell parse
check) is unaffected — the outer shells never look inside the quotes.

---
Closes #3545 — automated triage

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
2026-07-22 11:07:12 -07:00
Maximilian Roos e47132966b fix(picker): stop burning a core while background collect is pending (#3534)
`wt switch` burned ~100% of one core whenever the picker looked idle but
background collect work was still pending: a slow CI fetch, or an LLM
branch summary (`[list] summary = true` with a `commit.generation`
command). skim's reader polls its item channel with kanal's
`recv_timeout(1ms)`, and kanal's timeout wait yields in a loop instead
of parking, so an open-but-empty channel spins a full core for as long
as any `SkimItemSender` is alive. The handler held its sender for the
whole collect, a contract inherited from the skim 0.20 tuikit backend,
whose 100ms repaint heartbeat needed a live reader. In skim 5.x,
in-place row updates surface via injected `Event::Render` and never
touch the channel, so nothing needs the sender past the skeleton batch.

The fix consumes the handler's sender at its single send. The channel
now closes once the last batch is in (the skeleton, or the `--prs`
rows), and skim's reader exits while collect keeps grinding through
in-place updates.

Measured on the wt-perf picker-test repo, 10s window on an idle picker
with a `sleep 30` generation command pending: debug 98% → 1.5% of a
core, release 99% → 0.6%. A truly idle picker was already fine (~1%);
the burn only ever ran while a sender stayed alive. `/usr/bin/sample`
pinned the spin to `skim::reader::collect_items` →
`kanal::signal::Signal::wait_timeout` (4027 of 4095 frames).

Two bounded windows remain: picker startup until the skeleton batch
lands, and `--prs` until the forge call returns. Eliminating those needs
an upstream skim fix (the collect loop parking instead of polling); the
busy-poll is unchanged through skim 5.4.0.

Testing: a new unit test asserts the channel closes at the skeleton
send; the picker unit tests and the PTY `switch_picker` suite (which
exercise fast-skeleton EOF, preview auto-refresh, `--prs` streaming, and
alt-r reload) pass.

> _This was written by Claude Code on behalf of max_

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 11:02:47 -07:00
Maximilian Roos 4121dc979c refactor(wt-perf): cache fixtures in the platform cache dir, not /tmp or target/ (#3542)
## What

Move `wt-perf`'s benchmark/debug fixture repos out of
`std::env::temp_dir()` and `target/bench-repos/` into the per-user cache
dir, resolved by a new `wt_perf_cache_dir()`:

- `$WT_PERF_CACHE_DIR` if set, else `<cache>/wt-perf` via
`etcetera::choose_base_strategy().cache_dir()` — `~/.cache/wt-perf` (or
`$XDG_CACHE_HOME/wt-perf`) on Linux **and** macOS. This matches
worktrunk's own base-dir convention (`src/config/user/path.rs` resolves
user config through the same XDG-on-macOS strategy).
- `setup <config>` fixtures → `<cache>/<config>` (was
`temp_dir()/wt-perf-<config>`). `--path` still overrides.
- Real cloned fixtures (`prune-real`, the rust-lang/rust clone) →
`<cache>/bench-repos/` (was `target/bench-repos/`).
- In-process throwaway fixtures (`create_repo`) are unchanged — they
keep using `tempfile::TempDir`.

## Why

Both old homes were wrong for a *reused* fixture (these are given stable
names, persist between runs, and are referenced from docs and `-C
<path>` — that's a cache, not a temp file):

- **A fixed name in a shared `/tmp` (Linux)** collides across users:
`/tmp` is sticky (`1777`), so a second user's `setup` hits
`remove_dir_all().unwrap()` on a dir they don't own → `EPERM` → panic.
It's also a predictable-path/TOCTOU hazard, and `systemd-tmpfiles` reaps
`/tmp` per-file at 10 days by `max(atime,mtime,ctime)` — on a `noatime`
mount an actively-*read* fixture still loses cold
`.git/objects/pack/*.pack` mid-use → silent git corruption.
- **On macOS**, `temp_dir()` is already `/var/folders/.../T` (per-user,
`0700`), so the docs' `/tmp/wt-perf-*` paths were simply wrong there.
- **`target/`** is per-worktree (git worktrees don't share it) and wiped
by `cargo clean`, so the ~15 GiB rust clone was re-cloned per worktree —
worst for the most expensive fixture, in a worktree-heavy workflow.

The cache dir is per-user (no collision, no TOCTOU), stable and
discoverable (docs/`-C` references still work), shared across worktrees
(clone once per machine), and survives `cargo clean` — matching sccache,
cargo, rustup, Go, Bazel, and Hugging Face, which all place large
reusable caches there rather than in `/tmp`.

## Migration notes

- First bench/setup run after this rebuilds the cache under the new
location (the old `target/bench-repos/` is no longer read). Existing
fixtures can be dropped with `rm -rf target/bench-repos`.
- `.github/workflows/benchmarks.yaml` sets `WT_PERF_CACHE_DIR` and
caches `$WT_PERF_CACHE_DIR/bench-repos`, so the cached path and the path
wt-perf writes stay pinned together (no drift if a runner sets
`$XDG_CACHE_HOME`); key unchanged.
- Docs (`benches/CLAUDE.md`, `src/commands/CLAUDE.md`) updated to the
new paths, noting that `wt-perf setup` prints the exact path.

## Testing

- `cargo build --workspace --all-targets`, `cargo clippy --workspace
--all-targets --features shell-integration-tests -- -D warnings` —
clean.
- `cargo test -p wt-perf` — passes.
- Smoke-tested default resolution (`~/.cache/wt-perf/…` on macOS),
`$WT_PERF_CACHE_DIR` override, and the `prune-real --path` rejection
(now names the resolved cache path).

> _This was written by Claude Code on behalf of Maximilian_

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 03:05:10 -07:00
Maximilian Roos 0aca156ccd fix: use @ before path in -vv startup pointer message (#3543)
The \`-vv\` startup pointer (\`announce_trace_destination\` in
\`src/logging.rs\`) printed "Verbose logging to \<dir\>/", using "to"
before the path. The codebase convention (see the
\`writing-user-outputs\` skill) is \`@\` before paths in user-facing
output — #3521 already applied this to the \`-vv\` end-of-run block but
left this start-of-run pointer as the one remaining inconsistency.

Changes "Verbose logging to \<dir\>/" to "Verbose logging @ \<dir\>/"
and updates the matching test assertions/doc comment in
\`tests/integration_tests/diagnostic.rs\`. The historical wording quoted
in \`CHANGELOG.md\` is left as-is since it documents a past release.

> _This was written by Claude Code on behalf of max_
2026-07-22 02:46:21 -07:00
Worktrunk Bot a660d859ee refactor: unify subdir preservation for wt step relocate (#3346)
Route `wt step relocate`'s shell `cd` through the shared `resolve_subdir_in_target` helper, so every path-switching command (`switch`, `remove`/`merge`, `relocate`) preserves the user's subdirectory position identically — resolving the follow-up from #3344.

Gate `test_relocate_preserves_subdir` to Unix: subdir preservation only fires when the cwd is inside the moving worktree, which is exactly when `git worktree move` (a directory rename) fails on the legacy Windows console — a real limitation, not a test artifact, so the test documents the boundary rather than masking it.
2026-07-22 02:34:59 -07:00
Maximilian Roos 6a85da8f46 refactor(eval): render -v variables through the shared formatter (#3536)
`wt step eval -v` was the last of the four `-v` template-variable
listings to hand-roll its own formatting. The hook (foreground +
background) and alias sites all render through `format_hook_variables` /
`format_alias_variables`; eval instead sorted keys alphabetically,
padded, and joined them by hand. #3495 labelled all four block *headers*
with their owner, which made eval's differently-formatted *body* stand
out.

This adds a sibling `format_base_variables` for the bare `base_vars`
scope (no hook operation/infrastructure vars, no alias `args`) and
routes eval through it, so all four listings are one family.

Consequences for the eval listing, now matching the other three:

- curated help-table order instead of alphabetical
- deprecated aliases (`main_worktree`, `repo_root`, `worktree`,
`main_worktree_path`) dropped, as the other sites already omit them
- absent optional vars show `(unset)` (e.g. `owner` with no PR context)
- variable names render plain, not bold

Behavior-only change to the `-v` diagnostic lane; the `eval_verbose` /
`eval_format_json_verbose` snapshots capture the new output.

> _This was written by Claude Code on behalf of max_

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 02:27:19 -07:00
Maximilian Roos bf9e603ccd build(deps): hold skim at 5.1.0 — 5.3.1 breaks the picker on legacy Windows (#3538)
## Problem

skim 5.3.1 breaks the picker on the legacy Windows console. Every picker
PTY test on `test (windows)` fails with:

```
✗ interactive picker failed: Keyboard progressive enhancement not implemented for the legacy Windows API.
```

That is a crossterm keyboard-enhancement error: the picker (via skim
5.3.1) drives keyboard-enhancement handling that the legacy Windows
console API doesn't support, crashing the picker at runtime. ~40
`switch_picker` tests fail as a result.

## Evidence it's skim 5.3.1

- **#3526 (bump skim 5.1.0 → 5.3.1) merged with its own `full-tests
(windows)` already red** — the regression landed on main unnoticed.
- **main at skim 5.1.0 (`0958a365b`) was green on `test (windows)` the
same day.** The only relevant change between that green run and the
failures is the skim bump.
- The failure is a picker runtime crash, unrelated to any picker source
change — no `switch_picker` code moved.

Since it's on main, it reddens Windows CI for every open PR (e.g.
#3346), not just one branch.

## Fix

Pin `skim = "=5.1.0"` in `Cargo.toml` — the last Windows-green release —
with a comment naming the regression.

`Cargo.toml` specified `skim = "5.0"` (a caret range that `5.3.1`
satisfies), so #3526 changed **only** the lockfile. A lock-only revert
would silently drift back to 5.3.1 on the next `cargo update`, so the
hold has to live in the manifest. The lockfile downgrade (skim 5.3.1 →
5.1.0, frizbee 0.11.0 → 0.10.0 and the deps that pulls) follows from the
pin.

Unpin once skim's keyboard-enhancement path is guarded for the legacy
Windows console (upstream fix, or a worktrunk-side guard before enabling
enhancement).

## Testing

- `cargo run -- hook pre-merge --yes` — full suite green locally (4475
passed, 1 skipped), including the `switch_picker` tests that fail on
Windows at 5.3.1.
- CI will confirm `test (windows)` returns to green.

> _This was written by Claude Code on behalf of Maximilian Roos_

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 01:46:12 -07:00
dependabot[bot] 89b58e2522 chore: bump taiki-e/install-action from 2.83.3 to 2.84.0 (#3529)
Bumps
[taiki-e/install-action](https://github.com/taiki-e/install-action) from
2.83.3 to 2.84.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/releases">taiki-e/install-action's
releases</a>.</em></p>
<blockquote>
<h2>2.84.0</h2>
<ul>
<li>
<p>Support <code>d2</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1944">#1944</a>)</p>
</li>
<li>
<p>Support <code>protoc-gen-connect-openapi</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1922">#1922</a>,
thanks <a
href="https://github.com/JasterV"><code>@​JasterV</code></a>)</p>
</li>
<li>
<p>Update <code>convco@latest</code> to 0.7.0. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1941">#1941</a>,
thanks <a
href="https://github.com/graelo"><code>@​graelo</code></a>)</p>
</li>
<li>
<p>Update <code>just@latest</code> to 1.57.0.</p>
</li>
<li>
<p>Update <code>cargo-semver-checks@latest</code> to 0.49.0.</p>
</li>
<li>
<p>Update <code>tombi@latest</code> to 1.2.4.</p>
</li>
<li>
<p>Update <code>cosign@latest</code> to 3.1.2.</p>
</li>
</ul>
<h2>2.83.4</h2>
<ul>
<li>
<p>Update <code>vacuum@latest</code> to 0.29.10.</p>
</li>
<li>
<p>Update <code>uv@latest</code> to 0.11.29.</p>
</li>
<li>
<p>Update <code>syft@latest</code> to 1.48.0.</p>
</li>
<li>
<p>Update <code>prek@latest</code> to 0.4.10.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.7.</p>
</li>
<li>
<p>Update <code>cargo-shear@latest</code> to 1.13.2.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md">taiki-e/install-action's
changelog</a>.</em></p>
<blockquote>
<h2>[2.84.0] - 2026-07-20</h2>
<ul>
<li>
<p>Support <code>d2</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1944">#1944</a>)</p>
</li>
<li>
<p>Support <code>protoc-gen-connect-openapi</code>. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1922">#1922</a>,
thanks <a
href="https://github.com/JasterV"><code>@​JasterV</code></a>)</p>
</li>
<li>
<p>Update <code>convco@latest</code> to 0.7.0. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/1941">#1941</a>,
thanks <a
href="https://github.com/graelo"><code>@​graelo</code></a>)</p>
</li>
<li>
<p>Update <code>just@latest</code> to 1.57.0.</p>
</li>
<li>
<p>Update <code>cargo-semver-checks@latest</code> to 0.49.0.</p>
</li>
<li>
<p>Update <code>tombi@latest</code> to 1.2.4.</p>
</li>
<li>
<p>Update <code>cosign@latest</code> to 3.1.2.</p>
</li>
</ul>
<h2>[2.83.4] - 2026-07-17</h2>
<ul>
<li>
<p>Update <code>vacuum@latest</code> to 0.29.10.</p>
</li>
<li>
<p>Update <code>uv@latest</code> to 0.11.29.</p>
</li>
<li>
<p>Update <code>syft@latest</code> to 1.48.0.</p>
</li>
<li>
<p>Update <code>prek@latest</code> to 0.4.10.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.7.</p>
</li>
<li>
<p>Update <code>cargo-shear@latest</code> to 1.13.2.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/taiki-e/install-action/commit/a6b2e2dcd845ddd7f509ce4f3ed3d922b80cc5d9"><code>a6b2e2d</code></a>
Release 2.84.0</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/fbdd9c50c029b1f2d5667c090563e4a31cc3f43c"><code>fbdd9c5</code></a>
Update cargo-neat manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/424c5f90440984601897d473b7936cc3fd52bda8"><code>424c5f9</code></a>
Update changelog</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/a1fa02c1f9b8ef65d443ad6b3f0b99f5863b6f4f"><code>a1fa02c</code></a>
Support <code>protoc-gen-connect-openapi</code> (<a
href="https://redirect.github.com/taiki-e/install-action/issues/1922">#1922</a>)</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/9e22773f98774c41688b7cc39a5f7f7eaa4ca97d"><code>9e22773</code></a>
Update DEVELOPMENT.md</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/8d5009fee2da9de26fee96bb727c2df318ffce42"><code>8d5009f</code></a>
Support d2</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/5193316cc852ca0f37d4819875e939522c4f7c47"><code>5193316</code></a>
Update <code>tombi@latest</code> to 1.2.4</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/4c740c71c8320819d812216022c3ff178e1a3394"><code>4c740c7</code></a>
Update <code>tombi@latest</code> to 1.2.3</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/de240ff26f6e8b33bacd85a1a7c621c92d8d7c70"><code>de240ff</code></a>
Update <code>just@latest</code> to 1.57.0</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/dfca8548668aebabd66da598ea31d87a03819d43"><code>dfca854</code></a>
Update <code>cargo-semver-checks@latest</code> to 0.49.0</li>
<li>Additional commits viewable in <a
href="https://github.com/taiki-e/install-action/compare/v2.83.3...v2.84.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=taiki-e/install-action&package-manager=github_actions&previous-version=2.83.3&new-version=2.84.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 18:46:09 -07:00
dependabot[bot] 87715c305b chore: bump skim from 5.1.0 to 5.3.1 (#3526)
Bumps [skim](https://github.com/skim-rs/skim) from 5.1.0 to 5.3.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/skim-rs/skim/releases">skim's
releases</a>.</em></p>
<blockquote>
<h2>5.3.1 - 2026-07-19</h2>
<h2>Release Notes</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>Ignore KeyEventState (<a
href="https://redirect.github.com/skim-rs/skim/issues/1127">#1127</a>)</li>
</ul>
<h2>Install skim 5.3.1</h2>
<h3>Install prebuilt binaries via shell script</h3>
<pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-installer.sh
| sh
</code></pre>
<h3>Install prebuilt binaries via powershell script</h3>
<pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-installer.ps1
| iex&quot;
</code></pre>
<h2>Download skim 5.3.1</h2>
<table>
<thead>
<tr>
<th>File</th>
<th>Platform</th>
<th>Checksum</th>
</tr>
</thead>
<tbody>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-aarch64-apple-darwin.tar.xz">skim-aarch64-apple-darwin.tar.xz</a></td>
<td>Apple Silicon macOS</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-aarch64-apple-darwin.tar.xz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-apple-darwin.tar.xz">skim-x86_64-apple-darwin.tar.xz</a></td>
<td>Intel macOS</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-apple-darwin.tar.xz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-pc-windows-msvc.zip">skim-x86_64-pc-windows-msvc.zip</a></td>
<td>x64 Windows</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-pc-windows-msvc.zip.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-pc-windows-msvc.msi">skim-x86_64-pc-windows-msvc.msi</a></td>
<td>x64 Windows</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-pc-windows-msvc.msi.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-aarch64-unknown-linux-gnu.tar.xz">skim-aarch64-unknown-linux-gnu.tar.xz</a></td>
<td>ARM64 Linux</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-aarch64-unknown-linux-gnu.tar.xz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-unknown-linux-gnu.tar.xz">skim-x86_64-unknown-linux-gnu.tar.xz</a></td>
<td>x64 Linux</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-unknown-linux-gnu.tar.xz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-aarch64-unknown-linux-musl.tar.xz">skim-aarch64-unknown-linux-musl.tar.xz</a></td>
<td>ARM64 MUSL Linux</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-aarch64-unknown-linux-musl.tar.xz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-unknown-linux-musl.tar.xz">skim-x86_64-unknown-linux-musl.tar.xz</a></td>
<td>x64 MUSL Linux</td>
<td><a
href="https://github.com/skim-rs/skim/releases/download/v5.3.1/skim-x86_64-unknown-linux-musl.tar.xz.sha256">checksum</a></td>
</tr>
</tbody>
</table>
<h2>5.3.0 - 2026-07-19</h2>
<h2>Release Notes</h2>
<h3>🚀 Features</h3>
<ul>
<li>Add 'left' and <code>right</code> info display modes (<a
href="https://redirect.github.com/skim-rs/skim/issues/1120">#1120</a>)</li>
<li>Add <code>--hide-nth</code> to hide fields from display but keep
them searchable (<a
href="https://redirect.github.com/skim-rs/skim/issues/1122">#1122</a>)</li>
<li>Add bind and unbind actions (<a
href="https://redirect.github.com/skim-rs/skim/issues/1121">#1121</a>)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>Kitty keyboard protocol</li>
</ul>
<h3>🤖 CI</h3>
<ul>
<li>Add public-api check (<a
href="https://redirect.github.com/skim-rs/skim/issues/1124">#1124</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/skim-rs/skim/blob/master/CHANGELOG.md">skim's
changelog</a>.</em></p>
<blockquote>
<h2>[5.3.1] - 2026-07-19</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>Ignore KeyEventState (<a
href="https://redirect.github.com/skim-rs/skim/issues/1127">#1127</a>)</li>
</ul>
<h2>[5.3.0] - 2026-07-19</h2>
<h3>🚀 Features</h3>
<ul>
<li>Add 'left' and <code>right</code> info display modes (<a
href="https://redirect.github.com/skim-rs/skim/issues/1120">#1120</a>)</li>
<li>Add <code>--hide-nth</code> to hide fields from display but keep
them searchable (<a
href="https://redirect.github.com/skim-rs/skim/issues/1122">#1122</a>)</li>
<li>Add bind and unbind actions (<a
href="https://redirect.github.com/skim-rs/skim/issues/1121">#1121</a>)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>Kitty keyboard protocol</li>
</ul>
<h3>🤖 CI</h3>
<ul>
<li>Add public-api check (<a
href="https://redirect.github.com/skim-rs/skim/issues/1124">#1124</a>)</li>
</ul>
<h2>[5.2.0] - 2026-07-17</h2>
<h3>🚀 Features</h3>
<ul>
<li>Collapsed borders by default and <code>--border-no-collapse</code>
flag (<a
href="https://redirect.github.com/skim-rs/skim/issues/1117">#1117</a>)</li>
<li>Reduce binary size by removing uncommon image formats and color_eyre
(<a
href="https://redirect.github.com/skim-rs/skim/issues/1118">#1118</a>)</li>
</ul>
<h2>[5.1.4] - 2026-07-17</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>Preserve input order with --no-sort (<a
href="https://redirect.github.com/skim-rs/skim/issues/1115">#1115</a>)</li>
</ul>
<h3>New Contributors</h3>
<ul>
<li><a href="https://github.com/juneboku"><code>@​juneboku</code></a>
made their first contribution in <a
href="https://redirect.github.com/skim-rs/skim/pull/1115">#1115</a></li>
</ul>
<h2>[5.1.3] - 2026-07-16</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>Manually resize the Tui when not in fullscreen mode</li>
</ul>
<h3>🤖 CI</h3>
<ul>
<li>Fix fixed viewport resize test in non-interactive env (<a
href="https://redirect.github.com/skim-rs/skim/issues/1114">#1114</a>)</li>
</ul>
<h3>⚙️ Miscellaneous Tasks</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/skim-rs/skim/commit/6dbe37a7fa43f69d906f42b647a5b0221f721bd8"><code>6dbe37a</code></a>
release: v5.3.1 (<a
href="https://redirect.github.com/skim-rs/skim/issues/1128">#1128</a>)</li>
<li><a
href="https://github.com/skim-rs/skim/commit/6f94d80973063e3464ef169afbf27034642cde35"><code>6f94d80</code></a>
fix: ignore KeyEventState (<a
href="https://redirect.github.com/skim-rs/skim/issues/1127">#1127</a>)</li>
<li><a
href="https://github.com/skim-rs/skim/commit/4d093a42e1ebf94c64d7950e2d4817b30089ae05"><code>4d093a4</code></a>
release: v5.3.0 (<a
href="https://redirect.github.com/skim-rs/skim/issues/1123">#1123</a>)</li>
<li><a
href="https://github.com/skim-rs/skim/commit/3c3f26ebc923491031f2728928fd3c18efe46163"><code>3c3f26e</code></a>
fix: kitty keyboard protocol</li>
<li><a
href="https://github.com/skim-rs/skim/commit/ad97bfa7deeee352d743f41ec7cb8bd4b26b4bf6"><code>ad97bfa</code></a>
feat: add bind and unbind actions (<a
href="https://redirect.github.com/skim-rs/skim/issues/1121">#1121</a>)</li>
<li><a
href="https://github.com/skim-rs/skim/commit/ff98133bbd4502633a5b01fcadcadccccef437e0"><code>ff98133</code></a>
ci: add public-api check (<a
href="https://redirect.github.com/skim-rs/skim/issues/1124">#1124</a>)</li>
<li><a
href="https://github.com/skim-rs/skim/commit/dce26d622a7caec4649b2d379c029a64e4fad66e"><code>dce26d6</code></a>
feat: add <code>--hide-nth</code> to hide fields from display but keep
them searchable (...</li>
<li><a
href="https://github.com/skim-rs/skim/commit/55aa7dacd573ccea22f1c3fb655e0a4f91f297a7"><code>55aa7da</code></a>
feat: add 'left' and <code>right</code> info display modes (<a
href="https://redirect.github.com/skim-rs/skim/issues/1120">#1120</a>)</li>
<li><a
href="https://github.com/skim-rs/skim/commit/57a7487323b7f63f28a0e142ba38136b79dca11b"><code>57a7487</code></a>
release: v5.2.0 (<a
href="https://redirect.github.com/skim-rs/skim/issues/1119">#1119</a>)</li>
<li><a
href="https://github.com/skim-rs/skim/commit/bb6c03f3771766a1830e7c48c3abc26af02de97f"><code>bb6c03f</code></a>
feat: reduce binary size by removing uncommon image formats and
color_eyre (#...</li>
<li>Additional commits viewable in <a
href="https://github.com/skim-rs/skim/compare/v5.1.0...v5.3.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=skim&package-manager=cargo&previous-version=5.1.0&new-version=5.3.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 18:46:06 -07:00
dependabot[bot] 076e09a2e4 chore: bump tokio from 1.52.3 to 1.53.0 (#3525)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.52.3 to 1.53.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tokio-rs/tokio/releases">tokio's
releases</a>.</em></p>
<blockquote>
<h2>Tokio v1.53.0</h2>
<h1>1.53.0 (July 17th, 2026)</h1>
<h3>Added</h3>
<ul>
<li>fs: implement <code>From&lt;OwnedFd&gt;</code> and
<code>From&lt;OwnedHandle&gt;</code> for <code>File</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8266">#8266</a>)</li>
<li>metrics: add task schedule latency metric (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/7986">#7986</a>)</li>
<li>net: add <code>SocketAddr</code> methods to Unix sockets (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8144">#8144</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>io: add <code>#[inline]</code> to IO trait impls for in-memory types
(<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8242">#8242</a>)</li>
<li>net: implement UCred::pid on FreeBSD (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8086">#8086</a>)</li>
<li>net: support Nuttx target os (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8259">#8259</a>)</li>
<li>signal: refactor global variables on Windows (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8231">#8231</a>)</li>
<li>sync: <code>mpsc::{Receiver,UnboundedReceiver}</code> now drops
waker on drop, even if there are still senders (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8095">#8095</a>)</li>
<li>taskdump: support taskdumps on s390x (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8192">#8192</a>)</li>
<li>time: add <code>#[track_caller]</code> to <code>timeout_at()</code>
(<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8077">#8077</a>)</li>
<li>time: consolidate mutex locks on spurious poll (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8124">#8124</a>)</li>
<li>time: defer waker clone on spurious poll (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8107">#8107</a>)</li>
<li>time: move lazy-registration state into <code>Sleep</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8132">#8132</a>)</li>
<li>tracing: remove unnecessary span clone (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8126">#8126</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>io: do not treat zero-length reads as EOF in <code>Chain</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8251">#8251</a>)</li>
<li>net: use getpeereid for QNX peer credentials (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8270">#8270</a>)</li>
<li>runtime: avoid illegal state in <code>FastRand</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8078">#8078</a>)</li>
<li>sync: wake mpsc receiver when a queued <code>reserve[_many]</code>
returns permits (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8260">#8260</a>)</li>
<li>taskdump: skip double wake on
<code>Trace::capture</code>/<code>Trace::trace_with</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8043">#8043</a>)</li>
<li>time: avoid stack overflow in runtime constructor (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8093">#8093</a>)</li>
<li>time (alt timer): ensure timers stay in the same runtime after
<code>.reset()</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8169">#8169</a>)</li>
</ul>
<h3>IO uring (unstable)</h3>
<ul>
<li>fs: use io-uring for <code>fs::try_exists</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8080">#8080</a>)</li>
<li>fs: use io-uring for renaming files (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/7800">#7800</a>)</li>
<li>rt: flush io-uring CQE in case of CQE overflow (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8277">#8277</a>)</li>
</ul>
<h3>Documented</h3>
<ul>
<li>docs: clarify cancel safety wording (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8181">#8181</a>)</li>
<li>fs: clarify <code>create_dir_all</code> succeeds if path exists (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8149">#8149</a>)</li>
<li>io: add warning about stdout reordering with multiple handles (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8276">#8276</a>)</li>
<li>net: document pipe <code>try_read*</code>/<code>try_write*</code>
readiness behavior (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8032">#8032</a>)</li>
<li>runtime: document interaction with fork() (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8202">#8202</a>)</li>
<li>sync: clarify broadcast lagging semantics (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8239">#8239</a>)</li>
<li>sync: document memory ordering guarantees for Semaphore (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8119">#8119</a>)</li>
<li>task: explain why <code>yield_now</code> defers its waker (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8254">#8254</a>)</li>
<li>time: add panic docs to <code>timeout_at()</code> (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8077">#8077</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tokio-rs/tokio/commit/be689a35f5ade5a39e507f79d3ec85cdab27806f"><code>be689a3</code></a>
chore: prepare Tokio v1.53.0 (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8294">#8294</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/50f76c71ec7203013f7f0cda59deaa9016e93939"><code>50f76c7</code></a>
chore: prepare tokio-macros v2.7.1 (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8295">#8295</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/f61fccad3cd598cce743fc511a983364b77af92a"><code>f61fcca</code></a>
Merge 'tokio-1.52.4' into 'master' (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8290">#8290</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/efdba5fcf02c4b93d379114df136b994c3b21445"><code>efdba5f</code></a>
chore: prepare Tokio v1.52.4 (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8289">#8289</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/b0ba02e75507518baed6718b0c37105e430f3a93"><code>b0ba02e</code></a>
Merge 'tokio-1.51.4' into 'tokio-1.52.x' (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8288">#8288</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/7bcd2d343d997a658be5bc165520070c997fefbc"><code>7bcd2d3</code></a>
taskdump: remove crate disambiguators from output (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8288">#8288</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/f84b209126a9b0f66dae1025e30e44d217205513"><code>f84b209</code></a>
chore: prepare Tokio v1.51.4 (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8286">#8286</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/eacb98e18901fcbe011bfceddbc31853f1bf0c27"><code>eacb98e</code></a>
runtime: don't skip the driver when <code>before_park</code> schedules
work (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8222">#8222</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/5e16ee00faae5b81a58f70b734577b800e0b203b"><code>5e16ee0</code></a>
task: avoid replacing the JoinQueue waker in <code>try_join_next</code>
(<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8279">#8279</a>)</li>
<li><a
href="https://github.com/tokio-rs/tokio/commit/88212ab64afd2b2f87deeb073f9eef6aaaad3701"><code>88212ab</code></a>
sync: document memory ordering guarantees for Semaphore (<a
href="https://redirect.github.com/tokio-rs/tokio/issues/8119">#8119</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tokio-rs/tokio/compare/tokio-1.52.3...tokio-1.53.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=tokio&package-manager=cargo&previous-version=1.52.3&new-version=1.53.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 18:46:04 -07:00
dependabot[bot] 0958a365bb chore: bump the patch group with 6 updates (#3524)
Bumps the patch group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [anyhow](https://github.com/dtolnay/anyhow) | `1.0.103` | `1.0.104` |
| [clap](https://github.com/clap-rs/clap) | `4.6.1` | `4.6.2` |
| [serde](https://github.com/serde-rs/serde) | `1.0.228` | `1.0.229` |
| [which](https://github.com/harryfei/which-rs) | `8.0.4` | `8.0.5` |
| [regex](https://github.com/rust-lang/regex) | `1.13.0` | `1.13.1` |
| [ignore](https://github.com/BurntSushi/ripgrep) | `0.4.28` | `0.4.30`
|

Updates `anyhow` from 1.0.103 to 1.0.104
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dtolnay/anyhow/releases">anyhow's
releases</a>.</em></p>
<blockquote>
<h2>1.0.104</h2>
<ul>
<li>Update <code>syn</code> dev-dependency to version 3</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/dtolnay/anyhow/commit/1dbe1862aae650423e3361fbd20b7d17c5109cc3"><code>1dbe186</code></a>
Release 1.0.104</li>
<li><a
href="https://github.com/dtolnay/anyhow/commit/f6479f8e5e10761d7fecde0970cff363dc644d92"><code>f6479f8</code></a>
Update to syn 3</li>
<li>See full diff in <a
href="https://github.com/dtolnay/anyhow/compare/1.0.103...1.0.104">compare
view</a></li>
</ul>
</details>
<br />

Updates `clap` from 4.6.1 to 4.6.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/clap-rs/clap/releases">clap's
releases</a>.</em></p>
<blockquote>
<h2>v4.6.2</h2>
<h2>[4.6.2] - 2026-07-15</h2>
<h3>Fixes</h3>
<ul>
<li><em>(help)</em> Say <code>alias</code> when there is only one</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/clap-rs/clap/blob/master/CHANGELOG.md">clap's
changelog</a>.</em></p>
<blockquote>
<h2>[4.6.2] - 2026-07-15</h2>
<h3>Fixes</h3>
<ul>
<li><em>(help)</em> Say <code>alias</code> when there is only one</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/clap-rs/clap/commit/0fe0be302726f4253b9bee27eed48438c92917aa"><code>0fe0be3</code></a>
chore: Release</li>
<li><a
href="https://github.com/clap-rs/clap/commit/480af9d045453f4ab96d9bdd4d4b9f5aab3c272f"><code>480af9d</code></a>
docs: Update changelog</li>
<li><a
href="https://github.com/clap-rs/clap/commit/2b3ddd0294a147d1eda917cb303243bcde0c12ee"><code>2b3ddd0</code></a>
Merge pull request <a
href="https://redirect.github.com/clap-rs/clap/issues/6340">#6340</a>
from liskin/fix-completion-escape</li>
<li><a
href="https://github.com/clap-rs/clap/commit/7ffe7399ff032cc247eb0449cf8fcdfbfe55a4ec"><code>7ffe739</code></a>
fix(complete): Do not suggest options after &quot;--&quot;</li>
<li><a
href="https://github.com/clap-rs/clap/commit/d47fc4f8a5e9fcc16d0cae15b51e6eb1a8ed5832"><code>d47fc4f</code></a>
test(complete): Options suggested after escape (<code>--</code>)</li>
<li>See full diff in <a
href="https://github.com/clap-rs/clap/compare/clap_complete-v4.6.1...clap_complete-v4.6.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `serde` from 1.0.228 to 1.0.229
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/serde-rs/serde/releases">serde's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.229</h2>
<ul>
<li>Update to syn 3</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/serde-rs/serde/commit/7fc3b4c30c94f73a96ebd1553f2b090d928fc3a8"><code>7fc3b4c</code></a>
Release 1.0.229</li>
<li><a
href="https://github.com/serde-rs/serde/commit/6d6e9a11101354ce769a3438a088b6b9305c1863"><code>6d6e9a1</code></a>
Merge pull request <a
href="https://redirect.github.com/serde-rs/serde/issues/3085">#3085</a>
from dtolnay/syn3</li>
<li><a
href="https://github.com/serde-rs/serde/commit/6dec3b751126c8338cac0fe8085612d695e4ecf3"><code>6dec3b7</code></a>
Update to syn 3</li>
<li><a
href="https://github.com/serde-rs/serde/commit/cfe669241065984177ff63af8b45058e6e9b499d"><code>cfe6692</code></a>
Resolve mut_mut pedantic clippy lint</li>
<li><a
href="https://github.com/serde-rs/serde/commit/1023d077510b4aef36a41ef56fdb7798568a2654"><code>1023d07</code></a>
Update actions/upload-artifact@v6 -&gt; v7</li>
<li><a
href="https://github.com/serde-rs/serde/commit/dd682c2c86aa7629e77c1ccd93212d3729f4c66d"><code>dd682c2</code></a>
Update actions/checkout@v6 -&gt; v7</li>
<li><a
href="https://github.com/serde-rs/serde/commit/5f0f18b9211732f2d82f73b5a43e4f5ff3701251"><code>5f0f18b</code></a>
Update ui test suite to nightly-2026-06-01</li>
<li><a
href="https://github.com/serde-rs/serde/commit/63a1498f0e7be991ffac5939bdd202ca16e9a23f"><code>63a1498</code></a>
Regenerate stderr with trybuild normalization fixes</li>
<li><a
href="https://github.com/serde-rs/serde/commit/fa7da4a93567ed347ad0735c28e439fca688ef26"><code>fa7da4a</code></a>
Fix unused_features warning</li>
<li><a
href="https://github.com/serde-rs/serde/commit/6b1a17851ea3d86a56aa116ca1cbf428f8d5f22d"><code>6b1a178</code></a>
Unpin CI miri toolchain</li>
<li>Additional commits viewable in <a
href="https://github.com/serde-rs/serde/compare/v1.0.228...v1.0.229">compare
view</a></li>
</ul>
</details>
<br />

Updates `which` from 8.0.4 to 8.0.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/harryfei/which-rs/releases">which's
releases</a>.</em></p>
<blockquote>
<h2>8.0.5</h2>
<h2>What's Changed</h2>
<ul>
<li>Fix absolute path lookup when cwd is disabled by <a
href="https://github.com/weifanglab"><code>@​weifanglab</code></a> in <a
href="https://redirect.github.com/harryfei/which-rs/pull/126">harryfei/which-rs#126</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/weifanglab"><code>@​weifanglab</code></a> made
their first contribution in <a
href="https://redirect.github.com/harryfei/which-rs/pull/126">harryfei/which-rs#126</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/harryfei/which-rs/compare/8.0.4...8.0.5">https://github.com/harryfei/which-rs/compare/8.0.4...8.0.5</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/harryfei/which-rs/blob/master/CHANGELOG.md">which's
changelog</a>.</em></p>
<blockquote>
<h2>8.0.5</h2>
<ul>
<li>Bug fix: <a
href="https://redirect.github.com/harryfei/which-rs/pull/126">#126</a>
Do not use current directory for search when provided path is absolute.
Thanks <a
href="https://github.com/weifanglab"><code>@​weifanglab</code></a> for
your contribution to which!</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/harryfei/which-rs/commit/7fba0e04d0674bbe8ccf5bfb4f09b1d00925806f"><code>7fba0e0</code></a>
bump version number, update CHANGELOG.md</li>
<li><a
href="https://github.com/harryfei/which-rs/commit/e28a3bf34e41bcc009b990e6c05b4a6e6b01635f"><code>e28a3bf</code></a>
Fix absolute path lookup when cwd is disabled (<a
href="https://redirect.github.com/harryfei/which-rs/issues/126">#126</a>)</li>
<li>See full diff in <a
href="https://github.com/harryfei/which-rs/compare/8.0.4...8.0.5">compare
view</a></li>
</ul>
</details>
<br />

Updates `regex` from 1.13.0 to 1.13.1
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rust-lang/regex/blob/master/CHANGELOG.md">regex's
changelog</a>.</em></p>
<blockquote>
<h1>1.13.1 (2026-07-15)</h1>
<p>This is a release that fixes a bug where incorrect regex match
offsets could be
reported. Note that this doesn't impact whether a match occurs or not,
just
where it occurs. The match offsets are still valid for slicing, they
just may
not refer to the correct leftmost-first match. See
<a
href="https://redirect.github.com/rust-lang/regex/pull/1364">#1364</a>
for (many) more details.</p>
<p>Bug fixes:</p>
<ul>
<li><a
href="https://redirect.github.com/rust-lang/regex/issues/1354">#1354</a>:
Fixes previously unsound reverse suffix and inner optimizations.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/rust-lang/regex/commit/2b527599eb9eea0dcc288c704584f242f26a5c61"><code>2b52759</code></a>
1.13.1, redux</li>
<li><a
href="https://github.com/rust-lang/regex/commit/40e98238fff903f3e1ec95bbdb487185dd60504a"><code>40e9823</code></a>
1.13.1</li>
<li><a
href="https://github.com/rust-lang/regex/commit/75fcb962d6ea1c456f6f023c9537a66389413a85"><code>75fcb96</code></a>
changelog: 1.13.1</li>
<li><a
href="https://github.com/rust-lang/regex/commit/64ad0b618e043b791ed5385dd5504a436da1ddae"><code>64ad0b6</code></a>
automata: fix bug in reverse suffix/inner optimization</li>
<li><a
href="https://github.com/rust-lang/regex/commit/fa91c31a4291c9dda6afe19829e6fe2e3bbc2da5"><code>fa91c31</code></a>
automata: fix a bug caught by Codex review</li>
<li><a
href="https://github.com/rust-lang/regex/commit/30390ec3e8889aad830337cdf3a7a01ae195ae73"><code>30390ec</code></a>
automata: formatting tweaks</li>
<li><a
href="https://github.com/rust-lang/regex/commit/821a8eb1ad7860ddc788fe36f495036df63cfc35"><code>821a8eb</code></a>
automata: refactor reverse suffix/inner search slightly</li>
<li><a
href="https://github.com/rust-lang/regex/commit/10afd704d88d00ddfcd10218883a81b3ae5e4831"><code>10afd70</code></a>
automata: expose the extracted literals for inner literal
extraction</li>
<li><a
href="https://github.com/rust-lang/regex/commit/8c34f41d3c5a0e16ce17dfb964587cb48625a8d5"><code>8c34f41</code></a>
automata: avoid reverse suffix optimization for non-leftmost-first</li>
<li><a
href="https://github.com/rust-lang/regex/commit/5524f02430d2d118d5c34fde54136d08376de711"><code>5524f02</code></a>
test: add regression tests for failed reverse suffix/inner
optimizations</li>
<li>Additional commits viewable in <a
href="https://github.com/rust-lang/regex/compare/1.13.0...1.13.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `ignore` from 0.4.28 to 0.4.30
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/227381db0ee83dfa4341f1e27ff9617c0f5ad992"><code>227381d</code></a>
ignore-0.4.30</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/b621e65b4fc8a50b55576b07526f21c5d051ad71"><code>b621e65</code></a>
ignore: add incremental checking</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/c55818fd32d68cf742aea67bce86529f198bc985"><code>c55818f</code></a>
ignore: more pathutil clean-up</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/6e527e9202f85a39ab2c4698636710204eb096e0"><code>6e527e9</code></a>
ignore: add routine for checking if a path is hidden or not</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/626b8951acbced7ff710f4e01624a05f219eec38"><code>626b895</code></a>
ignore: refactor <code>is_hidden</code></li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/0d7054d8e466d6aa0a6bb6cf121e87225d26df44"><code>0d7054d</code></a>
ignore: fix deadlock when visitor panics</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/576005b322c41174bb21d76122b1411e5d983402"><code>576005b</code></a>
grep-searcher-0.1.17</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/432976d69cdff36d5a0d6845b093cf3f67262b43"><code>432976d</code></a>
grep-pcre2-0.1.10</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/41e0ae702bcbd47b093a33ee73f1497aa4ed20d6"><code>41e0ae7</code></a>
grep-matcher-0.1.9</li>
<li><a
href="https://github.com/BurntSushi/ripgrep/commit/40ffc6e0bd990ba6e56702ed1ec519b7ad96a1e7"><code>40ffc6e</code></a>
ignore-0.4.29</li>
<li>Additional commits viewable in <a
href="https://github.com/BurntSushi/ripgrep/compare/ignore-0.4.28...ignore-0.4.30">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 18:46:01 -07:00
Worktrunk Bot 65f02693ae docs(list): correct main_state priority order in field docstring (#3531) 2026-07-21 12:58:33 -07:00
Worktrunk Bot 56249f9122 fix: clear error when new branch name collides with existing branch namespace (#3528) 2026-07-20 07:08:09 -07:00
Worktrunk Bot c6eb148e62 docs(hook): correct pre-switch {{ branch }} resolution note (#3516) 2026-07-19 18:13:17 -07:00
Maximilian Roos 17add1f6dd fix: drop companion log paths from the -vv end-of-run message (#3521)
The `-vv` end-of-run block printed `trace.jsonl` and `subprocess.log` as
bare gutter lines under a headline that named only `diagnostic.md` — an
unannounced list whose relationship to the headline lived in a code
comment, and the third and fourth prints of the same directory in one
run. The start-of-run pointer already names the log directory, and the
report body already routes readers to the raw companions
(`subprocess_log_path` in the template; the profile heading names
`trace.jsonl` as its source), so the end block now announces only the
one human-facing file:

```
○ Diagnostics and performance profile saved @ ~/…/.git/wt/logs/diagnostic.md
↳ To report a bug, open an issue (https://github.com/max-sixty/worktrunk/issues/new) and attach a secret gist: gh gist create --web ~/…/diagnostic.md
```

The headline drops "Logs," (the raw logs were precisely what wasn't at
that path), and the hint now ends with the copyable gist command,
linking the plain `/issues/new` URL instead of the ~150-char
prefilled-body URL.

> _This was written by Claude Code on behalf of max_

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 11:39:49 -07:00
dependabot[bot] 013d1cc221 chore: bump KSXGitHub/github-actions-deploy-aur from 4.1.3 to 4.2.0 (#3472)
Bumps
[KSXGitHub/github-actions-deploy-aur](https://github.com/ksxgithub/github-actions-deploy-aur)
from 4.1.3 to 4.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ksxgithub/github-actions-deploy-aur/releases">KSXGitHub/github-actions-deploy-aur's
releases</a>.</em></p>
<blockquote>
<h2>v4.2.0</h2>
<p>Add a feature to sync AUR repo (<a
href="https://redirect.github.com/KSXGitHub/github-actions-deploy-aur/pull/52">KSXGitHub/github-actions-deploy-aur#52</a>).</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/KSXGitHub/github-actions-deploy-aur/commit/084b0d9b15415bf9cdb65d44dad1efe37a354050"><code>084b0d9</code></a>
style: consistency (<a
href="https://redirect.github.com/ksxgithub/github-actions-deploy-aur/issues/55">#55</a>)</li>
<li><a
href="https://github.com/KSXGitHub/github-actions-deploy-aur/commit/9e2f21095c586521806151200746082d8e02bb90"><code>9e2f210</code></a>
fix: force-add <code>PKGBUILD</code> and <code>.SRCINFO</code> in the
asset_dir/assets path (<a
href="https://redirect.github.com/ksxgithub/github-actions-deploy-aur/issues/53">#53</a>)</li>
<li><a
href="https://github.com/KSXGitHub/github-actions-deploy-aur/commit/7acb32fe8c43848121eee16dd39d8294ec2bf25b"><code>7acb32f</code></a>
feat: full asset sync (<a
href="https://redirect.github.com/ksxgithub/github-actions-deploy-aur/issues/52">#52</a>)</li>
<li>See full diff in <a
href="https://github.com/ksxgithub/github-actions-deploy-aur/compare/v4.1.3...v4.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=KSXGitHub/github-actions-deploy-aur&package-manager=github_actions&previous-version=4.1.3&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-19 11:21:35 -07:00
dependabot[bot] 99704db62f chore: bump taiki-e/install-action from 2.83.2 to 2.83.3 (#3497)
Bumps
[taiki-e/install-action](https://github.com/taiki-e/install-action) from
2.83.2 to 2.83.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/releases">taiki-e/install-action's
releases</a>.</em></p>
<blockquote>
<h2>2.83.3</h2>
<ul>
<li>
<p>Update <code>release-plz@latest</code> to 0.3.160.</p>
</li>
<li>
<p>Update <code>prek@latest</code> to 0.4.9.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.6.</p>
</li>
<li>
<p>Update <code>dprint@latest</code> to 0.55.2.</p>
</li>
<li>
<p>Update <code>cargo-dinghy@latest</code> to 0.8.5.</p>
</li>
<li>
<p>Update <code>cargo-binstall@latest</code> to 1.21.0.</p>
</li>
<li>
<p>Update <code>biome@latest</code> to 2.5.4.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md">taiki-e/install-action's
changelog</a>.</em></p>
<blockquote>
<h2>[2.83.3] - 2026-07-16</h2>
<ul>
<li>
<p>Update <code>release-plz@latest</code> to 0.3.160.</p>
</li>
<li>
<p>Update <code>prek@latest</code> to 0.4.9.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.7.6.</p>
</li>
<li>
<p>Update <code>dprint@latest</code> to 0.55.2.</p>
</li>
<li>
<p>Update <code>cargo-dinghy@latest</code> to 0.8.5.</p>
</li>
<li>
<p>Update <code>cargo-binstall@latest</code> to 1.21.0.</p>
</li>
<li>
<p>Update <code>biome@latest</code> to 2.5.4.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/taiki-e/install-action/commit/ed67fa35ac944f3a9b33f12c4dd43b6f31a47e20"><code>ed67fa3</code></a>
Release 2.83.3</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/618fa5589cc587c869ec39ae0606a6cf6ef03c0b"><code>618fa55</code></a>
Update prek manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/47579092c792f14738b668ee240d199bcad0d8e2"><code>4757909</code></a>
Update zizmor manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/f1fa00538cc2e7231cb60e4d47c24597e0c387b7"><code>f1fa005</code></a>
Update uv manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/aa8dc906017e56077bc125256c4d9301b1cde72a"><code>aa8dc90</code></a>
Update <code>release-plz@latest</code> to 0.3.160</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/b9654978ff643e657a453245addf012127caa2c5"><code>b965497</code></a>
Update <code>prek@latest</code> to 0.4.9</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/7aab3a9c373d60a23a5b89c212174c0baa6a0fa0"><code>7aab3a9</code></a>
Update <code>mise@latest</code> to 2026.7.6</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/bfee8d1ca4d6f82a5c3f7151f046e75e6c202ff5"><code>bfee8d1</code></a>
Update kingfisher manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/b65771b2e228b44f33eb596fbf78979075cd8aa7"><code>b65771b</code></a>
Update <code>dprint@latest</code> to 0.55.2</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/20468927b3c1d5f14e6c4c1379ced0c6cc1ed103"><code>2046892</code></a>
Update <code>cargo-dinghy@latest</code> to 0.8.5</li>
<li>Additional commits viewable in <a
href="https://github.com/taiki-e/install-action/compare/v2.83.2...v2.83.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=taiki-e/install-action&package-manager=github_actions&previous-version=2.83.2&new-version=2.83.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-19 11:21:30 -07:00
Worktrunk Bot 5967df2dfc chore(ci): weekly renovation 2026-07-19 (#3518) 2026-07-19 08:39:31 -07:00
Worktrunk Bot b1042cfc20 docs(picker): correct format_log_output hash-marker note (#3515) 2026-07-19 01:35:57 -07:00
Worktrunk Bot 86daf56dfe fix(diagnostic): avoid panic slicing config/log at non-UTF-8 boundaries (#3514) 2026-07-19 01:34:00 -07:00
Worktrunk Bot d44d68797a docs(extending): add workz to custom-subcommand examples (#3513) 2026-07-18 16:40:53 -07:00
Worktrunk Bot cda5080195 test(list): exercise real wide-char branch names in width test (#3511) 2026-07-18 07:35:37 +00:00
Rene Leonhardt 79be81a4bb fix(merge): Accept merge-shaped fast-forward histories (#3509) 2026-07-18 00:32:56 -07:00
Rene Leonhardt 6070b31f0c fix(testing): Isolate CLI logging environment (#3503)
## 🧢 Changes

- Remove inherited `RUST_LOG` from CLI integration-test children.
- Preserve explicit per-test logging overrides.
- Keep verbose trace assertions independent of the developer's shell.

## ☕️ Reasoning

The test harness should control the child CLI's logging baseline. A host
`RUST_LOG=warn` overrides `-vv`, suppresses debug trace records, and
makes
otherwise-correct diagnostic tests fail.

This was a real-world agentic coding blocker: full verification
inherited the
session environment and required an external `env -u RUST_LOG`
workaround.

## 🧪 Reproduction

```sh
RUST_LOG=warn cargo test --test integration \
  test_diagnostic_trace_log_contains_git_commands -- --exact
```

Before this fix, the assertion failed because `trace.log` lacked the
expected
Git command records:

```text
Trace log should contain git worktree list command
```

## ✅ Verification

- Focused harness test proves `RUST_LOG` is explicitly removed.
- The diagnostic regression passes with host `RUST_LOG=warn`.
- Combined publication-set pre-merge hook: 4,519 tests passed on macOS.

Developed with carefully directed, manually reviewed AI assistance.

Co-Authored-By: GPT-5.6 Sol <codex@openai.com>

Co-authored-by: GPT-5.6 Sol <codex@openai.com>
2026-07-17 19:44:45 -07:00
Worktrunk Bot 58abb88ee4 fix(progress): raise watchdog delay to 4s for deterministic snapshots (#3510)
## 🧢 Changes

Raise `WATCHDOG_STARTUP_DELAY` from 2s to 4s in `src/progress.rs`.

## ☕️ Reasoning

Follow-up to #3505 (closed). Rather than add a test-only env override to
disable the watchdog, the simpler fix is to push out the threshold at
which the delay indicator first appears.

The watchdog's 2s startup delay could inject a transient `Waiting for
the squash commit message (2s)` redraw into the README pre-merge
snapshot under broad-suite scheduling load, while the same test passed
when run alone. That made snapshot verification nondeterministic without
any change in product output.

At 4s the watchdog still surfaces genuinely slow commands, but the first
redraw lands past the window where test-harness scheduling jitter
injects it into fast, documented output.

## ✅ Verification

- `cargo build --lib` — clean.
- `cargo test --lib progress` — 31 passed, 0 failed (watchdog escalation
coverage intact).

Requested by @max-sixty in #3505.

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
2026-07-17 19:39:48 -07:00
Worktrunk Bot a1332d46bd chore: update tend workflows (0.1.10 → 0.1.11) (#3500)
Automated nightly regeneration of tend's workflow files, picking up the
upstream release.

**tend version:** 0.1.10 → 0.1.11

**Notable changes** (consumer-relevant):

- Skip no-op `tend-mention` sessions triggered by the bot's own comments
— a new pre-mention guard in the generated `tend-mention.yaml`
short-circuits before the engagement heuristics (max-sixty/tend#751).
- Respond to actionable bot self-reviews instead of exiting as a
self-loop: a review the review workflow leaves on its own PR is the
bot's reviewer role, so it gets actioned rather than silently skipped
(max-sixty/tend#762).
- Sandbox: adopter levers to reach inside the Claude-family sandbox, and
derive the sandbox `PATH` from the runner's `PATH` (max-sixty/tend#768,
max-sixty/tend#767).
- `running-in-ci`: permit maintainer-invited upstream contributions, and
prohibit self-authored attribution sign-offs (max-sixty/tend#770,
max-sixty/tend#773).
- Action reliability: self-heal duplicate `tend-outage` issues from
concurrent leg failures, and recover dropped cron ticks in
list-recent-runs via a previous-run anchor (max-sixty/tend#744,
max-sixty/tend#753).

Compare: https://github.com/max-sixty/tend/compare/0.1.10...0.1.11

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
2026-07-17 12:59:12 -07:00
Worktrunk Bot 3f0de454e6 fix(shell): don't truncate config scan at a non-UTF-8 line (#3499) 2026-07-17 11:00:48 -07:00
dependabot[bot] 8ab797f595 chore: bump max-sixty/tend from 0.1.10 to 0.1.11 (#3496) 2026-07-16 23:00:21 -07:00
Maximilian Roos 85c9241cb1 Name the template owner in the -v variables block (#3495)
## The question

When `wt` shows a `template variables:` block under `-v`, does it say
which template the variables belong to? Mostly no — and in one case it
genuinely can't be worked out from the header.

## What was there

Four sites print a variables listing, and none named its owner in the
header:

| Site | Header | How you'd tell what it's for |
|---|---|---|
| foreground hook (`command_executor.rs`) | `template variables:` | the
`hook_type` row at the bottom of the table, or the `Running …` line
below it |
| background hook (`hooks.rs`) | `template variables:` | same — but see
below |
| alias (`alias.rs`) | `template variables:` | only the `Running alias
greet` line below it |
| `wt step eval` (`eval.rs`) | `Available template variables` |
unambiguous (one template, named on the command line) |

The adjacent blocks in the same `-v` lane already label themselves — `○
eval source`, `○ user:noop result` — so the variables table was the odd
one out in its own family.

Background hooks turned that from inconvenient into ambiguous. `wt -v
remove <branch>` prints one table per hook type back to back, then a
*single* combined `Running post-remove: cleanup (user); post-switch:
notify (user)` line — two identical headers over two ~20-row tables that
differ only in their rows.

## The change

Prefix each header with the hook type, alias name, or `eval`.

```
- ○ template variables:                 ○ post-remove template variables:
- ○ template variables:                 ○ post-switch template variables:
```

`wt step eval -v` now reads as one labeled family:

```
○ eval template variables:
  branch = feature/auth-oauth2
○ eval source
  {{ branch }}
○ eval result
  feature/auth-oauth2
```

`eval`'s header was reworded from `Available template variables` for the
same shape; it was never ambiguous, but it's the fourth member of the
family and now matches the `source` / `result` headers directly beneath
it.

Display-only — no logic changed. Snapshots and the generated `step.md`
pages regenerated; `cargo run -- hook pre-merge --yes` green (4461
tests).

> _This was written by Claude Code on behalf of Maximilian Roos_

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 21:36:58 -07:00
Maximilian Roos 568b6de85f docs: consolidate duplicated explanations and trim slop (#3494)
Sweep of the docs for repetition and filler, from an audit of the
hand-authored pages, the command pages' source in `src/cli/mod.rs`, and
the plugin skill. Net −574 lines; every cut either had a surviving
canonical home or restated an adjacent sentence.

**One home per mechanism** (other mentions now link to it):

- `template-append` — the LLM commits guide owns the rendering
mechanism; the user- and project-config sections keep the key, an
example, and what is unique to them (the project approval gate and the
only-`template-append`-from-project scoping). Was explained in full in
three places.
- `-vv` diagnostic files — `wt config state logs` owns the four file
descriptions; the FAQ summarizes in one sentence and links.
- fsmonitor/trash cleanup — the FAQ's two overlapping `wt remove`
bullets merge into one that distinguishes own-daemon teardown from the
orphan sweep; troubleshooting.md's restatement compresses to a pointer,
keeping its unique wedged-daemon-on-live-worktree guidance.
- copy-ignored built-in excludes — the `wt step copy-ignored` page owns
the directory list (previously enumerated 4×); the config sections state
the rule and link.
- hook-types table — `wt hook` owns it; the extending guide replaces its
verbatim copy with a sentence.
- LLM tool commands — unchanged, deliberately: the apparent hand-synced
duplication between llm-commits.md and the config example is already
machine-pinned by `test_llm_docs_commands_match_config_example`, so it
cannot drift.

**Cut-over debt**: the deprecated `wt config state ci-status` section
shrinks to a deprecation pointer — its status table, fetch order, and
caching notes all duplicated the `wt list` CI-status section.

**Structure**: `wt step copy-ignored`'s "Features" list dissolves into
the sections that owned its facts (excludes → "What gets copied",
reflink → "Performance"); the four trailing "Note: This command is
experimental…" lines go (the `[experimental]` badge already appears
twice per section); shell-integration.md described the directive-file
mechanism twice and now describes it once.

**SKILL.md** drops from 339 to 181 lines: the permission-model section
duplicated the config-types bullets, the hook-type mapping appeared
twice, and the "Determining Which Config to Use" / "Validation Before
Adding Commands" scaffolding enumerated judgments an agent makes on its
own. The approvals-escalation and agent-handoff sections are untouched.

**Deliberately not addressed**: `wt list`'s schema 1 JSON tables (still
the default schema; the wholesale deletion lands when the default flips)
and corpus-wide em-dash density (a house-style decision, not a per-page
fix).

Generated mirrors (docs command pages, skill references, plugins mirror,
`dev/*.example.toml`, help snapshots) regenerated via
`test_docs_are_in_sync` and `cargo insta`.

> _This was written by Claude Code on behalf of max_

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 13:44:44 -07:00
Worktrunk Bot e459e3e6c2 fix(plugin): WorktreeRemove hook exits 0 when the worktree is already gone (#3493)
## Summary

Fixes #3488.

Claude Code (>= 2.1.211) auto-fires the plugin's `WorktreeRemove` hook
on session teardown for the recorded worktree path — but that worktree
may already be gone (removed by `wt merge` after a PR, or a manual `wt
remove`). In that case `wt remove <gone-path>` resolves the missing path
to a *branch-only* target and fails with `✗ No branch named <path>`
(exit 1). Claude Code treats a non-zero `WorktreeRemove` as a failed
removal and keeps the session row (`worktree could not be removed
(WorktreeRemove hook failed)`), so the completed background session can
no longer be deleted with Ctrl+X in the `claude agents` view.

Per @max-sixty's call on the issue, this fixes it directly in the hook
rather than adding a `--if-exists` flag (protected CLI surface) or
punting to Claude Code.

## Change

One guard in the `WorktreeRemove` hook command:

```diff
- ... cd "${CLAUDE_PROJECT_DIR:-.}" || exit 1; bash ".../wt.sh" remove --foreground "$p"'
+ ... cd "${CLAUDE_PROJECT_DIR:-.}" || exit 1; [ -e "$p" ] || exit 0; bash ".../wt.sh" remove --foreground "$p"'
```

If the recorded worktree path no longer exists on disk, the hook is a
no-op (exit 0). This is the narrowed form of the issue's Option 1:
leniency is scoped to "the worktree is already gone", not a blanket
success. When the path still exists, `wt remove` runs exactly as before,
so genuine failures (dirty / locked / unmerged branches — the #2939
spirit) still surface loudly and are never masked. It also doesn't
swallow a typo, since a typo'd path doesn't exist on disk only when it
also doesn't exist as a worktree — and Claude Code only ever fires this
hook with a path it recorded, not user input.

The guard lives inside the single-quoted `bash -c '...'` body, so it
doesn't touch outer login-shell (fish/zsh/bash) parsing, and it adds no
`-D`/`--force-delete`.

## Testing

- `test_claude_hook_commands_parse_in_all_shells` (fish/zsh/bash parse)
— passes
- `test_plugin_layout_is_consolidated` (includes the "no
`-D`/`--force-delete`" assertion on the WorktreeRemove command) — passes

This is orthogonal to #3489, which already landed the cwd
(`CLAUDE_PROJECT_DIR`) anchoring.

Co-authored-by: worktrunk-bot <worktrunk-bot@users.noreply.github.com>
2026-07-16 09:24:51 -07:00
Worktrunk Bot 52dce93760 fix: copy-ignored handles non-ASCII filenames (git quotePath) (#3487) 2026-07-16 02:18:50 -07:00
Jude Wang 5ebdcb1500 fix(plugin): anchor WorktreeRemove at the project dir (#3489) 2026-07-16 02:17:36 -07:00
Worktrunk Bot 1ebd7b043d docs: correct stale references found in nightly survey (#3490) 2026-07-16 02:16:48 -07:00
Worktrunk Bot 7735d115ce fix(tests): restore hidden-subcommand completion coverage (#3492) 2026-07-16 01:24:55 -07:00
Maximilian Roos 2746263920 fix(picker): keep branch names out of shared diff-preview cache entries (#3481)
The picker's branch-diff (tab 3) and upstream-diff (tab 4) disk caches
are keyed by SHAs only, so branches parked at the same commit — common
after `wt landed` resets merged branches to main's tip — share one
entry. The cached value was the finished pane with the row's branch name
baked into the empty-diff headline, so every same-SHA row showed the
first writer's name: `main has no file changes vs main` under another
branch's row (surfaced as the "preview shows another row's content"
oddity while A/B-testing #3439; skim was exonerated — it requests the
correct row).

The fix follows the Log cache's existing split: cache only the
branch-agnostic data (`BranchDiffCacheEntry { body }`,
`UpstreamDiffCacheEntry { ahead, behind, body }` — the name-free
rendered diff, `None` when empty) and render the branch-named headline
on read, on the hit and miss paths alike. `compute_diff_preview` now
returns `Option<String>` instead of taking a `no_changes_msg`, so a
branch name can't leak into a cached value again. No key/version bump:
old bare-string entries fail struct deserialization, read as a miss
(`cache::read`'s documented corrupt-entry semantics), and are recomputed
and overwritten in place.

Rendered output is byte-identical in every state, so no snapshot
changes.

**Testing**: regression tests pin the collision for both modes (second
same-SHA branch asserted to *hit* the first's entry and render its own
name), a migration test pins old-format-reads-as-miss, and the
previously untested empty-diff headlines (clean working tree; upstream
ahead/diverged/behind via `--allow-empty` commits) now have coverage
since they're lazily evaluated. Also verified end-to-end by driving the
picker in the wt-perf test repo: a poisoned old-format entry self-healed
and same-SHA rows render their own names.

> _This was written by Claude Code on behalf of max_

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 17:02:00 -07:00
Maximilian Roos f550a733f7 docs(changelog): fold #3483 into the 0.68.0 error-rendering entry (#3485)
Step-12 drift fold for the v0.68.0 release: #3483 (the follow-up
completing #3474) merged during the release PR CI window, so it ships in
0.68.0 but the changelog entry only covered the eight #3474 sites. The
entry now covers the full cutover and cites #3483.

> _This was written by Claude Code on behalf of max_
v0.68.0
2026-07-15 16:35:53 -07:00
Maximilian Roos fd97aa8bc3 Release v0.68.0 (#3484)
Release v0.68.0. Highlights: on-demand picker preview tabs (#3439),
bare-repo project config read from the object store when the default
branch is checked out nowhere (#3462), shell detection via the process
tree (#3455), and `wt config state` flagging a stale default-branch
cache (#3478). Full details in CHANGELOG.md.

> _This was written by Claude Code on behalf of max_
2026-07-15 16:18:23 -07:00