Skip to content

Sync upstream main (21 commits, remove/prune fixes) - #9

Merged
Bennyjitsu merged 22 commits into
mainfrom
sync-upstream-2026-09-23
Sep 23, 2026
Merged

Bennyjitsu merged 22 commits into
mainfrom
sync-upstream-2026-09-23

Conversation

@Bennyjitsu

Copy link
Copy Markdown
Owner

Syncs the fork's main with max-sixty/worktrunk main (21 commits, merged clean, no conflicts).

Why: codebench is about to make git wt the mandatory worktree lifecycle for Claude/Grok/Codex, relying on wt remove for teardown. Three of the incoming fixes land exactly there:

Remaining 17 are CI/deps/docs/upstream-skill housekeeping plus a GitLab-only wt list perf change.

Verification (Windows):

  • cargo build --release clean; binary reports v0.79.0-50-gffdc5e09e
  • cargo test --test integration -- remove prune: 216 passed, 0 failed
  • Diff scan of incoming src/ + Cargo.toml: no new dependencies, no unsafe, no network or new process-spawn code

Not run: full wt hook pre-merge --yes gate (WSL2).

After merge: rebuild and copy both wt.exe and git-wt.exe from main.

🤖 Generated with Claude Code

max-sixty and others added 22 commits September 20, 2026 23:30
The documentation terminal examples were captured one column narrower
than their content rail, leaving a character-sized trailing gap.

Align the content rail with the 99-column documentation capture, reduce
output-row right padding while preserving command-row copy-control
clearance, and cover the geometry across the responsive
table-of-contents transition.

Checks:

- `cargo run -- hook pre-merge --yes`
- `npm --prefix docs run check`
- `npm --prefix docs test`
- `npm --prefix docs run build`
- `npm --prefix docs run test:site`

