Skip to content

Update trigger - #4

Open
tylerc-govsignals wants to merge 1336 commits into
GovSignals:ConProgramming/two-phase-deployfrom
triggerdotdev:main
Open

Update trigger#4
tylerc-govsignals wants to merge 1336 commits into
GovSignals:ConProgramming/two-phase-deployfrom
triggerdotdev:main

Conversation

@tylerc-govsignals

Copy link
Copy Markdown
Collaborator

Closes #

✅ Checklist

  • I have followed every step in the contributing guide
  • The PR title follows the convention.
  • I ran and tested the code works

Testing

[Describe the steps you took to test this change]


Changelog

[Short description of what has changed]


Screenshots

[Screenshots]

💯

ericallam and others added 30 commits June 30, 2026 09:14
…errors (#4077)

## Summary

Two robustness fixes in the dashboard's error handling, found while
testing the billing-limit pause/resume flow.

## Toast cookie overflow

Toast messages are flashed into the `__message` session cookie, which
the session store rejects once the serialized cookie passes the
browser's ~4KB limit. Any call site that flashes a raw caught error (a
verbose database or validation message, for example) could turn a toast
into a failed request. `setErrorMessage` / `setSuccessMessage` now clamp
the message length, so a toast can never overflow the cookie. This
protects every toast helper at once.

## Pause/resume reporting

Resuming an environment that is paused by a billing limit is an
expected, user-actionable state, but `PauseEnvironmentService` threw it,
and the service's catch reports every throw at error level. It now
returns that case as a failure result, so callers still surface the
message to the user while genuine errors keep reporting.
Fixed trace rendering for child and nested runs in large traces.
Dashboard and trace API responses now load the requested run's trace
subtree instead of depending on the run span appearing in the initial
trace slice.
Invite acceptance could fail for cloud organizations with many projects
because the whole flow ran inside a single transaction and did too much
work before it completed. In larger orgs, that pushed the transaction
past its timeout and blocked the invite from being accepted.

This PR moves the expensive parts of invite acceptance out of the
transaction, excludes deleted projects from environment setup, fixes
error handling on /invites, and adds regression coverage for the failure
cases.
## Summary

Upgrades the dashboard form layer from `@conform-to` 0.9 to 1.x. No
behaviour change is intended; this is the conform API migration only.

conform 1.x peer-depends on `zod` `^3.21 || ^4`, so it runs on the
current zod 3 and is a prerequisite for upgrading the repo to zod 4:
conform 0.9 imports `ZodNativeEnum`, `ZodEffects`, and `ZodPipeline`,
all removed in zod 4, so the webapp cannot build against zod 4 until
conform is on 1.x. Landing this first (on zod 3) keeps the zod 4 PR
focused on zod alone.

## Testing
Did a bunch of local smoke tests and E2E playwright tests, several
rounds of different reviewers, all clean.
Adds a `redis_worker.queue.oldest_message_age` observable gauge (labeled
`worker_name`) and `SimpleQueue.oldestMessageAge()`, reporting the age
of the
oldest overdue message in each queue. Generic queue-stall signal: 0
while a
queue drains healthily, rising only when due work sits undrained
(blocked
dequeue, dead consumer, backpressure) — even when no items are being
processed.
- auto-reloading for setting up identity & access
- ui/ux improvements around the process of setting up connections for
the identity & access
Having issues with blacksmith runners coming online.
The `Exec` helper in `@trigger.dev/core` logs command args at debug
level (and in its output/error metadata). For commands that take a
credential directly on the command line - `--password`, `--token`,
`--secret`, etc. - that value is logged verbatim, so turning on debug
logging can surface secrets in log sinks.

This masks the value of known credential-bearing flags (both `--flag
value` and `--flag=value` forms) before the args are logged. The
executed command is untouched - only the logged copy is redacted. Added
a small unit test for the redaction helper.
Re-enables ~15 oxlint rules that were blanket-disabled before.
…un (#4094)

Fixes #4046

## Problem

When a single run creates more than 1000 idempotency keys (e.g. a large
batch trigger where each item calls `idempotencyKeys.create()`), the
original key and scope metadata is silently dropped for all but the most
recent 1000 keys.

`idempotencyKeys.create()` returns a plain 64-char hash and stores the
`{ key, scope }` mapping in an in-process catalog keyed by that hash.
That catalog was a fixed-size **LRU capped at 1000 entries**. Once a run
creates more than 1000 keys, the earliest mappings are evicted, so when
the SDK later looks them up to attach `idempotencyKeyOptions` to the
trigger call, it finds nothing and sends `undefined`. The affected runs
then:

- report `ctx.run.idempotencyKey` as the raw hash instead of the
user-provided key
- have no `idempotencyKeyScope`
- show empty `idempotency_key` / `idempotency_key_scope` in the
dashboard and analytics

Deduplication still works (the hash is intact); only the human-readable
metadata is lost, which makes the failure silent and hard to notice.

## Fix

- Replace the LRU catalog with an unbounded in-memory catalog, so every
key created within a run keeps its metadata regardless of how many are
created.
- Clear the catalog at each run boundary via
`resetExecutionEnvironment()` (both dev and managed workers), matching
how every other per-run manager is reset. Deployed workers reuse one
process across many runs (warm starts), so this bounds memory to a
single run's keys instead of accumulating across runs — which is the
reason the size cap existed in the first place.

## Tests

- New public-API test creates 3000 keys and asserts all of them
(including the first) retain their key/scope — this fails on `main` and
passes with the fix.
- New test for the in-memory catalog covers store/retrieve/overwrite,
large-N retention (no eviction), and `clear()`.
- New test asserts the catalog is emptied after a run-boundary reset.
- Replaces the previous LRU catalog + its eviction tests.

Verified: `@trigger.dev/core` and `trigger.dev` both build; all
idempotency tests pass. Changeset added (patch).
## Summary

Fixes flaky CLI v3 E2E tests by removing fixture-level parallelism.

The suite was using `describe.concurrent`, but each fixture test mutates
its fixture workspace during setup: removing `node_modules`,
renaming/restoring lockfiles, and running package installs. On
Windows/npm this can race or hit file-lock/cache contention, causing
intermittent failures.

## Fix

Run the CLI v3 E2E fixtures serially instead of concurrently.

## Expected impact

This should make the Windows/npm E2E job more stable. The E2E step may
slow down from ~30s to roughly ~60–90s in typical runs, with a
conservative upper bound around ~2 minutes.
…nsert (#4095)

## ✅ Checklist

- [ ] I have followed every step in the [contributing
guide](https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md)
- [x] The PR title follows the convention.
- [ ] I ran and tested the code works

---

## Testing

`pnpm run typecheck --filter @internal/clickhouse` passes. This only
adds a ClickHouse input-format setting to existing insert calls; the
setting affects type inference for newly-inserted/merged data and is
non-destructive to existing rows.

---

## Changelog

Sets
`input_format_json_infer_array_of_dynamic_from_array_of_different_types
= 1` on every native-JSON insert path:

- `task_runs_v2` (`output`, `error`) — `insertTaskRuns`,
`insertTaskRunsCompactArrays`, and the async-insert variants
- `task_events_v1` / `task_events_v2` (`attributes`)
- `metrics_v1`
- `sessions_v1`

### Why

Our JSON columns contain arrays with mixed element types (e.g.
`[{"key":"value"}, "string", "string"]`). With this setting off — which
is the effective default under `24.12` compatibility — ClickHouse infers
those as deeply nested unnamed `Tuple(JSON, Nullable(String), …)` types.
ClickHouse 26.2 introduced `input_format_binary_max_type_complexity`
(default 1000), and those tuple type trees exceeded the limit, causing
background merges to fail with **Code 117**.

With the setting on (the default since 25.8), mixed-type arrays are
inferred as a single `Array(Dynamic)` — a simpler, flatter type
representation that never approaches the complexity limit, even once the
upstream default limit is restored.

Setting this explicitly at insert time keeps behavior deterministic and
version-controlled, so it does not depend on the server profile or a
future compatibility bump. This is a forward-only change: it only
affects newly inserted/merged data and does not rewrite existing parts.
Our read path re-serializes these columns to strings (`toJSONString` via
the materialized `*_text` columns), so the internal Tuple →
Array(Dynamic) representation change is transparent to the application.

### Companion server-side setting

To also apply this on the ClickHouse side (covers merges and any writes
not going through these code paths), set it on the default user:

```sql
ALTER USER default SETTINGS input_format_json_infer_array_of_dynamic_from_array_of_different_types = 1;
```

---

## Screenshots

_N/A_

💯

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

https://claude.ai/code/session_01AaChyhestFMBYBWh6bgcCF

---
_Generated by [Claude
Code](https://claude.ai/code/session_01AaChyhestFMBYBWh6bgcCF)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Bumps the `@remix-run/*` family in the webapp from 2.17.4 to 2.17.5 to
keep dependencies current.

2.17.5 pulls `@remix-run/router` 1.23.2 → 1.23.3, so the local
route-matching perf patch was rebased onto 1.23.3 (regenerated via `pnpm
patch`). It is functionally identical to the previous one - the only
difference is that 1.23.3 already hoists `decodePath` out of the match
loop upstream, so that hunk is dropped; the per-route-tree branch cache
and the compiled-path cache are unchanged. Also updated the
`@remix-run/dev>tar-fs` override key to track the new dev version.

Verified locally against latest main: `typecheck --filter webapp`
passes, `--frozen-lockfile` is consistent, and the dev server boots and
server-renders pages cleanly (route matching exercised via the patched
router).
…updates (#4097)

Bumps the github-actions group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `6.0.2` |
`7.0.0` |
| [changesets/action](https://github.com/changesets/action) | `1.8.0` |
`1.9.0` |
|
[anthropics/claude-code-action](https://github.com/anthropics/claude-code-action)
| `1.0.133` | `1.0.157` |
| [actions/cache](https://github.com/actions/cache) | `5.0.5` | `6.1.0`
|
| [azure/setup-helm](https://github.com/azure/setup-helm) | `5.0.0` |
`5.0.1` |
|
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
| `3.0.0` | `3.0.1` |
|
[zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action)
| `0.5.6` | `0.5.7` |


Updates `actions/checkout` from 6.0.2 to 7.0.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="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/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>block checking out fork pr for pull_request_target and workflow_run
by <a href="/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
<li>getting ready for checkout v7 release by <a
href="/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li>
<li>update error wording by <a
href="/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="/aiqiaoy"><code>@​aiqiaoy</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p>
<h2>v6.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update changelog by <a
href="/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
<li>Fix checkout init for SHA-256 repositories by <a
href="/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>Update changelog for v6.0.3 by <a
href="/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="/yaananth"><code>@​yaananth</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="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/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v7.0.0</h2>
<ul>
<li>Block checking out fork PR for pull_request_target and workflow_run
by <a href="/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
</ul>
<h2>v6.0.3</h2>
<ul>
<li>Fix checkout init for SHA-256 repositories by <a
href="/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<h2>v6.0.2</h2>
<ul>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<h2>v6.0.1</h2>
<ul>
<li>Add worktree support for persist-credentials includeIf by <a
href="/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
</ul>
<h2>v6.0.0</h2>
<ul>
<li>Persist creds to a separate file by <a
href="/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>Update README to include Node.js 24 support details and requirements
by <a href="/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
</ul>
<h2>v5.0.1</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<h2>v5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>v4.3.1</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<h2>v4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="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/actions/checkout/commit/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"><code>9c091bb</code></a>
update error wording (<a
href="https://redirect.github.com/actions/checkout/issues/2467">#2467</a>)</li>
<li><a
href="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/actions/checkout/commit/1044a6dea927916f2c38ba5aeffbc0a847b1221a"><code>1044a6d</code></a>
getting ready for checkout v7 release (<a
href="https://redirect.github.com/actions/checkout/issues/2464">#2464</a>)</li>
<li><a
href="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/actions/checkout/commit/f0282184c7ce73ab54c7e4ab5a617122602e575f"><code>f028218</code></a>
Bump the minor-npm-dependencies group across 1 directory with 3 updates
(<a
href="https://redirect.github.com/actions/checkout/issues/2462">#2462</a>)</li>
<li><a
href="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/actions/checkout/commit/d914b262ffc244530a203ab40decab34c3abf34d"><code>d914b26</code></a>
upgrade module to esm and update dependencies (<a
href="https://redirect.github.com/actions/checkout/issues/2463">#2463</a>)</li>
<li><a
href="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/actions/checkout/commit/537c7ef99cef6e5ddb5e7ff5d16d14510503801d"><code>537c7ef</code></a>
Bump <code>@​actions/core</code> and <code>@​actions/tool-cache</code>
and Remove uuid (<a
href="https://redirect.github.com/actions/checkout/issues/2459">#2459</a>)</li>
<li><a
href="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/actions/checkout/commit/130a169078a413d3a5246a393625e8e742f387f6"><code>130a169</code></a>
Bump js-yaml from 4.1.0 to 4.2.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2461">#2461</a>)</li>
<li><a
href="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/actions/checkout/commit/7d09575332117a40b46e5e020664df234cd416f3"><code>7d09575</code></a>
Bump flatted from 3.3.1 to 3.4.2 (<a
href="https://redirect.github.com/actions/checkout/issues/2460">#2460</a>)</li>
<li><a
href="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/actions/checkout/commit/0f9f3aa320cb53abeb534aeb54048075d9697a0e"><code>0f9f3aa</code></a>
Bump actions/publish-immutable-action (<a
href="https://redirect.github.com/actions/checkout/issues/2458">#2458</a>)</li>
<li><a
href="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/actions/checkout/commit/f9e715a95fcd1f9253f77dd28f11e88d2d6460c7"><code>f9e715a</code></a>
block checking out fork pr for pull_request_target and workflow_run (<a
href="https://redirect.github.com/actions/checkout/issues/2454">#2454</a>)</li>
<li><a
href="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/actions/checkout/commit/df4cb1c069e1874edd31b4311f1884172cec0e10"><code>df4cb1c</code></a>
Update changelog for v6.0.3 (<a
href="https://redirect.github.com/actions/checkout/issues/2446">#2446</a>)</li>
<li>Additional commits viewable in <a
href="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/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0">compare
view</a></li>
</ul>
</details>
<br />

Updates `changesets/action` from 1.8.0 to 1.9.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="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/changesets/action/releases">changesets/action's
releases</a>.</em></p>
<blockquote>
<h2>v1.9.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/636">#636</a>
<a
href="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/changesets/action/commit/b072bccc4c664a373c42168eed9139dce1e003b1"><code>b072bcc</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Add a new <code>@changesets/action/pr-comment</code> sub-action to
comment on PRs</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/625">#625</a>
<a
href="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/changesets/action/commit/8795eee5eee884e887d352ac673a515ffe35aaa6"><code>8795eee</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Add a new <code>@changesets/action/pr-status</code> sub-action to
generate the changeset status comment for PRs as an alternative to the
<a href="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/apps/changeset-bot">Changesets Bot</a>.</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/535">#535</a>
<a
href="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/changesets/action/commit/34f64f6e2e1e47ddc183f174aa27c197aa47f520"><code>34f64f6</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! - Fixed
an issue with GitHub releases not being created for successfully
published packages when <em>some</em> packages failed to be published to
the registry.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/632">#632</a>
<a
href="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/changesets/action/commit/1d54b9e660e435237accbcae0b4581af3be641b4"><code>1d54b9e</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Simplify internal implementation to get changelog entries for a package
version</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/629">#629</a>
<a
href="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/changesets/action/commit/e0c90aa7fbd0cc26931a679c5abe9bbc0deb0b50"><code>e0c90aa</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Fix custom version and publish command argument parsing</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/645">#645</a>
<a
href="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/changesets/action/commit/f9585d966a9c7d2f668b97199990de6f885823cf"><code>f9585d9</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! -
Improved force-push handling when using <code>commitMode:
&quot;github-api&quot;</code> so updating an existing branch no longer
temporarily resets the target branch to the base commit, avoiding cases
where GitHub closes open pull requests during the update. This should
remove a possibility of a GitHub state race that caused the force-pushed
PRs not being reopened.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="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/changesets/action/blob/main/CHANGELOG.md">changesets/action's
changelog</a>.</em></p>
<blockquote>
<h1><code>@​changesets/action</code></h1>
<h2>2.0.0-next.3</h2>
<h3>Major Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/680">#680</a>
<a
href="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/changesets/action/commit/ca57073900dc678254406a052a03c0c8824e319d"><code>ca57073</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Add a new <code>push-git-tags</code> option that complements
<code>create-github-releases</code> to control specifically if git tags
should be created but not GitHub releases.</p>
<p>If <code>create-github-releases</code> was previously set to
<code>false</code>, which also indirectly disabled git tag creation, git
tags will now be created instead by default. If this is not desired, set
<code>push-git-tags</code> to <code>false</code> explicitly.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/681">#681</a>
<a
href="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/changesets/action/commit/73591071e61c7f61cf322dd7a6341dc29a8e1d4e"><code>7359107</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Rename the root action inputs and outputs to better match the
sub-actions' conventions.</p>
<p>Inputs:</p>
<ul>
<li><code>version</code> -&gt; <code>version-script</code></li>
<li><code>publish</code> -&gt; <code>publish-script</code></li>
<li><code>commit</code> -&gt; <code>commit-message</code></li>
<li><code>title</code> -&gt; <code>pr-title</code></li>
<li><code>branch</code> -&gt; <code>pr-base-branch</code></li>
</ul>
<p>Outputs:</p>
<ul>
<li><code>pull-request-number</code> -&gt; <code>pr-number</code></li>
</ul>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/674">#674</a>
<a
href="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/changesets/action/commit/164652bdd60525670d95291addb8c6f92833ac60"><code>164652b</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Remove support for passing custom GitHub token through the GITHUB_TOKEN
environment variable. It should be passed to the
<code>github-token</code> input instead.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/673">#673</a>
<a
href="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/changesets/action/commit/823cf741ca57c5e22652123d3a847dfafcd77ca0"><code>823cf74</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Update to Changesets v3 packages</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/668">#668</a>
<a
href="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/changesets/action/commit/0eae789230defbc4ad287e9b476aba7e842e34e0"><code>0eae789</code></a>
Thanks <a href="/bluwy"><code>@​bluwy</code></a>! -
Rename the input and output names to kebab-case instead of camelCase to
match the official GitHub actions pattern</p>
</li>
</ul>
<h3>Minor Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/changesets/action/pull/678">#678</a>
<a
href="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/changesets/action/commit/f71ae043ed5deb17952900091e009a60edef9507"><code>f71ae04</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! -
Published packages detection done through stdout parsing was replaced
with one based on the shared output file using
<code>CHANGESETS_OUTPUT</code> environment variable. When using custom
scripts this environment variable should always be passed down to the
Changesets CLI invocations.</li>
</ul>
<h2>2.0.0-next.2</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/670">#670</a>
<a
href="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/changesets/action/commit/5a8b9b721bf683e3bf9bd72ea92a685dc024147b"><code>5a8b9b7</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! -
Authenticate git CLI pushes with the configured GitHub token using Git
extra headers instead of writing to a global <code>.netrc</code>
file.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/670">#670</a>
<a
href="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/changesets/action/commit/5a8b9b721bf683e3bf9bd72ea92a685dc024147b"><code>5a8b9b7</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! - Derive
the Git server URL from the GitHub Actions context when configuring git
CLI authentication to support GitHub Enterprise Server setups.</p>
</li>
</ul>
<h2>2.0.0-next.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/663">#663</a>
<a
href="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/changesets/action/commit/ccb38113eaaa4a13eb6aabe09520e49cc8519b84"><code>ccb3811</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! - Fix
the computed publish plan path passed internally to <code>changeset
pack</code> by the <code>/pack</code> subaction.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/662">#662</a>
<a
href="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/changesets/action/commit/5c88881fff1f0d8b055d4a2d3a74a8ce843db6f3"><code>5c88881</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! - Fixed
usage of <code>--from-publish-plan</code> flag used by the
<code>/pack</code> subaction</p>
</li>
<li>
<p><a
href="https://redirect.github.com/changesets/action/pull/666">#666</a>
<a
href="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/changesets/action/commit/dc29b738b532d9e95f46b9bf493e2e3fdf48a7ed"><code>dc29b73</code></a>
Thanks <a
href="/Andarist"><code>@​Andarist</code></a>! - Fix
the <code>/version</code> subaction to not crash on missing
<code>pr-base-branch</code> input. This input is meant to be
optional.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="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/changesets/action/commit/a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d"><code>a45c4d5</code></a>
v1.9.0</li>
<li><a
href="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/changesets/action/commit/b459b1eaa0a3889b4eea8af244304a64da6331ce"><code>b459b1e</code></a>
Version Packages (<a
href="https://redirect.github.com/changesets/action/issues/637">#637</a>)</li>
<li><a
href="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/changesets/action/commit/f9585d966a9c7d2f668b97199990de6f885823cf"><code>f9585d9</code></a>
Update <code>@changesets/ghcommit</code> (<a
href="https://redirect.github.com/changesets/action/issues/645">#645</a>)</li>
<li><a
href="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/changesets/action/commit/020e8cc600a1e7e7b8b843654902f043f32387ea"><code>020e8cc</code></a>
Use internal bot for versioning (<a
href="https://redirect.github.com/changesets/action/issues/643">#643</a>)</li>
<li><a
href="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/changesets/action/commit/b072bccc4c664a373c42168eed9139dce1e003b1"><code>b072bcc</code></a>
Add simple PR comment sub-action (<a
href="https://redirect.github.com/changesets/action/issues/636">#636</a>)</li>
<li><a
href="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/changesets/action/commit/8795eee5eee884e887d352ac673a515ffe35aaa6"><code>8795eee</code></a>
Comment changeset status in PRs (<a
href="https://redirect.github.com/changesets/action/issues/625">#625</a>)</li>
<li><a
href="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/changesets/action/commit/34f64f6e2e1e47ddc183f174aa27c197aa47f520"><code>34f64f6</code></a>
Fixed an issue with GitHub releases not being created for successfully
publis...</li>
<li><a
href="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/changesets/action/commit/1d54b9e660e435237accbcae0b4581af3be641b4"><code>1d54b9e</code></a>
Simplify getChangelogEntry (<a
href="https://redirect.github.com/changesets/action/issues/632">#632</a>)</li>
<li><a
href="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/changesets/action/commit/031358f743b5a6199bd7a39bdc8b469280983df9"><code>031358f</code></a>
Update to typescript v6 (<a
href="https://redirect.github.com/changesets/action/issues/633">#633</a>)</li>
<li><a
href="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/changesets/action/commit/a0c05f7a4b1df776543903d7dca8e39cd787b30a"><code>a0c05f7</code></a>
Bump <code>@​changesets/changelog-github</code> from 0.5.2 to 0.7.0 (<a
href="https://redirect.github.com/changesets/action/issues/620">#620</a>)</li>
<li>Additional commits viewable in <a
href="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/changesets/action/compare/63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b...a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d">compare
view</a></li>
</ul>
</details>
<br />

Updates `anthropics/claude-code-action` from 1.0.133 to 1.0.157
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="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/anthropics/claude-code-action/releases">anthropics/claude-code-action's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.157</h2>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.157">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.157</a></p>
<h2>v1.0.156</h2>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.156">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.156</a></p>
<h2>v1.0.155</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: filter PR reviews and inline review comments to trigger time by
<a
href="/EffortlessSteven"><code>@​EffortlessSteven</code></a>
in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1385">anthropics/claude-code-action#1385</a></li>
<li>test: cover format-turns content-type fallbacks and system_other
handling by <a
href="/farmer-data"><code>@​farmer-data</code></a> in
<a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1421">anthropics/claude-code-action#1421</a></li>
<li>fix: allow @ in branch names (valid per git-check-ref-format) by <a
href="/bellalMohamed"><code>@​bellalMohamed</code></a>
in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1411">anthropics/claude-code-action#1411</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="/EffortlessSteven"><code>@​EffortlessSteven</code></a>
made their first contribution in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1385">anthropics/claude-code-action#1385</a></li>
<li><a
href="/farmer-data"><code>@​farmer-data</code></a>
made their first contribution in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1421">anthropics/claude-code-action#1421</a></li>
<li><a
href="/bellalMohamed"><code>@​bellalMohamed</code></a>
made their first contribution in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1411">anthropics/claude-code-action#1411</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.155">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.155</a></p>
<h2>v1.0.154</h2>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.154">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.154</a></p>
<h2>v1.0.153</h2>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.153">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.153</a></p>
<h2>v1.0.152</h2>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.152">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.152</a></p>
<h2>v1.0.151</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: skip workflow validation token exchange failures by <a
href="/Ryanoonan"><code>@​Ryanoonan</code></a> in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1417">anthropics/claude-code-action#1417</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="/Ryanoonan"><code>@​Ryanoonan</code></a>
made their first contribution in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1417">anthropics/claude-code-action#1417</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.151">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.151</a></p>
<h2>v1.0.150</h2>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.150">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.150</a></p>
<h2>v1.0.149</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(parse-sdk-options): prevent shell-quote from collapsing unquoted
Bash(X:*) rules to bare Bash by <a
href="/alexglynn"><code>@​alexglynn</code></a> in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1350">anthropics/claude-code-action#1350</a></li>
<li>fix(mcp): align allowed-tools parser with SDK option parser by <a
href="/bymle"><code>@​bymle</code></a> in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1373">anthropics/claude-code-action#1373</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="/alexglynn"><code>@​alexglynn</code></a>
made their first contribution in <a
href="https://redirect.github.com/anthropics/claude-code-action/pull/1350">anthropics/claude-code-action#1350</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/anthropics/claude-code-action/compare/v1...v1.0.149">https://github.com/anthropics/claude-code-action/compare/v1...v1.0.149</a></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="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/anthropics/claude-code-action/commit/428971d2ecd6e3a7cb0ee0da2a3a8b33fdb3678d"><code>428971d</code></a>
chore: bump Claude Code to 2.1.191 and Agent SDK to 0.3.191</li>
<li><a
href="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/anthropics/claude-code-action/commit/74eedf1a1892082d619c3edb66b9402da6520e7f"><code>74eedf1</code></a>
chore: bump Claude Code to 2.1.190 and Agent SDK to 0.3.190</li>
<li><a
href="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/anthropics/claude-code-action/commit/80b31826338489861333dc17217865dfe8085cdc"><code>80b3182</code></a>
chore: bump Claude Code to 2.1.187 and Agent SDK to 0.3.187</li>
<li><a
href="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/anthropics/claude-code-action/commit/360be9c8fc5d80cb33661e0ffd33dcef4c7155aa"><code>360be9c</code></a>
fix: allow @ in branch names (valid per git-check-ref-format) (<a
href="https://redirect.github.com/anthropics/claude-code-action/issues/1411">#1411</a>)</li>
<li><a
href="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/anthropics/claude-code-action/commit/e452eb9dce5f3ab14b90cf9386247fbcb3c4ac92"><code>e452eb9</code></a>
test: cover format-turns content-type fallbacks and system_other
handling (<a
href="https://redirect.github.com/anthropics/claude-code-action/issues/1">#1</a>...</li>
<li><a
href="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/anthropics/claude-code-action/commit/6b8063043eb8bc14e8448185a12d6d9dcf07ce55"><code>6b80630</code></a>
fix: filter PR reviews and inline review comments to trigger time (<a
href="https://redirect.github.com/anthropics/claude-code-action/issues/1385">#1385</a>)</li>
<li><a
href="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/anthropics/claude-code-action/commit/30544b674398ee15c84819bd87caf8a87e8c7b55"><code>30544b6</code></a>
chore: bump Claude Code to 2.1.186 and Agent SDK to 0.3.186</li>
<li><a
href="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/anthropics/claude-code-action/commit/2fee15510437d71399d9139ed60433470484a8fb"><code>2fee155</code></a>
chore: bump Claude Code to 2.1.185 and Agent SDK to 0.3.185</li>
<li><a
href="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/anthropics/claude-code-action/commit/51705da45eecce209d4700538bf8377d5b5fc695"><code>51705da</code></a>
chore: bump Claude Code to 2.1.183 and Agent SDK to 0.3.183</li>
<li><a
href="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/anthropics/claude-code-action/commit/806af32823ef69c8ef357086c573a902af641307"><code>806af32</code></a>
chore: bump Claude Code to 2.1.181 and Agent SDK to 0.3.181</li>
<li>Additional commits viewable in <a
href="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/anthropics/claude-code-action/compare/787c5a0ce96a9a6cfb050ea0c8f4c05f2447c251...428971d2ecd6e3a7cb0ee0da2a3a8b33fdb3678d">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/cache` from 5.0.5 to 6.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="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/actions/cache/releases">actions/cache's
releases</a>.</em></p>
<blockquote>
<h2>v6.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v6.1.0 - handle read-only cache
access by <a
href="/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1768">actions/cache#1768</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/actions/cache/compare/v6...v6.1.0">https://github.com/actions/cache/compare/v6...v6.1.0</a></p>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update packages, migrate to ESM by <a
href="/Samirat"><code>@​Samirat</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1760">actions/cache#1760</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/actions/cache/compare/v5...v6.0.0">https://github.com/actions/cache/compare/v5...v6.0.0</a></p>
<h2>v5.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/cache</code> to v5.1.0 - handle read-only cache
access by <a
href="/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1775">actions/cache#1775</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="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/actions/cache/compare/v5...v5.1.0">https://github.com/actions/cache/compare/v5...v5.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="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/actions/cache/blob/main/RELEASES.md">actions/cache's
changelog</a>.</em></p>
<blockquote>
<h1>Releases</h1>
<h2>How to prepare a release</h2>
<blockquote>
<p>[!NOTE]
Relevant for maintainers with write access only.</p>
</blockquote>
<ol>
<li>Switch to a new branch from <code>main</code>.</li>
<li>Run <code>npm test</code> to ensure all tests are passing.</li>
<li>Update the version in <a
href="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/actions/cache/blob/main/package.json"><code>https://github.com/actions/cache/blob/main/package.json</code></a>.</li>
<li>Run <code>npm run build</code> to update the compiled files.</li>
<li>Update this <a
href="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/actions/cache/blob/main/RELEASES.md"><code>https://github.com/actions/cache/blob/main/RELEASES.md</code></a>
with the new version and changes in the <code>## Changelog</code>
section.</li>
<li>Run <code>licensed cache</code> to update the license report.</li>
<li>Run <code>licensed status</code> and resolve any warnings by
updating the <a
href="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/actions/cache/blob/main/.licensed.yml"><code>https://github.com/actions/cache/blob/main/.licensed.yml</code></a>
file with the exceptions.</li>
<li>Commit your changes and push your branch upstream.</li>
<li>Open a pull request against <code>main</code> and get it reviewed
and merged.</li>
<li>Draft a new release <a
href="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/actions/cache/releases">https://github.com/actions/cache/releases</a>
use the same version number used in <code>package.json</code>
<ol>
<li>Create a new tag with the version number.</li>
<li>Auto generate release notes and update them to match the changes you
made in <code>RELEASES.md</code>.</li>
<li>Toggle the set as the latest release option.</li>
<li>Publish the release.</li>
</ol>
</li>
<li>Navigate to <a
href="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/actions/cache/actions/workflows/release-new-action-version.yml">https://github.com/actions/cache/actions/workflows/release-new-action-version.yml</a>
<ol>
<li>There should be a workflow run queued with the same version
number.</li>
<li>Approve the run to publish the new version and update the major tags
for this action.</li>
</ol>
</li>
</ol>
<h2>Changelog</h2>
<h3>6.1.0</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v6.1.0 to pick up <a
href="https://redirect.github.com/actions/toolkit/pull/2435">actions/toolkit#2435
Handle cache write error due to read-only token</a></li>
<li>Switch redundant &quot;Cache save failed&quot; warning to debug log
in save-only</li>
</ul>
<h3>6.0.0</h3>
<ul>
<li>Updated <code>@actions/cache</code> to ^6.0.1,
<code>@actions/core</code> to ^3.0.1, <code>@actions/exec</code> to
^3.0.0, <code>@actions/io</code> to ^3.0.2</li>
<li>Migrated to ESM module system</li>
<li>Upgraded Jest to v30 and test infrastructure to be ESM
compatible</li>
</ul>
<h3>5.0.4</h3>
<ul>
<li>Bump <code>minimatch</code> to v3.1.5 (fixes ReDoS via globstar
patterns)</li>
<li>Bump <code>undici</code> to v6.24.1 (WebSocket decompression bomb
protection, header validation fixes)</li>
<li>Bump <code>fast-xml-parser</code> to v5.5.6</li>
</ul>
<h3>5.0.3</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a
href="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/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li>
<li>Bump <code>@actions/core</code> to v2.0.3</li>
</ul>
<h3>5.0.2</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="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/actions/cache/commit/55cc8345863c7cc4c66a329aec7e433d2d1c52a9"><code>55cc834</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1768">#1768</a>
from jasongin/readonly-cache</li>
<li><a
href="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/actions/cache/commit/d8cd72f230726cdf4457ebb61ec1b593a8d12337"><code>d8cd72f</code></a>
Bump <code>@​actions/cache</code> to v6.1.0 - handle cache write error
due to RO token</li>
<li><a
href="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/actions/cache/commit/2c8a9bd7457de244a408f35966fab2fb45fda9c8"><code>2c8a9bd</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1760">#1760</a>
from actions/samirat/esm_migration_and_package_update</li>
<li><a
href="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/actions/cache/commit/e9b91fdc3fea7d79165fceb79042ef45c2d51023"><code>e9b91fd</code></a>
Prettier fixes</li>
<li><a
href="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/actions/cache/commit/e4884b8ff7f92ef6b52c79eda480bbc86e685adb"><code>e4884b8</code></a>
Rebuild dist</li>
<li><a
href="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/actions/cache/commit/10baf0191a3c426ea0fa4a3253a5c04233b6e18f"><code>10baf01</code></a>
Fixed licenses</li>
<li><a
href="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/actions/cache/commit/e39b386c9004d72a15d864ade8c0b3a702d47a37"><code>e39b386</code></a>
Fix test mock return order</li>
<li><a
href="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/actions/cache/commit/b6928203372a8571ff984c0c883ef3a1adfb0c06"><code>b692820</code></a>
PR feedback</li>
<li><a
href="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/actions/cache/commit/60749128a44d25d3c520a489e576380cf00ff3f1"><code>6074912</code></a>
Rebuild dist bundles as ESM to match type:module</li>
<li><a
href="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/actions/cache/commit/5a912e8b4af820fa082a0e75cfd2c782f8fbfe0e"><code>5a912e8</code></a>
Fix lint and jest issues</li>
<li>Additional commits viewable in <a
href="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/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9">compare
view</a></li>
</ul>
</details>
<br />

Updates `azure/setup-helm` from 5.0.0 to 5.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="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/azure/setup-helm/releases">azure/setup-helm's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.1</h2>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/271">#271</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/271">Fix
TypeScript 6.0 compatibility errors in run.ts</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/278">#278</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/278">fix: use
chmod 755 instead of 777 for downloaded helm binary and folder</a></li>
</ul>
<h3>Changed</h3>
<ul>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/286">#286</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/286">Bump
actions/checkout from 6.0.3 to 7.0.0 in /.github/workflows in the
actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/285">#285</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/285">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/284">#284</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/284">Bump
undici</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/283">#283</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/283">Bump the
actions group with 5 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/280">#280</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/280">Bump
actions/checkout from 6.0.2 to 6.0.3 in /.github/workflows in the
actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/279">#279</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/279">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/277">#277</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/277">Bump
vitest from 4.1.7 to 4.1.8 in the actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/276">#276</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/276">chore:
remove deprecated OliverMKing release workflow, pin to SHA</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/275">#275</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/275">Bump
actions/stale from 10.2.0 to 10.3.0 in /.github/workflows in the actions
group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/274">#274</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/274">Bump the
actions group with 3 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/273">#273</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/273">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/269">#269</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/269">Bump the
actions group across 1 directory with 7 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/268">#268</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/268">Bump
vite from 8.0.0 to 8.0.5</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/260">#260</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/260">Migrate
to ESM with esbuild/vitest and upgrade to node24 (v5.0.0)</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="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/Azure/setup-helm/blob/main/CHANGELOG.md">azure/setup-helm's
changelog</a>.</em></p>
<blockquote>
<h1>Change Log</h1>
<h2>[5.0.1] - 2026-06-23</h2>
<h3>Fixed</h3>
<ul>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/271">#271</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/271">Fix
TypeScript 6.0 compatibility errors in run.ts</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/278">#278</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/278">fix: use
chmod 755 instead of 777 for downloaded helm binary and folder</a></li>
</ul>
<h3>Changed</h3>
<ul>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/286">#286</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/286">Bump
actions/checkout from 6.0.3 to 7.0.0 in /.github/workflows in the
actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/285">#285</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/285">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/284">#284</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/284">Bump
undici</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/283">#283</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/283">Bump the
actions group with 5 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/280">#280</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/280">Bump
actions/checkout from 6.0.2 to 6.0.3 in /.github/workflows in the
actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/279">#279</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/279">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/277">#277</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/277">Bump
vitest from 4.1.7 to 4.1.8 in the actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/276">#276</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/276">chore:
remove deprecated OliverMKing release workflow, pin to SHA</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/275">#275</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/275">Bump
actions/stale from 10.2.0 to 10.3.0 in /.github/workflows in the actions
group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/274">#274</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/274">Bump the
actions group with 3 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/273">#273</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/273">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/269">#269</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/269">Bump the
actions group across 1 directory with 7 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/268">#268</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/268">Bump
vite from 8.0.0 to 8.0.5</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/260">#260</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/260">Migrate
to ESM with esbuild/vitest and upgrade to node24 (v5.0.0)</a></li>
</ul>
<h2>[5.0.0] - 2026-03-23</h2>
<h3>Changed</h3>
<ul>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/259">#259</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/259">Update
Node.js runtime from node20 to node24</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/263">#263</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/263">Bump
undici</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/257">#257</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/257">Bump
undici and @​actions/http-client</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/256">#256</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/256">Bump
minimatch</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/248">#248</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/248">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/247">#247</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/247">Bump the
actions group with 3 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/246">#246</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/246">Bump
@​types/node from 25.0.2 to 25.0.3 in the actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/245">#245</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/245">Bump the
actions group with 3 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/243">#243</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/243">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/240">#240</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/240">Bump
prettier from 3.6.2 to 3.7.3 in the actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/229">#229</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/229">Bump the
actions group across 1 directory with 3 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/231">#231</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/231">Bump
js-yaml from 3.14.1 to 3.14.2</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/234">#234</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/234">Bump
glob from 10.4.5 to 10.5.0</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/225">#225</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/225">Fix
build error</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/222">#222</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/222">Bump
@​types/node from 24.7.2 to 24.8.1 in the actions group</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/220">#220</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/220">Bump the
actions group across 1 directory with 4 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/216">#216</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/216">Bump the
actions group across 1 directory with 4 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/213">#213</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/213">Bump the
actions group with 2 updates</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/211">#211</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/211">Bump
undici</a></li>
<li><a
href="https://redirect.github.com/azure/setup-helm/issues/212">#212</a>
<a href="https://redirect.github.com/Azure/setup-helm/pull/212">Bump
jest from 30.0.5 to 30.1.2 in the actions group</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="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/Azure/setup-helm/commit/9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310"><code>9bc31f4</code></a>
build</li>
<li><a
href="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/Azure/setup-helm/commit/95ecf4967d92f8074e91c548e394f8ac547da403"><code>95ecf49</code></a>
Bump version to 5.0.1 and update CHANGELOG with recent changes (<a
href="https://redirect.github.com/azure/setup-helm/issues/287">#287</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/4180b1c05c03707c071b0c4ffb32f7ccf49b71bd"><code>4180b1c</code></a>
Bump the actions group with 2 updates (<a
href="https://redirect.github.com/azure/setup-helm/issues/285">#285</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/6949b7ff3ed0c7f9b29dc9eafb275834aacc7802"><code>6949b7f</code></a>
Bump undici (<a
href="https://redirect.github.com/azure/setup-helm/issues/284">#284</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/51ce767c788f32a9d2a8b911f38e9033afd42959"><code>51ce767</code></a>
Bump actions/checkout in /.github/workflows in the actions group (<a
href="https://redirect.github.com/azure/setup-helm/issues/286">#286</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/d6da4f47af55af3a717c150920167917cdd944b3"><code>d6da4f4</code></a>
Bump the actions group with 5 updates (<a
href="https://redirect.github.com/azure/setup-helm/issues/283">#283</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/7e2bc108ba1a7390c1467373bceaa033d6bb74e8"><code>7e2bc10</code></a>
Bump actions/checkout in /.github/workflows in the actions group (<a
href="https://redirect.github.com/azure/setup-helm/issues/280">#280</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/64d6be9869229723b9bbc197a01e7d2e3c81895c"><code>64d6be9</code></a>
Bump the actions group with 2 updates (<a
href="https://redirect.github.com/azure/setup-helm/issues/279">#279</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/69214f9d74fea2fd41b0d5ca2f5222dd5ba34fd4"><code>69214f9</code></a>
fix: use chmod 755 instead of 777 for downloaded helm binary and folder
(<a
href="https://redirect.github.com/azure/setup-helm/issues/278">#278</a>)</li>
<li><a
href="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/Azure/setup-helm/commit/9dad99fe3c3d2198a1403a6aab02375f0f27dd09"><code>9dad99f</code></a>
Bump vitest from 4.1.7 to 4.1.8 in the actions group (<a
href="https://redirect.github.com/azure/setup-helm/issues/277">#277</a>)</li>
<li>Additional commits viewable in <a
href="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/azure/setup-helm/compare/dda3372f752e03dde6b3237bc9431cdc2f7a02a2...9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310">compare
view</a></li>
</ul>
</details>
<br />

Updates `softprops/action-gh-release` from 3.0.0 to 3.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="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/softprops/action-gh-release/releases">softprops/action-gh-release's
releases</a>.</em></p>
<blockquote>
<h2>v3.0.1</h2>
<h2>3.0.1</h2>
<ul>
<li>maintenance release with updated dependencies</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="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/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's
changelog</a>.</em></p>
<blockquote>
<h2>3.0.1</h2>
<ul>
<li>maintenance release with updated dependencies</li>
</ul>
<h2>3.0.0</h2>
<p><code>3.0.0</code> is a major release that moves the action runtime
from Node 20 to Node 24.
Use <code>v3</code> on GitHub-hosted runners and self-hosted fleets that
already support the
Node 24 Actions runtime. If you still need the last Node 20-compatible
line, stay on
<code>v2.6.2</code>.</p>
<h2>What's Changed</h2>
<h3>Other Changes 🔄</h3>
<ul>
<li>Move the action runtime and bundle target to Node 24</li>
<li>Update <code>@types/node</code> to the Node 24 line and allow future
Dependabot updates</li>
<li>Keep the floating major tag on <code>v3</code>; <code>v2</code>
remains pinned to the latest <code>2.x</code> release</li>
</ul>
<h2>2.6.2</h2>
<h2>What's Changed</h2>
<h3>Other Changes 🔄</h3>
<ul>
<li>chore(deps): bump picomatch from 4.0.3 to 4.0.4 by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/775">softprops/action-gh-release#775</a></li>
<li>chore(deps): bump brace-expansion from 5.0.4 to 5.0.5 by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/777">softprops/action-gh-release#777</a></li>
<li>chore(deps): bump vite from 8.0.0 to 8.0.5 by <a
href="/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/781">softprops/action-gh-release#781</a></li>
</ul>
<h2>2.6.1</h2>
<p><code>2.6.1</code> is a patch release focused on restoring linked
discussion thread creation when
<code>discussion_category_name</code> is set. It fixes
<code>[#764](https://github.com/softprops/action-gh-release/issues/764)</code>,
where the draft-first publish flow
stopped carrying the discussion category through the final publish
step.</p>
<p>If you still hit an issue after upgrading, please open a report with
the bug template and include a minimal repro or sanitized workflow
snippet where possible.</p>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix: preserve discussion category on publish by <a
href="/chenrui333"><code>@​chenrui333</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/765">softprops/action-gh-release#765</a></li>
</ul>
<h2>2.6.0</h2>
<p><code>2.6.0</code> is a minor release centered on
<code>previous_tag</code> support for
<code>generate_release_notes</code>,
which lets workflows pin GitHub's comparison base explicitly instead of
relying on the default range.
It also includes the recent concurrent asset upload recovery fix, a
<code>working_directory</code> docs sync,
a checked-bundle freshness guard for maintainers, and clearer
immutable-prerelease guidance where
GitHub platform behavior imposes constraints on how prerelease asset
uploads can be published.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="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/softprops/action-gh-release/commit/718ea10b132b3b2eba29c1007bb80653f286566b"><code>718ea10</code></a>
release 3.0.1</li>
<li><a
href="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/softprops/action-gh-release/commit/f1a938b9d84ca9b770d0d8dfeb3e7285fe261e63"><code>f1a938b</code></a>
chore(deps): bump esbuild from 0.28.0 to 0.28.1 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/802">#802</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/0066ead0de7252b4876b36b5357fc3974619d36a"><code>0066ead</code></a>
chore(deps): bump vite from 8.0.14 to 8.0.16 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/806">#806</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/dc643cac6252aaa00c9b0b6c940d489cd7bf6b23"><code>dc643ca</code></a>
chore(deps): bump the npm group with 3 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/805">#805</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/85ee99b6b20742a3823a8a289ee5e6ceab44e8aa"><code>85ee99b</code></a>
chore(deps): bump actions/checkout in the github-actions group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/804">#804</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/9ed3cf9a6863b31f005d951c8d19de20628cf4eb"><code>9ed3cf9</code></a>
chore(deps): bump the npm group with 2 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/800">#800</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/3efcac8951299998593f871640ea8059d6818655"><code>3efcac8</code></a>
chore(deps): bump the npm group with 3 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/798">#798</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/05d6b9164aa74958de40b0179d6a773112fcdc7f"><code>05d6b91</code></a>
chore(deps): bump brace-expansion from 5.0.5 to 5.0.6 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/797">#797</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/403a5240f3837fa857f642062e05aad6bb3391ca"><code>403a524</code></a>
chore(deps): bump <code>@​types/node</code> from 24.12.2 to 24.12.3 in
the npm group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/796">#796</a>)</li>
<li><a
href="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/softprops/action-gh-release/commit/437e073e786973c6b6af97d9e445c41ae43b1d29"><code>437e073</code></a>
chore(deps): bump the npm group with 4 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/792">#792</a>)</li>
<li>Additional commits viewable in <a
href="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/softprops/action-gh-release/compare/b4309332981a82ec1c5618f44dd2e27cc8bfbfda...718ea10b132b3b2eba29c1007bb80653f286566b">compare
view</a></li>
</ul>
</details>
<br />

Updates `zizmorcore/zizmor-action` from 0.5.6 to 0.5.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="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/zizmorcore/zizmor-action/releases">zizmorcore/zizmor-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.5.7</h2>
<p>1.26.1 is now available via the action
1.26.1 is now the default version of zizmor used by the action</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="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/zizmorcore/zizmor-action/commit/192e21d79ab29983730a13d1382995c2307fbcaa"><code>192e21d</code></a>
Sync zizmor versions (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/127">#127</a>)</li>
<li><a
href="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/zizmorcore/zizmor-action/commit/2720f2673c0b64a8656d08b009ac239b9383c0ae"><code>2720f26</code></a>
Update README.md with new actions/checkout version (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/126">#126</a>)</li>
<li><a
href="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/zizmorcore/zizmor-action/commit/40b41b824eab0ad9c19ddf9856be25550729e6d8"><code>40b41b8</code></a>
chore(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/123">#123</a>)</li>
<li><a
href="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/zizmorcore/zizmor-action/commit/a687b25bf3aa149153e80ed5f45292e47589888c"><code>a687b25</code></a>
chore(deps): bump github/codeql-action from 4.35.5 to 4.36.0 in the
github-ac...</li>
<li><a
href="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/zizmorcore/zizmor-action/commit/64a6900ea7f40fab0caa7dcfc77b392d28fe0cb1"><code>64a6900</code></a>
add note to explain that the default value for
<code>online-checks</code> is different t...</li>
<li><a
href="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/zizmorcore/zizmor-action/commit/14050abd109fcba34e6e2f31a723280997808e82"><code>14050ab</code></a>
chore(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/118">#118</a>)</li>
<li><a
href="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/zizmorcore/zizmor-action/commit/ee9b4194a74f093e38908dbcfcb078f63eeef002"><code>ee9b419</code></a>
chore(deps): bump github/codeql-action in the github-actions group (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/116">#116</a>)</li>
<li><a
href="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/zizmorcore/zizmor-action/commit/fddf2b4aa9bf29290c6bf9866e6d113b0cdf6f67"><code>fddf2b4</code></a>
Bump pins in README (<a
href="https://redirect.github.com/zizmorcore/zizmor-action/issues/115">#115</a>)</li>
<li>See full diff in <a
href="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/zizmorcore/zizmor-action/compare/5f14fd08f7cf1cb1609c1e344975f152c7ee938d...192e21d79ab29983730a13d1382995c2307fbcaa">compare
view</a></li>
</ul>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: nicktrn <55853254+nicktrn@users.noreply.github.com>
Takes changesets out of rc prerelease mode so the next version bump
produces the stable 4.5.0 GA release rather than another release
candidate.
## Summary

Adds the `4.5.0` GA entry to the AI chat agents changelog covering the
`chat.agent` changes in that release: a new `apiClient` option on
`chat.headStart` and `chat.createStartSessionAction` for pointing chat
sessions at a different project or environment, the fix for messaging
chat agents deployed to a preview branch, and the fix for Head Start
handovers when the agent also defines a `prepareMessages` hook.

All four changes are from
[#4018](#4018).
Removes the release-candidate framing from the docs for the 4.5 GA: the
`@rc` install caveats on the `skills` CLI command, and the AI Agents and
Prompts release-candidate banner (a shared snippet used across the
ai-chat and prompts pages) plus the `>=4.5.0-rc.0` compatibility pin in
the AI reference.
# Trigger.dev v4.5.0

4.5.0 is the GA of the AI Agents platform. Everything built during the
prerelease line (durable agents, Sessions, AI Prompts) is now stable on
the `latest` tag, alongside a set of SDK and runtime improvements.

## AI Agents (`chat.agent`)

Run Vercel AI SDK chat completions as durable Trigger.dev tasks instead
of fragile API routes. A conversation runs as one long-lived task keyed
on `chatId`, so it survives page refreshes, network blips, redeploys,
and crashes, and every turn is a span in the dashboard.

```ts
import { chat } from "@trigger.dev/sdk/ai";
import { streamText, stepCountIs } from "ai";
import { anthropic } from "@ai-sdk/anthropic";

export const myChat = chat.agent({
  id: "my-chat",
  run: async ({ messages, signal }) => {
    return streamText({
      ...chat.toStreamTextOptions(), // system prompt, compaction, steering, telemetry
      model: anthropic("claude-sonnet-4-5"),
      messages,
      abortSignal: signal,
      stopWhen: stepCountIs(15),
    });
  },
});
```

## Sessions

The durable primitive underneath `chat.agent`, usable on its own: a
run-aware, bidirectional stream channel keyed on a stable `externalId`
whose `.in` / `.out` streams survive run boundaries (suspend, crash,
idle-timeout, redeploy). One Session spans many runs, which makes it a
good fit for agent inboxes and approval flows.

```ts
import { sessions } from "@trigger.dev/sdk";

// Create the session and trigger its first run (idempotent on externalId)
await sessions.start({
  type: "inbox",
  externalId: userId,
  taskIdentifier: "inbox-agent",
});

const session = sessions.open(userId);
await session.in.send({ text: "hello" });

const stream = await session.out.read({ signal: AbortSignal.timeout(30_000) });
for await (const chunk of stream) console.log(chunk); // durable across run swaps
```

## AI Prompts

Define prompt templates as code, versioned on every deploy, and override
the text or model from the dashboard without redeploying
(environment-scoped). Each generation links back to its prompt version
for usage, cost, and latency.

```ts
import { prompts } from "@trigger.dev/sdk";
import { z } from "zod";

export const supportPrompt = prompts.define({
  id: "customer-support",
  model: "gpt-4o",
  variables: z.object({ customerName: z.string(), issue: z.string() }),
  content: `You are a support agent for Acme.
Customer: {{customerName}}
Issue: {{issue}}`,
});

// Honors any active dashboard override, else the current deployed version
const resolved = await supportPrompt.resolve({ customerName: "Alice", issue: "Can't log in" });
// resolved.text, resolved.model, resolved.version
```

## `useChat` integration

`useTriggerChatTransport` is a Vercel AI SDK `ChatTransport` that runs
`useChat` over Trigger.dev realtime with no API routes. Text, tool
calls, reasoning, and `data-*` parts stream natively, and it works with
AI SDK v5, v6, and now v7.

## First-turn fast path (`chat.headStart`)

Runs the first turn in your warm server process while the agent boots in
parallel, cutting cold-start time-to-first-chunk roughly in half
(measured ~2.8s to ~1.2s). Available via the new
`@trigger.dev/sdk/chat-server` subpath.

## Human-in-the-loop, stop, and steering

The agent control surface: tool approvals (`needsApproval` +
`addToolApprovalResponse`), client-driven stop-generation, mid-execution
steering (`pendingMessages`), and between-turn context injection
(`chat.inject` / `chat.defer`), all durable across the conversation.

## Agent Skills

`skills.define({ id, path })` bundles a `SKILL.md` folder into your
deploy image. The agent gets a one-line summary up front and loads the
full instructions plus scoped `bash` / `readFile` tools on demand
(progressive disclosure), so a capability is something the model reaches
for rather than a pre-declared typed tool.

## `trigger skills` for coding assistants

`trigger skills` installs version-pinned Trigger.dev skills plus a
bundled docs snapshot into Claude Code, Cursor, GitHub Copilot, and
Codex, so your assistant's Trigger.dev knowledge stays current with your
installed SDK version. `trigger init` now offers to set up the MCP
server and skills too.

## Model library

A new Models page in the dashboard: a catalog of models grouped by
provider with context window, capabilities, and input / output pricing
per 1M tokens, plus a "Your models" tab showing per-model usage, cost,
and cache-hit sparklines from your actual traffic.

## Dev branches

Run multiple local `trigger dev` sessions in parallel (separate git
worktrees or coding agents) without runs colliding, each isolated with
its own dashboard, via `trigger dev --branch <name>`.

## `TriggerClient`

An instantiable client so one process can trigger and read across
projects, environments, and preview branches, each with its own auth and
baseURL, with no shared global state.

```ts
import { TriggerClient } from "@trigger.dev/sdk";

const prod = new TriggerClient({ accessToken: process.env.TRIGGER_PROD_KEY });
const preview = new TriggerClient({
  accessToken: process.env.TRIGGER_PREVIEW_KEY,
  previewBranch: "signup-flow",
});

await prod.tasks.trigger("send-email", { to: "user@example.com" });
await preview.runs.list({ status: ["COMPLETED"] });
```

## SDK and runtime

- AI SDK 7 support (v5 and v6 still supported), with OpenTelemetry
telemetry auto-wired
- Large trigger-payload offload: trigger payloads at or above 128KB
upload to object storage automatically, using the same auth and baseURL
as the trigger call
- Region support on the runs API: filter runs by region and read each
run's executing region (also on MCP `list_runs`)
- Duplicate task-id detection: `dev` and `deploy` fail with a clear
error instead of silently overwriting
- `envvars.upload` gains an `isSecret` flag to import redacted secret
variables
- Retry hardening: `TASK_MIDDLEWARE_ERROR` now retries under the task's
retry policy

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Once this is merged, oxlint is at a pretty sensible baseline.

**Enable `no-unused-vars`, `typescript/consistent-type-imports`, and
`import/no-duplicates` lint rules**

Turns on three previously-disabled oxlint rules across the monorepo and
fixes all violations:

- **`no-unused-vars`** – enabled as an error with standard ignore
patterns: unused function arguments are ignored by default (`args:
"none"`), variables/caught errors/destructured array elements prefixed
with `_` are allowed, and rest siblings are permitted.
- **`typescript/consistent-type-imports`** – enforced as an error; all
type-only imports now use the `import type` syntax.
- **`import/no-duplicates`** – enforced as an error; duplicate import
statements from the same module have been merged.

The remaining commits clean up the violations found across the codebase:
removing unused variables/imports/type aliases, adding `_` prefixes to
intentionally unused bindings, fixing duplicate imports, and converting
value imports to `import type` where appropriate.
Remove the `devBranchesEnabled` feature flag and enable behaviour by
default.
…an without GitHub verification (#4109)

## What & why

Two related fixes to how new cloud organizations get onboarded onto the
Free plan.

### 1. Route new cloud orgs through plan selection

New cloud organizations were created already activated, so they skipped
the plan-selection step and went straight to creating projects — which
meant their plan and usage limits were never set up. They're now created
deactivated and routed through plan selection, which activates them once
a plan is chosen. Self-hosted installs have no plan-selection step, so
they're activated immediately on creation and are unaffected.

The `Organization.v3Enabled` field is renamed to `isActivated` to better
describe what it now gates. It's mapped to the existing `v3Enabled`
column, so there's no data migration — only a schema/code rename.

### 2. Allow selecting the Free plan without GitHub verification

Choosing the Free plan no longer requires connecting and verifying a
GitHub account. The plan is applied immediately when selected. This
removes:

- the "Connect to GitHub" dialog and the GitHub-verified badge from the
plan picker
- the account-rejected state
- the now-unreachable GitHub-connect return routes

## Notes

- These changes pair with the corresponding change in the billing
service that applies the Free plan directly; they should be released
together.

## Testing

Verified locally end to end: a new cloud org is routed to plan
selection, the Free plan applies in one click with no GitHub step, the
org is activated, its usage allowance is provisioned, and it lands on
the new-project page.

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

Two related timezone bugs in the dashboard.

1. The date/time tooltip could show a UTC offset label that contradicted
the time it displayed. A viewer whose machine clock differs from their
saved timezone (or when a date falls in the other DST phase) would see
something like `Local (UTC +0)` next to a value that isn't at +0.
2. A user's timezone preference silently failed to save whenever their
browser reported a zone like `UTC`, `Etc/UTC`, or `Asia/Kolkata`,
leaving their timestamps stuck in a previously-saved timezone.

## Offset label

The "Local" row formatted its time using the viewer's configured
timezone but computed the `(UTC +n)` label from `new
Date().getTimezoneOffset()`, the browser's offset at the current moment.
Those are two independent sources, so they disagreed when the configured
timezone differed from the machine, and also when the displayed date was
in the opposite DST phase. The label is now derived from the same date
and timezone used to render the row (via `Intl.DateTimeFormat` with
`timeZoneName: "longOffset"`), so it always matches the displayed time.

## Preference persistence

`/resources/timezone` validated the incoming zone against
`Intl.supportedValuesOf("timeZone")`, which lists only canonical zone
ids. Browsers report zones that aren't in that list via
`resolvedOptions().timeZone`, notably `UTC` (and `Etc/UTC`,
`Asia/Kolkata`, `GMT`), so those requests returned 400 and the
preference was never stored. Validation now checks whether the runtime
can resolve the zone at all, which accepts every real zone and still
rejects invalid input.

Added unit tests for both.
Bumps the internal/toolchain Node version to the latest 22.x LTS
(`22.23.1`) and standardises it across the repo. Scope is the **platform
toolchain + the repo's own runtime images** (all `20 → 22` *upgrades*,
off the now-EOL node 20).

### Main changes
- Node `20.20.2 → 22.23.1` across all CI workflows, `.nvmrc`,
`CONTRIBUTING.md`, and the OSS `docker/Dockerfile` (digest-pinned).
- `@types/node → 22.20.0` (root dep + pnpm `overrides`, so the whole
workspace resolves to it); lockfile regenerated.
- `sdk-compat` matrix: adds Node 24 + 26 (keeps 20, still in `engines`).
- **App runtime images → node 22** (were on EOL node 20):
`apps/coordinator` → `node:22.23.1-bookworm-slim`;
`apps/docker-provider` + `apps/kubernetes-provider` → `node:22-alpine`
(reusing the exact digest `apps/supervisor` already runs, so all four
worker images are now identical). Stage aliases renamed off `node-20`.

### Possible issues / test notes
- `@types/node` 22.x can surface new TS errors — typecheck (now on 22)
is the gate.
- **Smoke-test the v3 worker path** — `coordinator` (`crictl`/CRI calls)
and the docker/kubernetes providers (talking to their daemons) now run
on node 22 (alpine/musl for the providers). Upgrade off EOL so low-risk,
but it's deployed runtime code with its own `publish-worker.yml`
pipeline.
## Summary

Long task names in the task landing page side menu pushed the **Test**
button off the edge of the panel instead of truncating. The heading now
truncates with an ellipsis so the Test button always stays in view, on
the standard and agent task pages.

## Root cause

The side menu lives in a fixed-width resizable panel with `overflow:
hidden`. Its header row is a grid item, and a grid item's default
`min-width: auto` lets it grow to its content's width. The title
`<span>` uses `truncate` (`white-space: nowrap`), whose min-content is
the full, untruncated name, so the header row expanded past the panel
and the Test button was clipped off the edge.

Adding `min-w-0` to the header container lets it shrink back to the
panel width so the title truncates. The scheduled task page already had
this class; the standard and agent pages did not.
## Bug

Manually pausing an environment works, but resuming it always fails
with:

> This environment is paused because your organization reached its
billing limit. Resolve the limit on the billing limits settings page to
resume.

even when no billing limit is in effect. Once paused by a user, an
environment cannot be resumed at all.

## Root cause

A manual pause leaves `RuntimeEnvironment.pauseSource` as `NULL` (only
billing-limit enforcement sets `BILLING_LIMIT`). The resume path in
`PauseEnvironmentService` guards its `updateMany` with:

```ts
NOT: { pauseSource: EnvironmentPauseSource.BILLING_LIMIT }
```

Prisma's `NOT` on a nullable field translates to SQL `!=`, which
excludes `NULL` rows. So the update matches zero rows for every
user-paused environment, and the zero-count branch (meant to catch a
race with billing-limit pausing) returns the misleading billing-limit
error.

Introduced in #3996 (the guard is correct for `BILLING_LIMIT` rows; it
just also swallows `NULL`).

## Fix

Explicitly include `pauseSource: null` rows:

```ts
OR: [
  { pauseSource: null },
  { NOT: { pauseSource: EnvironmentPauseSource.BILLING_LIMIT } },
]
```

Billing-limit-paused environments are still blocked from manual resume,
both by the `getManualPauseEnvironmentResult` guard and by this clause.

## Verification

Reproduced locally: paused an environment via `PauseEnvironmentService`
(DB shows `paused = true`, `pauseSource = NULL`), resume returned the
billing-limit error with `updateMany` matching 0 rows. With the fix,
resume succeeds and the environment unpauses. Billing-paused rows remain
excluded by the same clause.
)

Makes the app error page always render full screen — it previously
inherited the width/offset of whatever container the error boundary was
mounted in (e.g. the centered `max-w-xs` column in the root boundary),
so `min-h-screen` alone couldn't fill the viewport. The root container
now uses `fixed inset-0 z-50` to break out and cover the full screen
regardless of nesting.

Also changes the "Go to homepage" shortcut from `Cmd/Ctrl+G` (which
collides with the browser's native "Find Again") to `Enter`.
Stream dev logs over a local telnet/TCP socket. `trigger dev` mirrors
its terminal output on port 6767 by default (override with
--telnet-logs-port or TRIGGER_DEV_TELNET_LOGS_PORT, 0 disables). webapp,
supervisor, and coordinator each expose an opt-in stream gated on a
per-service *_TELNET_LOGS_PORT env var. New
@trigger.dev/core/v3/telnetLogServer module (localhost-only,
backpressure-safe, plain-text) plus optional static Logger.onLog /
SimpleStructuredLogger.onLog sinks.

Then you (or your agent) can use `nc` to connect and filter out the
stream.
<img width="1103" height="239" alt="image"
src="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/user-attachments/assets/b4d47efc-8a57-4185-a159-10f2806627ae"
/>
isshaddad and others added 30 commits July 30, 2026 14:55
…t threads to org tenant (#4368)

## What

Two changes, shipped together:

1. **SDK migration (TRI-12460).** `@team-plain/typescript-sdk` is
deprecated. Move the webapp to its successors — `@team-plain/graphql`
(client) and `@team-plain/ui-components` (`uiComponent` builder).
Behaviour-preserving: the `PlainClient` customer upsert + thread
creation move to the new `client.mutation.*({ input })` shape; the
client now throws on failure, so `sendToPlain` wraps its calls and logs,
staying best-effort.

2. **Org tenant attribution (TRI-12461).** When org context is
available, `sendToPlain` now upserts a Plain tenant keyed by `externalId
= org_id`, links the customer to it, and stamps the created thread with
that tenant — so support threads become attributable to a Trigger.dev
org. Wired into the four add-on quota requests and the plan-cancellation
feedback (which already have org context). The tenant steps are isolated
in their own try/catch and the thread's `tenantIdentifier` is gated on
their success, so a tenant failure never blocks thread creation.

## Not affected

- `customer.externalId` stays `User.id` — the customer cards +
impersonation link are unchanged.
- No ticket content leaves Plain.
- Callers without a single org (e.g. the feedback widget) are unchanged
— the org params are optional.

## Deploy prerequisite

The webapp's Plain API key needs three **new** scopes for attribution to
work (it already has `customer:create`, `customer:edit`,
`thread:create`):

- [x] `tenant:create`
- [x] `tenant:edit`
- [x] `customerTenantMembership:create`

Until granted, nothing breaks — `sendToPlain` logs the forbidden error
and creates the thread without attribution.

## Testing

- `pnpm typecheck --filter webapp` passes; oxfmt + oxlint clean.
- Ran the real `sendToPlain` end-to-end via a throwaway vitest harness
against live Plain — confirmed the code path executes; the live write is
gated only by the key scopes above.
…rs (#4426)

Members added by SSO just-in-time provisioning or Directory Sync never
got
their per-member DEVELOPMENT environments - only invite acceptance and
project creation created them. `trigger dev` returned "Environment not
found" for those members and the dashboard had no dev view.

ensureOrgMember now queues provisioning for every membership it settles,
so
both paths are covered and members missing environments are repaired on
their next sync. Provisioning runs as a common-worker job to keep
sign-in
and directory webhooks off the per-project write loop. A failed enqueue
surfaces for Directory Sync, whose worker retries the idempotent effect,
and is swallowed for sign-in, where the next login enqueues again.
Environment creation now tolerates a concurrent creator so the
project-creation loop and the job cannot collide on the unique index.

Also fixes environment resolution ignoring dev-environment ownership: a
member without their own dev environment could be handed a colleague's
and
have it persisted as their dashboard preference.
## Summary

Keeps the queue metrics ClickHouse tests stable as wall-clock time
advances.

## Root cause

The fixtures used fixed timestamps. Once those timestamps crossed the
tables' 30-day retention boundary, ClickHouse immediately expired the
inserted aggregate rows and all six tests read empty results.

The fixtures now derive a recent minute-aligned timestamp once per test
file. The second 10-second bucket and ranking window are derived from
the same anchor, preserving deterministic bucket relationships while
keeping rows inside both the raw and aggregate table TTLs.

Verified with `pnpm --filter @internal/clickhouse exec vitest run
src/queueMetrics.test.ts`.
)

`test/envParamRoute.ownership.test.ts` fails on main: 3 of its 4 tests
throw

```
Error: [vitest] No "hasAdminDisplayAccess" export is defined on the
"~/services/session.server" mock. Did you forget to return it from "vi.mock"?
```

#4421 added a `hasAdminDisplayAccess(user)` call to the `env.$envParam`
loader, and the test's `vi.mock` of `session.server` only returns
`requireUser`, so the call blows up. Both changes were green in their
own PR and only conflict once merged together, which is why nobody
caught it.

The mock now mirrors the real implementation rather than returning a
constant, so it stays correct if the test's user fixture is ever varied.
No assertions were changed: the tests were right, the mock was stale.

Worth flagging separately: no workflow runs on push to main, so this has
been red since #4421 landed without showing up anywhere. Every PR opened
since has inherited the failure.
<!-- ccr-slack-attribution -->
_Requested by **Eric Allam** · [Slack
thread](https://triggerdotdev.slack.com/archives/C0BEM9Z73TM/p1785491472104199)_

## Checklist

- [ ] I have followed every step in the [contributing
guide](https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md)
- [x] The PR title follows the convention.
- [ ] I ran and tested the code works

---

## Testing

Static checks only, all clean:

- `pnpm run typecheck --filter trigger.dev`
- `pnpm run format`
- `pnpm run lint`

No live task was triggered against a running project, so the "ran and
tested" box above is left unchecked.

---

## Changelog

**Before:** triggering a task through the MCP server always ran it in
the project's default region. There was no way to pick one.

**After:** the `trigger_task` tool accepts an optional `region` option,
so you can choose the region a run executes in.

**How:** `region: z.string().optional()` was added to
`TriggerTaskInput.options` in `packages/cli-v3/src/mcp/schemas.ts`. No
call-site change was needed — `tools/tasks.ts` passes `options` through
verbatim, and `TriggerTaskRequestBody.options.region` already existed.
The tool description in `docs/mcp-tools.mdx` gained a matching line, and
a patch changeset is included.

There is no batch-trigger MCP tool, so there is no sibling tool to
mirror this change on.

---

## Screenshots

N/A — no UI changes.

Co-authored-by: Claude <noreply@anthropic.com>
…reaming never completes (#4397)

## Summary

`batchTriggerAndWait()` could leave a parent run waiting forever. The
2-phase batch API blocks the parent on the batch's waitpoint as soon as
the batch is created, but the batch is only sealed at the end of item
streaming. If streaming never completed, nothing sealed the batch,
nothing completed the waitpoint, and the parent stayed suspended with no
timeout and no way to recover.

Supersedes #4016, which added the reaper alone.

## Fix

Admission for item streaming was being decided twice. Batch creation
passes its own rate limiter, which fixes `expectedCount` and blocks the
parent, and then the item stream had to pass the general API limiter as
well, competing with unrelated traffic. A second limiter could therefore
veto work the first had already committed the parent to. Creation now
mints a bounded grant that the item stream spends, so an admitted batch
can finish streaming. The grant is capped per batch rather than
exempting the path, and every failure mode (no grant, spent grant,
unreachable store) falls back to the normal limiter.

That makes stranding much rarer but not impossible, since a request
timeout or a crash can still end streaming for good. So a seal-timeout
reaper aborts any batch still unsealed after `BATCH_SEAL_TIMEOUT_MS` and
completes the parent's waitpoint with an error, letting
`batchTriggerAndWait()` reject instead of hang. It is race-safe against
a late seal, and it is only scheduled for batches that actually block a
parent, so fire-and-forget batches cost nothing.

Finally, the batches page used to report "Batch completion checked." for
these batches while doing nothing, because the completion path returns
early on an unsealed batch. It now says the batch cannot be resumed.

Rate limiting is no longer the reason a batch strands, so the reaper's
default stays at 30 minutes, comfortably above the SDK's worst-case
stream-retry budget.

## Verification

Unit and container tests cover the grant cap, the bypass ordering (it
runs after the authorization check, so it can never skip
authentication), and the reaper's abort, seal race, idempotency, and
no-waitpoint cases.

Also verified end-to-end against a running stack. With the general limit
exhausted, batch creation and other API calls returned 429 while a
granted batch still streamed and sealed; an ungranted batch id was rate
limited rather than bypassed; and the grant cut off exactly at its
configured attempt count. Reproducing the stranded state on a real
parent run, the batch was aborted at the timeout, the waitpoint
completed with an error, and the parent resumed and finished instead of
hanging. A parentless batch left unsealed was untouched well past the
reaper window.

## Verified against deployed runs

The reaper was proven end to end with a real deployed run (locally-run
supervisor, containerised
run) and a real network fault, rather than a simulated one: toxiproxy
severs the phase 2 item
stream mid-flight so every SDK stream retry genuinely fails, while phase
1 still succeeds. Only
the batch calls traverse the fault, so control-plane traffic is
untouched.

The reproduction is the shape that actually strands a parent: the task
catches the
`BatchTriggerError` the SDK throws and carries on, so the phase 1 block
outlives the thrown error
and the parent hangs at its next suspension point.

With the reaper disabled, the parent sat in `EXECUTING_WITH_WAITPOINTS`
for over 24 minutes holding
two blockers, and stayed stuck across a full infrastructure restart:

```
 type     | status    | has_timeout
 BATCH    | PENDING   | f            <- orphan, completedAfter NULL
 DATETIME | COMPLETED | t            <- the wait already elapsed
```

With the reaper enabled the same task under the same fault completed in
about 75 seconds with zero
blockers left, the batch `ABORTED`, and its waitpoint completed carrying
the error.

Two conditions are required to observe this at all, which is worth
knowing for any future test:
the run must be deployed rather than `trigger dev` (dev runs execute in
process and finish while
still holding blocker rows), and the wait after the caught error must
exceed the checkpoint
threshold, or it is served in process and never suspends.

### Why completing the batch waitpoint is sufficient

`batchTriggerAndWait` runs create, then stream, then wait. A phase 2
failure throws before the wait
is ever reached, and the reaper only fires on an unsealed batch, so the
parent is never suspended
awaiting the batch when it runs. The parent therefore does not need a
synthetic result, only to stop
being blocked. Note this reasoning depends on that ordering: if the wait
were ever reached with an
unsealed batch, completing the batch waitpoint alone would not settle
the caller.

## Follow-ups

- Batches stranded before this ships still need a one-off recovery; the
reaper only schedules at creation time.
- That same property leaves a gap if the process dies between creating
the batch and scheduling the job. A periodic sweep would close it, but
wants a supporting index.
- When a partially streamed batch aborts, children already enqueued keep
running while the parent fails. Left as-is deliberately, since
cancelling triggered work is a bigger semantic call.
)

## What
`startRunAttempt` — the run controller's first call when a run starts —
had no retry on transient connection errors. A brief connection blip on
that call would abandon the start and send the run back through the
queue, delaying its first attempt.

This adds a jittered backoff retry, matching the existing
`continueRunExecution` path with a shorter budget, so a transient blip
is ridden out in place instead of bouncing the run.

## Why a shorter budget
The continue path retries generously. Start-attempt keeps a tighter
budget (6 attempts, ~25-40s jittered) so it rides out a transient blip
but never keeps retrying past the point the run would already have been
requeued.

## Safety
Retrying is safe: start-attempt is guarded server-side by the snapshot
id — a retry after a start has already committed is rejected, so it can
never double-start an attempt. A pure connection error (the common case)
never reached the server.

## Scope
One retry-options object on `startRunAttempt`; no other behavior change.
Warm starts share this path and get the same resilience.
…4419)

A non-delayed run used to get two execution snapshots the moment it was
triggered: `RUN_CREATED` nested in the run-create transaction,
immediately followed by `QUEUED` from its own `BEGIN`/`INSERT`/`COMMIT`.
It now gets a single `QUEUED` snapshot written inside the create, and
the trigger path only publishes to the queue. One fewer row per run on
`TaskRunExecutionSnapshot`, and one fewer round trip on the trigger hot
path.

`EnqueueSystem` gains a `publishRun` seam that enqueues without writing
a snapshot. Every re-enqueue path (waitpoint resume, checkpoint restore,
delayed enqueue, pending version, retry requeue) still calls
`enqueueRun` and writes its own `QUEUED`, so only the first enqueue
changes. The `QUEUED` snapshot still commits before the queue message,
so a dequeue sees a dequeueable status exactly as before.

Two things for reviewers. Nesting the write skips
`createExecutionSnapshot`, which is what emits
`executionSnapshotCreated` and therefore the run timeline's `[engine]
QUEUED` entry, so the trigger path now emits it directly, the same way
the dequeue and attempt-start paths already do for their nested creates.
And `RUN_CREATED` is still written when a dequeued run has no background
worker yet, so the status and both `statuses.ts` helpers stay live and
existing rows keep reading correctly.

Delayed runs are untouched: `DELAYED` then `QUEUED` are two genuinely
different moments and stay two snapshots.

Rollback is a revert. Create-and-enqueue happen in one request in one
process, so no in-flight run needs both code paths to agree during a
rollout.


One note for whoever debugs this path later. The `QUEUED` snapshot now
commits before the queue publish, so a failed publish leaves the run
recorded as `QUEUED` with no queue message. That state was already
reachable, since the publish was never part of the snapshot transaction,
but it used to be recorded as `RUN_CREATED`, which was distinctive
because it never otherwise persisted. `QUEUED` with no message is
indistinguishable from a run waiting on a concurrency slot, so
trigger-time publish failure is now one more cause of an apparently
stuck queued run.
…te metric (#4442)

The pod-count backpressure source read
`apiserver_storage_objects{resource="pods"}` from an apiserver
`/metrics` scrape. That gauge is a periodically-refreshed cached count,
and it is served by whichever apiserver replica the scrape lands on —
replicas disagree with each other at the same instant, by enough to
swamp the engage/release hysteresis band. Engage and release timing was
therefore partly a function of scrape routing.

This replaces it with a single `limit=1` list of the workload namespace
and computes `remainingItemCount + items.length`. One pod object
transferred, no informer, no watch cache.

Two request-shape constraints are load-bearing and called out in the
code: passing a label or field selector makes the apiserver omit
`remainingItemCount` entirely, and setting `resourceVersion` serves a
cached count rather than a quorum read. Neither is passed.

`remainingItemCount` is only set when the list is truncated, so
`_continue` is the truncation signal — if it is absent the returned page
is the whole collection and `items.length` is already exact. If the list
*is* truncated and the count is missing or implausible, the fetcher
throws rather than guessing.

Failure semantics are unchanged: a throw lands in the monitor's existing
catch, exactly as the previous parse did. The hysteresis, verdict shape,
and gauge are untouched. RBAC is unchanged — the existing role already
grants `pods: list`.

The `/metrics` non-resource grant in the deployment role becomes unused,
and the scrape-timeout env var is now a slight misnomer. Both left alone
deliberately: the grant may be wanted again for other apiserver signals,
and renaming the var would need a coordinated config change for no
behavioural gain.

Tests cover the not-truncated, truncated, missing-count, negative-count
and timeout paths.
## Summary

Opening a filter sub-menu that has its own search field left the cursor
outside it, so you had to click into the field before you could type.
The cursor now lands in the search field every time a sub-menu opens.

`ComboBox` now focuses its input whenever the popover is open and the
field is present, so the cursor lands there both when a menu opens
normally and when a sub-menu mounts its field late. It is a no-op
wherever focus already worked.

Verified in the dashboard against the Tags menu: before, the field
mounted with focus still on the popover container; after, it mounts
focused and accepts typing straight away.
## Summary

Adds an admin-only "AI agent" storybook page exploring an animated
identity for the dashboard agent: a resting dot logo that animates while
the agent is thinking, then settles once it is done.

The lead experiment is a 5x5 dot matrix. Shapes are five-line string
bitmaps, a bright head walks each shape's route on a fixed beat, and it
only hands off between shapes on a dot the two share, so the rhythm
never breaks. It comes with 26 faces, six gradient palettes, and light
and dark treatments. Two earlier prototypes (a crisp logo that scatters
into orbiting dots, and a dotted triangle on tilted 3D orbits) are kept
in their own tabs for comparison. Everything is plain canvas code with
no new dependencies.

Also adds an `ask-ai` Button variant: secondary styling with a soft
trigger-green border and padding tuned around the leading logo. The
variant supplies the agent logo itself, so callers write `<Button
variant="ask-ai/small">Ask AI</Button>`. Passing a `LeadingIcon`
overrides it, which is how the thinking animation gets driven.

No release note: the storybook is admin gated and the button variant is
not used in product UI yet.
…run or span has un-ingestable JSON (#4358)

## Summary

A single run output, trace span, or payload carrying JSON that
ClickHouse can't ingest (for example nesting past its depth limit) used
to fail the whole insert batch, so unrelated runs and spans silently
disappeared from the runs list, traces, and logs. This keeps the rest of
the batch and handles the offending row instead of dropping everything
around it.

## Fix

Recovery is per-table, matched to what each table needs:

- **Runs** (`task_runs_v2`) keep their status. We follow ClickHouse's
failing-row hint to strip just the un-ingestable JSON column(s) so the
run still lands (its output reads from Postgres on the detail page), up
to a configurable limit (`RUN_REPLICATION_MAX_POISON_STRIPS_PER_BATCH`,
default `1`). Past the limit we stop and land the batch with
`allow_errors` in a single pass, skipping the remainder. Cost stays a
fixed handful of inserts no matter how large or poisoned a flush is.
- **Trace events and payloads** (high volume, append-only) recover with
a single `allow_errors` insert: the good rows land in one pass and only
the un-ingestable rows are skipped.

Before falling back, a lightweight sanitizer still repairs what it can
losslessly (lone UTF-16 surrogates, out-of-range integers) so a
repairable row lands in full.

To read the failing-row hint we patch `@clickhouse/client-common`: its
error parser truncates the server response and discards the `(at row N)`
position, so the patch preserves the full text for the recovery path to
read.
…tnami (#4249)

## Summary

Self-hosted deployments now run ClickHouse from the official
[`clickhouse/clickhouse-server`](https://hub.docker.com/r/clickhouse/clickhouse-server)
image instead of `bitnamilegacy/clickhouse`. Bitnami's free image
catalog is EOL and the frozen legacy archive tops out at ClickHouse
25.7.5, below the 25.8 minimum the platform requires since v4.5.0, which
broke every ClickHouse insert on chart-bundled deployments. Both stacks
now default to 26.2, the same version the platform is developed and
tested against.

Existing deployments keep their ClickHouse data with no manual
migration.

Fixes #4197.

## Details

**Docker Compose**: the `clickhouse` service uses the official image
with its native env vars, plus the recommended `nofile` ulimits. It
reuses the same named volume as before: a `data-paths.xml` config
override points ClickHouse at the `data/` subdirectory of the volume,
which is exactly the layout the Bitnami image used, so old volumes work
in place (including SQL-created users) and fresh installs get the
identical layout. The service follows the required-secrets model:
`CLICKHOUSE_PASSWORD` must be set, matching the other services.

**Helm chart**: the Bitnami ClickHouse subchart is replaced by a
chart-owned single-node StatefulSet and Service running the official
image (non-root, HTTP `/ping` probes, config overrides mounted into
`config.d`, and the same `data-paths.xml` layout compatibility). On
upgrade, the chart automatically adopts the data PVC left behind by the
old subchart (`data-<release>-clickhouse-shard0-0`) via `lookup`, and
`fsGroup` relabeling handles the uid change on first mount. Both the
ClickHouse server and the webapp read the password from the same
chart-managed datastore secret (auto-generated and retained across
upgrades), so the server credential and the app's connection URL always
match. Existing `clickhouse.*` values keep working: `auth` (including
`existingSecret`/`existingSecretKey`), `persistence` (including
`global.storageClass`), `resources`, `secure`, `external.*`,
`configdFiles`, and now `nodeSelector`/`tolerations`/`affinity`.
Bitnami-only keys (`shards`, `replicaCount`, `keeper`,
`resourcesPreset`) are gone; default `resources` requests/limits match
what the old preset applied. The docs state the 25.8 minimum for
bring-your-own ClickHouse.

## Upgrade caveats

An adversarial review of the upgrade path found a few cohorts that need
awareness (all documented):

- **GitOps tools that render with `helm template`** (no cluster access):
PVC auto-detection can't run, so `clickhouse.persistence.existingClaim`
must be set to the old PVC name or ClickHouse starts on a fresh empty
volume. Documented in the values file and the Kubernetes self-hosting
docs. Tools that run real helm installs (e.g. Flux) adopt automatically.
- **A pinned `CLICKHOUSE_IMAGE_TAG`** pointing at a Bitnami tag must be
updated to an official image tag; documented in the Docker self-hosting
docs.
- **Storage without `fsGroup` support** (NFS, hostPath): set
`clickhouse.volumePermissions.enabled: true` for a one-time
ownership-fixing init container.
- **Rollback is not automatic**: once the official image has run, file
ownership changes and the Bitnami image can no longer read the volume
without a manual chown, and ClickHouse does not support downgrades
across the version gap.

## Verification

- Full upgrade simulation for Compose, twice (before and after rebasing
onto the required-secrets release): booted the ClickHouse service from
the old compose file on `main` (Bitnami), wrote thousands of rows, then
brought the same project up with this branch's compose file. The
official 26.2 server came up healthy on the same volume with all rows
intact, SQL-created users working, and writes succeeding.
- Adoption scenarios tested against real containers: old volume + root
entrypoint (Compose), old volume owned by the Bitnami uid + non-root 101
with fsGroup-style group permissions (Kubernetes), and fresh volumes for
both.
- `helm lint`, `helm template` (default values, `existingClaim` set,
external ClickHouse, volumePermissions/scheduling toggles, and the
production example) and kubeconform all pass, mirroring the release CI
steps. The rendered webapp Deployment and ClickHouse StatefulSet resolve
to the same datastore secret key.
- Inserts using
`input_format_json_infer_array_of_dynamic_from_array_of_different_types`
(the setting that fails on 25.7.5) succeed on the upgraded volume.

## Upgrade preflight and docs

A production upgrade report on this branch surfaced two hazards that
predate this PR — both landed in chart 4.5.6 (#4316) — so they are fixed
here rather than left for the next person to hit.

**`secrets.existingSecret` gained two required keys.** The webapp
started reading `PROVIDER_SECRET` and `COORDINATOR_SECRET`, and when
`existingSecret` is set the chart generates nothing, so a missing key
only surfaced as a `CreateContainerConfigError` partway through the
webapp rollout. The pre-install/pre-upgrade validation now looks the
Secret up and fails with the complete list of missing keys, leaving the
running release untouched. It is skipped under `helm template` and
client-side dry-run, where `lookup` cannot read the cluster.

**Bundled datastore credentials moved into the chart-managed Secret**
(`<release>-clickhouse`/`admin-password` →
`trigger-datastore`/`clickhouse-admin-password`). The chart wires both
ends itself, but consumers outside it — maintenance CronJobs, Grafana
datasources, secret syncs — have to be repointed. A new `## Upgrading`
section in the Kubernetes docs carries the old→new mapping, the two new
keys, and a pointer to the ClickHouse image notes.

The existingSecret key list in the docs also named
`OBJECT_STORE_ACCESS_KEY_ID`/`OBJECT_STORE_SECRET_ACCESS_KEY`, which are
env var names rather than keys the chart reads; corrected to the real
key names and the condition under which they apply.

Verified on a throwaway kind cluster with `--dry-run=server`: a
pre-4.5.6 Secret fails with both key names listed, the documented
`kubectl patch` clears it, and default values, `existingClaim`, external
ClickHouse, volumePermissions/scheduling and the production example all
still render. A real `helm install` followed by an upgrade against an
incomplete Secret aborts with the release still at revision 1 and
`deployed`. `helm lint`, the CI render and kubeconform (59 resources, 0
invalid) pass.

---------

Co-authored-by: nicktrn <55853254+nicktrn@users.noreply.github.com>
…sk and agent pages (#4454)

## Summary

The task, scheduled task and agent pages now name their runs table with
its own title bar, and the controls that page the table sit beside it
rather than in the bar at the top of the page. The top bar keeps just
the date filter.

Two agent page layout bugs are fixed along the way: scrolling a wide
runs table sideways dragged the charts off screen with it, and the
details panel stopped short of the bottom of the window.

## Fix

The charts moved because the runs table had no horizontal scroller of
its own. `stickyHeader` swaps the table's `overflow-x-auto` for
`overflow-visible`, so the overflow escaped up to the page scroll box,
and setting only `overflow-y-auto` on that box leaves the computed
`overflow-x` at `visible`, which CSS then promotes to `auto`. The chart
grid is a sibling inside that box, so it scrolled too. The table now
keeps its own scroller (the same rule the queues list already documents)
and the page box clips x so this cannot recur.

The short panel was a second `PageContainer` wrapping the agent routes.
`PageContainer` is `grid-rows-[auto_1fr]`, so a lone child lands in the
`auto` row and its `h-full` resolves against content height instead of
the viewport.

This also reverts the global tooltip `max-w-[230px]` introduced in
[#4131](#4131), so
longer tooltips are no longer squeezed into a narrow column.

### Agent overview page showing table now scrolling
<img width="3452" height="1648" alt="CleanShot 2026-08-01 at 12 04
38@2x"
src="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/user-attachments/assets/ef1ac55d-8ffb-4278-983b-031ed21c1f55"
/>
…mit (#4445)

The Help & Feedback → "Contact us" form in the sidebar intermittently
failed to send. The `<Feedback>` dialog was nested inside the Help
popover, so clicking **Send** closed the popover and unmounted the form
mid-submit — canceling the `POST /resources/feedback` before it went
out. The message was silently lost (the success toast still shows). A
race, so it "worked sometimes"; the standalone "I'm stuck!" path was
unaffected.

**Fix:** host the Feedback dialog *outside* the popover (same pattern as
`AskAIRoot`) and open it from the menu item, so closing the popover no
longer tears down the form. `Feedback` gains an optional controlled
`open`/`setOpen` mode; existing `button`-triggered usages are unchanged.

## Changes

- `Feedback.tsx` — optional controlled `open`/`setOpen`; `button` now
optional.
- `HelpAndFeedbackPopover.tsx` — "Contact us…" opens a `<Feedback>`
hosted outside `PopoverContent`.
- `.server-changes/fix-sidebar-feedback.md` — user-facing note.

## Testing

Webapp typecheck passes. Sidebar "Contact us…" now sends on every
attempt (Network: `POST /resources/feedback` → `204`, never
`(canceled)`); "I'm stuck!" and the `?feedbackPanel=` open path
unchanged.
… it (#4438)

## Summary

The Queues list and queue detail pages opened on a 1 day window, and
went back to it every time you navigated between queues or reloaded.
They now default to the last hour, and the period you pick is remembered
across navigations and refreshes.

## Design

The last period is stored in a `queueMetricsPeriod` cookie, written
client-side whenever a `period` lands in the URL and read by both
loaders. A cookie rather than localStorage because the queues list
renders its per-queue metrics columns server-side: with localStorage the
page would paint the 1 hour default and then re-fetch, and the picker
would flash the wrong window.

Both pages resolve the window once, in one place, and pass it down:

```ts
period: resolveQueueMetricsPeriod({
  period: value("period"),   // a usable period in the URL wins
  from: value("from"),       // an absolute range means "no period"
  to: value("to"),
  defaultPeriod,             // otherwise the remembered default from the loader
}),
```

That keeps the picker pill and every chart query on the same value, so
no call site falls back to its own default. Periods the picker could
never produce (a hand-edited `?period=garbage`, or a window past the 30
day retention) fall back to the default, and the picker renders the
resolved window rather than the raw search param so the label can't
disagree with the data. Absolute from/to ranges, including drag-to-zoom,
are not remembered, since they would pin later visits to a window that
has gone stale.

While wiring that up: the two queue-metric queries that go straight to
ClickHouse (the list table and the concurrency-keys endpoint) never
applied the org's `queryPeriodDays` limit, so a hand-typed `?period=`
read further back than the plan allows. Everything behind
`/resources/metric` is already clipped that way by `executeQuery`; both
of these now clip with the same limit, capped at the retention window,
and the plan cap is resolved once per load and handed to the page
instead of each route deriving its own copy from the client-side
subscription.

Verified on both pages: default with no cookie is 1 hr, picking 6 hrs
survives navigating away and back to a param-free URL and a hard reload,
clearing the cookie returns to 1 hr, an oversized period falls back
without being remembered, and an absolute range still renders as a
range.
Restructures the Kubernetes self-hosting guide around two explicit paths
- an **evaluation install** (bundled datastores, one command) and a
**production install** (external datastores, your own secrets) - so
every configuration decision belongs to one path or the other instead of
being a flat list of options with caveats.

Also in this pass:

- Adds an architecture overview (component-to-`values.yaml` map) and a
post-install "verify it" step.
- Consolidates the previously scattered upgrade notes into a single
collapsible group, and cuts implementation detail and historical asides
that no longer apply.
- Removes a duplicated object-storage section (two configs in two
styles) and trims the Docker ClickHouse note down to what a self-hoster
needs to act on.
## Summary

Environment API keys backed by the additional-key table can authenticate
API requests using their stored effective scopes. Revoked and expired
keys are rejected, branch environments retain their existing routing
behavior, and last-used timestamps are updated on a throttled
best-effort basis.

## Design

API route builders receive the resolved ability and reject restricted
keys on routes without an authorization declaration. Existing
deployment, environment variable, queue, run, task, batch, session, and
waitpoint routes declare the resources they access.

Trigger and batch responses return server-signed public access tokens,
so additional keys never need access to the environment signing secret.
Root-key rotation also keeps public tokens valid for the existing grace
window.

## Feature notes
- Root environment keys remain unrestricted for backward compatibility.
Additional keys enforce their persisted scopes and fail closed on routes
   without an authorization declaration.
- Machine-key requests never exchange one credential for another.
Additional keys cannot retrieve the root key, and rotated root keys are
not upgraded
   during their grace window.
- Public JWT validation remains host-owned, while installed RBAC plugins
continue to supply root-key abilities.
- Unfiltered session and run listings preserve existing broad task-read
behavior. Filtered requests enforce the supplied task identifiers.
- Related-run summaries remain embedded in run retrieval for API
compatibility. Retrieving or mutating a related run independently still
requires
   permission for that run.
- Queue management authorizes at collection scope, matching the queue
permissions currently issued.
- Batch responses deliberately include server-signed public access
tokens for all clients. Selected-task credentials continue using their
original
   credential for per-item authorization.
- Two-phase batches authorize declared task identifiers before creation
and authorize every streamed item. Streaming paths that cannot declare
the
   complete task set remain fail closed.
- Authentication telemetry records successful credential resolution
separately from subsequent resource-authorization failures.
- API keys are high-entropy random tokens. SHA-256 is intentionally used
for deterministic indexed lookup, not password hashing.

## Deployment notes

The schema migration must be present before this code is deployed.
Because bearer resolution runs on every authenticated request, deploy
the resolver with additional-key lookup disabled, verify root-key and
public-token parity, then enable lookup before any additional keys can
be issued.

The multi-task authorization tightening changes the result for narrowly
scoped tokens that request tasks outside their grants. Observe
would-deny results before enforcing that check. Request-idempotency keys
are also newly isolated by environment and task, so a retry crossing the
deployment boundary may execute once more before old cache entries
expire.

## Follow-ups

- [x] Add a system-wide kill switch for additional-key lookup, defaulted
off for the initial deployment.
- [x] Add authentication observability by credential kind, result,
latency, and lookup path without recording credential values.
- [ ] ~Add would-deny observability and an independent enforcement
switch for multi-task authorization.~
- [ ] ~Add an independent switch for server-issued batch tokens while
root-key parity is verified.~
- [ ] Confirm every API route reachable by a restricted key has an
explicit authorization declaration or intentionally fails closed.
- [x] Verify root-key rotation, revoked-key grace, and public-token
validation through each bearer resolver path.
…4488)

GET /api/v1/reports/health threw `no catalog registered for report
"health"` in production (fine in dev): the catalog registered itself as
a side effect of a bare import, which the SSR build tree-shakes under
`"sideEffects": false`. Verified on the built server bundle — main's is
missing the catalog, this branch's carries it.

Fix: catalogs are values on the report registry entries; the resolver
reads them from there and the mutable register-at-import step is gone.
Adds `Leafgard` to the list of vouched outside contributors so their PRs
aren't auto-closed by the vouch check.

Closes #4487
## Summary

The four charts above the queues table aggregated over **at most the 25
queues on the current page**. They reused the loader's already-paginated
queue array as a ClickHouse `queue IN (...)` filter, so paging or
re-sorting changed the values, and a name search matching nothing
blanked the whole chart row. The stat tiles above them were already
environment-wide, so the two rows disagreed.

They now read `env_metrics`, the environment-level rollup that already
exists for exactly this (the built-in Queues dashboard and the health
report read it). That is both correct and queue-count-independent: no
`GROUP BY queue` across an entire environment, and no client-side
summing.

Note this is not only a paging artifact: page 1 under-reported too. On
the seeded environment below, page 1 read 82% saturation against a true
87%, because the environment's running total is not the sum of one page
of per-queue gauges.

Three related fixes ride along.

**Scheduling delay and throttling sawed to zero.** Both are
event-driven, so at the 10-second bucket a short range picks, most
buckets hold no samples at all and were drawn as `0ms`. Measured over a
1-hour window: **232 of 349 buckets had no scheduling-delay samples**. A
bucket where nothing started is not a bucket where nothing waited, so
the line was both ugly and wrong. TRQL grows a `minBucketSeconds` floor,
plumbed through the metric resource route, and the hero tiles set 60s.
Buckets that still have no samples render as a gap instead of a dive to
zero.

**The floor must not feed a width-dependent headline.** Two of the four
headlines are not peaks, so widening the plotted buckets moved them:

- **Throttled** is a share of buckets that saw any throttling, so a
single brief throttle came to mark a whole minute instead of ten
seconds: the same seeded events read 17% at 10s and 85% at 60s.
- **Scheduling delay p95** is a percentile, and merging quantile states
over a wider bucket yields a p95 between the sub-buckets' own. Two 240s
samples among twenty in one 10-second sub-bucket give a worst-of-six p95
of 240,000ms against a merged 60-second p95 of 5,000ms — a 48x
understatement of a headline whose tooltip claims it is the worst in the
window.

Both charts keep the floor, since a readable line was the point of it.
Their headlines now come from a second query at the range's natural
bucket width, via an optional `readout` on the tile, so each means what
its tooltip says regardless of how the plotted buckets are sized.
Saturation and backlog are genuinely width-invariant (a max of maxes is
the same at any width), so they are unchanged and issue no extra query.
Both caught by Devin in review; I had wrongly lumped p95 in with the
peaks.

**Charts reported a hydration mismatch on every render.** Recharts
resolved victory-vendor's CJS entry on the server and its ESM entry in
the browser. Those bundle different d3-shape builds, and the CJS one
predates d3-path's digit rounding, so every server-rendered curve
carried full-precision coordinates while the client rounded to 3
decimals:

```
Server: M0,3C0.9305555555555555,3,1.8611111111111112,3,...
Client: M0,3C0.931,3,1.861,3,...
```

Bundling recharts for SSR makes both sides resolve the same ESM build.
Verified: 45 of 45 server-rendered chart curves now match the client,
and the page loads with an empty console.

## Verification

An isolated stack with 40 seeded queues (20 heavily loaded, 20 idle) and
90 minutes of 10-second buckets written into `queue_metrics_raw_v1`, so
the real materialized views built `queue_metrics_v1`, `env_metrics_v1`
and the 5m rollup. Ground truth for the environment: 260 running against
a limit of 300 (**87% saturation**), 800 queued.

| | before | after |
| -- | -- | -- |
| Saturation, page 1 | 82% peak | **87% peak** |
| Saturation, page 2 | 5% peak | **87% peak** |
| Backlog / delay, page 2 | "No activity" | **800 peak / 59.5s** |
| Name search matching nothing | all four charts blank | charts stay
environment-wide |
| Metric refetches on a page change | 4, each painting a skeleton | **0,
no skeleton** |
| Buckets drawn as 0ms with no samples | 232 of 349 | **0** |
| Throttled readout | 17% | **17%**, unchanged by the wider buckets |
| Worst-p95 readout source | plotted buckets | **natural width**, so a
sub-minute spike is not averaged away |
| Crosshair reach, hovering one detail-page chart | 2 of 4 others | **4
of 4** |
| SSR chart curves mismatching the client | 45 | **0** |

The bucket floor was measured across ranges: it widens 10s to 60s at 30m
and 1h, and is correctly a no-op at 12h (300s) and 7d (3600s). One extra
request per page load, for the throttled readout.

The built-in Queues dashboard, which reads `env_metrics` independently,
agrees at 86.7% and 260 of 300.

`internal-packages/tsql` suite green (612 tests), including 5 new ones
for the floor that fail without it. Webapp typecheck, oxfmt and oxlint
clean. Spot-checked the Run metrics dashboard and the per-queue detail
page for SSR regressions from bundling recharts: both render, console
clean.

The queue detail page carries the same event-driven series, so its
scheduling delay, throttling and per-key mean delay take the same
treatment.

## Screenshots

<img width="2540" height="580" alt="after-page1-charts"
src="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/user-attachments/assets/6cd23f9c-e7fd-4918-bcfa-b1d3340b16d1"
/>

## Rollout

Already behind the per-organization `queueMetricsUiEnabled` flag, so
only gated orgs see any of it. Blast radius is chart values on one page
plus the SSR bundling of recharts; rollback is a revert with no data
migration.

## Stated limitations

- `wait_ms_count` and the quantile state both only count `wait_ms > 0`,
so "nothing started in this bucket" and "everything started instantly"
are indistinguishable in storage. Both render as a gap. Distinguishing
them needs a schema change, which is not in this PR.
- The queue name search deliberately no longer narrows the charts. It
only did so incidentally and incorrectly before (first 25 matches, and
blanked on zero matches). Search-scoped charts would need the full
unpaginated matching set and a server-side aggregate; worth its own
ticket if we want it.
- Bundling recharts for SSR grows the server bundle slightly. That is
the cost of both sides resolving one d3-shape build.
- The plotted delay line is a smoothed 60-second view, so a sub-minute
spike above the one-minute warning threshold can fail to colour the line
even though the headline reports it and colours itself.
- Every chart inside one synced group shares the floor, because the
hover crosshair is a reference line on a category x-axis and only draws
where the hovered bucket exists in the other chart's own data. That
costs the queue detail page's gauges some resolution (1 minute instead
of 10 seconds) in exchange for the crosshair working across the row.

Separately, while taking the screenshots I found a pre-existing
rendering bug unrelated to this change: a **perfectly flat** saturation
series draws no line at all (the readout still shows the right
percentage), which looks like the threshold gradient's offset
degenerating when the series min equals its max. It reproduces on
`main`, so it is not a regression here and I have left it alone; filed
as its own issue.

Refs TRI-12784
## Summary

Self-hosted Kubernetes deployments can now add tolerations to run pods,
so runs
can schedule onto tainted nodes. Previously the only way to do this was
to patch
the supervisor.

`KUBERNETES_RUNNER_TOLERATIONS` takes a comma separated list of
`key=value:effect`, or `key:effect` to tolerate any value. It applies to
every
run pod, and for runs from a schedule tree it merges with the existing
`KUBERNETES_SCHEDULED_RUN_TOLERATIONS`. Left unset, nothing changes: no
tolerations are added and the pod spec leaves the field off entirely.

The Helm chart takes it as a list:

```yaml
supervisor:
  config:
    kubernetes:
      runnerTolerations:
        - dedicated=runs:NoSchedule
        - spot:NoExecute
```

## Naming

The issue proposed `KUBERNETES_WORKER_TOLERATIONS`. This ships as
`KUBERNETES_RUNNER_TOLERATIONS` instead, because `RUNNER_*` is already
the prefix
for run pod settings (`RUNNER_HEARTBEAT_INTERVAL_SECONDS`,
`RUNNER_ADDITIONAL_ENV_VARS`, and `DOCKER_RUNNER_NETWORKS` for the
Docker
equivalent), whereas "worker" refers to the supervisor itself throughout
this app.

## Validation

Keys and values are checked against the Kubernetes naming rules when the
supervisor starts, so `dedicated=prod runs:NoSchedule` fails immediately
with a
message naming the offending entry. Without that check a bad value is
accepted at
startup and then rejected by the API server on every pod create, which
stops all
runs with the cause buried in an API error.
`KUBERNETES_WORKER_NODETYPE_LABEL` is
trimmed and validated for the same reason: surrounding whitespace is not
valid in
a label value, so a padded value fails every pod create today.

## Node selector off switch

`KUBERNETES_WORKER_NODETYPE_LABEL` accepts an empty string to skip the
node
selector entirely, so runs schedule on any node. This already worked and
the Helm
chart has always shipped it empty, but it was not documented. It is now.

The issue also asked for general node affinity configuration. That is
not
included: the node selector off switch plus tolerations covers the
reported
problem, and a free form affinity setting is a much larger config
surface to
commit to.

Fixes #4458
…#4444)

The dequeue brake released the moment its signal became unreadable.
`refresh()` caught any error from `source.read()` and set the verdict to
`null`, which `computeEngaged()` treats as not-engaged — so a few failed
reads dropped an engaged brake, silently, with no log and no metric.

That handling was symmetric while the risk is not. A source that has
stopped answering correlates with the pressure the brake exists for, so
releasing on read failure gives up protection at exactly the wrong
moment; holding too long only costs throughput.

Now a failed read keeps the last verdict instead of discarding it. The
verdict then ages normally, so the existing `maxVerdictAgeMs` check
becomes the grace window and still bounds how long a dead source can
hold the brake — a permanently unreachable source releases it rather
than pinning dequeuing forever. Because `computeEngaged()` only consults
staleness for an *engaged* verdict, a released one is unaffected and
stays released.

The default grace moves from 15s to 120s, comparable to how long the
brake normally stays engaged.

One guard worth calling out: holding is only safe when something bounds
it, so when `maxVerdictAgeMs` is unset the previous discard behaviour is
kept. Otherwise an unbounded hold could pin the brake indefinitely.

Read failures were previously invisible — the catch block neither logged
nor counted. Adds a `read_failures_total` counter, plus an error log on
the transition into failure rather than once per tick, since the refresh
loop runs every second.

The post-release ramp needs no change: it anchors off the
engaged-to-released transition, so a grace-window release still ramps
back up instead of snapping to full rate, which is what you want after a
blind period.

Tests cover holding while reads fail, releasing past the max age, and
the existing unbounded-config paths are unchanged.
## Summary

The webapp's server bundle imports `prop-types` directly, but the
package was declared only as a `devDependency`. A production install
therefore leaves it out and the built server fails to boot:

```
Failed to start server: Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'prop-types'
  imported from /triggerdotdev/apps/webapp/build/server/assets/server-build-*.js
```

Moving it to `dependencies` is the whole change.

## Why the bundle imports it

Nothing in the webapp's own code uses `prop-types` — there is no
reference to it, or to `PropTypes`, anywhere under `apps/webapp/app`. It
arrives through `recharts`, whose `react-smooth` dependency still
declares `propTypes` on its components.

That was invisible until recently. While `recharts` was resolved at
runtime, its `prop-types` import was satisfied inside `recharts`' own
dependency tree, which is production all the way down. #4486 added
`recharts` and `victory-vendor` to `ssr.noExternal` to fix a hydration
mismatch on every server-rendered chart; that inlines `react-smooth`
into the server bundle, which moves its `prop-types` import into the
webapp's own resolution scope — where the package was not available in
production.

So the bundling change was correct about *which* d3-shape build both
sides resolve, and wrong about what the production runtime would be able
to find.

## Verification

`docker/Dockerfile` builds the runtime dependencies with `pnpm install
--prod` against a `turbo prune --scope=webapp --docker` output, so I
reproduced exactly that: pruned the workspace, installed with `--prod`,
and imported `prop-types` from `apps/webapp`.

| | result |
| -- | -- |
| `main` as it stands (devDependency only) | `FAILS:
ERR_MODULE_NOT_FOUND` |
| with this change | `prop-types resolves OK` |

It resolves both as a CommonJS `require` and as an ESM `import`, which
is the form the bundle uses.

I also checked this is not one symptom of a wider problem: of the 169
bare specifier roots the server bundle imports, `prop-types` is the
**only** one that is a devDependency and not a production dependency.
The rest are node builtins or production dependencies.

The hydration fix from #4486 is unaffected — the rebuilt bundle still
carries the rounding d3-path build.

## Notes

`prop-types` is inert in production (its entry point swaps in
`factoryWithThrowingShims`), so this adds a 124 KB package that does no
work at runtime. It has to be resolvable regardless, because the import
is real.

An alternative would be adding `prop-types` to `ssr.noExternal` so it is
inlined and needs no runtime resolution. That keeps the dependency list
honest about the fact that the webapp itself does not use it, at the
cost of bundling a CommonJS package into the ESM server output. This
route is the smaller, better-understood change.

Worth following up separately: a check that every bare import in the
server bundle resolves from a production install would have caught this
before it landed. Local development installs every devDependency, so the
gap is invisible when the built server is run from a working tree.
Adds System Preferences, Dark and Light themes, gated by the
`hasThemeSwitcher` feature flag (off by default — dark stays the default
theme for everyone).

Old theme is now "Classic"and set as default. 
"System preferences" theme has both Light and Dark modes and uses your
laptop settings to use a correct one.
It has less color accents (specifically less colored text), and they are
the same for both modes, only grayscale values change between them. And
Light/Dark themes can be used separately.

New Contrast setting is available for System Preferences, Dark and Light
themes - it changes the contrast for the whole app. All new visual
Settings live in Account.
Adds `Rohan170603` to the list of vouched outside contributors so their
PRs aren't auto-closed by the vouch check.

Closes #4498
…#4493)

When a run reaches a terminal state, ask the checkpoint service to
reclaim the storage its checkpoints occupied. Storage for finished runs
is not otherwise reclaimed, so nothing frees it today.

**Off by default** behind `DELETE_CHECKPOINTS_ON_COMPLETION`, and the
service-side handler ships separately, so merging this changes no
behaviour.

## Where the tenancy comes from

Addressing a run's checkpoints needs org, project, environment,
deployment version and run id. All five are already in hand at
`attempt.complete`, and three are **signed** by the deployment token:

| Value | Source | Trust |
| -- | -- | -- |
| org | claim `org_id` | signed |
| environment | claim `environment_id` | signed |
| deployment version | claim `deployment_version` | signed |
| project ref | `x-trigger-workload-project-ref` header |
runner-supplied |
| run | route param | runner-supplied |

`authorizeWorkloadRequest` previously returned only `environment_id`,
and only in enforce mode, so it now also returns the verified `claims`.
That difference is deliberate and documented on the method: claims are
used to address a run's **own** resources locally, never to scope the
platform, which is why `environmentId` stays enforce-only.

The two runner-supplied values are safe because the signed ones are
outermost - a runner lying about either can only name something inside
its own org and environment, and a project ref that doesn't pair with
its signed environment matches nothing. The run id is read from
`params.runFriendlyId`, the same value the platform just validated,
rather than from the body or a header. Where both a claim and a header
exist (`deployment_version`), the claim wins.

## Placement

The call sits after `reply.json(...)`, so the runner sees no added
latency - the same shape the suspend route already uses. The service
enqueues and returns 202, so it is one fast local hop.

Terminal means `RUN_FINISHED` **or `RUN_PENDING_CANCEL`** - a run
cancelled mid-execution never restores, and skipping it would leave its
storage behind. Retries are excluded deliberately: reclamation is
per-run, so a retry is covered by the final completion.

Also gated on `!snapshotService`, so it stays inert where checkpoints
aren't the kind this reclaims.

## Observability

`checkpoint_delete_requests_total{result}` counts `sent` **and every
reason we decide not to send**: `disabled`, `not_terminal`, `no_claims`,
`no_project_ref`, `http_error`.

The negative labels are the point - without them, "no requests are
happening" looks identical to the feature being switched off.
`no_claims` is reachable even under enforcement, since enforce only
rejects a *present-but-invalid* token; an absent or legacy id still
passes with no claims attached.

## Notes for review

- **No changeset**: `CheckpointClient` is `core/v3/serverOnly`, an
internal service-to-service API rather than customer-facing surface.
- **No `.server-changes/` note**: there is nothing a dashboard user
would notice here. Happy to add one if you disagree.
- `pnpm run typecheck` can't complete in my checkout -
`@trigger.dev/database` fails to build on a missing `tsc` in the pnpm
store, unrelated to this diff. Verified with `tsc --noEmit` against the
supervisor project instead: **zero errors in `apps/supervisor/src`**.
Worth noting it caught a real bug here - the completion response is
wrapped, so the status is `data.result.attemptStatus`.

refs TRI-12789
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.