Commit graph

10 commits

Author SHA1 Message Date
Zhenjia ZHOU
5de12f75e3
docs(ccr): correct stale 5-minute TTL hints to 30 minutes (#2224)
## Description

The CCR store default TTL is `DEFAULT_TTL = 1800s` (30 minutes — see
`crates/headroom-core/src/ccr/mod.rs` and `config.py
store_ttl_seconds=1800`), but several user-facing hints and docstrings
still said "5 minutes", the old default. The opencode/openclaw retrieve
tools surfaced `(default TTL: 5 minutes)` in their expiry hint — exactly
the misleading message reported in #1023. (The CCR cache itself works;
the row-drop store bridge that populates the retrieve store landed for
#389.)

This corrects the two plugin hints, the `InMemoryCcrStore` docstrings,
the SQLite/backend default TTL comments, and the `smart_crusher` mirror
comment. The `mod.rs` comment that references "the *old* 5-minute
default" is intentionally left unchanged — it correctly describes
history.

## Type of Change

- [x] Documentation update

## Changes Made

- `plugins/openclaw/src/tools/headroom-retrieve.ts` +
`plugins/opencode/src/retrieve.ts`: retrieve-failure hint `5 minutes` →
`30 minutes`.
- `crates/headroom-core/src/ccr/backends/in_memory.rs`: two docstrings
(`5 minutes by default`, `5-minute TTL`) → `30 minutes` / `30-minute`.
- `crates/headroom-core/src/ccr/backends/mod.rs` + `sqlite.rs`:
SQLite/default backend TTL comments `5-minute` → `30-minute`.
- `headroom/transforms/smart_crusher.py`: mirror comment `defaults to 5
minutes` → `30 minutes`.

## Testing

- [x] Linting passes (`ruff` / `cargo check`)
- [x] Manual verification (see Real Behavior Proof)

### Test Output

```text
$ ruff format --check headroom/transforms/smart_crusher.py   # clean
$ cargo check -p headroom-core                                # Finished, no errors
```

## Real Behavior Proof

- Environment: macOS (Darwin), branch `feat/ccr-ttl-hint-fix` off
`main`.
- Exact command / steps: grepped every `5 minutes` / `5-minute` TTL
reference across the repo; confirmed the real default is `DEFAULT_TTL =
Duration::from_secs(1800)` (`ccr/mod.rs:66`), that
`InMemoryCcrStore::new()` uses `DEFAULT_TTL` (not a local 300s), and
that `config.py` sets `store_ttl_seconds = 1800 # 30 minutes`.
- Observed result: all stale CCR default-TTL "5 minutes" references now
read "30 minutes"; the one historical reference (`mod.rs`: "the old
5-minute default") is left as-is because it is accurate.
- Not tested: nothing runtime changed — these are docstring/comment/hint
string edits only, so there is no behavior to exercise.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [ ] I have commented my code — N/A (this PR is comments/strings)
- [x] I have made corresponding changes to the documentation (this *is*
the doc change)
- [x] My changes generate no new warnings
- [ ] I have added tests — N/A (no behavior change)
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md — N/A: user-facing hint/docstring
correction, no functional change

## Additional Notes

- Surfaced while root-causing #1023: the "cache permanently empty / TTL:
5 minutes" report is resolved on `main` (the store-bridge for #389
populates the retrieve store), but the stale "5 minutes" strings the
reporter actually saw were still in the tree. This PR fixes those.

---------

Co-authored-by: JerrettDavis <mxjerrett@gmail.com>
2026-07-15 18:15:53 +00:00
JD Davis
ea3d5a86b7
fix(deps): clear Dependabot lockfile alerts (#2175)
## Description

Clears the current dependency/security-audit blockers that are making
unrelated PRs red:

- `transformers 5.3.0` / `CVE-2026-5241`, fixed by requiring
`transformers>=5.5.0` in the locked optional dependency set.
- `sqlitedict <=2.1.0` via the optional `benchmark` extra's
`lm-eval[api]` dependency. There is no patched `sqlitedict` release, so
this PR removes the published/locked `benchmark` extra instead of
shipping a known-vulnerable transitive dependency.
- `esbuild >=0.27.3,<0.28.1` in the OpenCode plugin lockfile, fixed by
forcing `esbuild@0.28.1` through the OpenCode npm override and
regenerated lockfile.

The benchmark code still invokes `python -m lm_eval`; researchers who
need that harness should install `lm-eval[api]` in their benchmark
environment until its transitive vulnerability has a patched release.

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- `pyproject.toml`: remove the `benchmark` optional extra, document
external `lm-eval[api]` installation guidance, and require
`transformers>=5.5.0`.
- `uv.lock`: regenerate without the `benchmark` extra, removing
`lm-eval` and `sqlitedict` lock entries and locking the patched
transformers floor.
- `plugins/opencode/package.json`: add an `overrides` entry for
`esbuild@0.28.1`.
- `plugins/opencode/package-lock.json`: regenerate the OpenCode lockfile
with `esbuild@0.28.1`.

## Testing

- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [ ] Type checking passes (`mypy headroom`)
- [ ] New tests added for new functionality
- [x] Manual testing performed

### Test Output

```text
uv lock --check
rg -n -F 'sqlitedict' uv.lock        # no matches
rg -n -F 'name = "lm-eval"' uv.lock  # no matches
rg -n -F "extra == 'benchmark'" uv.lock # no matches
rg -n -F '0.27.7' plugins/opencode/package-lock.json plugins/opencode/package.json # no matches
npm ls esbuild --package-lock-only
npm audit --package-lock-only        # found 0 vulnerabilities
git diff --check
```

Previous GitHub checks were green. After merging current `main`, fresh
GitHub checks are running again; local targeted validation still passes.

## Real Behavior Proof

- Environment: Windows 11, Python 3.13.3, uv, npm in `plugins/opencode`,
Dependabot/pip-audit alert metadata from the failing PR jobs.
- Exact command / steps: inspected the regenerated Python and npm
lockfiles with `rg`, checked the uv lock with `uv lock --check`, checked
OpenCode's dependency tree with `npm ls esbuild --package-lock-only`,
and ran `npm audit --package-lock-only`.
- Observed result: `uv.lock` no longer contains `sqlitedict`, `lm-eval`,
or a `benchmark` extra marker; `transformers` resolves at the patched
`>=5.5.0` floor; OpenCode's lock resolves `esbuild@0.28.1`; `npm audit
--package-lock-only` reports 0 vulnerabilities; GitHub `Dependency audit
(pip-audit)` passes.
- Not tested: running the external `lm-eval` harness after installing it
separately.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] I have updated the CHANGELOG.md if applicable

## Screenshots (if applicable)

N/A - dependency and lockfile security fix.

## Additional Notes

The `benchmark` extra can be restored once the upstream `lm-eval[api]`
dependency chain stops pulling a vulnerable `sqlitedict` release.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-14 20:40:28 -07:00
dependabot[bot]
87151952ee
deps: bump @types/node from 22.20.0 to 26.1.1 in /plugins/opencode (#1688)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 22.20.0 to 26.1.1.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-09 17:02:04 -05:00
dependabot[bot]
8872bbc6a2
deps: bump the npm-minor-patch group across 4 directories with 18 updates (#1907)
Bumps the npm-minor-patch group with 12 updates in the /docs directory:

| Package | From | To |
| --- | --- | --- |
| [fumadocs-core](https://github.com/fuma-nama/fumadocs) | `16.10.3` |
`16.11.1` |
| [fumadocs-mdx](https://github.com/fuma-nama/fumadocs) | `15.0.12` |
`15.1.0` |
| [fumadocs-twoslash](https://github.com/fuma-nama/fumadocs) | `3.1.15`
| `3.3.0` |
| [fumadocs-ui](https://github.com/fuma-nama/fumadocs) | `16.10.3` |
`16.11.1` |
| [next](https://github.com/vercel/next.js) | `16.2.6` | `16.2.10` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) |
`19.2.4` | `19.2.7` |
|
[@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)
| `19.2.14` | `19.2.17` |
|
[react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom)
| `19.2.4` | `19.2.7` |
| [recharts](https://github.com/recharts/recharts) | `3.8.1` | `3.9.2` |
|
[@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss)
| `4.2.2` | `4.3.2` |
|
[@types/mdx](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mdx)
| `2.0.13` | `2.0.14` |
| [postcss](https://github.com/postcss/postcss) | `8.5.15` | `8.5.16` |

Bumps the npm-minor-patch group with 1 update in the /plugins/openclaw
directory:
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).
Bumps the npm-minor-patch group with 2 updates in the /plugins/opencode
directory:
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
and @opencode-ai/plugin.
Bumps the npm-minor-patch group with 3 updates in the /sdk/typescript
directory:
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest),
[@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript)
and [dotenv](https://github.com/motdotla/dotenv).

Updates `fumadocs-core` from 16.10.3 to 16.11.1
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ab09f500cb"><code>ab09f50</code></a>
Version Packages (<a
href="https://redirect.github.com/fuma-nama/fumadocs/issues/3405">#3405</a>)</li>
<li><a
href="889a296d06"><code>889a296</code></a>
docs: update stale content</li>
<li><a
href="a5c081d0c6"><code>a5c081d</code></a>
fix: UI inconsistencies</li>
<li><a
href="9a269030df"><code>9a26903</code></a>
Version Packages</li>
<li><a
href="3e33f4362f"><code>3e33f43</code></a>
perf(satteri): reduce clones</li>
<li><a
href="3597c9d1e6"><code>3597c9d</code></a>
perf(satteri): persist results</li>
<li><a
href="0f389cf3de"><code>0f389cf</code></a>
feat(satteri): decouple imports/exports from <code>compile()</code></li>
<li><a
href="4611f97d49"><code>4611f97</code></a>
feat(satteri): full rehype-toc functionality</li>
<li><a
href="d095300760"><code>d095300</code></a>
fix(satteri): workaround common issues</li>
<li><a
href="0297e25477"><code>0297e25</code></a>
configure pretrust</li>
<li>Additional commits viewable in <a
href="https://github.com/fuma-nama/fumadocs/compare/fumadocs-core@16.10.3...fumadocs@16.11.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `fumadocs-mdx` from 15.0.12 to 15.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/fuma-nama/fumadocs/releases">fumadocs-mdx's
releases</a>.</em></p>
<blockquote>
<h2>fumadocs-mdx@15.1.0</h2>
<h3>Default to Base UI</h3>
<p>Internal packages &amp; templates now use Base UI rather than Radix
UI.</p>
<h2>fumadocs-mdx@15.0.13</h2>
<h3>Require <code>collection</code> query param at regex matching</h3>
<p>Instead of passing through all JSON/YAML files, the meta loader now
requires <code>collection</code> query param to be triggered.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9a269030df"><code>9a26903</code></a>
Version Packages</li>
<li><a
href="3e33f4362f"><code>3e33f43</code></a>
perf(satteri): reduce clones</li>
<li><a
href="3597c9d1e6"><code>3597c9d</code></a>
perf(satteri): persist results</li>
<li><a
href="0f389cf3de"><code>0f389cf</code></a>
feat(satteri): decouple imports/exports from <code>compile()</code></li>
<li><a
href="4611f97d49"><code>4611f97</code></a>
feat(satteri): full rehype-toc functionality</li>
<li><a
href="d095300760"><code>d095300</code></a>
fix(satteri): workaround common issues</li>
<li><a
href="0297e25477"><code>0297e25</code></a>
configure pretrust</li>
<li><a
href="02c242b0da"><code>02c242b</code></a>
chore(satteri): clean code</li>
<li><a
href="3d80b8b242"><code>3d80b8b</code></a>
fix(mdx): ensure satteri integration is optional</li>
<li><a
href="0ec19af868"><code>0ec19af</code></a>
feat(satteri): more tests &amp; move remark-include</li>
<li>Additional commits viewable in <a
href="https://github.com/fuma-nama/fumadocs/compare/fumadocs-mdx@15.0.12...fumadocs-mdx@15.1.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `fumadocs-twoslash` from 3.1.15 to 3.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/fuma-nama/fumadocs/releases">fumadocs-twoslash's
releases</a>.</em></p>
<blockquote>
<h2>fumadocs-twoslash@3.3.0</h2>
<h3>Default to Base UI</h3>
<p>Internal packages &amp; templates now use Base UI rather than Radix
UI.</p>
<h2>fumadocs-twoslash@3.2.1</h2>
<h3>Migrate to <code>cnfast</code></h3>
<p>Drop <code>tailwind-merge</code>.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9a269030df"><code>9a26903</code></a>
Version Packages</li>
<li><a
href="3e33f4362f"><code>3e33f43</code></a>
perf(satteri): reduce clones</li>
<li><a
href="3597c9d1e6"><code>3597c9d</code></a>
perf(satteri): persist results</li>
<li><a
href="0f389cf3de"><code>0f389cf</code></a>
feat(satteri): decouple imports/exports from <code>compile()</code></li>
<li><a
href="4611f97d49"><code>4611f97</code></a>
feat(satteri): full rehype-toc functionality</li>
<li><a
href="d095300760"><code>d095300</code></a>
fix(satteri): workaround common issues</li>
<li><a
href="0297e25477"><code>0297e25</code></a>
configure pretrust</li>
<li><a
href="02c242b0da"><code>02c242b</code></a>
chore(satteri): clean code</li>
<li><a
href="3d80b8b242"><code>3d80b8b</code></a>
fix(mdx): ensure satteri integration is optional</li>
<li><a
href="0ec19af868"><code>0ec19af</code></a>
feat(satteri): more tests &amp; move remark-include</li>
<li>Additional commits viewable in <a
href="https://github.com/fuma-nama/fumadocs/compare/fumadocs-twoslash@3.1.15...fumadocs-twoslash@3.3.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `fumadocs-ui` from 16.10.3 to 16.11.1
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ab09f500cb"><code>ab09f50</code></a>
Version Packages (<a
href="https://redirect.github.com/fuma-nama/fumadocs/issues/3405">#3405</a>)</li>
<li><a
href="889a296d06"><code>889a296</code></a>
docs: update stale content</li>
<li><a
href="a5c081d0c6"><code>a5c081d</code></a>
fix: UI inconsistencies</li>
<li><a
href="9a269030df"><code>9a26903</code></a>
Version Packages</li>
<li><a
href="3e33f4362f"><code>3e33f43</code></a>
perf(satteri): reduce clones</li>
<li><a
href="3597c9d1e6"><code>3597c9d</code></a>
perf(satteri): persist results</li>
<li><a
href="0f389cf3de"><code>0f389cf</code></a>
feat(satteri): decouple imports/exports from <code>compile()</code></li>
<li><a
href="4611f97d49"><code>4611f97</code></a>
feat(satteri): full rehype-toc functionality</li>
<li><a
href="d095300760"><code>d095300</code></a>
fix(satteri): workaround common issues</li>
<li><a
href="0297e25477"><code>0297e25</code></a>
configure pretrust</li>
<li>Additional commits viewable in <a
href="https://github.com/fuma-nama/fumadocs/compare/fumadocs-ui@16.10.3...fumadocs@16.11.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `lucide-react` from 1.20.0 to 1.23.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lucide-icons/lucide/releases">lucide-react's
releases</a>.</em></p>
<blockquote>
<h2>Version 1.23.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(docs): prevent scrollbar layout shift on icons page by <a
href="https://github.com/g30r93g"><code>@​g30r93g</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4500">lucide-icons/lucide#4500</a></li>
<li>chore(docs): Remove certificates banner by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4504">lucide-icons/lucide#4504</a></li>
<li>ci(repo-journal.yml): GH copilot repo summary by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4505">lucide-icons/lucide#4505</a></li>
<li>ci(repo-journal.yml): Small fix in the workflow by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4508">lucide-icons/lucide#4508</a></li>
<li>ci(repo-journal.yml): Switch to token by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4509">lucide-icons/lucide#4509</a></li>
<li>feat(icons): added <code>paper-bag</code> icon by <a
href="https://github.com/dkast"><code>@​dkast</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4023">lucide-icons/lucide#4023</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/g30r93g"><code>@​g30r93g</code></a> made
their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4500">lucide-icons/lucide#4500</a></li>
<li><a href="https://github.com/dkast"><code>@​dkast</code></a> made
their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4023">lucide-icons/lucide#4023</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lucide-icons/lucide/compare/1.22.0...1.23.0">https://github.com/lucide-icons/lucide/compare/1.22.0...1.23.0</a></p>
<h2>Version 1.22.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(icons): add 6 database variant icons by <a
href="https://github.com/Barakudum"><code>@​Barakudum</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4336">lucide-icons/lucide#4336</a></li>
<li>ci(release.yml): Remove concurrency field to prevent release mess by
<a href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in
<a
href="https://redirect.github.com/lucide-icons/lucide/pull/4485">lucide-icons/lucide#4485</a></li>
<li>fix(docs): fix color input clipping by <a
href="https://github.com/Hsiii"><code>@​Hsiii</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4488">lucide-icons/lucide#4488</a></li>
<li>docs(site): add Deno to installation instructions by <a
href="https://github.com/bartlomieju"><code>@​bartlomieju</code></a> in
<a
href="https://redirect.github.com/lucide-icons/lucide/pull/4486">lucide-icons/lucide#4486</a></li>
<li>chore(deps): bump esbuild from 0.25.12 to 0.28.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4459">lucide-icons/lucide#4459</a></li>
<li>fix(docs): prevent private analytics token from blocking local dev
by <a href="https://github.com/Hsiii"><code>@​Hsiii</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4481">lucide-icons/lucide#4481</a></li>
<li>docs(installation.md): Remove outdate next tag in installation by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4495">lucide-icons/lucide#4495</a></li>
<li>fix(lucide-react-native): Fix context provider export by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4497">lucide-icons/lucide#4497</a></li>
<li>fix(astro): add Astro v7 compatibility by <a
href="https://github.com/iseraph-dev"><code>@​iseraph-dev</code></a> in
<a
href="https://redirect.github.com/lucide-icons/lucide/pull/4491">lucide-icons/lucide#4491</a></li>
<li>fix(icons): changed <code>carrot</code> icon by <a
href="https://github.com/jguddas"><code>@​jguddas</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4010">lucide-icons/lucide#4010</a></li>
<li>fix(icons): changed <code>ungroup</code> icon by <a
href="https://github.com/jguddas"><code>@​jguddas</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/3969">lucide-icons/lucide#3969</a></li>
<li>feat(icons): added <code>phi</code> icon also used as
<code>golden-ratio</code> by <a
href="https://github.com/whoisBugsbunny"><code>@​whoisBugsbunny</code></a>
in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4218">lucide-icons/lucide#4218</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/bartlomieju"><code>@​bartlomieju</code></a>
made their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4486">lucide-icons/lucide#4486</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lucide-icons/lucide/compare/1.21.0...1.22.0">https://github.com/lucide-icons/lucide/compare/1.21.0...1.22.0</a></p>
<h2>Version 1.21.0</h2>
<h2>What's Changed</h2>
<ul>
<li>ci(release.yml): Remove new-version in release flow by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4478">lucide-icons/lucide#4478</a></li>
<li>ci(release.yml): Fix workflow and remove <code>version</code>
scripts in package scripts by <a
href="https://github.com/ericfennis"><code>@​ericfennis</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4479">lucide-icons/lucide#4479</a></li>
<li>fix(docs): rename navigation category label by <a
href="https://github.com/Hsiii"><code>@​Hsiii</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4483">lucide-icons/lucide#4483</a></li>
<li>feat(icons): added <code>broken-bone</code> icon by <a
href="https://github.com/Patolord"><code>@​Patolord</code></a> in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4131">lucide-icons/lucide#4131</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Hsiii"><code>@​Hsiii</code></a> made
their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4483">lucide-icons/lucide#4483</a></li>
<li><a href="https://github.com/Patolord"><code>@​Patolord</code></a>
made their first contribution in <a
href="https://redirect.github.com/lucide-icons/lucide/pull/4131">lucide-icons/lucide#4131</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lucide-icons/lucide/compare/1.20.0...1.21.0">https://github.com/lucide-icons/lucide/compare/1.20.0...1.21.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5ff536e139"><code>5ff536e</code></a>
ci(release.yml): Fix workflow and remove <code>version</code> scripts in
package scripts...</li>
<li>See full diff in <a
href="https://github.com/lucide-icons/lucide/commits/1.23.0/packages/lucide-react">compare
view</a></li>
</ul>
</details>
<br />

Updates `next` from 16.2.6 to 16.2.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/next.js/releases">next's
releases</a>.</em></p>
<blockquote>
<h2>v16.2.10</h2>
<p>Contains no changes except publishing <code>@next/swc-wasm-web</code>
which was accidentally not published since 16.2.4.</p>
<h2>v16.2.9</h2>
<p>Empty release to ensure <code>next@latest</code> points at a stable
release. Next.js only allows publishing with Trusted Publishing enabled.
In order to fix NPM dist-tags, we have to release a new version.
Updating dist-tags is not possible with Trusted Publishing.</p>
<h2>v16.2.8</h2>
<p>Release with no changes in an attempt to fix <code>next@latest</code>
pointing at a prerelease version.</p>
<h2>v16.2.7</h2>
<blockquote>
<p>[!NOTE]
This release is backporting bug fixes. It does <strong>not</strong>
include all pending features/changes on canary.</p>
</blockquote>
<h3>Core Changes</h3>
<ul>
<li>Backport documentation fixes for v16.2 (<a
href="https://redirect.github.com/vercel/next.js/issues/93804">#93804</a>)</li>
<li>[backport] Patch <code>playwright-core</code> to resolve
<code>_finishedPromise</code> on <code>requestFailed</code> (<a
href="https://redirect.github.com/vercel/next.js/issues/93920">#93920</a>)</li>
<li>[backport] Fix dev mode hydration failure when page is served from
HTTP cache (<a
href="https://redirect.github.com/vercel/next.js/issues/93492">#93492</a>)</li>
<li>[backport] Fix catch-all <code>router.query</code> corruption with
<code>basePath</code> + <code>rewrites</code> (<a
href="https://redirect.github.com/vercel/next.js/issues/93917">#93917</a>)</li>
<li>[backport] Encode non-ASCII characters in cache tags at construction
(<a
href="https://redirect.github.com/vercel/next.js/issues/93918">#93918</a>)</li>
<li>[backport] Fix server action forwarding loop with middleware
rewrites (<a
href="https://redirect.github.com/vercel/next.js/issues/93919">#93919</a>)</li>
<li>[backport] Turbopack: switch from base40 to base38 hash encoding (<a
href="https://redirect.github.com/vercel/next.js/issues/93932">#93932</a>)</li>
<li>[ci] Disable hanging node 24 typescript tests on 16.2 backport
branch (<a
href="https://redirect.github.com/vercel/next.js/issues/94164">#94164</a>)</li>
<li>[backport] Fix &quot;type: module&quot; in project dir when using
standalone or adapters (<a
href="https://redirect.github.com/vercel/next.js/issues/94050">#94050</a>)</li>
<li>[backport] Propagate adapter preferred regions (<a
href="https://redirect.github.com/vercel/next.js/issues/94200">#94200</a>)</li>
<li>[16.2.x] Don't drop <code>FormData</code> entries (<a
href="https://redirect.github.com/vercel/next.js/issues/94240">#94240</a>)</li>
<li>[backport] feat(turbopack): add LocalPathOrProjectPath PostCSS
config resolution (<a
href="https://redirect.github.com/vercel/next.js/issues/94284">#94284</a>)</li>
</ul>
<h3>Credits</h3>
<p>Huge thanks to <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>, <a
href="https://github.com/icyJoseph"><code>@​icyJoseph</code></a>, <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>, <a
href="https://github.com/mischnic"><code>@​mischnic</code></a>, <a
href="https://github.com/bgw"><code>@​bgw</code></a>, <a
href="https://github.com/timneutkens"><code>@​timneutkens</code></a>,
and <a
href="https://github.com/lukesandberg"><code>@​lukesandberg</code></a>
for helping!</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9dadfd693c"><code>9dadfd6</code></a>
v16.2.10</li>
<li><a
href="534d9c144c"><code>534d9c1</code></a>
[16.2.x] Release pipeline updates (<a
href="https://redirect.github.com/vercel/next.js/issues/95160">#95160</a>)</li>
<li><a
href="98941fc427"><code>98941fc</code></a>
backport: docs fixes 16.2.x (<a
href="https://redirect.github.com/vercel/next.js/issues/94935">#94935</a>)</li>
<li><a
href="6e1a94de7c"><code>6e1a94d</code></a>
[16.2.x][ci]: fix release script to not strip newlines (<a
href="https://redirect.github.com/vercel/next.js/issues/94640">#94640</a>)</li>
<li><a
href="f37fad9405"><code>f37fad9</code></a>
v16.2.9</li>
<li><a
href="d9aaaedfd8"><code>d9aaaed</code></a>
[cd] Allow tagging semver-lower releases as <code>@latest</code> if
<code>@latest</code> po… (<a
href="https://redirect.github.com/vercel/next.js/issues/94627">#94627</a>)</li>
<li><a
href="6f1680448c"><code>6f16804</code></a>
v16.2.8</li>
<li><a
href="0dbc1d5c86"><code>0dbc1d5</code></a>
[16.2.x][cd] Ensure release can be triggered on old branches (<a
href="https://redirect.github.com/vercel/next.js/issues/94598">#94598</a>)</li>
<li><a
href="90e3c811e7"><code>90e3c81</code></a>
[16.2.x] Align Actions dependencies with Canary (<a
href="https://redirect.github.com/vercel/next.js/issues/94339">#94339</a>)</li>
<li><a
href="83f402c69d"><code>83f402c</code></a>
[16.2.x][cd] Stop fetching all tags when searching parent tag (<a
href="https://redirect.github.com/vercel/next.js/issues/94334">#94334</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vercel/next.js/compare/v16.2.6...v16.2.10">compare
view</a></li>
</ul>
</details>
<br />

Updates `react` from 19.2.4 to 19.2.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/react/releases">react's
releases</a>.</em></p>
<blockquote>
<h2>19.2.7 (June 1st, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Fixed missing <code>FormData</code> entries in Server Actions which
regressed in 19.2.6
(<a
href="https://redirect.github.com/facebook/react/pull/36566">#36566</a>
by <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
<h2>19.2.6 (May 6th, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Type hardening and performance improvements
(<a
href="https://redirect.github.com/facebook/react/pull/36425">#36425</a>
by <a href="https://github.com/eps1lon"><code>@​eps1lon</code></a> and
<a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
<h2>19.2.5 (April 8th, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Add more cycle protections (<a
href="https://redirect.github.com/facebook/react/pull/36236">#36236</a>
by <a href="https://github.com/eps1lon"><code>@​eps1lon</code></a> and
<a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/react/react/blob/main/CHANGELOG.md">react's
changelog</a>.</em></p>
<blockquote>
<h2>19.2.7 (June 1, 2026)</h2>
<h3>React Server Components</h3>
<ul>
<li>Fixed missing <code>FormData</code> entries in Server Actions which
regressed in 19.2.6 (<a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a> <a
href="https://redirect.github.com/facebook/react/pull/36566">#36566</a>)</li>
</ul>
<h2>19.2.6 (May 6, 2026)</h2>
<h3>React Server Components</h3>
<ul>
<li>Type hardening and performance improvements (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>, <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a> <a
href="https://redirect.github.com/facebook/react/pull/36425">#36425</a>)</li>
</ul>
<h2>19.2.5 (March 18, 2026)</h2>
<h3>React Server Components</h3>
<ul>
<li>Add more cycle protections (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>, <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a> <a
href="https://redirect.github.com/facebook/react/pull/36236">#36236</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6117d7cca4"><code>6117d7c</code></a>
Version 19.2.7 (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/36591">#36591</a>)</li>
<li><a
href="eaf3e95ca9"><code>eaf3e95</code></a>
Version 19.2.6</li>
<li><a
href="23f4f9f30d"><code>23f4f9f</code></a>
19.2.5</li>
<li>See full diff in <a
href="https://github.com/facebook/react/commits/v19.2.7/packages/react">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for react since your current version.</p>
</details>
<br />

Updates `@types/react` from 19.2.14 to 19.2.17
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react">compare
view</a></li>
</ul>
</details>
<br />

Updates `react-dom` from 19.2.4 to 19.2.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/react/releases">react-dom's
releases</a>.</em></p>
<blockquote>
<h2>19.2.7 (June 1st, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Fixed missing <code>FormData</code> entries in Server Actions which
regressed in 19.2.6
(<a
href="https://redirect.github.com/facebook/react/pull/36566">#36566</a>
by <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
<h2>19.2.6 (May 6th, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Type hardening and performance improvements
(<a
href="https://redirect.github.com/facebook/react/pull/36425">#36425</a>
by <a href="https://github.com/eps1lon"><code>@​eps1lon</code></a> and
<a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
<h2>19.2.5 (April 8th, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Add more cycle protections (<a
href="https://redirect.github.com/facebook/react/pull/36236">#36236</a>
by <a href="https://github.com/eps1lon"><code>@​eps1lon</code></a> and
<a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/react/react/blob/main/CHANGELOG.md">react-dom's
changelog</a>.</em></p>
<blockquote>
<h2>19.2.7 (June 1, 2026)</h2>
<h3>React Server Components</h3>
<ul>
<li>Fixed missing <code>FormData</code> entries in Server Actions which
regressed in 19.2.6 (<a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a> <a
href="https://redirect.github.com/facebook/react/pull/36566">#36566</a>)</li>
</ul>
<h2>19.2.6 (May 6, 2026)</h2>
<h3>React Server Components</h3>
<ul>
<li>Type hardening and performance improvements (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>, <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a> <a
href="https://redirect.github.com/facebook/react/pull/36425">#36425</a>)</li>
</ul>
<h2>19.2.5 (March 18, 2026)</h2>
<h3>React Server Components</h3>
<ul>
<li>Add more cycle protections (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>, <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a> <a
href="https://redirect.github.com/facebook/react/pull/36236">#36236</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6117d7cca4"><code>6117d7c</code></a>
Version 19.2.7 (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/36591">#36591</a>)</li>
<li><a
href="eaf3e95ca9"><code>eaf3e95</code></a>
Version 19.2.6</li>
<li><a
href="23f4f9f30d"><code>23f4f9f</code></a>
19.2.5</li>
<li>See full diff in <a
href="https://github.com/facebook/react/commits/v19.2.7/packages/react-dom">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for react-dom since your current version.</p>
</details>
<br />

Updates `recharts` from 3.8.1 to 3.9.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/recharts/recharts/releases">recharts's
releases</a>.</em></p>
<blockquote>
<h2>v3.9.2</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: clarify custom labels and ticks need SVG elements by <a
href="https://github.com/ishaanlabs-gg"><code>@​ishaanlabs-gg</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7524">recharts/recharts#7524</a></li>
<li>chore(deps): bump immer from 11.1.8 to 11.1.9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/recharts/recharts/pull/7526">recharts/recharts#7526</a></li>
<li>fix(Sankey): avoid exponential depth traversal on dense graphs by <a
href="https://github.com/dm-gthb"><code>@​dm-gthb</code></a> in <a
href="https://redirect.github.com/recharts/recharts/pull/7479">recharts/recharts#7479</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/ishaanlabs-gg"><code>@​ishaanlabs-gg</code></a>
made their first contribution in <a
href="https://redirect.github.com/recharts/recharts/pull/7524">recharts/recharts#7524</a></li>
<li><a href="https://github.com/dm-gthb"><code>@​dm-gthb</code></a> made
their first contribution in <a
href="https://redirect.github.com/recharts/recharts/pull/7479">recharts/recharts#7479</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/recharts/recharts/compare/v3.9.1...v3.9.2">https://github.com/recharts/recharts/compare/v3.9.1...v3.9.2</a></p>
<h2>v3.9.1</h2>
<h2>What's Changed</h2>
<ul>
<li>perf: optimize ScatterChart hover by reducing re-renders from O(n)
to O(1) by <a href="https://github.com/roy7"><code>@​roy7</code></a> in
<a
href="https://redirect.github.com/recharts/recharts/pull/7133">recharts/recharts#7133</a></li>
<li>fix(YAxis): render explicit ticks when a non-literal domain can't
resolve on empty data (<a
href="https://redirect.github.com/recharts/recharts/issues/7362">#7362</a>)
by <a href="https://github.com/nlenepveu"><code>@​nlenepveu</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7393">recharts/recharts#7393</a></li>
<li>fix: avoid Sankey nodes overlapping skipped-depth links by <a
href="https://github.com/pupuking723"><code>@​pupuking723</code></a> in
<a
href="https://redirect.github.com/recharts/recharts/pull/7471">recharts/recharts#7471</a></li>
<li>Add stacked bar chart with horizontal threshold line example by <a
href="https://github.com/nijuse"><code>@​nijuse</code></a> in <a
href="https://redirect.github.com/recharts/recharts/pull/7495">recharts/recharts#7495</a></li>
<li>fix(DefaultLegendContent): omit empty value from legend icon
aria-label by <a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a> in
<a
href="https://redirect.github.com/recharts/recharts/pull/7501">recharts/recharts#7501</a></li>
<li>chore(deps): bump immer from 10.2.0 to 11.1.8 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/recharts/recharts/pull/7452">recharts/recharts#7452</a></li>
<li>fix(getNiceTickValues): remove trailing duplicate tick when
allowDecimals=false by <a
href="https://github.com/JSap0914"><code>@​JSap0914</code></a> in <a
href="https://redirect.github.com/recharts/recharts/pull/7482">recharts/recharts#7482</a></li>
<li>Fix/per graphical item formatter prop by <a
href="https://github.com/shreedharbhat98"><code>@​shreedharbhat98</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7287">recharts/recharts#7287</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/pupuking723"><code>@​pupuking723</code></a>
made their first contribution in <a
href="https://redirect.github.com/recharts/recharts/pull/7471">recharts/recharts#7471</a></li>
<li><a href="https://github.com/nijuse"><code>@​nijuse</code></a> made
their first contribution in <a
href="https://redirect.github.com/recharts/recharts/pull/7495">recharts/recharts#7495</a></li>
<li><a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a>
made their first contribution in <a
href="https://redirect.github.com/recharts/recharts/pull/7501">recharts/recharts#7501</a></li>
<li><a href="https://github.com/JSap0914"><code>@​JSap0914</code></a>
made their first contribution in <a
href="https://redirect.github.com/recharts/recharts/pull/7482">recharts/recharts#7482</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/recharts/recharts/compare/v3.9.0...v3.9.1">https://github.com/recharts/recharts/compare/v3.9.0...v3.9.1</a></p>
<h2>v3.9.0</h2>
<h2>What's Changed</h2>
<h3>Animations</h3>
<p>3.9 comes with new animations! There are several bug fixes and what's
best, all animations are now fully customizable.</p>
<p>See the animations guide on <a
href="https://recharts.github.io/en-US/guide/animations/">https://recharts.github.io/en-US/guide/animations/</a></p>
<ul>
<li>Animation guide by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7179">recharts/recharts#7179</a></li>
<li>Animation tests by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7255">recharts/recharts#7255</a></li>
<li>New animation props by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7215">recharts/recharts#7215</a></li>
<li>test: cover legacy animation length changes by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7283">recharts/recharts#7283</a></li>
<li>test: add sparse animation path tests for Line component by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7295">recharts/recharts#7295</a></li>
<li>Export and document interpolate function by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7293">recharts/recharts#7293</a></li>
<li>test: enhance line animation tests for ComposedChart and responsive
by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7289">recharts/recharts#7289</a></li>
<li>Manual animations on website by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7483">recharts/recharts#7483</a></li>
<li>Add new example where chart animates by scroll by <a
href="https://github.com/PavelVanecek"><code>@​PavelVanecek</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7484">recharts/recharts#7484</a></li>
<li>fix: preserve single-value line dash gaps during animation by <a
href="https://github.com/puneetdixit200"><code>@​puneetdixit200</code></a>
in <a
href="https://redirect.github.com/recharts/recharts/pull/7405">recharts/recharts#7405</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b3451050c0"><code>b345105</code></a>
3.9.2</li>
<li><a
href="f27779c048"><code>f27779c</code></a>
npm i</li>
<li><a
href="85f9369f40"><code>85f9369</code></a>
chore(deps-dev): bump prettier from 3.8.4 to 3.9.4 (<a
href="https://redirect.github.com/recharts/recharts/issues/7520">#7520</a>)</li>
<li><a
href="52a2a896cf"><code>52a2a89</code></a>
fix(Sankey): avoid exponential depth traversal on dense graphs (<a
href="https://redirect.github.com/recharts/recharts/issues/7479">#7479</a>)</li>
<li><a
href="8a056c1018"><code>8a056c1</code></a>
chore(deps-dev): bump rollup from 4.61.1 to 4.62.2 (<a
href="https://redirect.github.com/recharts/recharts/issues/7527">#7527</a>)</li>
<li><a
href="2af6ec6f0f"><code>2af6ec6</code></a>
chore(deps): bump immer from 11.1.8 to 11.1.9 (<a
href="https://redirect.github.com/recharts/recharts/issues/7526">#7526</a>)</li>
<li><a
href="6f10d53cf6"><code>6f10d53</code></a>
docs: clarify custom labels and ticks need SVG elements (<a
href="https://redirect.github.com/recharts/recharts/issues/7524">#7524</a>)</li>
<li><a
href="c04f1a7678"><code>c04f1a7</code></a>
chore(deps-dev): bump lint-staged from 17.0.7 to 17.0.8 (<a
href="https://redirect.github.com/recharts/recharts/issues/7521">#7521</a>)</li>
<li><a
href="69c7a9630a"><code>69c7a96</code></a>
chore(deps-dev): bump glob from 11.1.0 to 13.0.6 (<a
href="https://redirect.github.com/recharts/recharts/issues/7522">#7522</a>)</li>
<li><a
href="6efaf16a1a"><code>6efaf16</code></a>
chore(deps): bump es-toolkit from 1.47.0 to 1.49.0 (<a
href="https://redirect.github.com/recharts/recharts/issues/7515">#7515</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/recharts/recharts/compare/v3.8.1...v3.9.2">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for recharts since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version modifies <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />

Updates `@tailwindcss/postcss` from 4.2.2 to 4.3.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">@​tailwindcss/postcss's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.2</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
<h2>v4.3.1</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Generate <code>0</code> instead of <code>calc(var(--spacing) *
0)</code> for spacing utilities like <code>m-0</code> and
<code>left-0</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">@​tailwindcss/postcss's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.2] - 2026-06-26</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
<h2>[4.3.1] - 2026-06-12</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="056a155072"><code>056a155</code></a>
4.3.2 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/20281">#20281</a>)</li>
<li><a
href="8a14a71010"><code>8a14a71</code></a>
4.3.1 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/20226">#20226</a>)</li>
<li><a
href="522288ca08"><code>522288c</code></a>
Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/20228">#20228</a>)</li>
<li><a
href="8dcdb66e8a"><code>8dcdb66</code></a>
Bump dependencies (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/20095">#20095</a>)</li>
<li><a
href="588bd7371f"><code>588bd73</code></a>
4.3.0 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/20023">#20023</a>)</li>
<li><a
href="12eb5ae7b6"><code>12eb5ae</code></a>
Cleanup noisy test output (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/20015">#20015</a>)</li>
<li><a
href="4255671c5f"><code>4255671</code></a>
Improve snapshot tests (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/20013">#20013</a>)</li>
<li><a
href="52f94c74bb"><code>52f94c7</code></a>
Improve codebase quality (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/19999">#19999</a>)</li>
<li><a
href="d194d4c3e6"><code>d194d4c</code></a>
docs: fix various typos in comments and documentation (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/19878">#19878</a>)</li>
<li><a
href="bfb5732b0b"><code>bfb5732</code></a>
Fall back to the plugin <code>base</code> when PostCSS has no
<code>from</code> option (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss/issues/19980">#19980</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/@tailwindcss-postcss">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​tailwindcss/postcss</code> since your current
version.</p>
</details>
<br />

Updates `@types/mdx` from 2.0.13 to 2.0.14
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mdx">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/react` from 19.2.14 to 19.2.17
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react">compare
view</a></li>
</ul>
</details>
<br />

Updates `postcss` from 8.5.15 to 8.5.16
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/releases">postcss's
releases</a>.</em></p>
<blockquote>
<h2>8.5.16</h2>
<ul>
<li>Fixed <code>Input#origin()</code> position (by <a
href="https://github.com/mizdra"><code>@​mizdra</code></a>).</li>
<li>Fixed <code>raws</code> after rehydrating a JSON AST (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed putting parent-less node in <code>nodes</code> of new node (by
<a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
<li>Fixed computing <code>offset</code> in <code>positionBy()</code> (by
<a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a>).</li>
<li>Fixed <code>rangeBy()</code> on <code>index: 0</code> (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's
changelog</a>.</em></p>
<blockquote>
<h2>8.5.16</h2>
<ul>
<li>Fixed <code>Input#origin()</code> position (by <a
href="https://github.com/mizdra"><code>@​mizdra</code></a>).</li>
<li>Fixed <code>raws</code> after rehydrating a JSON AST (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed putting parent-less node in <code>nodes</code> of new node (by
<a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
<li>Fixed computing <code>offset</code> in <code>positionBy()</code> (by
<a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a>).</li>
<li>Fixed <code>rangeBy()</code> on <code>index: 0</code> (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="92ccc93ff1"><code>92ccc93</code></a>
Release 8.5.16 version</li>
<li><a
href="818bdd6043"><code>818bdd6</code></a>
Update formatting</li>
<li><a
href="46e451068e"><code>46e4510</code></a>
Fix <code>Input#origin()</code> returning incorrect position (<a
href="https://redirect.github.com/postcss/postcss/issues/2036">#2036</a>)</li>
<li><a
href="34942ce76c"><code>34942ce</code></a>
Fix tests</li>
<li><a
href="d4feed6453"><code>d4feed6</code></a>
Don't clone root-less child nodes in container constructor (<a
href="https://redirect.github.com/postcss/postcss/issues/2097">#2097</a>)</li>
<li><a
href="da323fc8d3"><code>da323fc</code></a>
Revert version update to fix old Node.js on CI</li>
<li><a
href="8863369194"><code>8863369</code></a>
Update dependencies</li>
<li><a
href="3828982213"><code>3828982</code></a>
Preserve node raws when rehydrating a JSON AST (<a
href="https://redirect.github.com/postcss/postcss/issues/2100">#2100</a>)</li>
<li><a
href="d1e80b8303"><code>d1e80b8</code></a>
Fix Node#rangeBy() ignoring index 0 (<a
href="https://redirect.github.com/postcss/postcss/issues/2091">#2091</a>)</li>
<li><a
href="b91e4a6390"><code>b91e4a6</code></a>
Fix Node.js 26 tests</li>
<li>Additional commits viewable in <a
href="https://github.com/postcss/postcss/compare/8.5.15...8.5.16">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a href="https://www.npm...

_Description has been truncated_

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-09 09:38:37 -04:00
Parideboy
e8151f059b
fix(opencode): expose headroom/* models in injected provider config (#1716)
## Description

`headroom wrap opencode` (and `headroom install opencode`) injects a
`provider.headroom` block into the OpenCode config, but the block
contained **no `models` map**. OpenCode only resolves
`<provider>/<model>` ids that are listed in a custom provider's `models`
map, so every documented `headroom/*` model (see
`plugins/opencode/README.md`) failed with:

```text
Error: Model not found: headroom/claude-sonnet-4-6.
```

This PR adds the model map (mirroring `DEFAULT_MODELS` in
`plugins/opencode/src/provider.ts` and the README table) via a single
shared `headroom_provider_entry()` helper used by all three injection
sites. It also fixes a latent bug in the TS helper
`createHeadroomProvider`, which prefixed model **keys** with `headroom/`
— OpenCode would have registered them as `headroom/headroom/<id>`.

Not addressed here (flagged for maintainers): the `headroom-opencode`
npm package referenced by the plugin docs is not published to npm
(registry 404), so the transparent-transport interception path (which
would capture `github-copilot/*` traffic in the dashboard) still depends
on a locally built `plugins/opencode/dist/entry.opencode.js`. With this
fix, the documented `headroom/*` provider route works, so wrapped
OpenCode traffic is proxied and recorded when users select `headroom/*`
models.

Closes #1657

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- `headroom/providers/opencode/config.py`: added
`HEADROOM_OPENCODE_MODELS` (claude-sonnet-4-6, claude-opus-4-6,
claude-haiku-4-5-20251001, gpt-4o, gpt-4.1 — same names/limits as the TS
plugin) and a `headroom_provider_entry(port)` helper that includes the
`models` map; `_render_provider_block` and
`inject_opencode_provider_config` now use it instead of duplicating the
provider dict.
- `headroom/providers/opencode/runtime.py`:
`build_opencode_config_content` reuses `headroom_provider_entry()` so
`OPENCODE_CONFIG_CONTENT` exposes the models too.
- `plugins/opencode/src/provider.ts`: `createHeadroomProvider` no longer
prefixes model keys with `headroom/` (OpenCode namespaces model ids by
provider key; keys must be bare ids).
- `tests/test_providers_opencode_config.py`: assertions that the
injected provider block and `build_opencode_config_content` output
contain a `models` map with bare-id keys including `claude-sonnet-4-6`.

## Testing

- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [x] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [ ] Manual testing performed

### Test Output

```text
$ python -m pytest tests/test_providers_opencode_config.py -q
1 failed, rest passed — test_build_launch_env_with_project is a pre-existing
Windows-only failure (json.dumps escapes backslashes in the plugin path);
it fails identically on upstream/main without this change and passes on Linux.

$ ruff check headroom/providers/opencode tests/test_providers_opencode_config.py
All checks passed!
$ ruff format --check .
5 files already formatted
$ mypy headroom --ignore-missing-imports
Success (notes only, no errors)

$ cd plugins/opencode && npm run typecheck && npm test
tsc --noEmit: OK
Test Files  2 passed (2)
Tests  13 passed (13)
```

## Real Behavior Proof

- Environment: Windows 11, Python 3.13, Node v26.3.0, this branch with
the Rust core built locally.
- Exact command / steps: `python -c "from
headroom.providers.opencode.runtime import
build_opencode_config_content; import json;
print(json.dumps(build_opencode_config_content(port=8787,
include_mcp=False)['provider']['headroom'], indent=1))"`
- Observed result: the generated `headroom` provider block now contains
`"models"` with bare-id keys (`claude-sonnet-4-6`, `claude-opus-4-6`,
`claude-haiku-4-5-20251001`, `gpt-4o`, `gpt-4.1`), each with name and
context/output limits; previously the block had no `models` key, which
is exactly why OpenCode returned `Model not found:
headroom/claude-sonnet-4-6`.
- Not tested: a live `opencode run` round-trip against a real OpenCode
install (no OpenCode binary in this environment); dashboard event
capture for `github-copilot/*` models via the transport plugin (blocked
on the unpublished `headroom-opencode` artifact, see Description).

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable

## Additional Notes

- Docs: `plugins/opencode/README.md` already documents these models; no
doc change needed.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 15:20:14 -07:00
Rod Boev
c19347c310
fix(opencode): preserve custom OpenAI gateway paths (#1596)
## Description

Custom OpenAI-compatible gateways mounted under provider-specific
prefixes could miss Headroom's dedicated OpenAI compression routes when
used through the OpenCode transport. A request such as
`https://open.bigmodel.cn/api/coding/paas/v4/chat/completions` was
replayed to the proxy at `/api/coding/paas/v4/chat/completions`, so the
proxy selected catch-all passthrough instead of `/v1/chat/completions`.

This change keeps the proxy-facing entrypoints stable on
`/v1/chat/completions` and `/v1/responses` for OpenAI-compatible
suffixes, while preserving the original upstream path in an internal
header so the dedicated OpenAI handlers can reconstruct the real
provider URL.

Closes #1582

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- Normalize opencode-routed OpenAI-compatible `/chat/completions` and
`/responses` requests onto the proxy's stable `/v1/*` routes.
- Preserve the original upstream pathname in an internal
`x-headroom-original-path` signal for dedicated OpenAI handler
reconstruction.
- Reconstruct dedicated OpenAI upstream URLs from `x-headroom-base-url`
plus the preserved path prefix, while preserving request query strings
and rejecting non-HTTP base hints.
- Keep nearby non-OpenAI paths such as `/base/v1/messages` on existing
passthrough behavior.
- Add focused transport and proxy regression coverage for prefixed
gateway paths, invalid fallback cases, and internal-header stripping.

## Testing

- [x] Transport regression tests pass (`npm --prefix plugins/opencode
test -- src/transport.test.ts`)
- [x] Proxy regression tests pass (`uv run pytest
tests/test_proxy/test_openai_transport_path_prefix.py -q`)
- [x] Linting passes (`uv run ruff check
headroom/proxy/handlers/openai.py
tests/test_proxy/test_openai_transport_path_prefix.py`)
- [x] Type checking passes (`npm --prefix plugins/opencode run
typecheck`)
- [x] New tests added for the bugfix
- [ ] Manual testing performed

### Test Output

```text
npm --prefix plugins/opencode test -- src/transport.test.ts
PASS, 11 tests passed.

npm --prefix plugins/opencode run typecheck
PASS

uv run pytest tests/test_proxy/test_openai_transport_path_prefix.py -q
PASS, 7 tests passed.

uv run ruff check headroom/proxy/handlers/openai.py tests/test_proxy/test_openai_transport_path_prefix.py
PASS, all checks passed.
```

## Real Behavior Proof

- Environment: Windows, Python 3.12 via `uv`, Node 18+, focused OpenCode
transport and proxy handler tests.
- Exact command / steps: on `origin/main`, copy the updated
`plugins/opencode/src/transport.test.ts` into a base worktree and run
`npm --prefix plugins/opencode test -- src/transport.test.ts`; on this
branch, rerun that transport test plus `npm --prefix plugins/opencode
run typecheck` and `uv run pytest
tests/test_proxy/test_openai_transport_path_prefix.py -q`.
- Observed result: the base worktree fails because prefixed
`/chat/completions` and `/responses` requests still enter the proxy at
their provider path, while this branch passes with
`/v1/chat/completions` and `/v1/responses`, preserves
`x-headroom-original-path`, reconstructs the provider-prefixed upstream
URL and query string, falls back safely on invalid hints, and keeps
nearby `/base/v1/messages` traffic on passthrough.
- Not tested: full CI suite, live BigModel traffic, and generic
catch-all passthrough compression.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable

## Additional Notes

This completes the transport contract introduced in
https://github.com/headroomlabs-ai/headroom/pull/1573 by keeping
prefixed OpenAI-compatible traffic on Headroom's stable `/v1/*` surface
while preserving the real upstream path for dedicated-handler
reconstruction.

https://github.com/headroomlabs-ai/headroom/pull/1367 is adjacent global
proxy configuration work for direct deployments; this PR is the
per-request OpenCode transport fix for custom upstream path prefixes.

`CHANGELOG.md` is intentionally unchanged because this repo's release
pipeline generates changelog entries from conventional commits.

This stays scoped to `/chat/completions` and `/responses` suffixes.
Generic catch-all passthrough compression remains separate from this
bugfix slice.
2026-06-30 08:41:42 -07:00
Tejas Chopra
ad0034f981
fix(opencode): route native providers + load transport plugin, fix Serena context (#1573)
## Description

`headroom wrap opencode` looked like it worked (proxy started, opencode
launched) but **no inference reached the proxy**, so users saw zero
savings (#1572). Root causes:

1. The injected synthetic `headroom` provider
(`@ai-sdk/openai-compatible`) had **no `models` and no `apiKey`** →
opencode raised `ProviderModelNotFoundError`, and it only ever targets
OpenAI.
2. The wrap injected a reference to the **unpublished
`headroom-opencode` npm plugin**, which opencode silently failed to
resolve → the transparent transport never loaded.
3. Serena was launched with `--context opencode`, a context Serena does
not ship → crash on launch (#1549).

This PR makes `headroom wrap opencode` route opencode's traffic through
the proxy with the user's **own API key** (no key written to disk), and
gets the transparent transport plugin actually loading.

Closes #1572
Closes #1549

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)

## Changes Made

- **`runtime.py`** — two complementary routing layers (both verified
against opencode 1.17):
1. Override opencode's native `anthropic`/`openai` provider `baseURL` to
the proxy. Reliable, credential-independent (covers API key **and**
subscription), keeps native model metadata/limits, reuses the user's
existing key. This is the always-on layer and the only one a pip-only
install needs.
2. Load the transport plugin **by absolute path** when it has been built
(`headroom_opencode_plugin_path()`), self-configured via
`HEADROOM_PROXY_URL`. Covers providers we don't name (Gemini, Copilot,
custom gateways) and providers added mid-session. Loopback URLs aren't
double-routed, so the two layers coexist.
- **`wrap.py`** — Serena context `opencode` → `agent` (valid context).
- **`plugins/opencode/`** — new `src/entry.opencode.ts` loader entry
that exports **only** the plugin function (opencode rejects a module
with non-function exports: "Plugin export is not a function"); tsup
builds it as a second entry.
- **tests** — updated `test_providers_opencode_config.py` for path-based
plugin injection + a skip-when-unbuilt case.

## Testing

- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [x] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [x] Manual testing performed

### Test Output

```text
$ python -m pytest tests/test_providers_opencode_config.py tests/test_cli/test_wrap_opencode.py -q
72 passed in 0.59s

$ (cd plugins/opencode && npm test)
Test Files  2 passed (2)
     Tests  9 passed (9)

$ ruff check headroom/providers/opencode/runtime.py headroom/cli/wrap.py tests/test_providers_opencode_config.py
✓ Ruff: No issues found
$ mypy headroom/providers/opencode/runtime.py
Success: no issues found in 1 source file
```

## Real Behavior Proof

- **Environment:** macOS, opencode 1.17.11 (npm), headroom proxy 0.28.0
(local), Anthropic API key from `.env`.
- **Exact command:**
  ```
headroom wrap opencode --no-serena --no-context-tool --no-proxy --port
8787 \
-- run -m anthropic/claude-haiku-4-5-20251001 "Reply with exactly:
WRAPWORKS"
  ```
- **Observed result:** opencode printed `plugin=headroom-opencode`
(loaded, no error) and returned `WRAPWORKS`. The proxy log shows the
request routed through it:
  ```
event=outbound_request method=POST
path=https://api.anthropic.com/v1/messages source=passthrough
  event=proxy_inbound_response path=/v1/messages status=200
  PERF model=claude-haiku-4-5-20251001 cache_hit_pct=97 client=opencode
  ```
  Compression verified on a large tool_result (`client=opencode`):
  ```
Pipeline complete: 170653 -> 77 tokens (saved 170576, 100.0% reduction)
PERF tok_before=151309 tok_after=67 tok_saved=151242
transforms=router:tool_result:log client=opencode
  ```
- **Not tested:** custom OpenAI-compatible gateways (need the proxy to
honor `x-headroom-base-url` in the dedicated OpenAI handler — open PR
#1502); interactive TUI (verified the headless `opencode run` path).

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Additional Notes

- **Plugin shipping:** the plugin loads by repo-relative path, which
works for source/editable installs. `plugins/opencode/dist/` is
gitignored, so the plugin must be built (`cd plugins/opencode && npm
install && npm run build`) for layer 2 to activate; pip-only installs
gracefully fall back to layer 1 (native baseURL override). Bundling
`dist/` into the package or publishing `headroom-opencode` to npm is a
follow-up for universal shipping.
- **CHANGELOG:** N/A — handled by Release Please from the conventional
commit.
- Custom-gateway support depends on existing PR #1502 (honor
`x-headroom-base-url` in the dedicated OpenAI handlers); not duplicated
here.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-29 15:04:56 -07:00
Tejas Chopra
c2fc4d3753
fix(ccr): make headroom_retrieve a hash-only full-content lookup (#1532)
The optional `query` parameter on headroom_retrieve routed retrieval
through CompressionStore.search(), which BM25-scored the items inside a
single cached blob and dropped everything below a 0.3 relevance floor.
On small per-blob corpora with conversational queries this returned an
empty result the large majority of the time, so the LLM saw "nothing
found" for content that was actually present — pushing users to turn
compression off entirely.

Retrieval is fundamentally a hash lookup (this already matches the Rust
proxy's CCR store, which is put/get only — "no BM25 search"). Remove the
query/search path end to end and always return the full original
content:

Core (Python proxy):
- tool schemas (anthropic/openai/google) drop the `query` property
- parse_tool_call returns the hash (str | None) instead of (hash, query)
- response handler, proxy POST/GET/tool-call handlers, the MCP retrieve
tool, and the streaming feedback recorders retrieve by hash only
- proactive context-tracker expansion always restores full content
- delete CompressionStore.search() and its BM25 machinery (the bm25
module stays — it is still used by relevance/)
- CCRToolCall.query, CCRToolResult.was_search, and
ExpansionRecommendation.expand_full/search_query are removed

Plugins (advertised a now-defunct query param to the LLM):
- hermes (Python), openclaw + opencode (TypeScript) retrieve tools drop
`query` from their schemas, signatures, request URLs, and tests

Benchmarks/docs:
- ccr_regression + adversarial benchmarks switch from store.search() to
full hash retrieval (search input-injection tests repurposed to the
hash, the only remaining input surface)
- wiki/ARCHITECTURE.md, wiki/ccr.md, docs/content/docs/ccr.mdx,
config.py and store docstrings updated to describe hash-only retrieval

Tests updated to assert full-content retrieval and guard the removed
surface; the full CCR/proxy/store/TOIN suite passes. ruff + mypy clean.

## Description

<!-- Briefly explain the change and why it is needed. -->

Closes #

## Type of Change

- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- 

## Testing

<!-- Check what you actually ran, then paste the real command output
below. -->

- [ ] Unit tests pass (`pytest`)
- [ ] Linting passes (`ruff check .`)
- [ ] Type checking passes (`mypy headroom`)
- [ ] New tests added for new functionality
- [ ] Manual testing performed

### Test Output

```text
# Paste relevant command output or artifact links here
```

## Real Behavior Proof

- Environment:
- Exact command / steps:
- Observed result:
- Not tested:

## Review Readiness

- [ ] I have performed a self-review
- [ ] This PR is ready for human review

## Checklist

- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] I have updated the CHANGELOG.md if applicable

## Screenshots (if applicable)

Add screenshots to help explain your changes.

## Additional Notes

<!-- Mention any N/A checklist items, tradeoffs, follow-ups, or
maintainer context. -->
2026-06-28 10:32:43 -07:00
Rudimar Ronsoni
fa05ebc849
docs: clarify OpenCode integration (#1317)
## Description

Clarifies the OpenCode documentation follow-up for PR #1105 so users can
install `headroom-opencode`, configure provider routing, use the native
plugin, and copy working retrieve/compression helper examples.

## Type of Change

- [x] Documentation update
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change

## Changes Made

- Documented how `headroom wrap opencode` wires provider config, MCP
tools, and runtime environment.
- Documented the native `HeadroomPlugin` path, `HEADROOM_PROXY_URL`,
retrieve tooling, and programmatic config helpers.
- Fixed `plugins/opencode/README.md` examples so `compressWithHeadroom`
uses the exported options-object API and `headroom_retrieve` uses
`hash`.

## Testing

- [x] Type checks pass.
- [x] Unit tests pass.
- [x] Whitespace check passes.

### Test Output

```text
plugins/opencode: npm run typecheck
> tsc --noEmit

plugins/opencode: npm test
Test Files  2 passed (2)
Tests  9 passed (9)

docs: npm run types:check
✓ Types generated successfully

repo: git diff --check
(no output)
```

## Real Behavior Proof

- Environment: Local macOS worktree at
`docs/pr-1105-documentation-followup`, Node/npm project commands run
from `plugins/opencode` and `docs`.
- Exact command / steps: Updated the README snippets, ran `npm run
typecheck`, reran `npm test` with elevated permissions after the sandbox
blocked a local `127.0.0.1` listener, ran `npm run types:check` in
`docs`, and ran `git diff --check`.
- Observed result: Typecheck completed with `tsc --noEmit`; the OpenCode
package test suite reported 2 files and 9 tests passed; docs type
generation completed successfully; `git diff --check` produced no
output.
- Not tested: Browser-rendered documentation preview. `docs: npm run
build` was started locally but produced no output for roughly 90 seconds
and was stopped, so this follow-up does not claim a fresh local docs
build result.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Additional Notes

- The linked review comment asked for README examples to match
`compressWithHeadroom(messages, options)` and
`createHeadroomRetrieveTool` requiring `hash`; both snippets now match
the exported API.
2026-06-24 21:54:05 -05:00
Rudimar Ronsoni
b4571cc346
feat: headroom wrap opencode / unwrap opencode CLI (#1105)
## Summary

This PR implements transparent `headroom wrap opencode` support without
asking users to edit OpenCode provider URLs, choose an extra CLI flag,
or maintain a static provider list.

The wrapper now lives at the runtime transport boundary: OpenCode keeps
its user/provider config, while Headroom intercepts outbound provider
traffic in-process and routes it through the local Headroom proxy.

## What changed

### Transparent OpenCode wrapping

- `headroom wrap opencode` injects the `headroom-opencode` plugin
through `OPENCODE_CONFIG_CONTENT`.
- Existing OpenCode provider URLs are preserved. We do not rewrite user
config URLs to point at Headroom.
- Existing `OPENAI_BASE_URL` and `ANTHROPIC_BASE_URL` env vars are
preserved.
- Local OpenCode traffic, localhost traffic, and Headroom proxy traffic
bypass the shim to avoid loops.

### Runtime transport interception

- Added an OpenCode plugin transport shim that wraps:
  - `globalThis.fetch`
  - `http.request` / `http.get`
  - `https.request` / `https.get`
- External provider calls are routed to the local Headroom proxy.
- The original upstream origin is passed through `x-headroom-base-url`,
so the proxy can forward to the real provider without changing OpenCode
config.
- External `http2.connect` is blocked loudly instead of allowing direct
provider traffic to leak outside Headroom.

### Live provider additions

Provider coverage is no longer based on a static config scan. Because
routing happens at outbound request time, providers added mid-session
are routed through Headroom automatically as long as they use the
covered Node transport paths.

### Subagent and child-process coverage

- The parent OpenCode plugin sets a packaged Node preload shim through
`NODE_OPTIONS=--import=.../hook-shim/handler.js`.
- The transport shim patches `child_process.spawn`, `exec`, `execFile`,
and `fork` so child Node processes receive the Headroom preload even
when OpenCode passes a custom `env`.
- The child-process shim fails closed if it loads without
`HEADROOM_OPENCODE_TRANSPORT_PROXY_URL`.
- This closes the subagent leak path where a child Node process could
otherwise start without Headroom transport interception.

## Why this goes beyond PR #1089

PR #1089 improves OpenCode provider registration, but it still focuses
on provider config shape. This PR moves the enforcement boundary to
runtime transport interception.

This PR goes further because:

- No provider URL rewriting is required.
- New providers added mid-session are covered automatically.
- Subagents and child Node processes inherit the Headroom transport
shim.
- Direct external HTTP/2 paths fail loudly instead of leaking.
- The wrap remains transparent to the user's OpenCode provider config.
- The wrapper is fail-closed for unsupported child-process preload
state.

## Additional robustness fixes

While validating the change in Docker, the full Python suite exposed
unrelated Linux/container robustness issues. These are fixed in this PR
so the suite is green:

- Binary cache handling now treats cache paths under a non-writable
existing parent as unavailable, including when tests run as root in
Docker.
- `release_version.py` honors `MANUAL_VER` before git calls so direct
script execution works outside a `.git` checkout.
- Test logger isolation now resets relevant Headroom child loggers so
proxy logging setup cannot poison later `caplog` tests.
- The scanner missing-path test now uses a guaranteed missing `tmp_path`
child instead of relying on `/nonexistent/path`.

## Validation

All implementation validation was run inside Docker.

- Full Python suite from a fresh Docker copy: `6605 passed, 523
skipped`.
- Ruff on changed Python/OpenCode paths: passed.
- OpenCode plugin typecheck: passed.
- OpenCode plugin tests: `9 passed`.
- OpenCode plugin build: passed.
- Hook shim preload smoke test: passed.

## Notes

This PR intentionally does not add a CLI option. `headroom wrap
opencode` means full wrap. Either Headroom wraps OpenCode transparently,
or the path fails loudly instead of silently leaking provider traffic.

---------

Co-authored-by: Rudimar Ronsoni <6081613+rudironsoni@users.noreply.github.com>
2026-06-22 11:07:12 -05:00