> _This was written by Codex on behalf of max-sixty_
Bumps
[codecov/codecov-action](https://github.com/codecov/codecov-action) from
7.1.0 to 7.1.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/codecov/codecov-action/releases">codecov/codecov-action's
releases</a>.</em></p>
<blockquote>
<h2>v7.1.1</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(release): 7.1.1 by <a
href="https://github.com/thomasrockhu-codecov"><code>@​thomasrockhu-codecov</code></a>
in <a
href="https://redirect.github.com/codecov/codecov-action/pull/1973">codecov/codecov-action#1973</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/codecov/codecov-action/compare/v7.1.0...v7.1.1">https://github.com/codecov/codecov-action/compare/v7.1.0...v7.1.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/codecov/codecov-action/commit/303a32d7a59b442fa8d48b6a1cc6825c09c847a5"><code>303a32d</code></a>
chore(release): 7.1.1 (<a
href="https://redirect.github.com/codecov/codecov-action/issues/1973">#1973</a>)</li>
<li>See full diff in <a
href="https://github.com/codecov/codecov-action/compare/v7.1.0...v7.1.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=codecov/codecov-action&package-manager=github_actions&previous-version=7.1.0&new-version=7.1.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>
Bumps [clechasseur/rs-cargo](https://github.com/clechasseur/rs-cargo)
from 5.0.8 to 5.1.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/clechasseur/rs-cargo/releases">clechasseur/rs-cargo's
releases</a>.</em></p>
<blockquote>
<h2>v5.1.0</h2>
<p>New release supporting any Cargo-like tool, not just
<code>cross</code> or <code>cargo-hack</code>. Also includes updated
dependencies with security fixes.</p>
<h2>What's Changed</h2>
<ul>
<li>chore(deps): bump js-yaml from 3.15.1 to 3.15.2 in the npm_and_yarn
group across 1 directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/clechasseur/rs-cargo/pull/444">clechasseur/rs-cargo#444</a></li>
<li>feat: add support for any Cargo-like tool, update dependencies by <a
href="https://github.com/clechasseur"><code>@​clechasseur</code></a> in
<a
href="https://redirect.github.com/clechasseur/rs-cargo/pull/446">clechasseur/rs-cargo#446</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/clechasseur/rs-cargo/compare/v5.0.8...v5.1.0">https://github.com/clechasseur/rs-cargo/compare/v5.0.8...v5.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/a12d4742fa9b832ccb29dc394a68ab577b0c9fb8"><code>a12d474</code></a>
Merge pull request <a
href="https://redirect.github.com/clechasseur/rs-cargo/issues/446">#446</a>
from clechasseur/fix/update-deps</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/616591a16783f2dc66acebb6d44b1f17f3be6ba2"><code>616591a</code></a>
chore: no need to install Rust for JS tests</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/fc708847eb212f6e0e9cd3c86f36cf9048c6b5d1"><code>fc70884</code></a>
Merge remote-tracking branch 'origin/fix/update-deps' into
fix/update-deps</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/6865ea83a8714d7b153bc2650cf45aaeb19b7f23"><code>6865ea8</code></a>
feat: bump version to 5.1.0</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/d8a7778d7ed4fcc315ceda48017abb7acd960ba2"><code>d8a7778</code></a>
chore: set <code>build-warnings: warn</code> to be able to test
warnings</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/dc125d7fcbfcab3b2448ab8a10a7cc4bf696e7d0"><code>dc125d7</code></a>
Merge remote-tracking branch
'origin/renovate/actions-rust-lang-setup-rust-to...</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/d292f7b8ad975dce5e03f59267ce2d0a3a292c51"><code>d292f7b</code></a>
feat: update <code>@clechasseur/rs-actions-core</code> to 10.0.0</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/6a9d914da64ee73b2c6207a9f8b80ab6867f0e80"><code>6a9d914</code></a>
fix: update dependencies</li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/3d0012d8a793d6cf529b6836205fc13add233f60"><code>3d0012d</code></a>
chore: ignore warning about <code>isolatedModules: false</code></li>
<li><a
href="https://github.com/clechasseur/rs-cargo/commit/c7158e86c968466e17fc4a2d83175cfb53be1d84"><code>c7158e8</code></a>
chore(deps): bump js-yaml in the npm_and_yarn group across 1 directory
(<a
href="https://redirect.github.com/clechasseur/rs-cargo/issues/444">#444</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/clechasseur/rs-cargo/compare/v5.0.8...v5.1.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=clechasseur/rs-cargo&package-manager=github_actions&previous-version=5.0.8&new-version=5.1.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>
Bumps the docs-site group in /docs with 2 updates:
[@astrojs/starlight](https://github.com/withastro/starlight/tree/HEAD/packages/starlight)
and
[astro](https://github.com/withastro/astro/tree/HEAD/packages/astro).

Updates `@astrojs/starlight` from 0.42.0 to 0.42.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/withastro/starlight/releases">@​astrojs/starlight's
releases</a>.</em></p>
<blockquote>
<h2><code>@​astrojs/starlight</code><a
href="https://github.com/0"><code>@​0</code></a>.42.1</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/withastro/starlight/pull/4198">#4198</a>
<a
href="https://github.com/withastro/starlight/commit/96a44d4f296b512febc6e631a587103ec5297872"><code>96a44d4</code></a>
Thanks <a
href="https://github.com/mayank99"><code>@​mayank99</code></a>! -
Removes the <code>popover</code> attribute from the sidebar pane on
desktop viewports. This ensures the desktop sidebar doesn't stay in a
&quot;hidden&quot; popover visibility state.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/withastro/starlight/blob/main/packages/starlight/CHANGELOG.md">@​astrojs/starlight's
changelog</a>.</em></p>
<blockquote>
<h2>0.42.1</h2>
<h3>Patch Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/withastro/starlight/pull/4198">#4198</a>
<a
href="https://github.com/withastro/starlight/commit/96a44d4f296b512febc6e631a587103ec5297872"><code>96a44d4</code></a>
Thanks <a
href="https://github.com/mayank99"><code>@​mayank99</code></a>! -
Removes the <code>popover</code> attribute from the sidebar pane on
desktop viewports. This ensures the desktop sidebar doesn't stay in a
&quot;hidden&quot; popover visibility state.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/withastro/starlight/commit/a852070ea83ed2cc220a135fcecff202c3113852"><code>a852070</code></a>
[ci] release (<a
href="https://github.com/withastro/starlight/tree/HEAD/packages/starlight/issues/4199">#4199</a>)</li>
<li><a
href="https://github.com/withastro/starlight/commit/96a44d4f296b512febc6e631a587103ec5297872"><code>96a44d4</code></a>
remove <code>popover</code> attribute from sidebar-pane on wide
viewports (<a
href="https://github.com/withastro/starlight/tree/HEAD/packages/starlight/issues/4198">#4198</a>)</li>
<li>See full diff in <a
href="https://github.com/withastro/starlight/commits/@astrojs/starlight@0.42.1/packages/starlight">compare
view</a></li>
</ul>
</details>
<br />

Updates `astro` from 7.3.2 to 7.3.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/withastro/astro/releases">astro's
releases</a>.</em></p>
<blockquote>
<h2>astro@7.3.3</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17651">#17651</a>
<a
href="https://github.com/withastro/astro/commit/504333c2a0c7da3ca06e39ce37eee832192ba8ea"><code>504333c</code></a>
Thanks <a href="https://github.com/sxzz"><code>@​sxzz</code></a>! -
Refactors internal version handling to use a smaller, ESM-native
dependency</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17942">#17942</a>
<a
href="https://github.com/withastro/astro/commit/0bc5715a2990a84598a064ac8de52c08fffd1186"><code>0bc5715</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! -
Returns appropriate 400 and 404 responses from the image endpoint for
invalid and missing local image paths</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17700">#17700</a>
<a
href="https://github.com/withastro/astro/commit/b2222fc3cdbeb1b75029a109d13d19515e5260ae"><code>b2222fc</code></a>
Thanks <a
href="https://github.com/winklemad"><code>@​winklemad</code></a>! -
Fixes <code>Astro.preferredLocaleList</code> returning an empty list
when a locale is configured with the object form (<code>{ path, codes
}</code>) and the browser sends the code with different casing or an
underscore, such as <code>en-US</code> matching a configured
<code>en-us</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17941">#17941</a>
<a
href="https://github.com/withastro/astro/commit/394ff79954e5822e3884947a07d84fef0c72f31c"><code>394ff79</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! - Fixes
<code>astro preview --ignore-lock</code> (and <code>astro dev
--ignore-lock</code>) being refused when run from an AI agent
environment. The flag now starts the server in the foreground instead of
erroring, since agent detection only inferred background mode and was
never explicitly requested. An explicit <code>--background</code>
combined with <code>--ignore-lock</code> still errors.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17928">#17928</a>
<a
href="https://github.com/withastro/astro/commit/327792719475cf5b0023dd8983cfd0dc58070888"><code>3277927</code></a>
Thanks <a
href="https://github.com/ArmandPhilippot"><code>@​ArmandPhilippot</code></a>!
- Fixes TypeScript autocompletion for <code>getImage()</code> to suggest
all available predefined options.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17928">#17928</a>
<a
href="https://github.com/withastro/astro/commit/327792719475cf5b0023dd8983cfd0dc58070888"><code>3277927</code></a>
Thanks <a
href="https://github.com/ArmandPhilippot"><code>@​ArmandPhilippot</code></a>!
- Fixes a type error in <code>getImage()</code> options that allowed
passing both <code>widths</code> and <code>densities</code> at the same
time.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17857">#17857</a>
<a
href="https://github.com/withastro/astro/commit/2637ed10afd26f1f29db673616c6225eb0d848a6"><code>2637ed1</code></a>
Thanks <a
href="https://github.com/Princesseuh"><code>@​Princesseuh</code></a>! -
Improves rendering performance</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17943">#17943</a>
<a
href="https://github.com/withastro/astro/commit/2fc7ce98f982f45533d91b6ba5b95fce4eb54e11"><code>2fc7ce9</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! - Fixes
a WebAssembly error when importing <code>astro:actions</code> in tests
that run under <code>@cloudflare/vitest-pool-workers</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/18018">#18018</a>
<a
href="https://github.com/withastro/astro/commit/1b5a234f5205995ff3a1c7707c093e49f1f601e7"><code>1b5a234</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes trailing-slash redirect response body pointing to the incoming
URL instead of the redirect target. The <code>location</code> header was
correct, but the HTML body (<code>&lt;meta
http-equiv=&quot;refresh&quot;&gt;</code>, <code>&lt;title&gt;</code>,
and <code>&lt;a&gt;</code> tag) contained the original request path
without the trailing-slash correction or query string.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17905">#17905</a>
<a
href="https://github.com/withastro/astro/commit/eaf70fa3f0b5d01237d9af8110649ded2e239b5d"><code>eaf70fa</code></a>
Thanks <a
href="https://github.com/SudoDevStudio"><code>@​SudoDevStudio</code></a>!
- Fixes custom dev toolbar apps losing their UI after client-side
navigation with <code>&lt;ClientRouter /&gt;</code>.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/18011">#18011</a>
<a
href="https://github.com/withastro/astro/commit/558b301a3626e5f0fd3ae4e3997e0c6de53e9867"><code>558b301</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes prerendered Cloudflare pages rendering as <code>[object
Object]</code> when <code>nodejs_compat</code> is enabled in
<code>wrangler.toml</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17944">#17944</a>
<a
href="https://github.com/withastro/astro/commit/ba08e35fdc306219b69428e3e1c4e5816e116956"><code>ba08e35</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! - Fixes
a regression in <code>astro dev</code> where writes outside the module
graph (for example, <code>@astrojs/cloudflare</code>'s
<code>.wrangler/state</code> files) invalidated the middleware on every
request, causing repeated SSR reloads. Such writes no longer invalidate
the middleware.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17531">#17531</a>
<a
href="https://github.com/withastro/astro/commit/ae837dbc692ba831ab9cc5bfebef403d72980ca0"><code>ae837db</code></a>
Thanks <a
href="https://github.com/danilloestrela"><code>@​danilloestrela</code></a>!
- Updates <code>svgo</code> to <code>4.0.2</code> to resolve a security
advisory</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17953">#17953</a>
<a
href="https://github.com/withastro/astro/commit/dbbf10e606f64b4ba2b8362868b6a27a9a937eb8"><code>dbbf10e</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes a one-time page reload shortly after the first load on cold
dev-server starts when a project has framework components imported from
MDX content entries. MDX files are now included in the dev dependency
pre-bundling scan, so their framework dependencies are bundled up front
instead of being discovered (and reloaded for) at runtime.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17955">#17955</a>
<a
href="https://github.com/withastro/astro/commit/4e8ad9a40affe6ae0a6c268a2100a203415479b6"><code>4e8ad9a</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! -
Improves dev server startup time. The content config and dev server app
module graphs now begin compiling during server creation without
blocking the server from listening. Request handling waits for the
shared setup result when needed, cutting <code>astro dev</code> ready
time by roughly a third on projects with a content config.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17960">#17960</a>
<a
href="https://github.com/withastro/astro/commit/98380490cef49418770102829f160942051a65b9"><code>9838049</code></a>
Thanks <a
href="https://github.com/Chy-Zaber-Bin-Zahid"><code>@​Chy-Zaber-Bin-Zahid</code></a>!
- Improves the diagnostics of some Astro errors.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17998">#17998</a>
<a
href="https://github.com/withastro/astro/commit/0e5478dff592653f3fa72ad51a38915648e4e8ad"><code>0e5478d</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes SVG <code>&lt;style&gt;</code> elements nested inside
<code>&lt;defs&gt;</code> or other container elements not being hashed
for CSP</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17994">#17994</a>
<a
href="https://github.com/withastro/astro/commit/80f9f1d5364329de9ee97ef48d42fefe8535d2ef"><code>80f9f1d</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes <code>experimental.incrementalBuild</code> restoring pages with
stale CSS after a preprocessor partial changes or missing original
images referenced by restored pages</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17889">#17889</a>
<a
href="https://github.com/withastro/astro/commit/8ae6b4669c6543212d8384f883c33a4d50451aaa"><code>8ae6b46</code></a>
Thanks <a href="https://github.com/ajfAfg"><code>@​ajfAfg</code></a>! -
Fixes a bug where the dev server stripped the configured
<code>base</code> from URLs that only share a prefix with it. With
<code>base: '/s'</code>, requests to <code>/src/...</code> were
rewritten to <code>/rc/...</code> and failed, breaking those pages
during development.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17980">#17980</a>
<a
href="https://github.com/withastro/astro/commit/cfccafa9506250832b659b6c5c62c85ce081aee5"><code>cfccafa</code></a>
Thanks <a
href="https://github.com/gameroman"><code>@​gameroman</code></a>! -
Improves JSDoc for fonts api</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17953">#17953</a>
<a
href="https://github.com/withastro/astro/commit/dbbf10e606f64b4ba2b8362868b6a27a9a937eb8"><code>dbbf10e</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes CSS HMR for framework components rendered through content
entries after <code>ClientRouter</code> navigation</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17970">#17970</a>
<a
href="https://github.com/withastro/astro/commit/0b4dc3a211910b589d3805ab4dfedf11b0e712bb"><code>0b4dc3a</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! -
Improves serialization of transition animation values in generated
CSS</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17999">#17999</a>
<a
href="https://github.com/withastro/astro/commit/30ef3cbb76550d45ec59e6c3201544df859c997a"><code>30ef3cb</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes content collection HMR not updating prerendered pages when an
adapter enables a separate prerender environment (e.g.
<code>@astrojs/cloudflare</code> with <code>prerenderEnvironment:
'node'</code>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/18002">#18002</a>
<a
href="https://github.com/withastro/astro/commit/312ab49544eed1220453ed86c40896f49e31c7a9"><code>312ab49</code></a>
Thanks <a
href="https://github.com/shoutoutuoadi325"><code>@​shoutoutuoadi325</code></a>!
- Fixes redirect targets being corrupted when a dynamic route parameter
value contains <code>$</code> replacement patterns like
<code>$&amp;</code></p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md">astro's
changelog</a>.</em></p>
<blockquote>
<h2>7.3.3</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17651">#17651</a>
<a
href="https://github.com/withastro/astro/commit/504333c2a0c7da3ca06e39ce37eee832192ba8ea"><code>504333c</code></a>
Thanks <a href="https://github.com/sxzz"><code>@​sxzz</code></a>! -
Refactors internal version handling to use a smaller, ESM-native
dependency</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17942">#17942</a>
<a
href="https://github.com/withastro/astro/commit/0bc5715a2990a84598a064ac8de52c08fffd1186"><code>0bc5715</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! -
Returns appropriate 400 and 404 responses from the image endpoint for
invalid and missing local image paths</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17700">#17700</a>
<a
href="https://github.com/withastro/astro/commit/b2222fc3cdbeb1b75029a109d13d19515e5260ae"><code>b2222fc</code></a>
Thanks <a
href="https://github.com/winklemad"><code>@​winklemad</code></a>! -
Fixes <code>Astro.preferredLocaleList</code> returning an empty list
when a locale is configured with the object form (<code>{ path, codes
}</code>) and the browser sends the code with different casing or an
underscore, such as <code>en-US</code> matching a configured
<code>en-us</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17941">#17941</a>
<a
href="https://github.com/withastro/astro/commit/394ff79954e5822e3884947a07d84fef0c72f31c"><code>394ff79</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! - Fixes
<code>astro preview --ignore-lock</code> (and <code>astro dev
--ignore-lock</code>) being refused when run from an AI agent
environment. The flag now starts the server in the foreground instead of
erroring, since agent detection only inferred background mode and was
never explicitly requested. An explicit <code>--background</code>
combined with <code>--ignore-lock</code> still errors.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17928">#17928</a>
<a
href="https://github.com/withastro/astro/commit/327792719475cf5b0023dd8983cfd0dc58070888"><code>3277927</code></a>
Thanks <a
href="https://github.com/ArmandPhilippot"><code>@​ArmandPhilippot</code></a>!
- Fixes TypeScript autocompletion for <code>getImage()</code> to suggest
all available predefined options.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17928">#17928</a>
<a
href="https://github.com/withastro/astro/commit/327792719475cf5b0023dd8983cfd0dc58070888"><code>3277927</code></a>
Thanks <a
href="https://github.com/ArmandPhilippot"><code>@​ArmandPhilippot</code></a>!
- Fixes a type error in <code>getImage()</code> options that allowed
passing both <code>widths</code> and <code>densities</code> at the same
time.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17857">#17857</a>
<a
href="https://github.com/withastro/astro/commit/2637ed10afd26f1f29db673616c6225eb0d848a6"><code>2637ed1</code></a>
Thanks <a
href="https://github.com/Princesseuh"><code>@​Princesseuh</code></a>! -
Improves rendering performance</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17943">#17943</a>
<a
href="https://github.com/withastro/astro/commit/2fc7ce98f982f45533d91b6ba5b95fce4eb54e11"><code>2fc7ce9</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! - Fixes
a WebAssembly error when importing <code>astro:actions</code> in tests
that run under <code>@cloudflare/vitest-pool-workers</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/18018">#18018</a>
<a
href="https://github.com/withastro/astro/commit/1b5a234f5205995ff3a1c7707c093e49f1f601e7"><code>1b5a234</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes trailing-slash redirect response body pointing to the incoming
URL instead of the redirect target. The <code>location</code> header was
correct, but the HTML body (<code>&lt;meta
http-equiv=&quot;refresh&quot;&gt;</code>, <code>&lt;title&gt;</code>,
and <code>&lt;a&gt;</code> tag) contained the original request path
without the trailing-slash correction or query string.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17905">#17905</a>
<a
href="https://github.com/withastro/astro/commit/eaf70fa3f0b5d01237d9af8110649ded2e239b5d"><code>eaf70fa</code></a>
Thanks <a
href="https://github.com/SudoDevStudio"><code>@​SudoDevStudio</code></a>!
- Fixes custom dev toolbar apps losing their UI after client-side
navigation with <code>&lt;ClientRouter /&gt;</code>.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/18011">#18011</a>
<a
href="https://github.com/withastro/astro/commit/558b301a3626e5f0fd3ae4e3997e0c6de53e9867"><code>558b301</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes prerendered Cloudflare pages rendering as <code>[object
Object]</code> when <code>nodejs_compat</code> is enabled in
<code>wrangler.toml</code></p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17944">#17944</a>
<a
href="https://github.com/withastro/astro/commit/ba08e35fdc306219b69428e3e1c4e5816e116956"><code>ba08e35</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! - Fixes
a regression in <code>astro dev</code> where writes outside the module
graph (for example, <code>@astrojs/cloudflare</code>'s
<code>.wrangler/state</code> files) invalidated the middleware on every
request, causing repeated SSR reloads. Such writes no longer invalidate
the middleware.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17531">#17531</a>
<a
href="https://github.com/withastro/astro/commit/ae837dbc692ba831ab9cc5bfebef403d72980ca0"><code>ae837db</code></a>
Thanks <a
href="https://github.com/danilloestrela"><code>@​danilloestrela</code></a>!
- Updates <code>svgo</code> to <code>4.0.2</code> to resolve a security
advisory</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17953">#17953</a>
<a
href="https://github.com/withastro/astro/commit/dbbf10e606f64b4ba2b8362868b6a27a9a937eb8"><code>dbbf10e</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes a one-time page reload shortly after the first load on cold
dev-server starts when a project has framework components imported from
MDX content entries. MDX files are now included in the dev dependency
pre-bundling scan, so their framework dependencies are bundled up front
instead of being discovered (and reloaded for) at runtime.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17955">#17955</a>
<a
href="https://github.com/withastro/astro/commit/4e8ad9a40affe6ae0a6c268a2100a203415479b6"><code>4e8ad9a</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! -
Improves dev server startup time. The content config and dev server app
module graphs now begin compiling during server creation without
blocking the server from listening. Request handling waits for the
shared setup result when needed, cutting <code>astro dev</code> ready
time by roughly a third on projects with a content config.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17960">#17960</a>
<a
href="https://github.com/withastro/astro/commit/98380490cef49418770102829f160942051a65b9"><code>9838049</code></a>
Thanks <a
href="https://github.com/Chy-Zaber-Bin-Zahid"><code>@​Chy-Zaber-Bin-Zahid</code></a>!
- Improves the diagnostics of some Astro errors.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17998">#17998</a>
<a
href="https://github.com/withastro/astro/commit/0e5478dff592653f3fa72ad51a38915648e4e8ad"><code>0e5478d</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes SVG <code>&lt;style&gt;</code> elements nested inside
<code>&lt;defs&gt;</code> or other container elements not being hashed
for CSP</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17994">#17994</a>
<a
href="https://github.com/withastro/astro/commit/80f9f1d5364329de9ee97ef48d42fefe8535d2ef"><code>80f9f1d</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes <code>experimental.incrementalBuild</code> restoring pages with
stale CSS after a preprocessor partial changes or missing original
images referenced by restored pages</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17889">#17889</a>
<a
href="https://github.com/withastro/astro/commit/8ae6b4669c6543212d8384f883c33a4d50451aaa"><code>8ae6b46</code></a>
Thanks <a href="https://github.com/ajfAfg"><code>@​ajfAfg</code></a>! -
Fixes a bug where the dev server stripped the configured
<code>base</code> from URLs that only share a prefix with it. With
<code>base: '/s'</code>, requests to <code>/src/...</code> were
rewritten to <code>/rc/...</code> and failed, breaking those pages
during development.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17980">#17980</a>
<a
href="https://github.com/withastro/astro/commit/cfccafa9506250832b659b6c5c62c85ce081aee5"><code>cfccafa</code></a>
Thanks <a
href="https://github.com/gameroman"><code>@​gameroman</code></a>! -
Improves JSDoc for fonts api</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17953">#17953</a>
<a
href="https://github.com/withastro/astro/commit/dbbf10e606f64b4ba2b8362868b6a27a9a937eb8"><code>dbbf10e</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes CSS HMR for framework components rendered through content
entries after <code>ClientRouter</code> navigation</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17970">#17970</a>
<a
href="https://github.com/withastro/astro/commit/0b4dc3a211910b589d3805ab4dfedf11b0e712bb"><code>0b4dc3a</code></a>
Thanks <a
href="https://github.com/matthewp"><code>@​matthewp</code></a>! -
Improves serialization of transition animation values in generated
CSS</p>
</li>
<li>
<p><a
href="https://redirect.github.com/withastro/astro/pull/17999">#17999</a>
<a
href="https://github.com/withastro/astro/commit/30ef3cbb76550d45ec59e6c3201544df859c997a"><code>30ef3cb</code></a>
Thanks <a
href="https://github.com/apps/astro-factory"><code>@​astro-factory</code></a>!
- Fixes content collection HMR not updating prerendered pages when an
adapter enables a separate prerender environment (e.g.
<code>@astrojs/cloudflare</code> with <code>prerenderEnvironment:
'node'</code>)</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/withastro/astro/commit/8a3106e56abb46b0171688dd54d2570a308a70f6"><code>8a3106e</code></a>
[ci] release (<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/17939">#17939</a>)</li>
<li><a
href="https://github.com/withastro/astro/commit/5efea1bfea8fc59a0c566488eccdd4b2eea3667e"><code>5efea1b</code></a>
Add a version field to the astro-client-only fixture</li>
<li><a
href="https://github.com/withastro/astro/commit/80f9f1d5364329de9ee97ef48d42fefe8535d2ef"><code>80f9f1d</code></a>
Hash compiled CSS output in incremental build to detect Sass partial
changes ...</li>
<li><a
href="https://github.com/withastro/astro/commit/bc6572f5ef434fb8538883be0b12c6c2bc200fa0"><code>bc6572f</code></a>
Revert &quot;Forward user class to Picture's outer element&quot; (<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/18004">#18004</a>)
(<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/18030">#18030</a>)</li>
<li><a
href="https://github.com/withastro/astro/commit/0e5478dff592653f3fa72ad51a38915648e4e8ad"><code>0e5478d</code></a>
Normalize CRLF line endings before computing CSP hashes (<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/17998">#17998</a>)</li>
<li><a
href="https://github.com/withastro/astro/commit/30ef3cbb76550d45ec59e6c3201544df859c997a"><code>30ef3cb</code></a>
fix: invalidate prerender environment in invalidateDataStore (<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/17991">#17991</a>)
(<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/17999">#17999</a>)</li>
<li><a
href="https://github.com/withastro/astro/commit/312ab49544eed1220453ed86c40896f49e31c7a9"><code>312ab49</code></a>
Fix redirect targets when a param value contains a <code>$</code>
replacement pattern (#...</li>
<li><a
href="https://github.com/withastro/astro/commit/1b5a234f5205995ff3a1c7707c093e49f1f601e7"><code>1b5a234</code></a>
Fix trailing-slash redirect body to match the Location header target (<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/18018">#18018</a>)</li>
<li><a
href="https://github.com/withastro/astro/commit/558b301a3626e5f0fd3ae4e3997e0c6de53e9867"><code>558b301</code></a>
Fix prerendered Cloudflare pages rendering as [object Object] with
nodejs_com...</li>
<li><a
href="https://github.com/withastro/astro/commit/4464b3a90169ff5275dbde4a1292410c1371f50c"><code>4464b3a</code></a>
fix(assets): forward class to picture element in Picture component (<a
href="https://github.com/withastro/astro/tree/HEAD/packages/astro/issues/18003">#18003</a>)
(...</li>
<li>Additional commits viewable in <a
href="https://github.com/withastro/astro/commits/astro@7.3.3/packages/astro">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>
…#4211)

Bumps
[taiki-e/install-action](https://github.com/taiki-e/install-action) from
2.87.13 to 2.87.15.
<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.87.15</h2>
<ul>
<li>
<p>Update <code>syft@latest</code> to 1.52.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.9.10.</p>
</li>
<li>
<p>Update <code>kingfisher@latest</code> to 2.4.0.</p>
</li>
<li>
<p>Update <code>kache@latest</code> to 0.23.1.</p>
</li>
<li>
<p>Update <code>coreutils@latest</code> to 0.12.0.</p>
</li>
<li>
<p>Update <code>cargo-nextest@latest</code> to 0.9.145.</p>
</li>
</ul>
<h2>2.87.14</h2>
<ul>
<li>
<p>Update <code>vacuum@latest</code> to 0.30.6.</p>
</li>
<li>
<p>Update <code>uv@latest</code> to 0.12.15.</p>
</li>
<li>
<p>Update <code>typos@latest</code> to 1.50.2.</p>
</li>
<li>
<p>Update <code>sccache@latest</code> to 0.18.0.</p>
</li>
<li>
<p>Update <code>oxfmt@latest</code> to 1.83.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.9.9.</p>
</li>
<li>
<p>Update <code>kingfisher@latest</code> to 2.3.0.</p>
</li>
<li>
<p>Update <code>kache@latest</code> to 0.22.0.</p>
</li>
<li>
<p>Update <code>biome@latest</code> to 2.5.14.</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.87.15] - 2026-09-18</h2>
<ul>
<li>
<p>Update <code>syft@latest</code> to 1.52.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.9.10.</p>
</li>
<li>
<p>Update <code>kingfisher@latest</code> to 2.4.0.</p>
</li>
<li>
<p>Update <code>kache@latest</code> to 0.23.1.</p>
</li>
<li>
<p>Update <code>coreutils@latest</code> to 0.12.0.</p>
</li>
<li>
<p>Update <code>cargo-nextest@latest</code> to 0.9.145.</p>
</li>
</ul>
<h2>[2.87.14] - 2026-09-17</h2>
<ul>
<li>
<p>Update <code>vacuum@latest</code> to 0.30.6.</p>
</li>
<li>
<p>Update <code>uv@latest</code> to 0.12.15.</p>
</li>
<li>
<p>Update <code>typos@latest</code> to 1.50.2.</p>
</li>
<li>
<p>Update <code>sccache@latest</code> to 0.18.0.</p>
</li>
<li>
<p>Update <code>oxfmt@latest</code> to 1.83.0.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.9.9.</p>
</li>
<li>
<p>Update <code>kingfisher@latest</code> to 2.3.0.</p>
</li>
<li>
<p>Update <code>kache@latest</code> to 0.22.0.</p>
</li>
<li>
<p>Update <code>biome@latest</code> to 2.5.14.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/taiki-e/install-action/commit/4076c08d76dba979c11a7285295b0716c1d67908"><code>4076c08</code></a>
Release 2.87.15</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/f094888c5791ae387911f93453f99883b07e21d7"><code>f094888</code></a>
Update uv manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/df9870f5d066ae12320fddfddc94d0a33a827c0e"><code>df9870f</code></a>
Update <code>syft@latest</code> to 1.52.0</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/d432ab24a3d5e1a4c90d5d79dc75db5cca39349c"><code>d432ab2</code></a>
Update release-plz manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/f2e9e6cfe93e0a85218642d16cb0211924c3a79e"><code>f2e9e6c</code></a>
Update protoc manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/55468834f6c05f71d0252577556ae8db9209b7f6"><code>5546883</code></a>
Update <code>mise@latest</code> to 2026.9.10</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/6dfd42ab1ba4866ac60f829603c182c250acc5f3"><code>6dfd42a</code></a>
Update <code>kingfisher@latest</code> to 2.4.0</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/5157ed3a9e5930980b523c09776d2ee117dfdd20"><code>5157ed3</code></a>
Update <code>kache@latest</code> to 0.23.1</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/78a18ea63bde66c8cfc44b49547da89159f6692c"><code>78a18ea</code></a>
Update <code>coreutils@latest</code> to 0.12.0</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/b02e9c7b26f6b943d3c1b7c263caa72f85950d39"><code>b02e9c7</code></a>
Update <code>cargo-nextest@latest</code> to 0.9.145</li>
<li>Additional commits viewable in <a
href="https://github.com/taiki-e/install-action/compare/v2.87.13...v2.87.15">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.87.13&new-version=2.87.15)](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>
Regenerates the `tend-*` workflows with tend 0.2.13 (from 0.2.11).
Mechanically the diff is the action pin `max-sixty/tend/claude@0.2.11` →
`@0.2.13` in the eight workflows that run the agent, the
`astral-sh/setup-uv` pin `0.12.13` → `0.12.17` in the two that install
uv directly (`tend-mention`, `tend-notifications`), and a regenerated
header comment in all nine.

The upgrade that matters for this repo is in CI polling.
`poll_pr_checks.py` previously treated any gating check that settled
without a red conclusion as green — so a required check belonging to a
**cancelled** or **stale** run, or a `COMPLETED` check carrying no
conclusion at all, let the bot report a PR as green when nothing had
actually verified it. 0.2.13 splits those out as `unverified` and gives
`poll` a distinct exit code for them (max-sixty/tend#1323). Practically:
fewer "checks went green" claims on PRs whose required jobs were
cancelled, at the cost of some polls ending unverified rather than
green.

The rest, in rough order of how visible it is here:

- **Sandbox reliability** — the sandbox runtime now retries past a
transient bridge-socket failure at launch (max-sixty/tend#1327). That
failure is one of the shapes that produces a `tend-outage` issue, so it
should show up as fewer of those.
- **Sandbox environment** — root `/tmp` is writable inside the sandbox
(max-sixty/tend#1324); the `run-tend` skill's note that it was read-only
is gone. This repo's `running-tend` skill still restates that note, so
it goes stale when this merges — I'll follow up separately rather than
mix a skill edit into the generated-workflow diff.
- **Instruction-path pinning** — the `run-tend` skill's description of
which paths get restored from the PR base, and on which events, was
wrong in 0.2.11; `.agents/` is now named alongside `.claude/`, and the
event list is corrected (max-sixty/tend#1311). The restore behavior
itself is unchanged.
- **Auth hygiene** — the bot's claude.ai account is kept out of CI
sessions (max-sixty/tend#1328).
- **Harness pins** — claude-code 2.1.278 (max-sixty/tend#1330), uv
0.12.17 (max-sixty/tend#1331).

`.config/tend.yaml` pins no model, so the harness-default check found
nothing to adjust.

Full comparison:
max-sixty/tend@0.2.11...0.2.13

<details><summary>Copy-on-write sandbox view: landed and reverted within
this range</summary>

max-sixty/tend#1333 and max-sixty/tend#1334 moved the agent into the
job's own checkout and home through a copy-on-write view;
max-sixty/tend#1339 reverted both before 0.2.13. Nothing from that work
is in this diff — noted so a later reader doesn't chase it out of the
commit list.

</details>

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
…max-sixty#4217)

`main` now pins `max-sixty/tend/claude@0.2.13` (max-sixty#4215, merged as
`c5e17139a`), and two sandbox facts this overlay asserts stopped being
true of the sandbox sessions actually run in.

**Root `/tmp` is writable.**
[max-sixty/tend#1324](max-sixty/tend#1324)
("Make /tmp writable inside the sandbox") merged 2026-09-19, after
0.2.11 and before 0.2.12. In the `0.2.11...0.2.13` diff the sandbox's
own SRT test flips its probe: `touch /tmp/tend-unscoped` must fail at
0.2.11, while at 0.2.13 `touch /tmp/tend-sandbox-scratch` must succeed
and `/var/tmp` is the refused one. Tend dropped the matching paragraph
from its bundled `run-tend` skill in the same range, along with the
`TMPPREFIX` override whose comment said it existed only because zsh's
here-document default "sits in the read-only root /tmp".

**The agent workspace container moved to `/var/tmp`.**
`prepare_agent_workspace.py` at 0.2.13 calls
`mkdtemp(prefix="tend-agent-workspace-", dir="/var/tmp")`, so the
slugified session-log directory is `-var-tmp-…`, not `-tmp-…`.

Neither edit changes what a session should do. `${TMPDIR:-/tmp}` is
still where scratch files belong, and the log-path section's conclusion
— there is no literal to match on, so use `find "$DEST" -name '*.jsonl'`
— is if anything better supported by a container that moves between
releases. What goes is the justification attached to each, which is the
part that could go stale and did.

The old text was accurate right up to the merge: a write probe in this
run, still on 0.2.11, is refused with `Read-only file system`. It is
wrong from the next session on, which is why this is a deletion rather
than a rewrite — the overlay is better off not restating a boundary tend
owns and moves.

<details><summary>Where this was found</summary>

The `tend-review` session on max-sixty#4215 ([run
35570800500](https://github.com/max-sixty/worktrunk/actions/runs/35570800500))
noticed the overlay would go stale on merge and deliberately left it
alone, on the grounds that `.claude/**` is restored from the base branch
during a review session and a separate PR is the cleaner home. This is
that PR, opened from the `tend-review-runs` sweep that can edit
`.claude/skills/` from a `$TMPDIR` worktree.

</details>

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
Regenerates the tend workflows with tend 0.2.14 ahead of the nightly
update, to trial the release here.

0.2.14 runs the agent in a hardened systemd unit instead of Anthropic
Sandbox Runtime, over a copy-on-write view of the job's own checkout and
home (max-sixty/tend#1346, max-sixty/tend#1354). `sandbox_setup:` is
deprecated, so `init` now runs its commands as an ordinary step after
`setup:`, as the runner user, and the agent sees what they install
through the view. `.config/tend.yaml` keeps the key for now, so a
release that reverts 0.2.14 would still find it.

Release notes: https://github.com/max-sixty/tend/releases/tag/0.2.14

> _This was written by Claude Code on behalf of max-sixty_

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

Co-authored-by: Maximilian Roos <maximilian@MacBook-Pro-2.local>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…iew (max-sixty#4224)

tend 0.2.14 (landed today in max-sixty#4222) moved the agent off Anthropic
Sandbox Runtime and onto a hardened systemd unit over a copy-on-write
view of the job's own checkout and home. Four files here still describe
the 0.2.5–0.2.13 arrangement they were written for, and their central
claims are now observably false from inside a session. That matters
because `.github/CLAUDE.md` and `running-tend` are what an agent reads
before touching CI: told the runner's home is unreadable, it keeps
building hand-offs nothing needs and rules out a cache that would now
work. Comments and instructions only — no step, key, or behavior
changes.

## What stopped being true

Probed from tend 0.2.14 sessions:

| Documented claim | Observed |
| --- | --- |
| Agent PATH rewrites a leading `/home/runner` to `/home/tend-sandbox` |
`$HOME` is `/home/runner`, and PATH entries resolve there |
| The agent builds in a disposable `/tmp` clone | cwd is
`/home/runner/work/worktrunk/worktrunk`, the runner's own checkout |
| Sandbox Runtime denies reads across the runner's home and checkout |
`~/.cargo`, `~/.rustup/toolchains` and `~/.cargo-install` all read fine
|
| The cargo tools reach the agent through `/usr/local/bin` | `which -a
cargo-insta` lists
`/home/runner/.cargo-install/cargo-insta/bin/cargo-insta` first,
`/usr/local/bin` second |
| `.config/tend.yaml`'s probe runs inside the sandbox, and a missing
tool files a tend-outage issue | 0.2.14's generator emits the block as
an ordinary runner step *before* `max-sixty/tend/claude`, and the filing
is `report_failure.py`, a step *inside* that action under `if:
failure()` — so a probe failure skips it and leaves only its `::error::`
annotation |
| `running-tend`: the weekly `nix` commands fail with a permission error
| `nix store info` reports `cannot create Unix domain socket: Address
family not supported by protocol` |
| `running-tend`: `-home-runner-work-worktrunk-worktrunk/` "appears only
in runs predating the bump" | This session's logs are under
`/home/tend-sandbox/.claude/projects/-home-runner-work-worktrunk-worktrunk/`
— the prefix is back |

One claim in the same paragraphs was checked and kept: `nix` still
cannot reach the daemon, so `socket(AF_UNIX, …)` is blocked under the
systemd unit too, and the weekly `flake.lock` refresh still needs
max-sixty/tend#1197. Only the errno was wrong, in two places —
`.github/actions/tend-setup/action.yaml` said `EPERM` and `running-tend`
said "a permission error"; both now carry the message the probe actually
prints.

## What this deliberately leaves alone

- **`sandbox_setup:` stays.** max-sixty#4222 gave the reason: keeping the key
means a release reverting 0.2.14 still finds it. The comment above the
block now says so, so a later sweep reads it as a deliberate hold rather
than drift to fix. Its closing probe is still worth its place — it
asserts the five tools the pre-merge gate needs, whichever step
installed them, and fails the job naming the one that went missing.
- **The `/usr/local/bin` publish step stays**, re-described as the
second copy of those binaries it now is rather than the only route.

## One follow-up this opens but does not take

`tend-setup` carries no `rust-cache` step because a restored `~/.cargo`
and `<checkout>/target` were unreachable and at the wrong path. Both are
now reachable at the path a restore writes them to, so tend sessions
build cold only because nothing restores them. The comment moves from
"blocked until max-sixty/tend#1198" to "a measurement", but no cache is
added here: that is a behavior change with a real download cost across
eight workflows, and it wants its own PR with numbers.

<details><summary>Probe output</summary>

```
$ echo "HOME=$HOME"; whoami; pwd
HOME=/home/runner
tend-sandbox
/home/runner/work/worktrunk/worktrunk

$ which -a cargo-insta
/home/runner/.cargo-install/cargo-insta/bin/cargo-insta
/usr/local/bin/cargo-insta

$ ls ~/.rustup/toolchains
stable-x86_64-unknown-linux-gnu

$ which -a pre-commit
/home/runner/.local/bin/pre-commit

$ ls -d ~/.claude/projects/*/
ls: cannot access '/home/runner/.claude/projects/*/': No such file or directory
$ ls -d /home/tend-sandbox/.claude/projects/*/
/home/tend-sandbox/.claude/projects/-home-runner-work-worktrunk-worktrunk/

$ nix store info
Store URL: daemon
error: cannot create Unix domain socket: Address family not supported by protocol
```

The probe-ordering claim comes from the generated workflows rather than
a runtime probe: `.github/workflows/tend-review.yaml` puts the
`sandbox_setup:` block between `uses: ./.github/actions/tend-setup` and
`uses: max-sixty/tend/claude@0.2.14`, and `claude/action.yaml` at tag
0.2.14 runs `report_failure.py` as its own `if: failure()` step.

</details>

---------

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
<!--pre-commit.ci start-->
updates:
- [github.com/crate-ci/typos: v1 →
v1.50.2](crate-ci/typos@v1...v1.50.2)
<!--pre-commit.ci end-->

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…-sixty#4226)

Git calls a worktree entry prunable when the `.git` file its
registration points at is gone, which also happens when only that file
went and the directory stayed. A detached checkout under macOS's
`$TMPDIR` turned up this way, with its idle files deleted and its
directories kept. `wt step prune` selected such an entry and
unregistered it with `git worktree remove`, which skips its validation
only while the directory is absent:

```
✗ pruning stale worktree for (detached 59b73365)
  fatal: validation failed, cannot remove working tree: '…/checkout/.git' does not exist
```

The failure aborted every removal still queued and failed the run, so
each later prune in that repo failed the same way.

The scan now selects a detached stale entry only when its directory is
gone, the precondition `prune_worktree_entry` already documents. An
entry whose directory remains stays registered, as its branch-bearing
twin already does: `prepare_worktree_removal` refuses that one with
`WorktreeMissing` (max-sixty#3785).

Since max-sixty#3785, no `Prunable` entry can plan the worktree removal that runs
`pre-remove`/`post-remove`, so the pessimistic hook plan stops
registering them, and the two comments that said a stale entry with a
surviving directory plans a full removal are corrected. Live worktrees
are registered as before.

`test_prune_keeps_stale_detached_entry_whose_directory_remains` deletes
a detached worktree's `.git` file, then checks that prune succeeds,
removes an integrated sibling, and leaves the entry and its directory in
place. With the fix reverted, it fails with the error above.

> _This was written by Claude Code on behalf of max-sixty_

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

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…#4227)

Bumps
[taiki-e/install-action](https://github.com/taiki-e/install-action) from
2.87.15 to 2.87.16.
<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.87.16</h2>
<ul>
<li>
<p>Update <code>uv@latest</code> to 0.12.16.</p>
</li>
<li>
<p>Update <code>release-plz@latest</code> to 0.3.168.</p>
</li>
<li>
<p>Update <code>protoc@latest</code> to 3.36.2.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.9.11.</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.87.16] - 2026-09-19</h2>
<ul>
<li>
<p>Update <code>uv@latest</code> to 0.12.16.</p>
</li>
<li>
<p>Update <code>release-plz@latest</code> to 0.3.168.</p>
</li>
<li>
<p>Update <code>protoc@latest</code> to 3.36.2.</p>
</li>
<li>
<p>Update <code>mise@latest</code> to 2026.9.11.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/taiki-e/install-action/commit/9114bf4d891761788c546334fd37538eae1bf8b3"><code>9114bf4</code></a>
Release 2.87.16</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/bef0ddf2a7e45573907045d6d2e764dc0b552ec4"><code>bef0ddf</code></a>
Update <code>uv@latest</code> to 0.12.16</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/36f0b2e823393a7be9f1979cac5ddeae9d610fdf"><code>36f0b2e</code></a>
Update <code>release-plz@latest</code> to 0.3.168</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/d2e5cdac9618886e1720537b4a0a62115b877ae6"><code>d2e5cda</code></a>
Update <code>protoc@latest</code> to 3.36.2</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/257b23d8dab2f8e29e91dac29e711cb0fbcd03b9"><code>257b23d</code></a>
Update <code>mise@latest</code> to 2026.9.11</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/35afe7990d2eef47d2b201a4a6ae4f6e298d4826"><code>35afe79</code></a>
Update kingfisher manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/64a0f280bfe9ae5d011a89695ab3e0e3619e5fe8"><code>64a0f28</code></a>
Update kache manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/2df4de46f5f1f3b13bcca17f0cf1f02d131d3d4b"><code>2df4de4</code></a>
Update git-cliff manifest</li>
<li><a
href="https://github.com/taiki-e/install-action/commit/c5119b68d50710c31eb04b4cc7de00926f51ed77"><code>c5119b6</code></a>
Update cargo-leptos manifest</li>
<li>See full diff in <a
href="https://github.com/taiki-e/install-action/compare/v2.87.15...v2.87.16">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.87.15&new-version=2.87.16)](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>
…ixty#4228)

Git calls a worktree entry prunable once the `.git` its registration
names is gone. That happens when the whole directory is deleted, and
also when only the `.git` file goes: macOS's `$TMPDIR` sweep deletes
idle files and keeps directories, which left two such checkouts
registered in a real repo. Worktrunk unregistered stale entries with
`git worktree remove`, which refuses an entry whose directory remains
(`validation failed … .git does not exist`, `--force --force` included).
max-sixty#4226 stopped that from failing `wt step prune` by skipping the entry,
so it stayed `⊟` forever, and `wt remove` refused it with
`WorktreeMissing`.

`Repository::prune_worktree_entry` now reproduces `git worktree prune`
for the one named entry. Under the registry write lock it finds the
registration whose `gitdir` names the path, repeats git's
`should_prune_worktree` test (no `locked` file, nothing at the recorded
`.git`), and deletes `.git/worktrees/<id>`, which is git's
`delete_git_dir`. The directory and any files in it stay. The test runs
at deletion time, so an entry locked or reconnected since the scan is
refused rather than unregistered.

No git command does this for one entry: `git worktree prune` takes no
path, `remove` and `move` fail validation, and `repair` relinks rather
than unregisters. A repo-wide `git worktree prune` also unregisters
entries `wt step prune` deliberately keeps: branches with unmerged
commits, detached HEADs holding the only reference to their commits
(which `git gc` can then delete), the default branch's worktree, and
unborn orphans. The rationale sits in the `prune_worktree_entry`
docstring.

What changes for users:

- `wt step prune` and `wt remove <branch>` unregister a stale entry
whether its directory is gone or only its `.git` is. `wt remove feature`
on a recreated directory used to fail with `✗ Worktree directory missing
for feature`. It now prints `✓ Pruned stale worktree & removed branch
feature (same commit as main, _)` and leaves the directory in place.
- The picker's branch-only removal now unregisters the stale entry
before deleting the branch. Before, it deleted only the branch, leaving
an entry that named a deleted branch, which `wt step prune` skips as
unborn.
- A worktree path that became a regular file counts as having no `.git`,
matching git, instead of refusing.
- Messages no longer call every stale entry "directory missing". The
switch/merge/push error reads `Worktree for X is stale; its directory or
.git is gone`, the `⊟` legend reads `Prunable (worktree directory or its
.git gone)`, and the retained-branch line reads `Pruned stale worktree
for X`. Where the directory remains, that error's hint offers `git
worktree repair <path>` instead of `git worktree prune`, which would
sweep every stale entry in the repo.

Unregistering deletes the entry's index, per-worktree reflog and any
in-progress rebase, merge, cherry-pick, revert or bisect state. While
the entry exists, `git worktree repair <path>` restores all of it
(recreating the directory first if it went too); afterwards staged files
survive only as dangling blobs. So here worktrunk is more careful than
`git worktree prune`. `Repository::stale_worktree_work` reads the
registration: `diff-index --cached --quiet HEAD` against its index, plus
the same state files `WorkingTree::operation_in_progress` reads, now
shared as `operation_in_progress_at`. An entry holding either is kept:

- `wt step prune` skips it silently, as it skips a dirty or locked
worktree.
- `wt remove` refuses with `✗ Worktree for feature is stale but holds
staged changes` (or `… with a rebase in progress`) and `↳ To discard the
stale worktree, run wt remove -f feature; to restore it, run git
worktree repair <path>`. `--force` waives the check, as it waives a live
worktree's uncommitted changes.
- On an unborn `HEAD` the index is compared against the empty tree, as
`git diff --cached` does, so an orphan worktree with nothing staged
still unregisters. A check that fails for any other reason keeps the
entry.

The deletion-time test in `prune_worktree_entry` closes the gap after
the check: a stale entry has no `.git` to stage through, and one
repaired in between is refused.

Tests: unit tests cover `prune_worktree_entry`'s refusals (live, locked,
unregistered, a `.git` it can't stat), each stale shape (absent,
directory without `.git`, path now a file), and its wait on the registry
lock. Removing either check or the lock fails them. The picker tests
cover both a pruned stale entry and a failed prune that keeps the
branch, `wt remove` on a detached stale entry is pinned to its error,
and a shim that fails the branch's CAS delete checks that prune still
unregisters the entry and reports the kept branch. The two tests that
use a permission bit as the failure trigger skip under root, which
ignores it. The prune and picker tests cover a directory that remains.
`test_prune_surfaces_failing_metadata_prune` now triggers the failure
with a read-only registration directory.
`test_prune_metadata_removals_serialize` and its two git shims are
removed: they intercepted `git worktree remove` teardowns, which this
path no longer runs. For the work guard, a unit test runs
`stale_worktree_work` on clean, staged, bisecting, `--no-checkout` (no
index), unborn-with-a-staged-file and unborn-with-an-emptied-index
registrations. `test_prune_keeps_stale_entries_holding_work` checks that
prune keeps a staged branch entry and a bisecting detached one while
pruning a clean one. `test_remove_stale_worktree_holding_staged_changes`
pins the refusal and checks that `wt remove -f` then prunes the entry
and leaves the files.

> _This was written by Claude Code on behalf of max-sixty_

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Regenerates the nine `tend-*.yaml` workflows with tend 0.2.15 (from
0.2.14). The version bump and the `astral-sh/setup-uv` pin (v10.1.0 →
v10.2.0, in the `tend-mention` and `tend-notifications` preflight jobs)
are mechanical; one step actually moves, in `tend-mention.yaml`.

**`tend-mention` measures its queue delay before checkout and setup.**
The "Compute queue delay" step used to run after `actions/checkout` and
`./.github/actions/tend-setup`, so the number it recorded was the wait
for the job to start *plus* the several minutes this repo's setup action
takes to install the Rust toolchain and sandbox tools. It now runs
first, and the delay reports the queue wait alone
([max-sixty/tend#1365](max-sixty/tend#1365)).

Behavior that arrives inside the action rather than in these files, and
that shows up in what the bot posts here:

- **PR reviews lead with a finding.** A review body now opens with
something actionable instead of restating the verdict GitHub already
renders in its own header
([max-sixty/tend#1362](max-sixty/tend#1362)),
and a follow-up review scopes itself to what the latest push changed
while still reading the whole PR
([max-sixty/tend#1368](max-sixty/tend#1368)).
- **Fewer self-directed fix rounds on bot PRs.** On a PR with no human
author the review session applies its own findings; each further round
now has to clear a higher bar, so a bot PR stops accumulating marginal
follow-up commits
([max-sixty/tend#1366](max-sixty/tend#1366)).
- **`AGENTS.override.md` joins the pinned instruction paths.** Codex
reads it in preference to `AGENTS.md`, so on a PR-derived checkout it is
now restored from the base commit alongside `CLAUDE.md`, `AGENTS.md`,
`.claude/`, and `.agents/` — a fork can no longer reach the session
through that filename. The same release makes a restrict-updates ruleset
a `tend check` requirement; this repo already satisfies it (`tend check`
passes every line today)
([max-sixty/tend#1367](max-sixty/tend#1367)).

Full comparison:
[0.2.14...0.2.15](max-sixty/tend@0.2.14...0.2.15).

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
…ion (max-sixty#4231)

`.github/scripts/list-recent-runs.sh` has had no caller since March. It
was extracted in max-sixty#1302 to feed the `review-reviewers` skill ("Run
`.github/scripts/list-recent-runs.sh` for recently completed Claude CI
runs"), and max-sixty#1676 moved that skill to the tend repo while replacing the
hand-written Claude workflows with generated ones. The script survived
the move; its only reference didn't.

Nothing references it today — neither the repo (`git grep
list-recent-runs` returns nothing outside the file itself) nor tend's
bundled skills, which is where the calling skill now lives. The deletion
empties `.github/scripts/`, so the directory goes with it.

No test accompanies this: the change removes an unreferenced file and
alters no behavior to regress.

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
)

The `# Usage` block on `is_shell_integration_line` lists uninstall as a
caller. Uninstall has not read it since
`is_shell_integration_line_for_uninstall_any_cmd` was introduced —
`scan_rc_file_for_uninstall` and `is_worktrunk_managed_content` both
call that one instead. The two docstrings now both claim the destructive
path: the sibling's says "Used by `wt config shell uninstall`, which
deletes the lines it matches. That makes a false positive destructive",
which is the reasoning that should govern one function and not the
other.

The list also omits the caller that matters most for how carefully this
function has to behave. `contains_shell_integration`, install's
idempotency check, is gated on `is_shell_integration_line` at both call
sites (`configure_shell.rs`, in the exists-check before the append and
again in `append_shell_integration_if_missing`). So the closing claim —
"false negatives only cause incorrect messaging" — is wrong for install:
a miss there reads an already-configured rc file as unconfigured and
appends a second copy of the line to a user-owned file. Uninstall
removes every line it matches, so the duplicate isn't stranded, but a
write is a different cost from a wrong hint, and the docstring is what a
later change to this function would be read against.

The `# Impact of False Negatives` section had a second inaccuracy of the
same kind: it claimed detection is consulted only while shell
integration is inactive, and that no warnings are shown once the wrapper
is active. That holds for `Shell::is_shell_configured()`'s consumers in
`src/output/shell_integration.rs`, which only ask off the not-active
path, but not for `wt config show` — it calls
`scan_for_detection_details` unconditionally and reports an unmatched
line as a possible false negative regardless of `shell_active`. The
exemption is now scoped to `is_shell_configured()`, with `wt config
show` described on its own.

So the rewrite lists the three real callers, says explicitly that
uninstall is not one, and splits the false-negative analysis three ways:
the gated messaging cases, `wt config show`'s ungated warning, and
install's write.

Comments only; no behavior changes, so there is nothing to regress-test.
`RUSTDOCFLAGS='-Dwarnings' cargo doc --no-deps --document-private-items`
(the repo's `doc` pre-merge step) passes, which is what checks the new
intra-doc link.

---------

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
…branch (max-sixty#4233)

An orphan worktree (`git worktree add --orphan`) has an unborn branch
until its first commit: `HEAD` names `refs/heads/<branch>`, but no such
ref exists. `wt remove` planned a branch deletion for it anyway, so it
misreported the branch or failed:

- A live orphan worktree: `wt remove fresh` printed `↳ Branch unmerged;
to delete, run wt remove -D fresh`, a command that then fails with `No
branch named fresh`. With `--foreground` it removed the worktree and
then exited 1 with git's `fatal: Needed a single revision`.
- A stale one (directory or `.git` gone): `wt remove fresh` printed `✓
Pruned stale worktree for fresh` followed by `○ Branch fresh retained;
has unmerged changes` and the same `wt remove -D` hint.

Now the removal planner treats an unborn branch as having nothing to
delete and plans `Keep` for it, the way it already handles a branch that
a sibling checkout still uses. The output is just `✓ Removed fresh
worktree` (or `◎ Removing fresh worktree in background`) or `✓ Pruned
stale worktree for fresh`. The planner reads this from the ref snapshot
it already holds, so it adds no git call. The picker's removal goes
through the same planner.

`test_remove_orphan_worktree` removes a live and a stale orphan
worktree, each with a remote-tracking branch of the same name. The
remote branch catches a check that counts remote branches, which would
take the branch for existing.

> _This was written by Claude Code on behalf of max-sixty_

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…x-sixty#4236)

`repo_path()` resolved a non-bare repository to
`parent(git_common_dir)`, which is the work tree only when the git
directory sits inside it. With `git init --separate-git-dir` the git
directory is a store elsewhere and that parent names the store's
neighbourhood instead, so `{{ repo_path }}.{{ branch }}` placed every
new worktree beside the store and `wt list` rendered the main worktree's
path as the store. `repo_path()` now consults the `gitdir` backlink git
keeps next to the common dir, so both surfaces name the work tree.

`wt remove` failed outright in this layout rather than misplacing
anything — it runs git from the resolved repo path, and the store's
parent is not a repository, so the command died on `fatal: not a git
repository`. That is the same root cause and is fixed here too; the
issue reports it as a second symptom.

The same wrong path reached `wt list` through the correction in
`list_worktrees` that already existed for submodules: git's
`get_main_worktree()` derives its main-worktree entry by stripping a
trailing `/.git` from the common dir, and a separate git dir has no such
suffix, so git reports the store there too. That correction defers to
`repo_path()`, so this one change fixes both.

The backlink is the same file format as a linked worktree's
`.git/worktrees/<name>/gitdir`, including the relative form git writes
under `worktree.useRelativePaths` and resolves against the directory the
file sits in. So it is read through the existing
`registration_worktree_path`, which already implements that rule, rather
than through a second parse — a re-derived rule here would be correct on
the absolute form and silently wrong for anyone with that setting on.

The backlink is one-way, so it is confirmed rather than trusted: the
work tree it names must point back at this common dir, via the existing
`git_dir_at` helper. A backlink left by a work tree that has since moved
or been replaced falls through to the old `parent(git_common_dir)`
answer rather than to a path that no longer holds the repository.

**What this leaves.** Only `git worktree repair` writes the backlink —
`git init --separate-git-dir` and `git clone --separate-git-dir` leave
the store without one, and a repository that has never been repaired
still records its work tree nowhere for `wt` to find. Running `git
worktree repair` from the work tree is now an effective remedy where
before it changed nothing, but a freshly created repository of this
shape still resolves to the store's parent until it is run. Closing that
gap needs a decision this PR doesn't take: the work tree is derivable
from `wt`'s own discovery path, but only when `wt` runs in the main work
tree, so using it would make `{{ repo_path }}` depend on where the
command was invoked. The alternatives — having `wt` write the backlink
itself, or caching the work tree in git config the way
`worktrunk.default-branch` is — both put a write on a read path.

<details><summary>Reproduction and verification</summary>

The four tests added to `src/git/repository/tests.rs` build the layout
with `git init --separate-git-dir` plus `git worktree repair`. Both
`repo_path` and `list_worktrees` tests fail before the change with
`.../store` against an expected `.../work`. A third plants an unrelated
repository where the work tree used to be and pins the fall-through — it
fails if the round-trip check is dropped. The fourth sets
`worktree.useRelativePaths` before the repair, so git writes
`../../work/.git`, and pins that `repo_path` still names the work tree;
it accepts the absolute form too, since git honors the setting only from
2.48 and worktrunk supports 2.43.

End to end with the built binary, matching the issue's repro:

```
# before `git worktree repair` — unchanged, the gap described above
{"action":"created","branch":"probe","path":".../e2e/store.probe",...}
# after `git worktree repair`
{"action":"created","branch":"probe2","path":".../e2e/work.probe2",...}
```

`wt list` then renders the main worktree as `.` rather than the store.

One adjacent surface this PR does not touch: `try_repo_at` in
`src/git/recover.rs` admits a directory only when its `.git` is a
directory, which is never true of a separate-git-dir work tree. Worth a
look separately; no user-visible symptom verified here.

</details>

Refs max-sixty#4235 — automated triage

---------

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
The picker PTY wait could overshoot `wt-drop` onto a streamed PR row and
keep sending Down until it timed out ([Windows
failure](https://github.com/max-sixty/worktrunk/actions/runs/35705096628)).
Re-issued arrows now move toward the target visible in the current
frame, recovering from both async cursor resets and overshoots.

Cursor readiness and steering share the same item-area reader. The fixed
test terminal uses the production reverse layout: query, one header row,
then items. Reading that area excludes query/header matches and accepts
blank loading gutters without classifying gutter glyphs. Preview text
remains outside the match area. Existing removal guards use the same
reader, and filtered tests wait for selection to reach a matching item
before reading row order.

Regression coverage includes the recorded overshoot, header exclusion,
missing rows, typed queries with blank gutters, and a real PTY test that
deliberately overshoots a filtered row and steers back. All 37
picker-related tests pass locally. The full pre-merge hook passes on the
final revision: 4,957 tests passed, one skipped, plus formatting,
Clippy, documentation, and doctests. This changes only test helpers and
their regression coverage.

> _This was written by Codex on behalf of max-sixty_

---------

Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Roos <m@maxroos.com>
@Bennyjitsu
Bennyjitsu merged commit f49fcb0 into main Sep 23, 2026
28 of 29 checks passed
@Bennyjitsu
Bennyjitsu deleted the sync-upstream-2026-09-23 branch September 23, 2026 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants