Commit Graph
1462 Commits
Author SHA1 Message Date
6439572ecd fix(ui): sync cron validity + settle branch test for radix-ui 1.6.4 (#9966)
## Thinking Path

> - Paperclip is the open-source app people use to manage AI agents for
work
> - The `ui` package contains React components that drive the agent
scheduling and workspace configuration UX
> - Dependabot PR #9895 bumped `@radix-ui/react-*` from 1.6.0 → 1.6.4,
which changed the internal effect-scheduling order inside Dialog and
Select primitives
> - Two `workspaces-a` CI tests started failing:
`RoutineRunVariablesDialog` and `editable-sections / TriggersSection`
> - Root cause for both: radix 1.6.4's changed scheduling pushes a
cascaded state update one render-tick later, and each test asserted
before that tick landed
> - This PR fixes the two affected surfaces at the source (one
production fix, one test fix) so the radix bump can land cleanly
> - The benefit is unblocking PR #9895 without compromising test
fidelity or production correctness

## Linked Issues or Issue Description

Refs #9895 — this PR fixes the two `workspaces-a` test failures that
blocked the radix-ui 1.6.0 → 1.6.4 Dependabot bump.

**Root cause:** radix-ui 1.6.4 changed the internal effect-scheduling
order inside its Dialog and Select primitives, pushing certain cascaded
state updates one render-tick later than before. Two tests each asserted
against the intermediate state, before the deferred tick landed.

**Affected tests (both now pass at radix 1.6.0 AND 1.6.4):**

1. `editable-sections / TriggersSection` — `ScheduleEditor`
disabled-button assertion
2. `RoutineRunVariablesDialog` — workspace branch propagation assertion

Production behavior is unchanged and correct in both cases (verified via
tracing).

## What Changed

- **`ui/src/components/ScheduleEditor.tsx`** — `onValidityChange` is now
called synchronously inside the custom-cron `onChange` handler, not only
via the passive `useEffect` below. Previously there was a one-render
window where an invalid draft still read as valid to the parent (button
enabled); this closes that window. The effect call is preserved as a
safety net for other entry paths; only the `onChange` path is new.
- **`ui/src/components/RoutineRunVariablesDialog.test.tsx`** — the
post-mount settle loop now waits for the branch value to actually appear
in an `<input>` (`value === "pap-1634-routine-branch"`) rather than
exiting as soon as the workspace card mounts. The card reports its
branch name through an effect callback that triggers a follow-up render;
the old loop exited one tick too early. Iteration cap raised from 10 →
20 to give the extra tick room.

This PR intentionally does **not** bump radix-ui — that stays in #9895.

## Verification

```sh
# TypeScript — clean at radix 1.6.0 (master):
tsc -p ui/tsconfig.json

# Targeted vitest:
npx vitest run ui/src/components/RoutineRunVariablesDialog.test.tsx
npx vitest run ui/src/components/editable-sections
npx vitest run ui/src/components/ScheduleEditor

# Full ui suite — green with radix 1.6.4 installed locally (371 files / 3035 tests):
npx vitest run --project ui

# check-forbidden-tokens — clean
```

All of the above pass at **both** radix 1.6.0 (current master) and
1.6.4.

## Risks

Low risk. The production change (`ScheduleEditor.tsx`) adds a
synchronous call to an already-injected `onValidityChange` prop — same
value, earlier in the same event cycle. No new state, no new effects, no
API changes. The test change tightens an assertion (waits longer, checks
a more specific condition) rather than relaxing one.

## Model Used

Claude Sonnet (Anthropic) — Paperclip agent workflow; model family
claude-sonnet-4-x with tool use and extended reasoning enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Harold Kim <harold@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-21 12:49:11 -05:00
le-czs c1f6698ec5 fix(ui/invite): make pending-approval admin guidance non-clickable (#6786)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies, and
humans onboard into companies via invite links.
> - Some invite types (`company_join` with
`requires_company_admin_approval`) require an admin to approve the join
request after the invitee submits it.
> - While the requester waits, the invitee sees the
`AwaitingJoinApprovalPanel` in `InviteLanding`, which describes where
the admin needs to go to approve the request.
> - That panel rendered the destination — "Company Settings → Access" —
as two clickable `<a href="/company/settings/access">` links, even
though the surrounding copy is plainly addressed to the admin ("Ask
**them** to visit ..."), not the requester.
> - First-time invitees naturally click the only underlined link on the
screen, are sent to `/company/settings/access`, hit the "No company
access" panel (they have no membership yet), and conclude the invite
flow is broken.
> - This PR removes the navigation by rendering both "Company Settings →
Access" references as plain styled text (`<p>` / `<span>`), so the
guidance stays visible but cannot be followed by the requester.
> - The benefit is that the post-submit invite experience matches the
copy's intent — guidance for the admin, not navigation for the
requester.

Fixes #6784.

## What Changed

- `ui/src/pages/InviteLanding.tsx` — In `AwaitingJoinApprovalPanel`,
replace the two `<a href={approvalUrl}>Company Settings → Access</a>`
elements with `<p>` and `<span>` containing the same text. Remove the
now-unused `approvalUrl` constant.
- `ui/src/pages/InviteLanding.test.tsx` — Update the existing "pending
approval page" test: it previously asserted two anchor tags pointing at
`/company/settings/access`; it now asserts **zero** anchors while the
text "Company Settings → Access" still appears twice (in the "Approval
page" box and inline in the "Ask them to visit ..." sentence). Renamed
the test description from "...linked access instructions" to
"...non-clickable access instructions" to reflect the contract.

## Verification

```
pnpm vitest run ui/src/pages/InviteLanding.test.tsx
```

Result: 8 / 8 pass, including the updated "shows the pending approval
page with the company icon and non-clickable access instructions" case.

Manual reproduction (master @ `242a2c2f`,
`deploymentMode=authenticated`, `bind=lan`, embedded Postgres):

1. As instance admin, generate a `company_join` invite that requires
admin approval.
2. In a fresh browser profile, open the invite link.
3. Fill **Create your account** and submit.
4. The "Request to join \<company\>" panel appears.
5. Hover the "Company Settings → Access" mentions — no underline, no
link cursor; clicking does nothing. The text is still readable and the
surrounding copy ("Ask them to visit ...") still conveys the instruction
to the requester.

Before / after screenshots: see issue #6784 — the "before" state lands
users on `/company/settings/access` which renders "No company access".
After this PR the guidance is informational only.

## Risks

Low. UI-only change confined to one function in `InviteLanding.tsx` plus
its matching test. No API contracts, routes, or data shapes are
modified. The removed `approvalUrl` constant was only referenced by the
two anchor elements.

## Model Used

- Anthropic Claude Opus 4.7 (`claude-opus-4-7`, 1M context, extended
thinking enabled).
- Tools: file editing, Bash, Playwright reproduction against a
self-hosted Paperclip instance running master @ `242a2c2f`, and the
Paperclip monorepo's own Vitest suite for verifying the test update.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots (will attach in PR thread)
- [x] I have updated relevant documentation to reflect my changes (no
docs files needed updating)
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-07-21 10:22:17 -07:00
dependabot[bot] a3f583b5a9 build(deps-dev): bump @tailwindcss/vite from 4.3.0 to 4.3.3 (#9892)
Bumps
[@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite)
from 4.3.0 to 4.3.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">@​tailwindcss/vite's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.3</h2>
<h3>Fixed</h3>
<ul>
<li>Support <code>--watch --poll[=ms]</code> in
<code>@tailwindcss/cli</code> when filesystem events are unreliable or
unavailable (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20297">#20297</a>)</li>
<li>Canonicalization: match arbitrary hex colors against theme colors
case-insensitively (e.g. <code>bg-[#fff]</code> and
<code>bg-[#FFF]</code> → <code>bg-white</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20298">#20298</a>)</li>
<li>Prevent Preflight from overriding Firefox's native
<code>iframe:focus-visible</code> outline styles (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20292">#20292</a>)</li>
<li>Ensure <code>theme('colors.foo')</code> in JS plugins resolves
correctly when both <code>--color-foo</code> and
<code>--color-foo-bar</code> exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20299">#20299</a>)</li>
<li>Ensure fractional opacity modifiers work with named shadow sizes
like <code>shadow-sm/12.5</code>, <code>text-shadow-sm/12.5</code>,
<code>drop-shadow-sm/12.5</code>, and <code>inset-shadow-sm/12.5</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20302">#20302</a>)</li>
<li>Parse selectors like <code>[data-foo]div</code> as two selectors
instead of one (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20303">#20303</a>)</li>
<li>Ensure <code>@tailwindcss/postcss</code> rebuilds when a
preprocessor like Sass changes the input CSS without changing the input
file on disk (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20310">#20310</a>)</li>
<li>Ensure CSS nesting is handled even when Lightning CSS isn't run,
such as in <code>@tailwindcss/browser</code> and Tailwind Play (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20124">#20124</a>)</li>
<li>Prevent achromatic theme colors from shifting hue when mixed in
polar color spaces like <code>oklch</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20314">#20314</a>)</li>
<li>Ensure <code>--spacing(0)</code> is optimized to <code>0px</code>
instead of <code>0</code> so it remains a <code>&lt;length&gt;</code>
when used in <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20319">#20319</a>)</li>
<li>Load <code>@parcel/watcher</code> only when needed in
<code>@tailwindcss/cli --watch</code> mode, so one-off builds and
<code>--watch --poll</code> work when <code>@parcel/watcher</code> can't
be loaded (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20325">#20325</a>)</li>
<li>Use explicit platform fonts instead of <code>system-ui</code> and
<code>ui-sans-serif</code> so CJK text respects the page's
<code>lang</code> attribute on Windows (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20318">#20318</a>)</li>
<li>Prevent <code>@tailwindcss/upgrade</code> from rewriting ignored
files when run from a subdirectory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20329">#20329</a>)</li>
<li>Ensure earlier <code>@source</code> rules pointing to nested files
are scanned when later <code>@source</code> rules point to files in
parent folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20335">#20335</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from triggering full page
reloads when scanned files are processed by Vite but haven't been loaded
as modules yet (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20336">#20336</a>)</li>
</ul>
<h2>v4.3.2</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
<h2>v4.3.1</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">@​tailwindcss/vite's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.3] - 2026-07-16</h2>
<h3>Fixed</h3>
<ul>
<li>Support <code>--watch --poll[=ms]</code> in
<code>@tailwindcss/cli</code> when filesystem events are unreliable or
unavailable (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20297">#20297</a>)</li>
<li>Canonicalization: match arbitrary hex colors against theme colors
case-insensitively (e.g. <code>bg-[#fff]</code> and
<code>bg-[#FFF]</code> → <code>bg-white</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20298">#20298</a>)</li>
<li>Prevent Preflight from overriding Firefox's native
<code>iframe:focus-visible</code> outline styles (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20292">#20292</a>)</li>
<li>Ensure <code>theme('colors.foo')</code> in JS plugins resolves
correctly when both <code>--color-foo</code> and
<code>--color-foo-bar</code> exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20299">#20299</a>)</li>
<li>Ensure fractional opacity modifiers work with named shadow sizes
like <code>shadow-sm/12.5</code>, <code>text-shadow-sm/12.5</code>,
<code>drop-shadow-sm/12.5</code>, and <code>inset-shadow-sm/12.5</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20302">#20302</a>)</li>
<li>Parse selectors like <code>[data-foo]div</code> as two selectors
instead of one (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20303">#20303</a>)</li>
<li>Ensure <code>@tailwindcss/postcss</code> rebuilds when a
preprocessor like Sass changes the input CSS without changing the input
file on disk (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20310">#20310</a>)</li>
<li>Ensure CSS nesting is handled even when Lightning CSS isn't run,
such as in <code>@tailwindcss/browser</code> and Tailwind Play (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20124">#20124</a>)</li>
<li>Prevent achromatic theme colors from shifting hue when mixed in
polar color spaces like <code>oklch</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20314">#20314</a>)</li>
<li>Ensure <code>--spacing(0)</code> is optimized to <code>0px</code>
instead of <code>0</code> so it remains a <code>&lt;length&gt;</code>
when used in <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20319">#20319</a>)</li>
<li>Load <code>@parcel/watcher</code> only when needed in
<code>@tailwindcss/cli --watch</code> mode, so one-off builds and
<code>--watch --poll</code> work when <code>@parcel/watcher</code> can't
be loaded (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20325">#20325</a>)</li>
<li>Use explicit platform fonts instead of <code>system-ui</code> and
<code>ui-sans-serif</code> so CJK text respects the page's
<code>lang</code> attribute on Windows (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20318">#20318</a>)</li>
<li>Prevent <code>@tailwindcss/upgrade</code> from rewriting ignored
files when run from a subdirectory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20329">#20329</a>)</li>
<li>Ensure earlier <code>@source</code> rules pointing to nested files
are scanned when later <code>@source</code> rules point to files in
parent folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20335">#20335</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from triggering full page
reloads when scanned files are processed by Vite but haven't been loaded
as modules yet (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20336">#20336</a>)</li>
</ul>
<h2>[4.3.2] - 2026-06-26</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
<h2>[4.3.1] - 2026-06-12</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/c2b24dd15fed1c59dd521bd86082f520c9f5ad0d"><code>c2b24dd</code></a>
4.3.3 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20334">#20334</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/bdcd7087b332d263353d46ed366b7b08040ded7a"><code>bdcd708</code></a>
Don't trigger a full page reload for scanned files that Vite processes
as mod...</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/056a1550721d4bf79ff732d5ab9414fa83f7064f"><code>056a155</code></a>
4.3.2 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20281">#20281</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/bb6a10937c7e1434db39919fbb4df4a8982dba7f"><code>bb6a109</code></a>
use <code>.ts</code> instead of <code>.css</code></li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/8a14a710102cae195f6811e8578bef9477bc6be9"><code>8a14a71</code></a>
4.3.1 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20226">#20226</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/73983e1cf5bc0ae721f4568cc24a5b5067b6b90b"><code>73983e1</code></a>
Fix 'Sourcemap is likely to be incorrect' warnings when using
`@tailwindcss/v...</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/@tailwindcss-vite">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>
2026-07-21 12:16:25 -05:00
dependabot[bot] 34f5674cbe build(deps): bump react-i18next from 17.0.9 to 17.0.10 (#9889)
Bumps [react-i18next](https://github.com/i18next/react-i18next) from
17.0.9 to 17.0.10.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md">react-i18next's
changelog</a>.</em></p>
<blockquote>
<h2>17.0.10</h2>
<ul>
<li>fix(warnings): the <code>useTranslation</code> and
<code>Trans</code> &quot;You will need to pass in an i18next
instance&quot; warnings now match the <code>useSSR</code> wording,
mentioning the props/context alternatives and the most common
unexplained cause at scale: duplicate react-i18next copies in monorepo
setups. The <code>Trans</code> variant also referenced the internal
<code>i18nextReactModule</code> name; it now points to the public
<code>initReactI18next</code> API.</li>
<li>feat(warnings): development-only warning
(<code>SUSPENDED_WHILE_LOADING</code>, logged once) right before
<code>useTranslation</code> suspends while translations are loading.
With the default <code>useSuspense: true</code> and no
<code>&lt;Suspense&gt;</code> boundary this previously surfaced as a
blank screen or a cryptic React error; the warning now names both fixes
(add a <code>&lt;Suspense&gt;</code> boundary or set
<code>react.useSuspense: false</code>). No-op in production builds; the
<code>process.env.NODE_ENV</code> check is wrapped so runtimes without a
<code>process</code> global (raw ESM in the browser, some edge runtimes)
stay silent instead of throwing.</li>
<li>ci: weekly workflow typechecking the test suite against
<code>@types/react@next</code> / <code>@types/react-dom@next</code>, so
the next React major's type changes (like the React 18
<code>TFunctionResult</code>/children wave) surface before user
reports.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/i18next/react-i18next/commit/3b71c2766c2507781ccfb7b2b7a638b3ab339958"><code>3b71c27</code></a>
17.0.10</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/57c3500e6a18764eb30ef433f0899ea781c99bad"><code>57c3500</code></a>
build</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/c62476f4d10d7a8d77d6eb5b70ece5c960c978a0"><code>c62476f</code></a>
chore: sync package-lock with i18next ^26.2.0 devDependency bump</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/0126bd1cada6bcf98aa764f32e9f17e5f690e431"><code>0126bd1</code></a>
improve instance warnings (monorepo hint) + dev-only suspense warning +
weekl...</li>
<li>See full diff in <a
href="https://github.com/i18next/react-i18next/compare/v17.0.9...v17.0.10">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 12:04:36 -05:00
dependabot[bot] dc7f09be0d build(deps-dev): bump vitest from 4.1.8 to 4.1.10 (#9886)
Bumps
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
from 4.1.8 to 4.1.10.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.10</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Check fs access in builtin commands
[backport to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Hiroshi Ogawa</strong> and <strong>OpenCode
(claude-opus-4-8)</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10680">vitest-dev/vitest#10680</a>
<a href="https://github.com/vitest-dev/vitest/commit/5c18dd267"><!-- raw
HTML omitted -->(5c18d)<!-- raw HTML omitted --></a></li>
<li><strong>vm</strong>: Fix external module resolve error with deps
optimizer query for encoded URI [backport to v4]  -  by <a
href="https://github.com/SveLil"><code>@​SveLil</code></a> and <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10661">vitest-dev/vitest#10661</a>
<a href="https://github.com/vitest-dev/vitest/commit/bae52b511"><!-- raw
HTML omitted -->(bae52)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.9...v4.1.10">View
changes on GitHub</a></h5>
<h2>v4.1.9</h2>
<h3>🐞 Bug Fixes</h3>
<ul>
<li>Fix <code>importOriginal</code> with optimizer and query import
[backport to v4] - by <strong>Hiroshi Ogawa</strong>, <strong>David
Harris</strong>, <strong>Codex</strong>and <strong>Vladimir</strong> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10546">vitest-dev/vitest#10546</a>
<a href="https://github.com/vitest-dev/vitest/commit/a5180190c"><!-- raw
HTML omitted -->(a5180)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>:
<ul>
<li>Wait for orchestrator readiness before resolving browser sessions
[backport to v4] - by <strong>Vladimir</strong> and <strong>Séamus
O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10555">vitest-dev/vitest#10555</a>
<a href="https://github.com/vitest-dev/vitest/commit/7fb29651a"><!-- raw
HTML omitted -->(7fb29)<!-- raw HTML omitted --></a></li>
<li>Wait for iframe tester readiness before preparing [backport to v4] -
by <strong>Vladimir</strong> and <strong>Séamus O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10497">vitest-dev/vitest#10497</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10556">vitest-dev/vitest#10556</a>
<a href="https://github.com/vitest-dev/vitest/commit/fbc626c40"><!-- raw
HTML omitted -->(fbc62)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>mocker</strong>:
<ul>
<li>Hoist vi.mock() for vite-plus/test imports [backport to v4] - by
<strong>Hiroshi Ogawa</strong>, <strong>LongYinan</strong>,
<strong>Claude Opus 4.8</strong> and <strong>Vladimir</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10548">vitest-dev/vitest#10548</a>
<a href="https://github.com/vitest-dev/vitest/commit/2c9559c02"><!-- raw
HTML omitted -->(2c955)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>pool</strong>:
<ul>
<li>Prevent test run hang on worker crash [backport to v4] - by
<strong>Ari Perkkiö</strong> and <strong>Jattioui Ismail</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10543">vitest-dev/vitest#10543</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10564">vitest-dev/vitest#10564</a>
<a href="https://github.com/vitest-dev/vitest/commit/934b0f587"><!-- raw
HTML omitted -->(934b0)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5><a
href="https://github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitest-dev/vitest/commit/db616d227b6e0cb07a94f5d1bba262ee95db7e46"><code>db616d2</code></a>
chore: release v4.1.10 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10718">#10718</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/bae52b5112a6fd8200101b88bf8af9685d077295"><code>bae52b5</code></a>
fix(vm): fix external module resolve error with deps optimizer query for
enco...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a7a61e78c7d0718f00173cff6800a91a344457d4"><code>a7a61e7</code></a>
chore: release v4.1.9 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10598">#10598</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/934b0f587cb61d8338d83f525295322692a2db40"><code>934b0f5</code></a>
fix(pool): prevent test run hang on worker crash (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10543">#10543</a>)
[backport to v4] (#...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/7fb29651afbae2a9b0cefe6c031a9308f168ac60"><code>7fb2965</code></a>
fix(browser): wait for orchestrator readiness before resolving browser
sessio...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a5180190c1be7089e3705e3dd9e84fea118d09d3"><code>a518019</code></a>
fix: fix <code>importOriginal</code> with optimizer and query import
[backport to v4] (#...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 12:04:11 -05:00
dependabot[bot] e171e6f9e6 build(deps): bump react-router-dom from 7.16.0 to 7.18.1 (#9888)
Bumps
[react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom)
from 7.16.0 to 7.18.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/react-router-dom@7.18.1/packages/react-router-dom/CHANGELOG.md">react-router-dom's
changelog</a>.</em></p>
<blockquote>
<h2>v7.18.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Fix incorrect <code>package.json</code> <code>main</code> field for
CommonJS builds (<a
href="https://redirect.github.com/remix-run/react-router/pull/15238">#15238</a>)</li>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.18.1"><code>react-router@7.18.1</code></a></li>
</ul>
</li>
</ul>
<h2>v7.18.0</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.18.0"><code>react-router@7.18.0</code></a></li>
</ul>
</li>
</ul>
<h2>v7.17.0</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.17.0"><code>react-router@7.17.0</code></a></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/remix-run/react-router/commit/afdf85d3c15448a41017514caca2aca038d3e9ca"><code>afdf85d</code></a>
Release v7.18.1 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15253">#15253</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/2ecaa1ddbbcd583999dda46dd5413e907e8a46f3"><code>2ecaa1d</code></a>
Fix react-router-dom main entry metadata (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15238">#15238</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/6fb1e79f8304eddd8b78759edea83cb32389ebf5"><code>6fb1e79</code></a>
Release v7.18.0 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15187">#15187</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/195a0d03c1417127ccee73853058c8521beb4fce"><code>195a0d0</code></a>
Release v7.17.0 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15145">#15145</a>)</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router-dom@7.18.1/packages/react-router-dom">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=react-router-dom&package-manager=npm_and_yarn&previous-version=7.16.0&new-version=7.18.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 12:03:39 -05:00
dependabot[bot] 8cdb3552b4 build(deps): bump @lexical/link from 0.46.0 to 0.48.0 (#9885)
Bumps
[@lexical/link](https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link)
from 0.46.0 to 0.48.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/lexical/releases">@​lexical/link's
releases</a>.</em></p>
<blockquote>
<p>v0.48.0 is a maintenance release focused on bug fixes across
Markdown, tables, lists, links, and selection. It's headlined by a fix
for a v0.46.0 regression that broke native text drag-and-drop (<a
href="https://redirect.github.com/facebook/lexical/pull/8842">#8842</a>)
and a couple of notable security hardening fixes. It also adds a handful
of new features, including an <code>MdastHtmlExtension</code> with
examples for authoring custom Markdown constructs (collapsibles,
<code>kbd</code>, alerts, footnotes), a customizable Yjs shared-type
root name for collaborative editing, and new table row manipulation
helpers.</p>
<h2>New APIs &amp; Features</h2>
<ul>
<li><a
href="https://lexical.dev/docs/api/modules/lexical_table"><code>@lexical/table</code></a>
— Added <code>$moveTableRow</code> for reordering table rows, plus the
previously missing <code>$unmergeCellNode</code> export (<a
href="https://redirect.github.com/facebook/lexical/pull/8833">#8833</a>)</li>
<li><a
href="https://lexical.dev/docs/api/modules/lexical_yjs"><code>@lexical/yjs</code></a>
/ <a
href="https://lexical.dev/docs/api/modules/lexical_react"><code>@lexical/react</code></a>
— The Yjs shared-type root name is now customizable, so Lexical can
share a Yjs document with other content that uses a different root key
(<a
href="https://redirect.github.com/facebook/lexical/pull/8841">#8841</a>)</li>
<li><a
href="https://lexical.dev/docs/api/modules/lexical_extension"><code>@lexical/extension</code></a>
/ <a
href="https://lexical.dev/docs/api/modules/lexical_mdast"><code>@lexical/mdast</code></a>
— Added <code>MdastHtmlExtension</code> and Markdown custom-construct
examples (collapsible sections, <code>kbd</code>, alerts, footnotes)
demonstrating how to extend the Markdown ↔ mdast pipeline. See the <a
href="https://lexical.dev/docs/serialization/markdown-mdast">Markdown
&amp; mdast serialization guide</a> (<a
href="https://redirect.github.com/facebook/lexical/pull/8826">#8826</a>)</li>
</ul>
<h2>Notable Fixes</h2>
<p><strong>Drag &amp; drop (fix for v0.46.0 regression)</strong></p>
<ul>
<li>Don't cancel <code>dragover</code> for text drags, so native drops
work again (<a
href="https://redirect.github.com/facebook/lexical/pull/8842">#8842</a>)</li>
</ul>
<p><strong>Security</strong></p>
<ul>
<li><code>LinkNode.sanitizeUrl()</code> now fails closed on unparseable
URLs, preventing a potential XSS vector (<a
href="https://redirect.github.com/facebook/lexical/pull/8846">#8846</a>)</li>
<li>Fixed a <code>serialize-javascript</code> dependency vulnerability
(<a
href="https://redirect.github.com/facebook/lexical/pull/8803">#8803</a>)</li>
</ul>
<p><strong>Markdown &amp; code</strong></p>
<ul>
<li>Roundtrip overlapping inline formats correctly through
mdast/Markdown (<a
href="https://redirect.github.com/facebook/lexical/pull/8825">#8825</a>)</li>
<li>Force re-tokenization after an async language load so highlighting
appears once the grammar is ready (<a
href="https://redirect.github.com/facebook/lexical/pull/8830">#8830</a>)</li>
</ul>
<p><strong>Tables</strong></p>
<ul>
<li>Auto-scroll while drag-selecting cells past the visible edge (<a
href="https://redirect.github.com/facebook/lexical/pull/8822">#8822</a>)</li>
<li>Enable table copy in read-only mode (<a
href="https://redirect.github.com/facebook/lexical/pull/8845">#8845</a>)</li>
</ul>
<p><strong>Lists &amp; character limit</strong></p>
<ul>
<li>Backspace at the start of a list item now outdents or converts to a
paragraph (<a
href="https://redirect.github.com/facebook/lexical/pull/8829">#8829</a>)</li>
<li>Merge adjacent <code>OverflowNode</code>s in
<code>useCharacterLimit</code> (<a
href="https://redirect.github.com/facebook/lexical/pull/8831">#8831</a>)</li>
<li>Count block separators when wrapping character-limit overflow (<a
href="https://redirect.github.com/facebook/lexical/pull/8840">#8840</a>)</li>
</ul>
<p><strong>Links &amp; selection</strong></p>
<ul>
<li>Disable link opening for disabled autolinks (<a
href="https://redirect.github.com/facebook/lexical/pull/8839">#8839</a>)</li>
<li>Skip <code>scrollIntoViewIfNeeded</code> when the selection rect is
above the editor, fixing a Safari RTL caret jump (<a
href="https://redirect.github.com/facebook/lexical/pull/8848">#8848</a>)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>[lexical-mdast][lexical-markdown] Bug Fix: Roundtrip overlapping
inline formats by <a
href="https://github.com/etrepum"><code>@​etrepum</code></a> in <a
href="https://redirect.github.com/facebook/lexical/pull/8825">facebook/lexical#8825</a></li>
<li>[lexical-table][lexical-playground] Bug Fix: Auto-scroll while
drag-selecting cells past the visible edge by <a
href="https://github.com/JohnJunior"><code>@​JohnJunior</code></a> in <a
href="https://redirect.github.com/facebook/lexical/pull/8822">facebook/lexical#8822</a></li>
<li>[lexical-code-shiki] Bug Fix: force re-tokenize after async language
load by <a
href="https://github.com/ochevallier"><code>@​ochevallier</code></a> in
<a
href="https://redirect.github.com/facebook/lexical/pull/8830">facebook/lexical#8830</a></li>
<li>[lexical-react] Bug Fix: Merge adjacent OverflowNodes in
useCharacterLimit by <a
href="https://github.com/mayrang"><code>@​mayrang</code></a> in <a
href="https://redirect.github.com/facebook/lexical/pull/8831">facebook/lexical#8831</a></li>
<li>Open playground links in a new tab by <a
href="https://github.com/potatowagon"><code>@​potatowagon</code></a> in
<a
href="https://redirect.github.com/facebook/lexical/pull/8837">facebook/lexical#8837</a></li>
<li>[lexical-rich-text][lexical-plain-text] Bug Fix: don't cancel
dragover for text drags so native drops work again by <a
href="https://github.com/etrepum"><code>@​etrepum</code></a> in <a
href="https://redirect.github.com/facebook/lexical/pull/8842">facebook/lexical#8842</a></li>
<li>[lexical-link] Bug Fix: disable link opening for disabled autolink
in… by <a
href="https://github.com/ochevallier"><code>@​ochevallier</code></a> in
<a
href="https://redirect.github.com/facebook/lexical/pull/8839">facebook/lexical#8839</a></li>
<li>[lexical-table] Feature: Add $moveTableRow function &amp; Add
missing export for $unmergeCellNode by <a
href="https://github.com/hamo-o"><code>@​hamo-o</code></a> in <a
href="https://redirect.github.com/facebook/lexical/pull/8833">facebook/lexical#8833</a></li>
<li>[lexical-list] Bug Fix: Backspace at start of list item outdents or
converts to paragraph by <a
href="https://github.com/mayrang"><code>@​mayrang</code></a> in <a
href="https://redirect.github.com/facebook/lexical/pull/8829">facebook/lexical#8829</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/lexical/blob/main/CHANGELOG.md">@​lexical/link's
changelog</a>.</em></p>
<blockquote>
<h2>v0.48.0 (2026-07-16)</h2>
<ul>
<li>lexical-reactlexical-table Bug Fix Enable table copy in read-only
mode (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8845">#8845</a>)
mayrang</li>
<li>lexical-extensionlexical-mdastdev-mdast-editor-example Feature Add
MdastHtmlExtension and Markdown custom-construct examples (collapsible,
kbd, alerts, footnotes) (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8826">#8826</a>)
Bob Ippolito</li>
<li>Fix fail closed in LinkNode.sanitizeUrl() on unparseable URLs (XSS)
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8846">#8846</a>)
xiezhenjia-meta</li>
<li>lexical Chore Fix serialize-javascript package dependency
vulnerability (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8803">#8803</a>)
vijay ojha</li>
<li>lexical-react Bug Fix Count block separators in character limit
overflow wrapping (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8840">#8840</a>)
mayrang</li>
<li>lexical-yjslexical-react Feature Customizable Yjs shared-type root
name (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8841">#8841</a>)
mayrang</li>
<li>lexical-list Bug Fix Backspace at start of list item outdents or
converts to paragraph (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8829">#8829</a>)
mayrang</li>
<li>lexical-table Feature Add moveTableRow function Add missing export
for unmergeCellNode (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8833">#8833</a>)</li>
<li>lexical-link Bug Fix disable link opening for disabled autolink in
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8839">#8839</a>)
Olivier Chevallier</li>
<li>lexical-rich-textlexical-plain-text Bug Fix dont cancel dragover for
text drags so native drops work again (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8842">#8842</a>)
Bob Ippolito</li>
<li>Open playground links in a new tab (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8837">#8837</a>)
Sherry</li>
<li>lexical-react Bug Fix Merge adjacent OverflowNodes in
useCharacterLimit (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8831">#8831</a>)
mayrang</li>
<li>lexical-code-shiki Bug Fix force re-tokenize after async language
load (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8830">#8830</a>)
Olivier Chevallier</li>
<li>lexical-tablelexical-playground Bug Fix Auto-scroll while
drag-selecting cells past the visible edge (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8822">#8822</a>)
Oleksandr Trukhnii</li>
<li>lexical-mdastlexical-markdown Bug Fix Roundtrip overlapping inline
formats (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8825">#8825</a>)
Bob Ippolito</li>
<li>v0.47.0 (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8821">#8821</a>)
Bob Ippolito</li>
<li>v0.47.0 Lexical GitHub Actions Bot</li>
</ul>
<h2>v0.47.0 (2026-07-10)</h2>
<ul>
<li>lexicallexical-rich-text Bug Fix Fix formatText toggle direction and
add SETTEXTFORMATCOMMAND (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8807">#8807</a>)
mayrang</li>
<li>scripts Bug Fix Let npm prompt for OTP when publishing bootstrap
stubs (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8820">#8820</a>)
Bob Ippolito</li>
<li>lexical-playground Bug Fix Clear inline font-size when converting to
heading (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8800">#8800</a>)
mayrang</li>
<li>lexical-tablelexical-playground Feature setTableRowIsHeader and
setTableColumnIsHeader utilities (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8815">#8815</a>)
mayrang</li>
<li>lexical-website Documentation Update Rewrite testing guide (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8811">#8811</a>)
mayrang</li>
<li>lexical-mdastlexical-rich-text Feature lexicalmdast, a
micromarkmdast-based alternative to lexicalmarkdown (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8794">#8794</a>)
Bob Ippolito</li>
<li>Make dependency-check resilient to transient registry errors (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8818">#8818</a>)
Gerard Rovira</li>
<li>lexical Refactor Move event module globals into per-editor
InputState (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8809">#8809</a>)
mayrang</li>
<li>lexical Bug Fix getDocument() should fall back to the global
document when there is no active editor (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8813">#8813</a>)
Sherry</li>
<li>lexical-playground Bug Fix Keep cell background color modal open on
first click (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8806">#8806</a>)
sahir</li>
<li>lexical-playground Bug Fix Use consistent default maxWidth for
markdown-imported images (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8810">#8810</a>)
mayrang</li>
<li>lexical-devtoolslexical-playground Chore Update flow, hermes, and
babel packages to latest (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8795">#8795</a>)
Bob Ippolito</li>
<li>Add a 7-day pnpm minimumReleaseAge to match the Dependabot cooldown
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8808">#8808</a>)
Gerard Rovira</li>
<li>lexical Chore Fix tmp package dependency vulnerability (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8802">#8802</a>)
vijay ojha</li>
<li>lexical Chore Add missing Flow type declarations (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8799">#8799</a>)
mayrang</li>
<li>lexical-markdown Feature Add generateNodesFromMarkdownString (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8789">#8789</a>)
mayrang</li>
<li>lexicallexical-playground Chore Refactor IME composition test
infrastructure and add browser-level coverage (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8793">#8793</a>)
mayrang</li>
<li>lexical-playground Bug Fix Use viewBox dimensions for unsized
Excalidraw output (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8798">#8798</a>)
mayrang</li>
<li>lexical-table Bug Fix Export insertTableRowAtNode and
insertTableColumnAtNode (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8791">#8791</a>)</li>
<li>lexical-playgroundlexical-website Feature Add Vercel Analytics and
Speed Insights (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8796">#8796</a>)
Gerard Rovira</li>
<li>lexicallexical-eslint-plugin Feature Add getDocument() API and
Shadow DOM lint enforcement (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8788">#8788</a>)
mayrang</li>
<li>scripts Bug Fix strip misplaced pure annotations from prod builds
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8786">#8786</a>)
Bob Ippolito</li>
<li>lexical Bug Fix deleteCharacter overwrites X11 PRIMARY selection via
Selection.modify (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8774">#8774</a>)
Bob Ippolito</li>
<li>lexical-playground Bug Fix Support Unicode URLs in autolink matcher
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8787">#8787</a>)
mayrang</li>
<li>lexical-table Feature Spread pasted TSV text across table cells (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8780">#8780</a>)
mayrang</li>
<li>Breaking Changelexical Bug Fix Preserve DOM element when composing
on segmented TextNode middle (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8784">#8784</a>)
mayrang</li>
<li>Breaking Changelexical-reactlexical-devtools-core Chore Drop React
17 support, baseline is now React 18 (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8782">#8782</a>)
Bob Ippolito</li>
<li>lexical-playgroundlexical Feature Ruby annotation node with floating
editor (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8741">#8741</a>)
mayrang</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/facebook/lexical/commit/284b7491d014c412a11ecc8e4b8ea8e09e07f7e9"><code>284b749</code></a>
v0.48.0</li>
<li><a
href="https://github.com/facebook/lexical/commit/365516c5fcdcc141561dcbb2eb43b707b48dd5b8"><code>365516c</code></a>
Fix: fail closed in LinkNode.sanitizeUrl() on unparseable URLs (XSS) (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8846">#8846</a>)</li>
<li><a
href="https://github.com/facebook/lexical/commit/71562324c7d2154f64d79f6d20803f67b9bd9c11"><code>7156232</code></a>
[lexical-link] Bug Fix: disable link opening for disabled autolink in…
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8839">#8839</a>)</li>
<li><a
href="https://github.com/facebook/lexical/commit/e4b7cc3f420226059c8aa30df6e89bd5fadbea90"><code>e4b7cc3</code></a>
v0.47.0 (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8821">#8821</a>)</li>
<li><a
href="https://github.com/facebook/lexical/commit/a7666ab11f5e8c674a3f5ca8a83d2e92f1b171d0"><code>a7666ab</code></a>
[*][lexical-devtools][lexical-playground] Chore: Update flow, hermes,
and bab...</li>
<li><a
href="https://github.com/facebook/lexical/commit/e649ab28b7e2dd58c1b4798c446e611f54356518"><code>e649ab2</code></a>
[lexical][lexical-eslint-plugin] Feature: Add $getDocument() API and
Shadow D...</li>
<li><a
href="https://github.com/facebook/lexical/commit/7b76175cc96d99489c2f3c792db193cf2d9bc127"><code>7b76175</code></a>
[lexical-playground] Bug Fix: Support Unicode URLs in autolink matcher
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8787">#8787</a>)</li>
<li><a
href="https://github.com/facebook/lexical/commit/62a4b30f382b4dc60cacd1a9d753a2d1f44d9f5e"><code>62a4b30</code></a>
[lexical][*] Feature: registerEventListener / registerEventListeners DOM
help...</li>
<li><a
href="https://github.com/facebook/lexical/commit/d04ea9e83609bcbdf729287010b6a297ee6a0ac5"><code>d04ea9e</code></a>
[lexical-a11y][lexical-react][lexical-playground][lexical-website]
Feature: @...</li>
<li><a
href="https://github.com/facebook/lexical/commit/51d47b77e852e646091ff5cb7675264fd9aa234e"><code>51d47b7</code></a>
[lexical] Bug Fix: Clean up trailing shadow root after select-all delete
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical-link/issues/8751">#8751</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/facebook/lexical/commits/v0.48.0/packages/lexical-link">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@lexical/link&package-manager=npm_and_yarn&previous-version=0.46.0&new-version=0.48.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 12:03:36 -05:00
DottaandPaperclip 53d6297f75 fix(ui): simplify external object labels and star controls (#9929)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents and their work
> - Operators rely on task detail properties and header actions to scan
linked resources and make quick decisions
> - External GitHub objects used a long pull-request label and repeated
mention counts that added visual noise without adding state
> - The task-detail star action also rendered as a labelled outline
button, unlike the compact star controls used elsewhere
> - These inconsistencies made dense task-detail surfaces slower to scan
and broke Paperclip's content-first visual language
> - This pull request shortens the GitHub pull-request label, removes
duplicate mention-count decoration, and aligns the detail star action
with the icon-only control pattern
> - The benefit is a calmer, more consistent task-detail experience with
accessible labels preserved for assistive technology

## Linked Issues or Issue Description

No matching public GitHub issue or open pull request was found.

**What happened?**

On the task detail surface, linked GitHub pull requests were labelled
`Github Pull Request` and could show a repeated `×N` mention count. The
detail-header star control used a labelled outline button rather than
the compact icon-only star pattern.

**Expected behavior**

Linked pull requests should use the concise `Github PR` label without
duplicate mention-count decoration, and the detail star action should
render as an accessible icon-only ghost button consistent with
neighboring controls.

**Steps to reproduce**

1. Open a task with a linked GitHub pull request mentioned more than
once.
2. Inspect the external-object property label and value row.
3. Inspect the star action in the task detail header.

**Paperclip version or commit:** `230126d80b` (`master` at preparation
time)

**Deployment / installation:** Local development, built from source.

**Scope:** Core UI; not adapter-specific, database-related, or
configuration-related.

## What Changed

- Render GitHub pull-request property labels as `Github PR`.
- Remove repeated external-object mention-count decoration from property
values.
- Render detail-header star controls as icon-only ghost buttons while
preserving `aria-label`, pressed, busy, error, and tooltip states.
- Expand component coverage for concise labels, duplicate-count
suppression, visual variants, and accessible star actions.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/IssueProperties.test.tsx
src/components/StarToggle.test.tsx` — 54 tests passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- Visual review (before/after plus normal, starred, pending, and error
states):
https://htmlpreview.github.io/?https://gist.githubusercontent.com/cryppadotta/9688862a8826c1134aa2b2e8c16509d8/raw/45cb4921851f8968b21e7490e0d705161a9e165d/star-toggle-review.html
- `pnpm check:token-gates` — reports five existing `#9627` violations in
files unchanged by this PR; the same values are present on `master`.

## Risks

- Low risk: changes are limited to task-detail presentation and tests.
- The star action remains fully accessible through its existing ARIA
label and tooltip, but it no longer displays visible text.
- External-object mention counts remain available in data; only the
redundant property-row decoration is removed.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5.3 Codex, tool-enabled coding agent with repository
and shell access.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-21 09:14:29 -05:00
DottaandPaperclip 59eee4829c fix(inbox): stop archived items from resurfacing (#9931)
## Thinking Path

> - Paperclip is the control plane operators use to coordinate AI-agent
companies and review work needing attention.
> - The Inbox is the operator-facing surface that aggregates tasks
requiring attention across server state and shared client polling.
> - Archiving a task optimistically removed it, but ordinary background
activity and stale polling responses could make it reappear seconds
later.
> - The server therefore needs to distinguish genuine user-attention
events from routine agent/system activity.
> - The client also needs a bounded local archive guard across every
Inbox query path while the server mutation and in-flight polls settle.
> - This pull request fixes both resurrection paths and adds
race-focused regression coverage.
> - The benefit is stable archive behavior without hiding a genuine
archive failure after reconciliation or reload.

## Linked Issues or Issue Description

### Pre-submission checklist

- [x] Searched existing open and closed issues and pull requests; no
duplicate implementation was found.
- [x] Reproduced on `master` before this branch.
- [x] Confirmed this is a Paperclip core bug, not adapter or provider
behavior.

### What happened?

Archiving an Inbox task hid it optimistically, then background refresh
activity could insert it back into the list seconds later.

### Expected behavior

A successfully archived task remains hidden during normal polling. A
genuine failed archive may become visible again after reconciliation or
reload.

### Steps to reproduce

1. Open Inbox with a visible task.
2. Archive the task.
3. Wait for shared polling or routine agent activity to refresh task
data.
4. Observe the archived task reappear without a hard page refresh.

### Paperclip version or commit

`master` before this branch.

### Deployment mode

Built from source using the local development application.

### Installation method

Built from source (`pnpm`).

### Agent adapter(s) involved

Not adapter-specific; this is a core Inbox bug.

### Database mode

Not database-mode-specific.

### Access context

Board (human operator).

### Additional context

The failure had independent server and client causes: routine activity
could resurface archived rows server-side, while stale shared-poll
responses could bypass optimistic client removal.

## What Changed

- Restrict server-side Inbox resurfacing to explicit user-attention
events rather than any issue activity write.
- Add a bounded client-side archive guard with confirmation, failure
restoration, and cache reconciliation behavior.
- Apply the guard to Inbox rendering, badge counts, optimistic cache
updates, and shared-poll result application.
- Classify the generic compact Inbox query so stale shared-poll data
cannot bypass the guard.
- Add server visibility-matrix tests and UI race-condition regression
tests.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/hooks/useSharedPolling.test.ts src/lib/inboxArchiveCache.test.ts
src/pages/Inbox.test.tsx` — 25 passed.
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/issues-service.test.ts` — 107 passed.
- Branch rebased cleanly onto current `origin/master` before push.

## Risks

- Low-to-moderate behavioral risk: resurfacing is intentionally
narrower, so the server tests cover human comments, mentions,
interactions, and status transitions that must still regain attention.
- The client guard is bounded and cleared on mutation failure, limiting
the risk of hiding a task whose archive did not persist.
- No schema, migration, public API, workflow, dependency-lock, or
visual-token changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude via Claude Code (`claude_local`; prior
implementation/review run, exact underlying model ID and context window
were not retained in the handoff metadata), with repository tool use and
test execution.
- OpenAI `gpt-5.5` via Codex CLI for final review repair and PR
preparation, with reasoning, repository editing, GitHub tooling, and
code execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and
linked/described the result above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip task identifier
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation where needed; no
documentation change is required for this bug fix
- [x] I have considered and documented risks above
- [x] All Paperclip-authored commits include the required co-author
trailer

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-21 08:13:14 -05:00
DottaandPaperclip 26890650b2 test(ui): cover secret creation within folders (#9927)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Secrets UI lets operators navigate slash-delimited secret names
as folders
> - PR #9913 shipped create-in-folder behavior for company and per-user
secrets
> - The production behavior is already on master, but several
create-in-folder interaction paths lack retained regression coverage
there
> - Without that coverage, prefix composition, derived keys, prefix
removal, and staged empty folders could regress unnoticed
> - This pull request adds focused render tests without changing
production behavior
> - The benefit is safer maintenance of the folder-based secrets
workflow with a small, reviewable patch

## Linked Issues or Issue Description

- Refs #9913

## What Changed

- Added render coverage for creating a company secret from a folder and
deriving its key from the full slash-delimited name.
- Added coverage for per-user secret prefixes and exposing the full name
when the prefix chip is removed.
- Added coverage for inline folder-name validation and URL-backed
staging of an empty folder.

## Verification

- `env -u PAPERCLIP_IN_WORKTREE -u PAPERCLIP_WORKTREE_NAME -u
PAPERCLIP_CONFIG -u PAPERCLIP_HOME -u PAPERCLIP_INSTANCE_ID -u
PAPERCLIP_CONTEXT pnpm exec vitest run
ui/src/pages/Secrets.render.test.tsx` — 29 tests passed.
- `pnpm check:token-gates` — reports five existing `#9627` literals in
unrelated files; this PR changes no token-gated component code and
introduces no new violation.

## Risks

- Low risk: test-only change with no production, API, schema, migration,
dependency, or runtime behavior changes.
- The tests exercise existing DOM interactions and may need updates if
the Secrets creation UI copy or controls intentionally change.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex CLI managed coding agent with repository inspection, code
execution, Git/GitHub, and Paperclip API tools. The managed harness does
not expose the exact underlying model ID or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
— the assigned execution branch name is fixed by the task
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes — no
documentation change is needed for test-only coverage
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-21 08:08:55 -05:00
DottaandPaperclip b9f4073a13 fix(ui): use searchable agent picker for secret access (#9918)
## Thinking Path

> - Paperclip is the control plane people use to manage AI-agent
companies.
> - Operators need to grant secrets to specific agents safely and
efficiently.
> - The secrets access sheet previously used a native select while
similar agent-assignment surfaces use a searchable picker.
> - That inconsistency makes finding an agent slow and error-prone as
companies grow.
> - This pull request reuses the shared agent picker behavior for
single-agent secret access grants.
> - The benefit is a consistent, searchable selection experience without
changing secret-access semantics.

## Linked Issues or Issue Description

Refs #9797

**Problem / motivation:** The in-sheet agent access form introduced in
#9797 renders every grantable agent in a native select. In companies
with many agents, operators cannot filter by name or title and the
experience differs from other agent-selection surfaces.

**Proposed solution:** Add a single-select variant beside the existing
`AgentMultiSelect`, then use it in the secret access grant form.

**Alternatives considered:** Keeping a native select would preserve less
code but would not scale or align with existing searchable agent
selection.

**Roadmap alignment:** This is a focused usability fix for an existing
core control-plane surface and does not overlap an unstarted roadmap
initiative.

## What Changed

- Added `AgentSelect`, a searchable single-agent popover that filters by
agent name and title.
- Replaced the secret access form's native select with the shared
searchable picker.
- Added focused coverage for filtering, selecting, callback behavior,
and popover closure.

## Verification

- `pnpm exec vitest run ui/src/components/AgentMultiSelect.test.tsx` —
passes (3 tests).
- `pnpm --filter @paperclipai/ui typecheck` — passes.
- `pnpm check:token-gates` — branch adds no violations; the command
currently fails on five unchanged `#9627` literals already present on
`master`.
- Manual: open Secrets, choose a secret, add agent access, filter by
agent name or title, select the result, and grant access.

## Risks

- Low risk: the change is limited to agent selection UI and preserves
the existing grant request payload.
- The new picker depends on the existing popover/input primitives and
resets its filter when closed.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5-series coding agent (exact runtime model ID and
context-window size are not exposed), with reasoning, repository tool
use, terminal execution, and GitHub CLI capabilities.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-20 18:00:34 -05:00
b94907f8af feat(ui): navigate slash-named secrets as folders (#9913)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators store company and user secrets under human-readable names
> - Slash-delimited names already express useful hierarchy, but the
Secrets page previously rendered them as one flat list
> - Large secret collections therefore became harder to scan, navigate,
and create within consistently named groups
> - A client-derived folder model preserves the existing server contract
while making those names navigable
> - This pull request adds folder browsing, URL-addressable paths,
global search, and create-in-folder behavior without adding folder
records
> - The benefit is a more scalable secrets workflow with no migration or
API compatibility risk

## Linked Issues or Issue Description

Slash-delimited secret names such as `dev/github/oauth/clientid`
currently appear as raw flat rows. This change treats name prefixes as
client-side navigation folders on the main Secrets tab while leaving
stored names, API contracts, validation, and the database unchanged.

- Wireframes and interaction specification:
https://pages.paperclip.ing/pap-14698-secrets-folders/
- Folder paths are derived only from secret names; there is no
server-side folder entity or data-model change.

## What Changed

- Added pure secret-path utilities for normalized segments, breadcrumbs,
nested folder listings, counts, and leaf/path rendering.
- Added a Folders/Flat view to the main Secrets tab with folder-first
sorting, breadcrumbs, empty-folder states, filters, and global search
results.
- Added URL navigation through `?path=<normalized/path>` so deep links,
reload, browser Back, and new-tab folder navigation work.
- Persisted the preferred view in `localStorage` under
`paperclip.secrets.viewMode`; an explicit `?path=` deep link takes
precedence for that visit.
- Added create-in-folder behavior with a removable prefix chip, staged
New folder paths, inline segment validation, and full-name key
derivation.
- Kept My secrets flat while rendering slash-delimited names with muted
paths and emphasized leaves.
- Added unit/render coverage for path helpers, folder navigation, and
create-in-folder behavior.

## Verification

- `pnpm exec vitest run ui/src/pages/secrets/secret-path.test.ts
ui/src/pages/Secrets.render.test.tsx` — 35 tests passed.
- `pnpm -r typecheck` — passed.
- `pnpm test:run` — server suite passed 2,707 tests and UI suite passed
3,022 tests; one unrelated CLI doctor test was environment-sensitive
because this agent inherited AWS variables.
- `env -u AWS_PROFILE -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u
AWS_SESSION_TOKEN -u AWS_REGION -u AWS_DEFAULT_REGION pnpm exec vitest
run cli/src/__tests__/secrets.test.ts` — 8 tests passed.
- `pnpm build` — passed.
- `pnpm check:token-gates` — feature files are clean; the command
reports five existing `#9627` color literals outside this diff.

## Risks

- Low data risk: folders are derived client-side from existing names,
with no schema, migration, API, or stored-name changes.
- URL behavior changes only the main Secrets tab and uses the additive
`?path=` contract.
- View preference is browser-local and scoped to the
`paperclip.secrets.viewMode` key.
- Renaming or deleting the last secret under an open prefix
intentionally leaves the user on an empty-folder state instead of
redirecting.
- “Move to folder…” bulk prefix rename remains deferred because it is a
multi-secret mutation with separate conflict and partial-failure
semantics.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI `gpt-5.5` via Codex CLI for PR preparation, verification,
GitHub/Paperclip tool use, and codebase analysis; the managed harness
does not expose the active context-window size.
- Anthropic Claude Opus 4.8 (1M context) and Claude Fable 5 assisted
earlier implementation/design commits, as recorded in their commit
trailers; both used repository and code-editing tools.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
— the assigned shared execution branch name is fixed for this work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-20 16:11:35 -05:00
f12bb27bcd feat: make issue monitors visible across task surfaces (#9783)
## Thinking Path

> - Paperclip is the open source control plane people use to supervise
AI-agent companies.
> - Operators need task execution state to be visible where they read,
reply to, and manage an issue.
> - Scheduled monitor state was easy to miss because it lived in a
description-area card and used inconsistent, mostly static time copy.
> - The task page, composer, retry card, and properties panel therefore
needed one shared monitor-state and countdown language.
> - This pull request adds shared live-ticking time utilities, moves
monitor status into a top-of-page banner and composer strip, and
redesigns the properties row with complete read-only details.
> - The benefit is that operators can immediately understand when an
agent resumes, why it is waiting, and how to act without hunting across
the page.

## Linked Issues or Issue Description

Issue monitors can schedule a future agent check, retry, or wake, but
the UI did not present that state consistently or prominently. The
existing description-area activity card competed with issue content, the
composer did not explain that replying wakes the agent early, compact
properties copy truncated important details, and relative times did not
share a live two-unit formatter.

This change makes scheduled monitor state visible and consistent across
the issue header, reply composer, properties panel, and scheduled-retry
card. Related prior server-side recovery visibility work: #9629
(distinct scope).

## What Changed

- Added shared two-unit monitor ETA/offset formatters and a live-ticking
countdown hook, including compact absolute-time rules for Today,
weekday, and cross-year dates.
- Replaced the description-area monitor activity card with a top-of-page
status banner and added an inline composer strip that explains replies
wake the agent before the scheduled check.
- Redesigned the properties Monitor row as readable two-line copy with
attempt state, due/overdue/cleared wording, click-to-edit behavior, and
a hover/tap details tooltip.
- Adopted the shared two-unit formatting in the scheduled-retry card and
added focused coverage for monitor formatting, state transitions,
visibility, and controls.
- Added the approved wireframe package and published reference:
https://pages.paperclip.ing/pap-14557-monitor-visibility/

## Verification

- `pnpm vitest run ui/src/lib/issue-monitor.test.tsx
ui/src/components/IssueMonitorBanner.test.tsx
ui/src/components/IssueProperties.test.tsx` — 3 files, 74 tests passed.
- `pnpm -r typecheck` — passed.
- `pnpm build` — passed with existing Vite optimization/chunk-size
warnings.
- UX review approved the rendered real components across desktop/mobile,
light/dark, and the scheduled/retrying/due/overdue/cleared/none state
matrix.
- QA passed 6/6 criteria in Chromium, including a live countdown
transition without refresh. Review evidence included the P2 banner
state-matrix screenshot and the P3 properties-row and details-tooltip
screenshots, plus a dark-mode capture.
- `pnpm check:token-gates` currently reports five pre-existing `#9627`
comment literals on `origin/master`; this branch introduces none of
those literals or any new token violation.

## Risks

- Low-to-moderate UI behavior risk: monitor copy and placement change
across several issue surfaces, but all derive from one shared state
builder and focused tests cover the state matrix.
- Countdown rendering wakes once per minute while a visible monitor is
scheduled; the hook is limited to active monitor surfaces and stops when
hidden.
- No database, API contract, migration, telemetry, or authorization
behavior changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, `gpt-5.6-sol`; context-window metadata was unavailable
in this runtime; reasoning, repository tool use, command execution, and
test execution enabled. Earlier implementation commits were assisted by
Claude Fable 5 and Claude Opus 4.8 (1M context), as credited in their
commit trailers.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-18 14:39:37 -05:00
67616dd7ea Rework secrets dialog and add in-sheet agent access (#9797)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents and the credentials those agents need for work.
> - The secrets UI is responsible for making credential creation
understandable and for showing where credentials are used.
> - The create flow previously exposed an editable generated key too
early, used an unnatural field order, and rendered uneven provider tab
rows.
> - The detail sheet also lacked an in-context way to see and manage
which agents reference a selected secret.
> - This pull request makes the create dialog follow a predictable
name-to-value flow and adds agent access management directly to the
secret details sheet.
> - The benefit is a clearer secrets workflow with fewer accidental key
edits and less navigation when granting or revoking agent access.

## Linked Issues or Issue Description

**Subsystem affected:** `ui/` — React + Vite board UI

**Problem or motivation:** Creating a secret currently makes its
generated key look immediately editable, places fields in an awkward
keyboard order, and applies provider-tab overrides that produce uneven
rows. After creation, operators cannot inspect or change agent access
from the selected secret's detail sheet.

**Proposed solution:** Generate the key from the path-style name and
keep it read-only until an explicit Edit action; place Value directly
after Name; use the standard tab sizing; and add an Agent access section
that reads and updates `secret_ref` / `user_secret_ref` environment
bindings through agent adapter configuration.

**Alternatives considered:** Keeping access management only on agent
configuration screens was rejected because it hides a secret-centric
question—“which agents can use this?”—and requires repetitive
navigation. Keeping the key always editable was rejected because the
generated value should be the safe default.

**Roadmap alignment:** No matching item was found in `ROADMAP.md`; this
is a focused usability and access-management improvement to the existing
secrets surface.

**Additional context:** GitHub search found no duplicate PR for this
dialog and in-sheet access change. PR #9321 also mentions user-secret
resolution but addresses unrelated skills-route behavior.

## What Changed

- Auto-generate the create-secret key from Name, keep it read-only by
default, and expose an explicit Edit action.
- Use a path-style Name placeholder (`/dev/foo/bar`) and place Value
immediately after Name for natural keyboard navigation.
- Remove tab sizing/whitespace overrides that caused uneven provider-tab
row heights.
- Add an Agent access section to the Details tab that lists referencing
agents and grants or revokes `secret_ref` / `user_secret_ref`
environment bindings in place.
- Cover company secrets and each-user definitions with focused render
tests.

## Verification

- `pnpm exec vitest run ui/src/pages/Secrets.render.test.tsx` — 17/17
passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm check:token-gates` — changed files are clean; the
repository-wide command currently reports five pre-existing `#9627`
violations in unrelated files (`Sidebar.tsx`, `Inbox.tsx`,
`IssueDetail.tsx`, `Issues.tsx`, and `Routines.tsx`).
- Additional secrets verification completed during implementation: 35/35
adjacent secrets tests passed, and the flow was checked in a real
browser in light and dark themes.

## Risks

- Agent access mutations update adapter environment configuration, so
malformed legacy env entries could affect how a binding is displayed or
revoked.
- Each-user definitions use `user_secret_ref` rather than `secret_ref`;
focused tests cover selecting the correct binding type.
- No database or API contract changes are included.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude Fable 5 assisted with the implementation using
repository-aware code editing and test execution.
- OpenAI GPT-5.5 via Codex CLI assisted with PR preparation, branch
hygiene, focused verification, GitHub operations, and review/check
loops.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-18 14:39:06 -05:00
Dotta 83765f08d1 fix(ui): reap React 19.2 performance-track measures (memory leak) (#9827)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its web UI is a long-lived single-page app; users leave tabs open
for hours/days
> - We chased multi-GB tab memory growth through several fixes (#9569,
#9624, #9627, #9701) that cut real churn — but the footprint kept
climbing
> - A heap-snapshot diff on a 12-hour tab finally showed the true cause:
of 13.2M heap nodes, **12.1M were `PerformanceMeasure` objects** — React
19.2 emits a `performance.measure()` per component render for its
DevTools "Performance Tracks" and never clears them
> - These are native objects, so `performance.memory` never reported
them (it read a flat ~74 MB while the real heap was ~308 MB), which is
why our earlier heap/DOM sampling looked stable while the footprint
ballooned
> - This pull request periodically clears the User Timing measure
buffer, since nothing in the app consumes it
> - The benefit is that long-lived tabs stop accumulating millions of
native `PerformanceMeasure` objects, eliminating the remaining unbounded
growth

## Linked Issues or Issue Description

No public GitHub issue exists; describing inline per CONTRIBUTING.md →
"Link Issues or Describe Them In-PR", following the bug report template.
This is the root-cause fix for the memory growth chased in #9569 / #9624
/ #9627 / #9701.

**What happened?**

Long-lived browser tabs grew to multiple GB of memory footprint over
hours/days. A heap snapshot of a 12h tab showed **13.2M nodes, of which
12.1M were `PerformanceMeasure`** (vs ~1.0M total nodes on a fresh tab).
Live capture showed **~340 `performance.measure()` calls/sec**, named
after React components with a `detail.devtools` payload — React 19.2's
"Performance Tracks". Nothing ever clears them, so they accumulate
without bound.

**Expected behavior**

A long-lived tab should not accumulate millions of `PerformanceMeasure`
entries. Idle/long-running tabs should hold a bounded footprint.

**Steps to reproduce**

Open the app (React 19.2 production build), leave a tab open with normal
activity, and run `performance.getEntriesByType('measure').length`
periodically — it climbs unbounded (12.3M after ~12h).
`performance.clearMeasures()` drops it to near-zero and frees the
memory.

**Paperclip version or commit**

Branch `fix/react-perf-measure-leak`, off `master` (after #9701).

**Deployment mode**

Local dev (`pnpm dev` build served by the dev instance), web UI. React
19.2.7. Not adapter-specific.

## What Changed

- **`ui/src/lib/perf-measure-reaper.ts` (new)** —
`startPerfMeasureReaper(intervalMs = 10_000)` clears
`performance.clearMeasures()` on a timer and returns a stop function. It
never calls `getEntriesByType('measure')` (which would materialize the
huge buffer). Honors a `window.__paperclipKeepPerfMeasures = true`
opt-out so a developer recording a React Performance Track in DevTools
can keep the entries.
- **`ui/src/main.tsx`** — start the reaper at app boot.
- Only *measures* are cleared — React's tracks pass explicit start/end
times and leave no marks, and the app doesn't use the User Timing API at
all (verified), so nothing else is affected.

## Verification

- **Root cause proven** by heap-snapshot diff: fresh tab ~1.0M nodes vs
12h tab 13.2M nodes, 12.1M of them `PerformanceMeasure`; live capture
showed ~340 measures/sec with `detail.devtools` and React component
names.
- **Fix proven live**: `performance.clearMeasures()` on the aged tab
dropped the buffer from **12,418,266 → 1,500** and reclaimed the memory
(heap `perf.memory` 308 → 269 MB, plus the ~12M native objects, which
are the bulk of the footprint).
- `vitest`: `perf-measure-reaper.test.ts` — interval clearing, `stop()`,
opt-out flag, and no-API no-op. All pass.
- `tsc -b` clean.

## Risks

Very low, client-only.
- Clearing the User Timing measure buffer only affects the DevTools
Performance panel's React track *history*; normal users never consume
it. Developers who want to record it can set
`window.__paperclipKeepPerfMeasures = true`.
- Only `performance.clearMeasures()` is called (not `clearMarks`), so
any mark-based timing elsewhere is untouched; a grep confirmed the app
makes no `performance.mark()/measure()` calls of its own.
- Adds exactly one 10s interval (negligible), and `clearMeasures()` does
not materialize the buffer.

Note: this is a React 19.2 upstream behavior (its performance tracks are
emitted in the production build and never cleared). If React later gates
or clears them, this reaper can be removed.

## Model Used

- **Provider:** Anthropic, via the Claude Code CLI.
- **Model:** Claude Opus 4.8 (`claude-opus-4-8`).
- **Reasoning mode:** Extended thinking enabled.
- **Capabilities used:** tool use (shell, file editing), the Chrome
DevTools MCP to reproduce and profile, and a streaming heap-snapshot
parser to identify the `PerformanceMeasure` accumulation.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above (continues #9701; no duplicates)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have considered and documented any risks above
- [ ] I have updated relevant documentation to reflect my changes (N/A —
no user-facing docs; rationale documented inline)
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-18 14:05:25 -05:00
DottaandPaperclip 051ae4d102 feat: restore decision training library and inspector (#9779)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies and supervise governed work.
> - Decisions capture high-value operator judgment, and the
decision-training foundation merged in #9702 freezes that evidence for
later evaluation and learning.
> - Operators still need the UI from the closed stacked PR #9718 to
intentionally capture examples and inspect the resulting dataset.
> - GitHub automatically closed #9718 when its stacked base branch was
deleted after #9702 merged, leaving the server foundation on `master`
without the corresponding UI.
> - This pull request restores the final UI and its still-required
supporting API fields directly on current `master`, while excluding the
obsolete migration and duplicated server-foundation diffs.
> - The benefit is a reviewable replacement PR that preserves the
completed decision-training workflow without replaying stale stack
history.

## Linked Issues or Issue Description

- Refs #9718
- Refs #9702

## What Changed

- Restored the top-level `/training` library and record inspector with
search, filters, JSONL export, notes editing, and evidence tabs.
- Restored the Decisions-row training affordance and capture drawer,
including preview, provenance, deletion, cache refresh, and approval
consistency behavior.
- Restored the shared types and focused server support needed by the UI
without reintroducing decision-training migrations or the already-merged
server foundation.
- Restored focused UI and attention-service tests from the final #9718
state.
- Credit to the authors and reviewers of #9718; this recovery
transplants their final reviewed delta after the stacked base deletion.

## Verification

- `pnpm exec vitest run ui/src/pages/Training.test.tsx
ui/src/components/DecisionTrainingDrawer.test.tsx
ui/src/components/AttentionQueueRow.test.tsx
server/src/__tests__/attention-service.test.ts
server/src/__tests__/decision-training.test.ts` — 5 files, 48 tests
passed.
- `pnpm --filter @paperclipai/shared typecheck` — passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts` — 3
tests passed; confirms exact route/OpenAPI parity for the restored
preview endpoint.
- `pnpm check:token-gates` — the restored files are clean; the
repository-wide command currently reports five pre-existing false
positives where comments reference GitHub issue `#9627` as if it were a
color literal.

## Risks

- Low migration risk: this PR contains no database migrations and is
based directly on current `master`.
- The main behavioral risk is cache invalidation across Decisions and
Training views; focused tests cover capture, update, deletion, row
state, and approval refresh behavior.
- The token-gate baseline remains red on unrelated `#9627` comment
references; this PR does not modify those files.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5.3-Codex, reasoning with repository/tool access and
code execution. Context window not exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-17 13:27:32 -05:00
DottaandPaperclip a090c09ee5 feat: add decision training snapshot foundation (#9702)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies and their work
> - Human approvals, issue interactions, and execution decisions already
capture high-value decision moments
> - Those moments are currently transient and cannot be reused as stable
evaluation or training examples
> - Reusable examples need a server-owned, immutable snapshot so later
comments or runs cannot leak into the recorded state
> - Human notes need to remain editable and auditable without changing
the captured state
> - This pull request adds the database model, snapshot capture service,
API, export format, and attention-feed enrichment for decision training
> - The benefit is a durable, inspectable foundation for evaluating
whether agents can reproduce good human decisions from only the context
available at decision time

## Linked Issues or Issue Description

### Subsystem affected

Cross-cutting (`server/`, `packages/db`, and `packages/shared`).

### Problem or motivation

Paperclip has no durable dataset for converting human decisions into
evaluation-ready examples. Teams need to capture pending or resolved
decisions with the exact issue context, comments, runs, and repository
evidence available at a cutoff, while preventing future context from
leaking into the example.

### Proposed solution

Store immutable, schema-versioned snapshots anchored to durable
interaction, approval, or execution-decision records; keep notes
separately editable with history; expose human-only CRUD, list, and
JSONL export APIs.

### Alternatives considered

Client-generated snapshots were rejected because they duplicate cutoff
logic and cannot reliably enforce no-leakage boundaries. Automatic
outcome backfill was deferred so captured examples remain faithful to
what was known at capture time.

### Roadmap alignment

Supports the roadmap direction of turning completed work and decision
patterns into reusable organizational knowledge.

### Additional context

The implementation records explicit commit-resolution confidence
(`exact`, `nearest_run`, `workspace`, or `none`) so downstream
evaluation can distinguish evidence quality.

## What Changed

- Added the `decision_training_examples` schema and idempotent migration
with company, issue, and source/author indexes.
- Added shared types for decision-training records, notes history, and
versioned snapshots.
- Added a single server-side snapshot capture path with inclusive
comment cutoffs, pre-cutoff run capture, durable decision payloads, and
explicit commit-resolution confidence.
- Added create, list, detail, notes-only update, delete, and JSONL
export routes with human-only write authorization and activity logging
that skips no-op note submissions.
- Added per-user `trainingExampleId` enrichment to attention items.
- Added focused embedded-Postgres tests for cutoff boundaries,
post-cutoff leakage, immutable snapshots, human-only writes, duplicate
prevention, notes history, attention enrichment, and export shape.
- Updated UI test and Storybook attention-item factories for the new
required `trainingExampleId` contract.

## Verification

- `pnpm exec vitest run server/src/__tests__/decision-training.test.ts`
— 10 tests passed.
- `pnpm --filter @paperclipai/db typecheck` — passed, including
migration numbering and safety checks.
- `pnpm --filter @paperclipai/shared typecheck` — passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.

## Risks

- The migration adds a new table and indexes only; it does not rewrite
existing rows or install resolve-time hooks.
- Snapshot JSON can grow with long comment threads and run histories; v1
intentionally favors complete, inspectable examples over aggressive
truncation.
- Commit SHA resolution is evidence-based and records `exact`,
`nearest_run`, or `none` so downstream consumers can account for
confidence.
- The API is additive, but future UI work must continue to treat the
snapshot as immutable and use notes-only updates.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex using `gpt-5.3-codex`, with repository tool use, terminal
execution, and code-editing capabilities; context-window size is not
exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-17 12:17:34 -05:00
1f1f545238 feat: add built-in summarizer and summary slots (#9713)
## Thinking Path

> - Paperclip is the open source control plane people use to organize,
govern, and understand AI-agent work
> - Operators need concise, current status views across projects and
execution workspaces without manually reading every issue and run
> - Paperclip already has auditable issues, documents, built-in agents,
routines, and live run events, but no first-class summary-slot workflow
connecting those systems
> - A built-in Summarizer can generate status prose through ordinary
governed tasks while summary slots provide stable, revisioned
destinations for that output
> - The UI needs to show current summaries, generation progress,
failures, revisions, and streaming draft status in the places operators
already work
> - This pull request adds the end-to-end summary-slot data, API, agent,
orchestration, and UI surfaces behind an experimental setting
> - The benefit is decision-oriented status context that remains
company-scoped, auditable, retryable, and inexpensive by default

## Linked Issues or Issue Description

No public GitHub issue exists for this feature.

**Problem**

Operators currently have to reconstruct project and workspace status by
reading many issues, runs, and comments. This makes it hard to identify
decisions, review queues, recent work, and the next event worth
watching.

**Proposed capability**

Add an experimental summary system with revisioned summary slots for
projects and workspaces, a paused-by-default built-in Summarizer agent,
governed generation tasks, live draft status, and reusable UI cards.

**Expected behavior**

- Summary data remains company-scoped and revisions remain auditable.
- Generation runs through normal issue/agent orchestration and
deduplicates active requests.
- Only the linked built-in Summarizer generation task can author a slot
revision.
- Operators can generate, retry, inspect revisions, and follow draft
progress from project and workspace views.
- The feature remains opt-in and background generation remains paused by
default.

## What Changed

- Added summary-slot schema, idempotent migrations, shared contracts,
validators, API paths, and service tests.
- Added company-scoped summary-slot routes for reading revisions,
requesting generation, and guarded Summarizer writes with activity
logging.
- Added terminal generation finalization, failure reasons, assignment
wakeups, and orchestration integration.
- Added the paused-by-default built-in Summarizer bundle, low-cost
runtime defaults, status-summarization skill, and stale-summary routine.
- Added summary cards, revision selection, retry/configuration states,
live draft streaming, transcript chunk handling, and project/workspace
integrations.
- Updated Claude local parsing for streamed status output and expanded
server, adapter, shared, database, catalog, and UI coverage.

## Verification

- `pnpm -r typecheck`
- `pnpm exec vitest run packages/db/src/summary-slots-schema.test.ts
packages/shared/src/summary-slot.test.ts
server/src/__tests__/summary-slot-routes.test.ts
server/src/__tests__/summary-slots.test.ts
server/src/__tests__/built-in-agents.test.ts
ui/src/components/SummarySlotCard.test.tsx
ui/src/components/SummarySlotCard.status.test.tsx
ui/src/components/useSummaryDraftStream.test.tsx
ui/src/lib/summary-draft-stream.test.ts
ui/src/lib/run-log-chunks.test.ts
ui/src/context/LiveUpdatesProvider.hook.test.tsx` — 113 tests passed
- `pnpm test:run` — server and UI suites passed; one CLI AWS doctor test
was affected by inherited `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`,
and passed when those host credentials were removed
- `pnpm exec vitest run cli/src/__tests__/secrets.test.ts` with
inherited AWS credential variables removed — 8 tests passed
- `pnpm build`
- `pnpm check:token-gates` currently reports nine `#9627` comment
references introduced by current `master`; none are in this PR diff

## Risks

- Database risk is limited by incrementally ordered, idempotent
migrations and migration safety checks.
- Summary generation creates normal issues/runs, so misconfiguration can
produce failed slots; the UI exposes retryable failure reasons and agent
configuration entry points.
- Streaming draft parsing depends on the documented `STATUS:` protocol;
final persisted revisions remain the source of truth.
- The feature is experimental, opt-in, and its built-in routine is
paused with no background token spend by default.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI GPT-5.3 Codex with reasoning, repository tool use, code
execution, GitHub CLI, and Paperclip control-plane integration. Earlier
branch commits also record Claude model co-authorship where applicable.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 11:03:07 -05:00
DottaandPaperclip 009410164f Fix inbox unread badge alignment (#9685)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Inbox lets operators scan task state and distinguish unread
activity at a glance
> - Read and unread rows should keep the same status-and-title alignment
so the list remains easy to scan
> - The mark-read dot previously participated in flex layout, which
added an extra leading column and visibly indented unread rows
> - Parent rows also needed special handling because their collapse
chevron occupies the normal leading gutter
> - This pull request moves the unread dot out of desktop flex flow,
preserves a consistent leading spacer, and positions parent-row dots
after the chevron
> - The benefit is consistent alignment for read, unread, leaf, nested,
and collapsible parent rows without hiding tree controls

## Linked Issues or Issue Description

### What happened?

In the Inbox, an unread row rendered its status icon and title farther
right than an equivalent read row because the mark-read dot occupied its
own flex column. On a collapsible parent row, the dot also competed with
the leading chevron.
### Expected behavior

Read and unread Inbox rows keep identical status/title alignment while
preserving the unread affordance and any tree-expansion controls.
### Steps to reproduce

  1. Run Paperclip from `master` and open the Inbox at desktop width.
  2. Compare otherwise-equivalent read and unread leaf rows.
  3. Expand a task tree containing an unread depth-zero parent.
4. Observe the unread row indentation and the dot competing with the
parent chevron.
### Paperclip version or commit

Reproduced against the pre-fix `master` parent of this PR.
- **Deployment mode:** Local dev (`pnpm dev`).
- **Installation method:** Built from source.
- **Agent adapters involved:** Not adapter-specific; this is a core
Inbox UI bug.
- **Database mode:** Not database-related.
- **Access context:** Board (human operator).
- **Additional context:** No logs or configuration are involved; the
regression is visual layout behavior covered by focused component/page
tests.

## What Changed

- Render the desktop unread dot as an absolute overlay so it does not
consume row width; retain the existing in-flow behavior on mobile.
- Add an `unreadDotPlacement` option so depth-zero collapsible parents
place the dot after the leading chevron.
- Reserve the same leading spacer for read and unread non-chevron Inbox
rows.
- Expand `IssueRow` and Inbox tests to cover leaf alignment, nested
rows, parent chevrons, fading state, and mobile behavior.

## Verification

- `pnpm exec vitest run ui/src/components/IssueRow.test.tsx
ui/src/pages/Inbox.test.tsx` — 2 files, 30 tests passed.
- `pnpm check:token-gates` — all three token gates clean across 630
scanned files.
- Browser QA (desktop 1280px and mobile 375px) — PASS: read/unread
desktop content measured at identical x positions; nested guides, parent
chevron hit target, fading state, and mobile mark-read hit targets
verified.

## Risks

- Low risk: the change is isolated to Inbox row presentation and has
focused regression coverage.
- The main visual risk is breakpoint-specific placement of the mark-read
dot; tests explicitly cover desktop absolute positioning and mobile
in-flow positioning.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex `gpt-5.6-sol`, high reasoning effort, with
repository/tool execution. The runtime did not expose a context-window
size.
- Original implementation commit also records assistance from Claude
Opus 4.8.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-17 09:20:44 -05:00
5d42382df4 feat(ui): stabilize workspace service controls (#9705)
## Thinking Path

> - Paperclip is the open source control plane people use to coordinate
AI-agent work.
> - Execution workspaces provide the local service loop where operators
start, stop, restart, inspect, and open workspace services.
> - The existing header exposed those actions through separate controls
whose position and labeling changed across runtime states.
> - That movement made the most common development actions harder to
scan and easier to misclick, especially with multiple services or long
URLs.
> - The design therefore uses one fixed-geometry, state-aware control
bar and keeps service-specific detail behind a compact disclosure.
> - This pull request adds that control surface, maps existing runtime
data and every pending mutation into it, and integrates it into the
execution-workspace header without changing server contracts.
> - The benefit is a calmer, predictable service-control loop across
stopped, transitional, running, unhealthy, failed, multi-service, and
narrow-width states.

## Linked Issues or Issue Description

### Subsystem affected

`ui/ — React + Vite board UI`

### Problem or motivation

Execution-workspace service actions move and change shape as runtime
state changes, while URLs and multi-service status compete for header
space. During bulk actions, operators also need every targeted service
to show its transitional state immediately.

### Proposed solution

Use one fixed-geometry, state-aware service control bar in the workspace
header. Map existing runtime records into a stable status, URL, and
actions model, and track each in-flight bulk request independently until
it settles.

### Alternatives considered

Keeping the separate quick-control buttons was rejected because their
geometry changes by state. Showing every service inline was rejected
because it makes the header too wide; per-service detail remains in a
compact disclosure and the Services tab.

### Roadmap alignment

Reviewed `ROADMAP.md`; this focused execution-workspace UI improvement
does not duplicate a listed roadmap initiative.

### Additional context

The published design and state viewer is available at
https://pages.paperclip.ing/pap-14233-workspace-service-controls/.

## What Changed

- Added `WorkspaceServiceControlBar`, a fixed-geometry responsive
control for single- and multi-service runtime states.
- Added 15 Storybook states covering running, stopped, transitions,
unhealthy, failed, disabled, long-URL, mobile, and multi-service
behavior.
- Replaced `WorkspaceRuntimeQuickControls` in the execution-workspace
header with adapters that map live services and all pending requests
into the new control model.
- Added focused unit coverage for service-entry construction, bulk
pending overlays, request resolution, clipboard feedback, and header
integration.

## Verification

- `cd ui && NODE_ENV=development pnpm vitest run
src/components/WorkspaceServiceControlBar.test.tsx
src/components/WorkspaceRuntimeControls.test.tsx
src/pages/ExecutionWorkspaceDetail.test.tsx` — 29 tests passed.
- `NODE_ENV=development pnpm --dir ui typecheck` — passed.
- `pnpm check:token-gates` — all token gates clean.
- Reviewed the Storybook captures for all primary states.

## Risks

- Low-to-moderate UI risk: service controls depend on adapter mapping
from existing runtime records; focused tests cover single-service and
bulk-action mapping and integration paths.
- Multi-service bulk actions intentionally apply to all eligible
services, while per-service actions remain in the disclosure.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, exact model ID `gpt-5.3-codex`; runtime-managed context
window; coding/reasoning mode with repository, terminal, Git, GitHub
CLI, and test execution tools.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-16 21:07:04 -05:00
DottaandPaperclip a015ac7a57 fix(ui): allow interrupting queued issue runs (#9725)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The issue detail chat lets operators send messages while an issue
run is live
> - Messages sent during a live run are shown as queued and can expose
an interrupt action
> - The UI only treated running runs as interruptible, even though
queued runs can also own the pending message
> - That mismatch hid the interrupt button after sending a message while
the agent run was still queued
> - This pull request treats queued and running issue runs as
interruptible and preserves the exact target run on optimistic and
persisted comments
> - The benefit is that operators can immediately interrupt the queued
run their message is waiting behind

## Linked Issues or Issue Description

- **What happened:** Sending a message while an issue-owned agent run
was in `queued` state showed the message as pending but did not make the
interrupt action available.
- **Expected behavior:** A message queued behind either a queued or
running issue run should retain that run as its interrupt target and
expose the interrupt control.
- **Steps to reproduce:** Open an in-progress issue with an issue-owned
run still queued, send a chat message, and inspect the queued message
actions.
- **Version/commit:** Reproduced against the pre-change `master` UI
behavior.
- **Deployment mode:** Paperclip board UI with a queued issue execution
run.

## What Changed

- Generalized issue-run resolution from running-only to
queued-or-running interruptible runs.
- Used the interruptible run consistently for optimistic queue metadata,
persisted comment decoration, cancel controls, and targeted
interruption.
- Added a regression test that sends a message behind a queued run and
verifies the exact run is cancelled.

## Verification

- `pnpm exec vitest run ui/src/pages/IssueDetail.test.tsx` — 44 tests
passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm check:token-gates` — repository-wide gate currently reports nine
pre-existing `#9627` comment literals; this patch adds no token literals
or gate violations.

## Risks

- Low risk: the behavior change is limited to selecting queued
issue-owned runs as valid interrupt targets in the existing chat flow.
- Cancellation remains targeted by run ID, and the regression test
verifies the queued run ID is preserved through optimistic and persisted
comment states.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI `gpt-5.4` via Codex CLI; context-window size is not exposed by
this runtime; reasoning-enabled with repository, shell, GitHub CLI, and
code-execution tools.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-16 16:55:51 -05:00
59fb27ff79 feat(inbox): let agents safely tidy user inboxes (#9724)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies and their work
> - The inbox is a per-user attention view, so archiving an item must
not alter the underlying issue, assignment, or status
> - Agents can help responsible users tidy resolved work only when the
action is company-scoped, reversible, policy-controlled, and fully
attributable
> - The database and authorization foundations landed in #9654 and
#9658, but the end-to-end archive routes, audit details, agent workflow
guidance, and operator UI still need to ship together
> - Separate stacked PRs #9659 and #9661 made the complete behavior
harder to review and land as one coherent capability
> - This pull request consolidates the remaining server,
shared-contract, documentation, skill, and UI work on top of current
master
> - The benefit is a single reviewable change that lets agents safely
archive responsible-user inbox items and lets users control or undo that
behavior

## Linked Issues or Issue Description

### Subsystem affected

Cross-cutting inbox management across shared contracts, server
authorization/routes/services, shipped agent skills, and the board UI.

### Problem or motivation

Agents may complete work whose issue remains in the responsible user's
Mine inbox. Existing board-user archive behavior does not provide the
agent-facing policy endpoints, target resolution, heartbeat-run
attribution, typed denials, conservative workflow guidance, or UI needed
for safe agent-managed cleanup.

### Proposed solution

Allow authorized agents to archive or unarchive responsible-user inbox
items under the user's open, allowlist, or disabled policy; preserve
actor/agent/run attribution in issue detail and activity records; expose
policy controls and agent archive attribution in the UI; and document
conservative cleanup rules for agents and PR gardening.

### Alternatives considered

- Reuse generic issue mutation permissions: rejected because inbox state
belongs to a target user and requires user-scoped authorization.
- Automatically archive every completed or closed item: rejected because
completion signals can still require human review or a decision.
- Keep the backend and UI as separate stacked PRs: superseded by this
consolidated PR so the complete user-visible behavior can be reviewed
and verified together.

### Related work

- Builds on merged foundations #9654 and #9658.
- Supersedes the remaining stacked changes in #9659 and #9661.
- `ROADMAP.md` has no overlapping inbox archive or inbox authorization
initiative.

## What Changed

- Added shared inbox-agent policy types and validators plus
company-scoped self-service policy routes and OpenAPI coverage.
- Enabled agent archive/unarchive mutations with responsible-user
targeting, policy enforcement, typed failures, attribution, idempotency,
and detailed activity auditing.
- Returned agent archive attribution in issue detail and documented
reversible inbox cleanup semantics in the implementation spec and
Paperclip skill.
- Added conservative PR-gardening inbox tidy guidance that keeps GitHub
access read-only and avoids archiving work that still needs human
action.
- Added the Profile settings policy control and Issue Properties
attribution/unarchive UI with focused component coverage and narrow-pane
handling.

## Verification

- `pnpm exec vitest run
server/src/__tests__/inbox-archive-routes.test.ts
server/src/__tests__/inbox-agent-policy-routes.test.ts
server/src/__tests__/authorization-service.test.ts
server/src/__tests__/openapi-routes.test.ts
ui/src/components/InboxAgentPolicyControl.test.tsx
ui/src/components/IssueProperties.test.tsx` — 110 passed.
- `pnpm --filter @paperclipai/db exec vitest run
src/inbox-archive-agent-policies-migration.test.ts` — 1 passed.
- `node --test
.agents/skills/pr-gardening/scripts/pr-gardening.test.mjs` — 9 passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm check:token-gates` — changed files are clean; the
repository-wide command currently reports nine unrelated pre-existing
`#9627` literals outside this PR's diff.

## Risks

- Agent inbox mutations broaden an existing endpoint path, so
authorization and target resolution must remain fail-closed; focused
route and authorization tests cover allowed and denied paths.
- Archive state affects only the responsible user's inbox presentation
and remains reversible; it does not mutate issue status, assignment, or
visibility.
- The UI policy defaults to the existing open behavior, while allowlist
and disabled modes can reduce agent access.
- This PR intentionally builds on #9654 and #9658 and contains no new
migration number or modification to an already-applied migration.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex using GPT-5.4, medium reasoning, repository tool use,
shell execution, code review, and test execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change
(`feat/inbox-agent-archive-complete`) and contains no internal Paperclip
ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 16:49:18 -05:00
DottaandPaperclip 89af58b6dc Clarify task-level model overrides in issue properties (#9710)
## Thinking Path

> - Paperclip is the control plane where operators configure and inspect
AI-agent work.
> - An issue can override the assigned agent's primary model for that
task.
> - The issue-properties UI labeled that per-task setting as `Custom ·
<model>`, which could be read as a property of the model rather than a
replacement of the agent default.
> - Operators need the UI to distinguish the agent's primary model from
an issue-specific override at both the collapsed summary and selection
point.
> - This pull request renames the lane presentation to `Override` and
adds concise provenance text without changing the stored lane value or
adapter configuration behavior.
> - The benefit is that operators can immediately understand which model
will run and why it differs from the agent default.

## Linked Issues or Issue Description

No matching public GitHub issue was found. Related implementation work:
#9700 moved Codex ACPX model configuration to startup and is already on
`master`; #9355 also addresses ACP session-config rejection behavior.
Those PRs concern execution behavior, while this PR is limited to
clarifying the issue-level override UI.

Bug report details:

- **What happened?** The issue-properties Model row displayed `Custom ·
<model>` for a task-level
`assigneeAdapterOverrides.adapterConfig.model`. Operators could misread
`Custom` as describing the model itself and could not see that the value
replaced the agent's primary model for this issue.
- **Expected behavior:** The UI should explicitly identify a task-level
model as an override and explain that it replaces the agent's primary
model for the issue.
- **Steps to reproduce:** Configure an agent with a primary model, set a
different model on an issue, and inspect the Model row and model picker
in Issue Properties.
- **Paperclip version or commit:** Reproduced on the pre-change branch
derived from current `master`.
- **Deployment mode:** Local development or any deployment using the
board UI.
- **Installation method:** Built from source.
- **Agent adapters involved:** Adapter-agnostic; any adapter exposing
model selection.
- **Database mode:** Not database-related.
- **Access context:** Board operator viewing issue properties.
- **Relevant logs or output:** Not applicable; this is a presentation
ambiguity.
- **Relevant config:** An issue-level
`assigneeAdapterOverrides.adapterConfig.model` differing from the
assigned agent's primary model.
- **Additional context:** The internal lane identifier remains `custom`;
only user-facing copy and explanatory text change.
- **Privacy checklist:** No private instance links, internal ticket IDs,
secrets, usernames, or local paths are included.

## What Changed

- Renamed the collapsed issue model label from `Custom · <model>` to
`Override · <model>` and added a provenance tooltip.
- Renamed the model-picker lane from `Custom` to `Override` and added
explanatory subtext at the selection point.
- Updated the Issue Properties component test to assert the new label.
- Added an isolated Storybook fixture for the task model override state
so visual review has a stable target.

## Verification

- `pnpm exec vitest run ui/src/components/IssueProperties.test.tsx` — 43
tests passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `git diff --check public-gh/master...HEAD` — passed.
- `pnpm check:token-gates` — the changed files are clean, but the
repo-wide command currently reports nine unrelated `#9627` comment
references already present on `master` as color literals.

## Risks

- Low risk: this changes display strings and explanatory copy only;
override storage, lane identifiers, API contracts, and execution
behavior are unchanged.
- The global token-gate false positive may also appear in CI until the
unrelated `#9627` references on `master` are allowlisted or the scanner
ignores issue-number comments.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex coding agent assisted this PR preparation using medium
reasoning, repository-aware shell execution, Git/GitHub tooling, and
local test/typecheck execution. The hosted runtime did not expose an
exact model ID or context-window size to this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-16 15:53:03 -05:00
DottaandPaperclip 52aea90263 feat: organize skills with nested folders and My Skills (#9633)
## Thinking Path

> - Paperclip is the open source control plane people use to organize
and govern AI-agent companies
> - Company skills are durable resources that users browse, import,
assign, and maintain over time
> - A flat skill list plus tags does not provide a stable location or
hierarchy for personal, company, project-imported, and bundled skills
> - Folder paths need to be canonical, company-scoped, safe to move, and
preserved across re-imports without changing skill IDs
> - The `/skills` UI also needs traversal, breadcrumbs, move/create
flows, and a dedicated My Skills namespace that work on desktop and
mobile
> - This pull request adds the folder data model and APIs, reserved-root
lifecycle, project import behavior, and the folder-first skills
experience
> - The benefit is a predictable filesystem-like organization model
while tags remain available for cross-cutting classification

## Linked Issues or Issue Description

Refs #9619 — the reviewed folder foundation was intentionally closed and
folded into this combined feature PR.
Refs #9026 — earlier flat-folder attempt superseded by this integrated
implementation.
Refs #3281 — related skill organization proposal; this PR uses canonical
persisted folders rather than deriving groups from skill keys, and does
not add hidden-skill behavior.

**Feature request**

- **Problem:** Skills currently lack a canonical hierarchical location,
making personal skills, project imports, bundled skills, and
company-authored skills difficult to traverse and manage at scale.
- **Proposed behavior:** Add nested company-scoped folders with stable
paths, reserved My/Projects/Bundled roots, subtree queries, safe
move/create operations, and a folder-first `/skills` library UI.
- **Import behavior:** New project scans file skills under
`projects/<project-slug>`; later imports update content without
overriding a user-selected folder.
- **Alternatives considered:** Tags alone remain useful for
cross-cutting classification, but they do not provide canonical
location, nesting, reserved namespaces, or stable import placement.
- **Roadmap alignment:** Extends the completed Skills Manager and
Scheduled Routines capabilities without duplicating an active roadmap
item.

## What Changed

- Adds `folders` persistence for routine and skill folders, nested
canonical paths, parent/slug/system-key fields, migration backfills, and
reapply-safe migrations `0174`–`0175` after current master migrations.
- Adds company-scoped folder CRUD, cycle/depth/namespace validation,
reserved My/Projects/Bundled lifecycle, item moves, subtree filtering,
and folder paths on skill results.
- Preserves project-import placement: first import files into the
project folder, while re-import keeps user-owned placement and stable
skill IDs.
- Adds the `/skills` folder tree rail, tags facet, breadcrumbs,
subfolder browser, move/new-folder dialog, canonical detail location,
inline tag editing, and folder-aware Studio creation.
- Keeps bundled skills read-only even when their source metadata is
incomplete by detecting the reserved Bundled folder and hiding
selection/move actions.
- Extends routine folder UI and OpenAPI coverage, and adds regression
tests across migrations, services, routes, tree helpers, pages, and
Studio creation.

## Verification

- `pnpm exec vitest run
packages/db/src/nested-skill-folders-migration.test.ts
server/src/__tests__/folders-routes.test.ts
server/src/__tests__/folders-service.test.ts
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/routines-service.test.ts
ui/src/components/folders/FolderControls.test.tsx
ui/src/components/folders/SkillFolderTree.test.tsx
ui/src/components/folders/skill-folder-tree.test.ts
ui/src/pages/CompanySkills.test.tsx ui/src/pages/Routines.test.tsx
ui/src/pages/SkillStudio.test.tsx
ui/src/lib/company-skill-routes.test.ts ui/src/lib/skill-create.test.ts`
— 13 files, 192 tests passed.
- `pnpm exec vitest run ui/src/pages/CompanySkills.test.tsx
ui/src/components/folders/SkillFolderTree.test.tsx` — 2 files, 20 tests
passed after preserving the existing PR's bundled-skill fixes.
- `pnpm -r typecheck` — passed for all workspace packages.
- `pnpm test:run` — passed in an isolated CI-like environment with
inherited Paperclip runtime identity and static AWS credential variables
removed.
- `pnpm build` — production build passed for all workspace packages.
- Greptile iteration 2 — 5/5 confidence with zero unresolved threads on
commit `ff2d67aa71`.
- Latest-head GitHub checks — all success, neutral, or skipped; PR is
mergeable with a clean merge state.
- `pnpm check:token-gates` — reports nine existing `#9627` comment false
positives already present on `master`; this PR introduces no new token
violation.

## Risks

- **Migration/backfill:** `0174` creates the foundation and `0175` adds
nested/reserved semantics. Both are ordered after current master
migration `0173`, are covered by numbering/safety checks, and are
designed to be reapply-safe.
- **Reserved namespaces:** My, Projects, and Bundled roots are
service-managed. Regression coverage prevents namespace squatting,
cross-company folder use, bundled writes, cycles, and excessive depth.
- **Behavioral change:** Project scans choose a project folder only on
initial creation; existing skills deliberately retain their current
folder during refresh.
- **UI scope:** The folder rail applies to the Installed library;
Catalog retains the discovery-oriented category sidebar.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI `gpt-5.5` in Codex CLI, medium reasoning mode; runtime did not
expose a context-window value. Used repository/file tools, terminal
execution, Git/GitHub operations, test execution, and code editing.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-16 15:50:45 -05:00
LeonSGP d62c5adb7a fix(ui): stop recreating markdown mention observers (#3809)
Fixes #3759

## Thinking Path

> - Paperclip orchestrates AI agents and issue workflows, so the comment
composer has to stay stable under normal typing.
> - The affected subsystem is the shared markdown comment editor used
across issue and workflow surfaces.
> - That editor decorates mention links after Lexical updates the
editable DOM.
> - The current mention decoration effect recreates its
`MutationObserver` whenever `value` changes, which happens on every
keystroke.
> - That observer also reacts to the DOM mutations produced by mention
decoration itself, creating unnecessary observer churn in Chrome.
> - This pull request keeps one observer instance alive, batches
decoration work into `requestAnimationFrame`, and disconnects the
observer while decoration writes run.
> - The benefit is lower observer churn while preserving the existing
mention chip behavior.

## What Changed

- Removed `value` from the mention-decoration observer effect dependency
list so the observer is not recreated on every external value update.
- Batched mention decoration with `requestAnimationFrame` and
temporarily disconnected the observer while DOM decorations are applied
to avoid self-triggered feedback loops.
- Added a regression test that verifies external value changes do not
recreate the mention decoration observer.

## Verification

- `pnpm install --frozen-lockfile`
- `pnpm --filter @paperclipai/ui exec tsc --noEmit`
- `pnpm --filter @paperclipai/ui exec vitest run
src/components/MarkdownEditor.test.tsx` currently fails before test
collection on the existing repo baseline with `TypeError: undefined is
not an object (evaluating 'z.string')` from
`packages/shared/src/adapter-type.ts`

## Risks

- Low risk. The change is scoped to the mention decoration observer
lifecycle and keeps the existing decoration logic intact.
- The main behavior change is deferring decoration to the next animation
frame instead of running immediately on every observed mutation.

## Model Used

- OpenAI Codex, GPT-5-based coding agent with local tool use in the
Codex CLI environment.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [ ] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-07-16 10:44:17 -07:00
Dotta 8b04147ca4 perf(ui): stop polling the event-sourced company live-runs list (#9701)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its web UI keeps live views fresh with a live-events websocket plus
React Query, and #9627 began replacing polling with event-sourcing
(pushing data into the cache)
> - After the churn fixes (#9624) and #9627 shipped, a long-lived tab's
memory footprint was still climbing, so I re-profiled with the Chrome
DevTools MCP
> - The dominant remaining churn is React Query re-arming a polled
query's `refetchInterval` timer on **every** observer notification — and
our live-event handlers `setQueryData(liveRuns(companyId))` on nearly
every event, so each pushed update re-arms every `liveRuns` observer's
timer (the sidebar is always mounted)
> - #9627 event-sourced the live-runs data but left the now-redundant
`refetchInterval` in place, so we did half the fix — the poll is pure
waste and the thing re-arming timers
> - This pull request removes `refetchInterval` from the event-sourced
company live-runs queries so the frequent cache writes have no timer to
re-arm
> - The benefit is that the steady-state timer churn on the
most-observed resource collapses, so the off-heap footprint stops
climbing

## Linked Issues or Issue Description

No public GitHub issue exists; describing inline per CONTRIBUTING.md →
"Link Issues or Describe Them In-PR", following the bug report template.
Continues #9569 / #9624 / #9627.

**What happened?**

With the earlier fixes deployed, a browser tab left open on the app kept
growing its memory footprint. MCP profiling showed ~100+ `setInterval`
create/clear cycles per 5s on an aged tab (vs ~16 fresh), all from React
Query's refetch-interval timers being re-armed on every `setQueryData`
to the frequently-written `liveRuns(companyId)` query.

**Expected behavior**

A resource whose data is pushed (event-sourced) should not also poll;
cache writes should not repeatedly re-arm interval timers. Idle tabs
should hold a bounded footprint.

**Steps to reproduce**

Open a tab with agents streaming, leave it open, and instrument
`setInterval`/`clearInterval`: the churn rate climbs and traces to
`QueryObserver.updateTimers` (`refetchInterval`) for `liveRuns`,
re-armed by every live-event cache write.

**Paperclip version or commit**

Branch `perf/drop-live-runs-refetch-interval`, off `master` (after
#9627).

**Deployment mode**

Local dev (`pnpm dev`), web UI. Core UI live-updates plumbing; not
adapter-specific.

## What Changed

- Set `refetchInterval: false` on every site that polls the **plain**
`queryKeys.liveRuns(companyId)` query (event-sourced by #9627):
`Sidebar`, `SidebarAgents`, `Issues`, `Inbox`, `IssueDetail`
(companyLiveRuns), `ProjectDetail` (×2), `Routines`,
`ExecutionWorkspaceDetail`, `bridge-init`.
- Removed the now-unused `useVisibilityRefetchInterval` interval
vars/imports in `Issues`, `Inbox`, `IssueDetail`.
- **Left variant-key sites polling on purpose** — `Agents` page
(`[...liveRuns, "agents-page"]`) and `ActiveAgentsPanel` (`[...liveRuns,
scope, …]`) are NOT event-sourced by #9627 (different exact cache key),
so dropping their poll would make them stale. Those are a later phase.
- Freshness for the converted queries now comes from event-sourcing
(#9627) + its reconnect reconcile; the initial mount fetch and cross-tab
publish (`usePublishSharedQueryData`) still happen.

## Verification

- MCP profiling identified the churn: the single churning callback is
React Query's `refetchInterval` timer, re-armed by
`setQueryData(liveRuns)` on live events.
- `vitest`: all affected suites pass (`Sidebar`, `SidebarAgents`,
`Issues`, `Inbox`, `IssueDetail`, `ProjectDetail`, `Routines`,
`ExecutionWorkspaceDetail`, `LiveUpdatesProvider`) — 153 tests.
- Updated two `SidebarAgents` linger-window tests: they advanced fake
timers to the *exact* linger-expiry boundary and had relied on
poll-induced re-renders to flush. The linger self-schedules its own
`setTimeout`, so the tests now cross the boundary with a small margin +
an explicit flush (no product change).
- `tsc -b` clean.
- End-to-end footprint reduction should be re-measured against a rebuilt
bundle with the same instrumentation.

## Risks

Low, client-only.
- `liveRuns(companyId)` freshness now depends entirely on event-sourcing
+ reconnect reconcile (both from #9627). If an event path is missed, the
reconnect handler refetches once; durable replay is a planned later
phase.
- Variant-key run lists (Agents page, ActiveAgentsPanel) are unchanged
and still poll, so they don't regress.
- Issue-scoped run queries (`issues.liveRuns/activeRun/runs`) are
**not** touched here — they aren't event-sourced yet and are a separate
phase.

## Model Used

- **Provider:** Anthropic, via the Claude Code CLI.
- **Model:** Claude Opus 4.8 (`claude-opus-4-8`).
- **Reasoning mode:** Extended thinking enabled.
- **Capabilities used:** tool use (shell, file editing), and the Chrome
DevTools MCP to re-profile the live instance and pinpoint the
`refetchInterval` timer churn.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work (a perf/plumbing change)
- [x] I have searched GitHub for duplicate or related PRs and linked
them above (continues #9627; no duplicates)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have considered and documented any risks above
- [ ] I have updated relevant documentation to reflect my changes (N/A —
no user-facing docs; rationale documented inline)
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-16 11:42:04 -05:00
DottaandPaperclip 6ec059ab4e fix(server): suppress stale handoff alarms during live continuation (#9695)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The control plane records a successful-run handoff when productive
work ends without a durable next-step disposition
> - That handoff state was derived only from the latest activity event,
without checking whether a corrective run or wake was currently alive
> - As a result, actively progressing issues could still show a
high-severity missing-disposition alarm and blocked-inbox row
> - The same stale required event could also remain indefinitely when a
later successful run correctly skipped recovery because another valid
continuation path already existed
> - This pull request makes the derived state liveness-aware, suppresses
attention only while the live path exists, and resolves stale required
events on valid-path skips
> - The benefit is that productive work stays calm while genuine stalls
still resurface automatically when liveness disappears

## Linked Issues or Issue Description

- **Bug:** An issue whose latest successful-run handoff event is
`required` continues to report a missing disposition even while a
heartbeat run, scheduled retry, or queued/deferred/claimed wake is
actively targeting that issue.
- **Expected behavior:** The API should expose current continuation
liveness, the blocked inbox should suppress the alarm only while that
path remains live, and a later successful run that skips recovery
because a valid path exists should durably resolve the stale event.
- **Related but distinct:** #9370 changes disposition freshness at
detection time; #8748 adds an explicit policy opt-out. This PR preserves
detection/escalation policy and fixes read-time/current-liveness state.

## What Changed

- Extended `SuccessfulRunHandoffState` with `hasLiveContinuation` and
optional `liveRunId` evidence.
- Added bounded liveness hydration for required handoff states using
active heartbeat-run and wake-request signals.
- Suppressed `missing_disposition` blocked-inbox rows only while a run,
scheduled retry, or live wake targets the issue.
- Added durable `issue.successful_run_handoff_resolved` logging when
handoff detection skips because another valid continuation path owns the
next action.
- Added focused regressions for live/absent derived state, self-healing
attention suppression, valid-path skip classification, and
resolved-event logging.
- Updated UI normalization and fixtures for the shared contract without
changing rendering behavior.

## Verification

- `pnpm --filter @paperclipai/shared typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm vitest run
server/src/services/recovery/successful-run-handoff.test.ts
server/src/__tests__/issue-list-assignee-filter-routes.test.ts
server/src/__tests__/issue-blocker-attention.test.ts` — 56 passed
- `pnpm vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts -t "queues one
finish-handoff wake when a successful run leaves in-progress work
without a next action"` — 1 passed
- `git diff --check`

## Risks

- Low risk: no schema or migration changes, and detection, bounded
correction attempts, and escalation behavior are unchanged.
- Liveness lookups are limited to issues whose latest handoff state is
`required`; blocked-inbox suppression reuses rows already loaded by that
query path.
- Suppression is read-time and self-healing: when the run or wake stops,
the alarm returns on the next fetch.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex using `gpt-5.4`, tool-enabled software-engineering
workflow with repository, shell, test, Git, GitHub, and Paperclip
control-plane access. Context-window size is not exposed by this
runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-16 10:49:47 -05:00
DottaandClaude Opus 4.8 054b076b58 fix(ui): keep inbox hover and j/k keyboard selection in sync across list reshapes (#9680)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Inbox is the primary triage surface; it supports both mouse
hover and `j`/`k` keyboard navigation over a flat, expandable list of
rows
> - Hover and keyboard selection are meant to be a single shared
"cursor": hovering a row and then pressing `j`/`k` should continue from
the hovered row, not jump elsewhere
> - A prior hover-perf rewrite moved the hovered row into a numeric
`hoveredIndexRef` and nulled it whenever the list reshaped; because the
inbox polls constantly, any refresh between hovering and pressing a key
dropped the hovered index
> - With the hovered index dropped, the next keypress fell back to
selection index `0`, stranding the cursor at the top of the list instead
of continuing from the hovered row
> - This pull request tracks the hovered row's stable identity (a nav
key) alongside the numeric index and re-anchors it by key across
reshapes, mirroring the existing keyboard-selection reconciliation
> - The benefit is that mouse hover and keyboard navigation stay in sync
exactly as intended, even while the inbox is polling

## Linked Issues or Issue Description

**Bug report**

- **What happened:** In the Inbox, hovering a row with the mouse and
then pressing `j`/`k` (or another keyboard shortcut) does not continue
from the hovered row. If the list refreshes (which happens on the
inbox's constant polling) in the moment between hovering and pressing a
key, keyboard selection snaps back to the top row instead.
- **Expected behavior:** The keyboard cursor should be in sync with the
hovered row — pressing `j`/`k` after hovering should move relative to
the row the mouse is over.
- **Steps to reproduce:**
  1. Open the Inbox with several rows.
  2. Hover the mouse over a row partway down the list.
  3. Wait for (or trigger) a background poll/refresh of the list.
  4. Press `j` or `k`.
5. Observe selection jumps to the top of the list instead of continuing
from the hovered row.
- **Root cause:** The `[flatNavItems]` effect nulled `hoveredIndexRef`
on every list reshape. Since hover also clears the keyboard selection
band to `-1`, the fallback selection index resolved to `0`.

## What Changed

- Hoisted `navEntryKey` to module scope so it can compute a stable,
index-independent identity for a nav row from both the hover handler and
the reshape effect.
- Added `hoveredNavKeyRef` to track the hovered row's stable key
alongside the existing numeric `hoveredIndexRef`, set whenever the
pointer selects a row.
- On list reshape, re-anchor the hovered index by key (find the row with
the same key) instead of unconditionally dropping it; only drop the
hover when the row is actually gone. This mirrors the existing
`selectedIndex` key-based reconciliation.
- Added a unit test that hovers a row, reshapes the list via a simulated
poll, presses `j`, and asserts selection continues from the hovered row.

## Verification

- `pnpm --filter ./ui exec vitest run src/pages/Inbox.test.tsx` → 15/15
passing, including the new hover→`j`/`k` sync test and the existing
keyboard-nav tests.
- The new test explicitly covers the reshape-during-hover path that the
prior test suite had deferred to live/e2e verification.

## Risks

- Low risk. The change is confined to the Inbox's in-memory
hover/selection bookkeeping (two refs and one effect); it adds no new
renders (hover still paints via CSS `:hover`) and touches no data
fetching, routing, or persistence. Behavior is unchanged when the list
does not reshape; when it does, the hover now follows the same row
instead of being dropped.

## Model Used

- Claude Opus 4.8 (Anthropic), model id `claude-opus-4-8`, used with
extended thinking and tool use (file edits, running the UI test suite
locally).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 07:50:48 -05:00
DottaandClaude Opus 4.8 cf7711ecc5 feat(ui): explain when a message won't reopen a blocked issue (Rule C, PAP-13554) (#9417)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - When an agent's task is `blocked`, humans often comment on the issue
thread expecting it to reopen and resume
> - If the issue stays `blocked` because an unresolved (not-done)
blocker still gates the reopen path, the UI said nothing — the human
"sent a message and nothing happened" (a real silent-failure report)
> - That silence makes the product feel broken even though the gate is
working as designed
> - This pull request adds Rule C copy to the existing
`IssueBlockedNotice` surface: when a comment won't reopen a blocked
issue, it explains why and names the deepest unresolved blocker leaf
with its status
> - The benefit is that the human immediately understands the task is
*paused, not stuck*, and knows exactly which task to act on to unblock
it

## Linked Issues or Issue Description

<!-- No public GitHub issue — describing the underlying problem inline
(path B), following the feature issue template. -->

**Problem or motivation**

A human comments on a `blocked` issue expecting it to move back to
`todo` and resume. When the reopen gate keeps it blocked because an
unresolved (not-`done`) blocker remains, nothing in the UI communicates
this, so the user perceives a dropped message ("I sent a message and
nothing happened").

**Proposed solution**

Reuse the existing amber `IssueBlockedNotice` surface (the designated
blocked/recovery surface — no new component). When a message won't
reopen a blocked issue, the notice states that it won't reopen yet,
names the unresolved blocker leaf with its status (e.g. "Still blocked
by PAP-XXXXX (in progress)"), and reassures that it reopens
automatically once the blocker is done. UI-only; no server change.

**Alternatives considered**

Adding a server signal (a reopen-suppressed reason on the comment/notice
payload) was considered but rejected as unnecessary — the
unresolved-blocker set is already available client-side, so the copy is
derived in the component. Done-but-pending-finalize blockers are `done`,
so they fall out of the unresolved set into the standard reopen (Rule B)
path and are correctly not shown as reopen-suppressed.

## What Changed

- `ui/src/components/IssueBlockedNotice.tsx`: added reopen-suppressed
messaging for `blocked` issues that still have unresolved blockers — a
lead sentence ("a message won't reopen it yet, then it reopens
automatically"), the named unresolved blocker leaf with its status, and
an "and N other task(s)" summarization when multiple blockers remain.
- `ui/src/components/IssueBlockedNotice.test.tsx`: added/updated tests
covering the single, nested-chain (deepest-leaf), multiple-blocker, and
empty-blocker states, plus the not-a-reopen-case (`in_progress`) path.
- `ui/storybook/stories/issue-blocked-notice.stories.tsx`: new Storybook
stories rendering each notice state for copy review.

## Verification

- `cd ui && tsc -b` — typecheck clean (previously failed TS2322 on the
story meta; fixed by a default `args`).
- Vitest: `IssueBlockedNotice.test.tsx` green (single / nested /
multiple / empty / in-progress states).
- Storybook stories rendered at 1440×900 for all four states;
screenshots posted on the tracking issue.
- UXDesigner reviewed the notice copy and signed off (no copy edits
required).

## Risks

Low risk. UI-only, additive copy on an already-shipped amber notice
surface; no server or schema changes. The reopen behavior itself is
unchanged — this only explains the existing gate. Worst case is copy
wording, which had a design review.

## Model Used

Claude — claude-opus-4-8 (Opus 4.8), extended thinking, with tool use /
code execution in the Paperclip harness.

---

- [x] I searched the GitHub PR list for similar/duplicate PRs before
opening this one.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 02:34:53 -05:00
f44a002b8d fix(ui): restore prefix-aware company export/import links (#6648)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Each company workspace in the web UI is mounted under a URL prefix
(e.g. `/NEU/company/...`), and `Link` from `@/lib/router` applies that
prefix automatically via `applyCompanyPrefix`
> - Company Settings rendered its Org Chart, Export, Import, and Cloud
Upstream buttons as raw `<a href>` anchors, which drop the prefix, so
those pages 404 on prefixed instances (#2910);
`CompanyExport.filePathFromLocation` also failed to locate
`/company/export/files/` inside prefixed URLs, breaking export file
previews
> - #2951 fixed the Settings links with `<Link to>` plus tests, but the
sandbox-settings work in #4415 reverted the links back to `<a href>`,
silently reintroducing the bug (#6647)
> - This pull request restores the prefix-aware `<Link>` for all four
Settings links, normalizes the pathname with `toCompanyRelativePath()`
before matching the export-files marker, and adds regression tests
covering every route so the fix cannot be lost again
> - The benefit is that export/import/org-chart/cloud-upstream
navigation and export file previews work on every prefixed deployment

## Linked Issues or Issue Description

Fixes: #6647
Refs #2910 (original report: `/company/export` → prefix `COMPANY` → not
found)
Refs #2951 (original fix with `<Link to>` + tests — merged, then lost)
Refs #4415 (sandbox settings PR that reverted Settings back to `<a
href>`)

## What Changed

- **`ui/src/pages/CompanySettings.tsx`**: use `Link` from `@/lib/router`
for the Org Chart, Export, Import, and Cloud Upstream buttons (replacing
raw `<a href>`)
- **`ui/src/pages/CompanyExport.tsx`**: resolve file paths from prefixed
URLs by normalizing with `toCompanyRelativePath()` before matching
`/company/export/files/`
- **`ui/src/lib/company-routes.test.ts`**: regression tests for
export/import/cloud-upstream/org prefix rewriting, double-prefix
prevention, and export file URL normalization

## Verification

```bash
pnpm vitest run ui/src/lib/company-routes.test.ts
```

Manual:

1. Open `http://localhost:3100/NEU/company/settings` (or your company
prefix).
2. Click **Export** / **Import** — URL should stay under
`/:prefix/company/...`.
3. On export, select a file — URL should be
`/:prefix/company/export/files/...` and preview should load.

The change is navigation-target-only (no visual/layout changes), so
before/after is shown as the resolved URLs:

| Link | Before (prefix dropped → not found) | After |
|------|-------------------------------------|-------|
| Export | `/company/export` | `/NEU/company/export` |
| Import | `/company/import` | `/NEU/company/import` |
| Org Chart | `/org` | `/NEU/org` |
| Cloud Upstream | `/company/settings/cloud-upstream` |
`/NEU/company/settings/cloud-upstream` |

## Risks

Low — same approach as #2951; only navigation/parsing, no API changes.

## Model Used

- Original implementation: authored by @qbamca in Cursor (agentic
editor; the session's exact model ID was not recorded)
- Follow-up commit (merge-conflict resolution) and this description
update: Claude Fable 5 (Anthropic, `claude-fable-5`, extended thinking,
agentic tool use), operated by the Commit Capital triage team

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes (no
doc changes required — behavior matches documented routing)
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(pending re-review of the conflict-resolution commit)
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Jakub Mikiciuk <jmikiciuk@igus.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Andrew Aymeloglu <aaymeloglu@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 22:52:40 -05:00
DottaandPaperclip 8eff54bc47 [codex] Explain AWS secret creation failures in the UI (#9645)
## Thinking Path

> - Paperclip is the open source control plane operators use to manage
AI-agent companies.
> - Operators can store runtime secrets in provider vaults such as AWS
Secrets Manager.
> - The server already preserves sanitized AWS failure details,
including the failed operation, required IAM capability, region, and
safe recovery options.
> - The create-secret dialog reduced that structured response to a
generic message, leaving operators unable to understand or fix failed
AWS writes.
> - This pull request keeps the safe structured error through the UI and
presents concise, actionable diagnostics without exposing raw AWS
principals or account details.
> - The benefit is that operators can correct IAM access or link an
existing AWS secret immediately instead of debugging an opaque failure.

## Linked Issues or Issue Description

No public issue was found for this exact UI gap.

Bug report:
- What happened: creating a Paperclip-managed value in AWS Secrets
Manager could fail with a generic dialog error even though the API
returned safe, actionable provider details.
- Expected behavior: the dialog should identify the AWS operation,
required IAM capability, region, provider vault, and safe alternative
while keeping raw cloud-provider details redacted.
- Steps to reproduce: configure an AWS Secrets Manager provider vault
without `secretsmanager:CreateSecret`, then create a Paperclip-managed
secret using that vault.
- Paperclip version/commit: current `master` before this PR.
- Deployment mode: Paperclip server with an AWS Secrets Manager provider
vault.

Related prior server-side propagation work:
- Refs #9161

## What Changed

- Preserve the structured `ApiError` returned by failed create-secret
mutations instead of reducing it to a string.
- Render AWS-specific, sanitized diagnostics with the required IAM
capability, region, provider vault, operation, and external-reference
recovery option.
- Add a full dialog render regression test that verifies actionable
details appear and raw AWS ARN/account information does not.

## Verification

- `pnpm exec vitest run ui/src/pages/Secrets.render.test.tsx` — 1 file
passed, 15 tests passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm check:token-gates` — all gates clean.
- `git diff --check public-gh/master...HEAD` — passed.

### Visual Verification

QA verified both states in Chromium at head `357cd2271` using the real
`Secrets` component and confirmed that raw AWS account, ARN,
assumed-role, and provider exception details are absent from the
rendered DOM.

**AWS access-denied diagnostics**

![AWS access-denied
diagnostics](https://pages.paperclip.ing/pap-14130-secret-error/aws-access-denied.png)

**Generic non-AWS fallback**

![Generic non-AWS
fallback](https://pages.paperclip.ing/pap-14130-secret-error/generic-error.png)

## Risks

Low risk. The change only affects failed create-secret presentation in
the UI; successful secret creation, API contracts, schema, and
migrations are unchanged. The structured details are server-sanitized,
and the regression test confirms raw AWS principal/account data is not
rendered.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI `gpt-5.4` via Codex CLI, with tool-enabled repository editing,
shell execution, Git, GitHub, and Paperclip API access. Reasoning mode
and exact context-window size were not exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-15 21:47:07 -05:00
DottaandPaperclip 8368fb30b0 fix(routines): coalesce sub-hourly catch-up runs (#9649)
## Thinking Path

> - Paperclip is the open source control plane people use to run
AI-agent companies.
> - Scheduled routines support catch-up policies when the server resumes
after missed cron ticks.
> - The existing capped replay policy dispatched once per missed tick,
which can flood the board after downtime for frequent schedules.
> - Sub-hourly routines usually need one prompt catch-up execution
rather than historical per-tick replay, while hourly-or-slower schedules
may rely on the existing behavior.
> - This pull request coalesces missed sub-hourly ticks into one
execution and keeps the slower-schedule behavior unchanged.
> - The benefit is bounded recovery work without changing the semantics
of lower-frequency scheduled routines.

## Linked Issues or Issue Description

### What happened?

When a scheduled routine using `enqueue_missed_with_cap` resumes after
several missed sub-hourly cron ticks, Paperclip dispatches one catch-up
execution for every missed tick. Those executions arrive in a
same-second burst and can flood the board with duplicate-looking work.

### Expected behavior

Sub-hourly schedules should advance past all missed ticks but dispatch
exactly one catch-up execution. Hourly-or-slower schedules should retain
capped per-tick replay.

### Steps to reproduce

1. Build Paperclip from `master` and create a routine with a sub-hourly
cron schedule and `catchUpPolicy: enqueue_missed_with_cap`.
2. Set its persisted `nextRunAt` far enough in the past to cover several
scheduled occurrences.
3. Run routine catch-up processing.
4. Observe multiple catch-up dispatches instead of one coalesced
execution.

### Paperclip version or commit

Reproduced on `master` before this PR.

### Deployment mode

Built from source in local development with embedded PGlite.

## What Changed

- Classify sub-hourly cadence from timezone-aware scheduled occurrences,
avoiding daily multi-minute false positives while supporting schedules
restricted to active days.
- Coalesce all missed sub-hourly ticks into one catch-up dispatch while
advancing `nextRunAt` to the next future occurrence.
- Preserve capped per-tick replay for hourly-or-slower schedules.
- Clarify the catch-up policy labels in both routine editing surfaces.
- Add regression coverage for both the coalesced and preserved
behaviors.

## Verification

- `pnpm exec vitest run server/src/__tests__/routines-service.test.ts
--testNamePattern='coalesces multiple missed sub-hourly ticks|continues
replaying each missed hourly tick|continues replaying missed ticks for
daily schedules with multiple minute values|coalesces sub-hourly
schedules restricted to weekdays'` — 4 passed.
- `pnpm check:token-gates` — all gates clean.
- `git diff --check origin/master...HEAD` — clean.

## Risks

- Low-to-moderate behavioral risk: sub-hourly routines using
`enqueue_missed_with_cap` now intentionally receive one recovery
execution instead of one per missed tick.
- Hourly-or-slower schedules retain their previous capped replay
behavior, limiting the compatibility surface.
- No schema, migration, workflow, or lockfile changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex CLI with GPT-5.5, medium reasoning, code execution and
repository tool use; the runtime did not expose a context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-15 21:46:10 -05:00
DottaandPaperclip f1508a7929 feat(decisions): expand image rows into gallery (#9532)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies and review work that needs human attention.
> - The Decisions page condenses approvals, failed runs, reviews, and
issue interactions into a scannable attention queue.
> - Some decision rows already include screenshot evidence, but the
collapsed thumbnail stack is too small for meaningful inspection.
> - Image-only rows were not expandable because expansion was previously
reserved for inline decision resolvers.
> - Reviewers therefore had to leave the Decisions page before they
could understand the visual evidence attached to a row.
> - This pull request makes rows with images expandable and presents a
readable, linked gallery while preserving the compact collapsed view.
> - The benefit is faster evidence review without sacrificing queue
density or existing inline-resolution behavior.

## Linked Issues or Issue Description

No public GitHub issue currently tracks this feature.

### Subsystem affected

`ui/` — React + Vite board UI

### Problem or motivation

Screenshot evidence in Decisions rows is only visible as small
overlapping thumbnails, and non-inline rows cannot expand to show it.
This makes visual review unnecessarily slow and forces reviewers to
navigate away from the queue.

### Proposed solution

Treat active rows with images as expandable, render the first three
images at a readable size in an expanded gallery, and link images plus
any remaining-image affordance to the related issue.

### Alternatives considered

Always rendering large images would make the queue difficult to scan;
opening the issue immediately preserves density but prevents in-context
review. An explicit expandable gallery keeps both behaviors available.

### Roadmap alignment

`ROADMAP.md` does not list overlapping Decisions image-gallery work.
This is a focused improvement to the existing review surface rather than
a new product area.

### Additional context

The Storybook variants document both the collapsed thumbnail treatment
and deterministic expanded gallery state for reviewer inspection.

## What Changed

- Allow active Decisions rows with screenshot evidence to expand even
when they have no inline resolver.
- Keep compact thumbnails in collapsed rows and render up to three
larger, linked images when expanded.
- Add an accessible remaining-image tile that links to the related issue
when more screenshots exist.
- Add component coverage for image-only expansion and the
remaining-image issue link.
- Add collapsed and expanded image-gallery Storybook variants, including
deterministic initial expansion.

## Verification

- `pnpm exec vitest run ui/src/components/AttentionQueueRow.test.tsx`
- `pnpm check:token-gates`
- `pnpm --dir ui typecheck`
- `pnpm --dir ui build-storybook`
- QA visual verification (light + dark, no defects):
https://github.com/paperclipai/paperclip/pull/9532#issuecomment-4964769485

## Risks

- Low risk: the change is isolated to Decisions row rendering and
Storybook fixtures.
- Rows with images gain a new expansion interaction, but existing inline
resolver behavior and deep links remain intact.
- The gallery intentionally limits the in-row preview to three images to
avoid unbounded row height.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude Opus 4.8 assisted with the original implementation
and tests.
- OpenAI `gpt-5.4` via Codex CLI assisted with current-master rebase
integration, verification, and PR preparation. The runtime
context-window size is not exposed; capabilities used include reasoning,
repository tool use, code execution, and test execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-15 20:08:21 -05:00
DottaandPaperclip d32ed88443 fix(recovery): route recovery by failure cause (#9634)
## Thinking Path

> - Paperclip is the open source control plane people use to coordinate
AI-agent companies and their work.
> - Its recovery subsystem detects stranded issue execution and decides
whether to retry, escalate, or request operator intervention.
> - The existing recovery path used a mostly generic owner ladder and
generic execution contract, so transient failures could wake a manager
who then performed the deliverable instead of repairing and returning
the task.
> - Provider quota failures also entered the same takeover path even
when the correct action was to wait for capacity and retry the original
assignee.
> - Recovery actions already retain the source owner and evidence needed
to choose a cause-specific route, render a scoped contract, and measure
whether work was handed back.
> - This pull request adds a cause-keyed recovery playbook, propagates
its contract through every built-in adapter, and makes resolved recovery
actions return work to the original owner by default.
> - The benefit is bounded self-recovery that preserves task ownership,
avoids needless management takeover, and makes recovery outcomes
observable.

## Linked Issues or Issue Description

No matching public GitHub issue was found.

Related recovery work was reviewed but is not duplicated here: #9630
restores bounded recovery continuations, #8807 changes one
assignee-ranking case, and #9404 records runtime-failure transition
evidence. This change instead introduces cause-specific routing and
recovery contracts across the recovery lifecycle.

### What happened?

When an issue became stranded, recovery generally selected an owner
through the same fallback ladder and rendered the normal execution
contract. That made the recovery wake look like ordinary deliverable
work, even when the correct action was to retry the original agent,
repair its runtime, or wait for a provider quota reset.

### Expected behavior

Recovery should select a response by failure cause, tell the recipient
to recover rather than complete the deliverable, suppress takeover wakes
for provider quota waits, and return repaired work to its original
assignee unless the recovery owner explicitly completes it.

### Actual behavior

Recovery could escalate transient failures to management, omit the
cause-specific next action from the wake, and leave the recovery owner
assigned after the runtime problem was resolved.

### Impact

The generic path creates avoidable management work, ownership churn, and
budget consumption while obscuring whether recovery successfully
returned work to the responsible agent.

## What Changed

- Added cause-keyed routing for process loss, missing disposition,
provider quota limits, Codex output inactivity, workspace validation
failures, and fallback recovery causes.
- Added recovery-scoped wake rendering that replaces the generic
execution contract with the failure summary, original assignee, attempt
count, next action, and cause-specific playbook instruction.
- Propagated the structured recovery contract through all built-in
adapter execution paths, including Hermes local and gateway adapters.
- Added provider-quota wait monitoring so capacity failures schedule the
original assignee instead of enqueueing a takeover wake.
- Added hand-back behavior and `handed_back` / `owner_completed` outcome
accounting when recovery actions are resolved.
- Added focused routing, renderer, quota-monitor, and hand-back
regression coverage plus implementation-spec documentation.

## Verification

- `pnpm exec vitest run packages/adapter-utils/src/server-utils.test.ts
server/src/__tests__/heartbeat-process-recovery.test.ts
server/src/__tests__/heartbeat-workspace-branch-containment.test.ts
server/src/__tests__/issue-recovery-actions.test.ts`
  - 4 test files passed; 194 tests passed.
- Targeted `pnpm --filter ... typecheck` across
`@paperclipai/adapter-utils`, `@paperclipai/shared`,
`@paperclipai/server`, `@paperclipai/ui`, and all nine changed adapter
packages.
  - 13 affected workspace packages passed typecheck.
- `pnpm check:token-gates`
  - All UI token gates passed.

## Risks

- Recovery routing behavior changes for stranded work, so an incorrectly
classified cause could select a different recipient than before;
fallback causes retain the existing management ladder.
- Provider quota detection depends on structured failure evidence and
conservative text matching; unmatched failures continue through fallback
recovery.
- Adapter prompt plumbing changes across built-ins, covered by shared
renderer tests and compile-time call signatures.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex with exact model ID `gpt-5.6-sol`, using reasoning, tool
use, and code execution. The runtime does not expose its configured
context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-15 20:04:42 -05:00
3ae2c30f2f feat(skills): import skills from projects (#9620)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies.
> - Company skills make reusable agent behavior discoverable and
editable from one place.
> - Projects already contain skill directories, but operators had to
import each skill path manually.
> - Copying those skills would break the desired write-through workflow
between Skill Studio and the source project.
> - The server therefore needs a safe preview/select/import contract
that only accepts rediscovered, workspace-contained candidates.
> - The UI needs a guided project picker that explains reference
semantics, handles conflicts, and remains usable on mobile.
> - This pull request adds that end-to-end project skill import flow
with authorization, tenant-scope, traversal, and symlink regression
coverage.
> - The benefit is faster bulk onboarding while keeping project files as
the single source of truth.

## Linked Issues or Issue Description

**Feature request**

**Problem:** Importing several skills already stored in a Paperclip
project requires operators to discover and submit each local path
individually. This is slow, hides which well-known directories were
searched, and makes conflict/already-imported states difficult to
evaluate before mutation.

**Proposed solution:** Add an “Import skills from project” flow that
previews skills from well-known directories, lets operators selectively
import eligible candidates, and stores local-path references so Skill
Studio edits write through to the project files.

**Alternatives considered:** Copying files into company-managed skill
storage was rejected because it creates divergent copies. Trusting
client-supplied paths was rejected because imports must be constrained
to server-rediscovered, workspace-contained candidates.

**Additional context:** GitHub duplicate search found no existing issue
or PR for this exact workflow. Refs #3799 for related skill-import
inventory behavior; this PR does not claim to close that issue.

## What Changed

- Extend `scan-projects` with backward-compatible preview and
selective-import modes, typed validation, candidate statuses, and
OpenAPI coverage.
- Discover project skills under `skills`, `.agents/skills`,
`.claude/skills`, `.codex/skills`, `.cursor/skills`, `.opencode/skills`,
and `.gemini/skills`.
- Re-discover selections server-side, enforce company/project/workspace
scope, and reject traversal or symlink escapes before creating
`local_path` references.
- Add the Skills-page menu entry and responsive project import dialog
with project selection, grouped candidates, select all/deselect all,
conflicts, empty/error/403 states, and import results.
- Add route, service, and component regressions for preview
authorization, cross-tenant selections, traversal/symlink safety,
selection counts, grouping, and result semantics.

### Screenshots

**Choose a project**

![Choose a
project](https://raw.githubusercontent.com/cryppadotta/paperclip-prs/refs/heads/pr-assets/import-skills-from-project/01-pick-project.png)

**Review discovered skills**

![Review discovered
skills](https://raw.githubusercontent.com/cryppadotta/paperclip-prs/refs/heads/pr-assets/import-skills-from-project/03-select.png)

**Mobile selection footer**

![Mobile selection
footer](https://raw.githubusercontent.com/cryppadotta/paperclip-prs/refs/heads/pr-assets/import-skills-from-project/select-390.png)

**Import result**

![Import
result](https://raw.githubusercontent.com/cryppadotta/paperclip-prs/refs/heads/pr-assets/import-skills-from-project/06-result.png)

## Verification

- `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/company-skills-routes.test.ts
ui/src/pages/skills/ImportSkillsFromProjectDialog.test.tsx` — 3 files,
81 tests passed.
- `pnpm check:token-gates` — all token gates clean.
- `pnpm --filter @paperclipai/shared typecheck` — passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- Security review passed after adding tenant-scope and
unauthorized-preview regressions; UX re-review approved desktop/mobile
surfaces; QA passed all seven acceptance areas including write-through
editing, deduplication, conflicts, empty state, and permission denial.

## Risks

- Files remain referenced in project workspaces, so moving or deleting a
source directory can make an imported skill unavailable; the UI
explicitly communicates the reference behavior.
- New well-known directory scans may discover more candidates than older
versions, but preview mode prevents mutation until the operator confirms
a selection.
- The endpoint remains backward compatible: omitting `mode` preserves
the prior full-import behavior.
- No schema migration or telemetry event changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude Opus 4.8 with tool use/code execution assisted with
the UI implementation and UX polish. OpenAI Codex CLI with tool use/code
execution assisted with server implementation, security fixes,
regression coverage, integration, and PR preparation; the runtime did
not expose Codex's exact backing model ID or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 18:01:44 -05:00
DottaandClaude Opus 4.8 02a4f52277 perf(ui): event-source the company live-runs list (Phase 1) (#9627)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its web UI keeps live views fresh with React Query, coordinated by a
live-events websocket (`/api/companies/:id/events/ws`) and cross-tab
polling
> - We already cut the worst live-update churn (#9569, #9624), but the
deeper issue is that even the "push" path is *push-the-signal,
pull-the-data*: a websocket event triggers `invalidateQueries` → an HTTP
refetch
> - The company live-runs list (`queryKeys.liveRuns`) is the
most-observed resource — the sidebar renders it on nearly every page —
so its refetch is the most ambient source of churn, fired on every
`heartbeat.run.queued` / `heartbeat.run.status` event
> - Those events already carry enough (`runId`, `status`) to update the
cached list directly, so this pull request event-sources that list
instead of refetching it
> - The benefit is that the always-observed live-runs list stops
refetching on run lifecycle events — the first concrete step of the
push-over-poll redesign

## Linked Issues or Issue Description

No public GitHub issue exists; describing inline per CONTRIBUTING.md →
"Link Issues or Describe Them In-PR", following the bug report template.
This continues the memory/CPU-churn work from #9569 and #9624.

**What happened?**

Live agent-run tabs accrue high idle CPU and off-heap memory because
live-update events cause HTTP refetches. Profiling showed the company
live-runs list — observed on almost every page via the sidebar — being
refetched on every run status change, one of the most frequent ambient
refetches.

**Expected behavior**

A websocket event that already carries the changed data should update
the cached list directly, without an HTTP round-trip, so the
always-observed live-runs list does no refetch on routine run lifecycle
events.

**Steps to reproduce**

Open the app with agents running and watch the network panel: `GET
/api/companies/:id/live-runs` fires on each `heartbeat.run.status` /
`heartbeat.run.queued` event even though the event payload already
describes the change.

**Paperclip version or commit**

Branch `perf/live-runs-event-sourced`, off `master` (after #9624).

**Deployment mode**

Local dev (`pnpm dev`), web UI. Core UI live-updates plumbing; not
adapter-specific.

## What Changed

- **`ui/src/lib/live-runs-cache.ts` (new)** — pure `removeRunFromList` /
`patchRunStatusInList` helpers for the cached `LiveRunForIssue[]`.
- **`ui/src/context/LiveUpdatesProvider.tsx`** — on
`heartbeat.run.queued` / `heartbeat.run.status`, patch
`liveRuns(companyId)` in place instead of invalidating it:
  - terminal status → remove the run from the list,
  - status change on a run already in the list → update it in place,
- a genuinely new run (can't be reconstructed from the event) → fall
back to a single `invalidateQueries` refetch.
- Removed the blanket `liveRuns` invalidation from
`invalidateHeartbeatQueries`.
- On websocket **reconnect**, refetch `liveRuns` once to reconcile
events missed while disconnected (durable replay is a later phase).
- Other resources these events invalidate (`dashboard`, `costs`,
`sidebarBadges`, `agents.list`, agent detail) are unchanged — they're
lower-frequency / less-often-observed and are follow-up phases. This
keeps the change scoped and **client-only** (no server changes).

## Verification

- `vitest`: new `live-runs-cache.test.ts` (remove/patch/no-op/undefined)
and new lifecycle-handler cases in `LiveUpdatesProvider.test.ts`
(terminal→remove, present→patch, new→needs-refetch) via
`__liveUpdatesTestUtils`. All existing `LiveUpdatesProvider` tests still
pass (33 total across the two files).
- `tsc -b` clean.
- Runtime: the event-sourced path is covered by unit tests; end-to-end
refetch reduction should be re-measured against a rebuilt bundle with
the network panel / MCP instrumentation.

## Risks

Low, and client-only.
- **Staleness across a dropped connection:** an event missed while the
socket is down isn't replayed yet, so the reconnect handler refetches
`liveRuns` once to reconcile. Durable event replay (Last-Event-ID) is a
planned later phase; until then reconnect-reconcile covers the gap.
- **New-run fallback:** a genuinely new run still triggers one refetch
(it can't be reconstructed from the event alone), so no new runs are
missed.
- Aggregate resources (dashboard/costs/badges) are untouched and still
invalidate (already coalesced), so their behavior is unchanged.

Follow-up phases (from the design discussion): event-source
`activity`/comments and the remaining class-B resources; give pure-poll
resources events and drop their intervals; add durable event sequence +
reconnect replay; and a shared bus (Postgres `LISTEN/NOTIFY`) only when
the API tier scales to >1 replica.

## Model Used

- **Provider:** Anthropic, via the Claude Code CLI.
- **Model:** Claude Opus 4.8 (`claude-opus-4-8`).
- **Reasoning mode:** Extended thinking enabled.
- **Capabilities used:** tool use (shell, file editing), sub-agent
fan-out to inventory the client polling and server push infrastructure,
and the Chrome DevTools MCP to reproduce/profile the churn that
motivated this redesign.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work (a perf/plumbing change, not planned core feature
work)
- [x] I have searched GitHub for duplicate or related PRs and linked
them above (continues #9569 / #9624; no duplicates)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have considered and documented any risks above
- [ ] I have updated relevant documentation to reflect my changes (N/A —
no user-facing docs; rationale documented inline)
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 15:40:35 -05:00
DottaandClaude Opus 4.8 3e348b96b9 perf(ui): cut live-updates churn that inflates tab memory (#9624)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its web UI keeps live views (issue threads, run transcripts,
dashboard) fresh via React Query polling plus a live-events websocket,
coordinated across tabs with a `BroadcastChannel` layer
> - Long-lived tabs viewing live agent runs grew to multi-GB memory
footprints while their JS heap stayed ~60–200 MB — so the memory is
off-heap (Blink/native + committed allocator arenas), not a classic JS
leak
> - Live profiling of a reproduced 2.7 GB / 66 MB tab showed 15–30% idle
CPU, ~3 fetches/sec across overlapping poll loops, and ~8 `setInterval`
create/clear cycles per second whose rate grew ~7× as the tab aged —
relentless allocation churn that inflates committed memory the OS never
reclaims, amplified across tabs by the cross-tab fan-out
> - This pull request cuts that churn at its four largest sources
(invalidation storm, per-instance 1 s timers, redundant polling,
unbounded streamed-run set)
> - The benefit is that idle tabs do far less periodic work, so their
off-heap footprint stops ballooning over a long session

## Linked Issues or Issue Description

No public GitHub issue exists; describing inline per CONTRIBUTING.md →
"Link Issues or Describe Them In-PR", following the bug report template.

**What happened?**

Browser tabs viewing live agent runs grew to 8–16 GB memory footprint
over a long session (multiple tabs open), while each tab's "live" JS
heap stayed only ~150–250 MB. Every idle tab also burned 15–30% CPU.
Tabs eventually approached the ~4 GB V8 heap ceiling / OS pressure and
could crash.

**Expected behavior**

Tabs viewing live runs should hold a bounded footprint and do minimal
work while idle, regardless of how long they stay open or how many tabs
are open.

**Steps to reproduce**

Open several issue/run tabs that have agents actively streaming and
leave them open for a while. Watch Chrome's Task Manager: Memory
Footprint climbs into the GBs while "JavaScript Memory" stays small, and
CPU stays high on idle tabs. Reproduced in ~90 minutes: a tab reached
2.7 GB footprint on a 66 MB JS heap, and the per-second timer-churn rate
was ~7× higher on a 90-minute-old tab than a fresh one.

**Paperclip version or commit**

Branch `fix/live-updates-churn`, off `master`.

**Deployment mode**

Local dev (`pnpm dev`), web UI. Not adapter-specific — core UI
live-updates plumbing (observed with `claude_local` / `codex_local`
runs).

## What Changed

- **`ui/src/lib/query-invalidation-batcher.ts` (new)** —
`createInvalidationBatcher` throttles + de-dupes React Query
invalidations into one flush per ~300 ms, and
`createCoalescingQueryClient` wraps the client via a `Proxy` so only
`invalidateQueries` is batched (optimistic `setQueryData` writes stay
immediate). Wired into `LiveUpdatesProvider`, which previously
invalidated synchronously on every websocket event.
- **`ui/src/hooks/useSecondTick.ts` (new)** — one shared, ref-counted,
page-wide 1 s ticker. `useLiveElapsed` in `IssueChatThread` now uses it
instead of a per-instance `setInterval` that forced a full-thread
re-render every second per live element.
- **`ui/src/components/transcript/useLiveRunTranscripts.ts`** — when the
realtime websocket is enabled, the recurring log poll backs off to a 30
s safety-net cadence instead of polling every 2 s on top of the live
stream. Added a marker for the durable poll→push rearchitecture.
- **`ui/src/lib/issueChatTranscriptRuns.ts`** —
`resolveIssueChatTranscriptRuns` now caps the streamed run set
(live/active runs always kept; most-recent linked runs fill up to 20) so
a large run history can't open a live-transcript poll per historical
run.
- **`ui/src/main.tsx`** — explicit `gcTime` so cross-tab-published cache
entries for unobserved resources are collected promptly.
- Tests for the batcher, shared ticker, and run cap.

## Verification

- `vitest`: new suites `query-invalidation-batcher.test.ts` (batcher
collapses 20 invalidations → 1 flush; keeps distinct keys/variants;
dispose cancels; proxy passes non-invalidate methods through),
`useSecondTick.test.tsx` (single ref-counted timer, stops when idle),
`issueChatTranscriptRuns.test.ts` (cap keeps newest + live). All pass.
- Existing affected suites pass: `LiveUpdatesProvider` (23),
`IssueChatThread` (), `useLiveRunTranscripts`,
`AgentDetail.instructions` — 109 tests across affected files.
- `tsc -b` clean.
- Behavior confirmed by live profiling before the change (2.7 GB / 66 MB
tab, ~8 interval churns/sec growing 7× with age). Runtime churn
reduction should be re-measured against a rebuilt bundle with the same
instrumentation.

## Risks

Low-to-moderate; all changes reduce work rather than add features.
- **Invalidation batching** delays live-driven refetches by up to ~300
ms. Optimistic `setQueryData` writes (e.g. the visible issue's new
comment) remain immediate, so foreground updates still feel instant;
only the safety-net refetch is throttled. Non-live invalidations (user
actions, mutations) are unaffected — they use the real client.
- **Poll back-off** relies on the websocket as the live source when
realtime is enabled; a 30 s fallback poll still covers gaps/reconnects
(both the transcript hook and `LiveUpdatesProvider` also
auto-reconnect).
- **Run cap (20)** means an issue with a very large run history streams
live transcripts only for its live/active + 20 most-recent runs; older
runs still open normally via their run pages.
- Downstream test fallout (timing-sensitive tests around
invalidation/polling) may need adjustment — flagged intentionally for
follow-up.

Durable follow-up (out of scope, marked in code): replace transcript/run
polling with server push (SSE/websocket deltas) so idle tabs do no
periodic work at all.

## Model Used

- **Provider:** Anthropic, via the Claude Code CLI.
- **Model:** Claude Opus 4.8 (`claude-opus-4-8`).
- **Reasoning mode:** Extended thinking enabled.
- **Capabilities used:** tool use (shell, file editing), sub-agent
fan-out for codebase analysis, and the Chrome DevTools MCP to reproduce
and profile the memory/CPU churn on a live instance.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work (a bug/perf fix, not planned core feature work)
- [x] I have searched GitHub for duplicate or related PRs and linked
them above (none found)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have considered and documented any risks above
- [ ] I have updated relevant documentation to reflect my changes (N/A —
no user-facing docs; rationale documented inline)
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 14:17:37 -05:00
89ce36d7af feat(skills): open-by-default company skill policy and core UX (#9564)
## Thinking Path

> - Paperclip uses company skills to make agent capabilities reusable
across an organization.
> - Skill operations currently mix capability availability with
permission checks, which creates avoidable setup friction and
inconsistent denial handling.
> - The policy contract needs to remain open by default while allowing
company-scoped restrictions for governed deployments.
> - Core owns the canonical policy actions, persistence, evaluation, API
behavior, safe import boundaries, and generic denial/read-only UI.
> - Enterprise policy-editor implementation belongs in the separate
`paperclip-ee` repository and is intentionally excluded from this PR.

### Problem or motivation

Company skill operations can encounter permission dead ends even when no
explicit restriction has been configured, and import-source
classification can drift between policy evaluation and execution.

### Proposed solution

Define eight canonical skill policy actions, default all actions to
allowed, persist company-scoped restrictions, expose policy evaluation
APIs, normalize import sources at the boundary, and update Skill Studio
to present actionable restriction states without embedding Enterprise
Edition implementation in the core repository.

### Alternatives considered

Keeping capability checks distributed across routes and UI surfaces was
rejected because it duplicates policy logic and makes denial behavior
inconsistent. Shipping the Enterprise policy editor in this repository
was rejected because `paperclip-ee` is a separate repository and must
receive its own PR.

### Roadmap alignment

Extends the completed **Skills Manager** roadmap area by adding coherent
governance and removing workflow dead ends.

### Additional context

The core API contract remains suitable for a separate Enterprise Edition
editor, but this PR contains no `paperclip-ee` package or EE-specific UI
integration code.

## What Changed

- Added the company skill policy contract to product and implementation
documentation, including the open-by-default rule, eight canonical
actions, decision shape, and core/EE ownership boundary.
- Added the company-scoped policy schema, migration `0170`, shared
validators, policy service, REST routes, OpenAPI coverage, and focused
server tests.
- Hardened import policy enforcement by normalizing import sources and
keeping source classification consistent between policy evaluation and
execution.
- Updated core Skill Studio behavior to remove generic permission dead
ends and show actionable policy/platform denial states only when an
operation is actually denied.
- Removed the `plugin-paperclip-ee` package, Docker wiring, EE
discovery/deep-link helpers, and EE-specific UI tests/stories from this
PR so that implementation can be submitted separately to the EE
repository.
- Preserved open-by-default behavior when no explicit company
restriction exists.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/skill-studio/SkillPolicySurfaces.test.tsx
src/lib/skill-policy-denial.test.ts` — 20/20 passed.
- `pnpm --filter @paperclipai/ui exec tsc --noEmit` — passed.
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/worktree-config.test.ts` — 12/12 passed.
- `pnpm check:token-gates` — passed with all gates clean.
- `git diff --check` — passed.
- `git diff --name-only origin/master | rg
'paperclip-ee|ee-skill-policy'` — no matches.

## Risks

- Migration `0170` introduces company policy persistence; rollout
depends on the migration applying before policy routes are exercised.
- Open-by-default is an intentional behavioral policy: deployments
expecting implicit denials must configure explicit restrictions.
- Import normalization is security-sensitive and should retain focused
review.
- The separate EE editor must stay contract-compatible with the core
policy API as policy actions evolve.

## Model Used

- OpenAI Codex CLI, runtime model identifier and context-window size not
exposed by this execution environment; reasoning, repository tool use,
shell execution, and code review capabilities enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details available to this runtime)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked or
described the result above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run focused tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green on the latest head
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Evyatar Bluzer <bluzername@users.noreply.github.com>
2026-07-15 11:42:40 -05:00
DottaandPaperclip f712cedbc2 feat(mcp) [split 7/8]: activate Apps and gateway UI (#9562)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Governed MCP access spans contracts, runtime enforcement, adapters,
UI surfaces, and operator verification
> - The parity reference PR #9534 is too large for effective automated
or human review
> - The feature therefore needs a linear stack whose individual diffs
stay below the 100-file review limit
> - This pull request is split 7/8 and focuses on Apps/Gateways UI and
feature-flagged activation
> - The benefit is a standalone, testable review boundary while
preserving byte-for-byte parity at the top of the stack

## Linked Issues or Issue Description

- Related parity reference: #9534
- Problem: The standalone UI foundation needs feature-flagged routes,
navigation, app detail flows, gateways, Storybook scenarios, and QA
configuration.
- Proposed solution: Adds Apps/Gateways pages and components,
navigation/route activation, remaining page integrations, Storybook
stories, and QA Vite configuration.
- Alternatives considered: keeping #9534 as one 403-file review, or
rewriting the feature to manufacture seams; both were rejected in favor
of path extraction plus compile-driven boundary moves.
- Roadmap alignment: this advances the existing governed MCP/tool-access
work already represented by #9534; it does not introduce a separate
roadmap initiative.
- Stack position: base branch is
`pap10341-split/06-ui-tools-foundation`.
- Merge policy: merge bottom-up, in order, only after the complete
eight-PR stack has been reviewed and the top-of-stack parity gate
remains empty.
- Requested review: UXDesigner sanity pass on Apps/Gateways flows and
flag-off behavior; Greptile on every PR.

## What Changed

- Adds Apps/Gateways pages and components, navigation/route activation,
remaining page integrations, Storybook stories, and QA Vite
configuration.
- Keeps this PR below 100 changed files and independently typecheckable.
- Preserves the final tree from #9534 when combined with the other seven
stack levels.

## Verification

- `pnpm typecheck`
- `pnpm check:token-gates` — all gates clean
- Focused UI Vitest run with `NODE_ENV=test` — 17 files, 147 tests
passed

## Risks

- Navigation or flag regressions could expose incomplete experiences;
activation remains controlled by existing experimental settings.
- Stack risk: merging out of order can expose incomplete layers;
mitigate by following the documented bottom-up merge policy.
- Parity risk: later edits to an intermediate branch can drift from
#9534; mitigate by re-running the empty top-of-stack diff before merge.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, exact model ID `gpt-5.4`; runtime-managed context
window; medium reasoning with repository, shell, Git, GitHub CLI, and
code-execution tools enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] Internal references are omitted except the execution-plan link
explicitly required for this coordinated split stack
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge


## Stack Coordination

- Internal execution plan:
[PAP-13874](/PAP/issues/PAP-13874#document-plan)
- Parity reference: #9534
- Stack: #9556 → #9557 → #9558 → #9559 → #9560 → #9561 → #9562 → #9563
- Merge bottom-up only after full-stack review and an empty parity diff
at #9563.


## UI Evidence

QA captured these from the live Garden MCP split stack at 1440px and
verified clean rendering:

![Apps
connections](https://raw.githubusercontent.com/paperclipai/paperclip/42512d030c96f678c379fbd97d8b7c1737d654fc/doc/screenshots/garden-mcp-split-stack/apps-list.png)

![Gateway
detail](https://raw.githubusercontent.com/paperclipai/paperclip/42512d030c96f678c379fbd97d8b7c1737d654fc/doc/screenshots/garden-mcp-split-stack/gateway-detail.png)

![BYO connect
wizard](https://raw.githubusercontent.com/paperclipai/paperclip/42512d030c96f678c379fbd97d8b7c1737d654fc/doc/screenshots/garden-mcp-split-stack/byo-connect.png)

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-14 15:40:08 -05:00
DottaandPaperclip a116713b9a feat(mcp) [split 6/8]: add Tools and Profiles UI foundation (#9561)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Governed MCP access spans contracts, runtime enforcement, adapters,
UI surfaces, and operator verification
> - The parity reference PR #9534 is too large for effective automated
or human review
> - The feature therefore needs a linear stack whose individual diffs
stay below the 100-file review limit
> - This pull request is split 6/8 and focuses on UI API, shared
components, and Tools/Profile surfaces
> - The benefit is a standalone, testable review boundary while
preserving byte-for-byte parity at the top of the stack

## Linked Issues or Issue Description

- Related parity reference: #9534
- Problem: Operators need typed clients and administration surfaces that
compile independently before navigation exposes them.
- Proposed solution: Adds UI APIs, hooks, libraries, shared components,
Tools/Profiles pages, and the plugin settings consumer required by the
new company-scoped API.
- Alternatives considered: keeping #9534 as one 403-file review, or
rewriting the feature to manufacture seams; both were rejected in favor
of path extraction plus compile-driven boundary moves.
- Roadmap alignment: this advances the existing governed MCP/tool-access
work already represented by #9534; it does not introduce a separate
roadmap initiative.
- Stack position: base branch is
`pap10341-split/05-runtime-integration`.
- Merge policy: merge bottom-up, in order, only after the complete
eight-PR stack has been reviewed and the top-of-stack parity gate
remains empty.
- Requested review: UXDesigner sanity pass on Tools/Profile surfaces;
Greptile on every PR.

## What Changed

- Adds UI APIs, hooks, libraries, shared components, Tools/Profiles
pages, and the plugin settings consumer required by the new
company-scoped API.
- Keeps this PR below 100 changed files and independently typecheckable.
- Preserves the final tree from #9534 when combined with the other seven
stack levels.

## Verification

- `pnpm typecheck`
- `pnpm check:token-gates` — all gates clean
- Focused UI Vitest run with `NODE_ENV=test` — 28 files, 183 tests
passed

## Risks

- Large dead-code UI additions can drift from activation routes; PR 7
supplies the registration layer and top-level parity catches omissions.
- Stack risk: merging out of order can expose incomplete layers;
mitigate by following the documented bottom-up merge policy.
- Parity risk: later edits to an intermediate branch can drift from
#9534; mitigate by re-running the empty top-of-stack diff before merge.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, exact model ID `gpt-5.4`; runtime-managed context
window; medium reasoning with repository, shell, Git, GitHub CLI, and
code-execution tools enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] Internal references are omitted except the execution-plan link
explicitly required for this coordinated split stack
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge


## Stack Coordination

- Internal execution plan:
[PAP-13874](/PAP/issues/PAP-13874#document-plan)
- Parity reference: #9534
- Stack: #9556 → #9557 → #9558 → #9559 → #9560 → #9561 → #9562 → #9563
- Merge bottom-up only after full-stack review and an empty parity diff
at #9563.


## UI Evidence

QA captured these from the live Garden MCP split stack at 1440px and
verified clean rendering:

![Profiles
index](https://raw.githubusercontent.com/paperclipai/paperclip/ac72de3ec85feb14c5ec1ed0a3d39b29baa0abff/doc/screenshots/garden-mcp-split-stack/profiles-index.png)

![Profile
wizard](https://raw.githubusercontent.com/paperclipai/paperclip/ac72de3ec85feb14c5ec1ed0a3d39b29baa0abff/doc/screenshots/garden-mcp-split-stack/profile-wizard.png)


![Policies](https://raw.githubusercontent.com/paperclipai/paperclip/ac72de3ec85feb14c5ec1ed0a3d39b29baa0abff/doc/screenshots/garden-mcp-split-stack/policies.png)

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-14 15:31:12 -05:00
Dotta c6d4ee10f7 test: align current-master regression expectations (#9577)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its server and UI test suites protect company-scoped plugin access
and instance settings behavior
> - Recent governed-access contracts intentionally added company
invocation scope and new experimental-setting defaults
> - Four existing tests were not updated consistently with those
contracts, causing current-master CI failures unrelated to the changes
under review
> - The runtime behavior is intentional, so changing production code
would weaken the new authorization and settings contracts
> - This pull request aligns the stale tests with current behavior and
removes one UI assertion accidentally pulled forward from a later
stacked feature
> - The benefit is a focused, low-risk repair that restores master CI
without changing application behavior

## Linked Issues or Issue Description

- **Bug:** Current master has four regression failures in plugin
authorization, plugin execution-workspace bridging, instance settings
normalization, and experimental settings UI tests.
- **Expected behavior:** Tests provide required company/invocation
scope, use the governed object-shaped secret reference contract, include
all current defaults, and only assert UI controls implemented at this
stack level.
- **Actual behavior:** Tests exercised obsolete request shapes or
expected a later-stack Apps toggle that is not present on current
master.
- **Reproduction:** Run the four test files listed in the Verification
section on master before this commit.

## What Changed

- Updates plugin config authorization coverage to include company scope
and an object-shaped `secret_ref` binding.
- Supplies invocation company scope to execution-workspace host-client
tests.
- Adds `enableApps` and `enableSmokeLab` to normalized settings
expectations.
- Removes the premature Apps toggle UI test introduced without its
later-stack implementation.

## Verification

- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/plugin-execution-workspace-bridge.test.ts
server/src/__tests__/instance-settings-service.test.ts
ui/src/pages/InstanceExperimentalSettings.test.tsx` — 73 tests passed.
- `pnpm exec vitest run
packages/plugins/sdk/tests/host-client-factory.test.ts
server/src/__tests__/plugin-secrets-handler.test.ts
server/src/__tests__/instance-settings-routes.test.ts
ui/src/lib/instance-settings.test.ts` — 39 tests passed.
- `git diff --check` — passed.

## Risks

- Low risk: test-only changes with no production runtime, schema, API,
or UI behavior changes.
- The removed Apps toggle assertion should return in the later stacked
change that introduces the actual control.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, exact model ID `gpt-5.4`; runtime-managed context
window; medium reasoning with repository, shell, GitHub CLI, and
code-execution tools enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-07-14 14:03:03 -05:00
DottaandPaperclip 1de0a3bb1e feat(mcp) [split 2/8]: add governed access contracts (#9557)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Governed MCP access spans contracts, runtime enforcement, adapters,
UI surfaces, and operator verification
> - The parity reference PR #9534 is too large for effective automated
or human review
> - The feature therefore needs a linear stack whose individual diffs
stay below the 100-file review limit
> - This pull request is split 2/8 and focuses on database schema and
shared governance contracts
> - The benefit is a standalone, testable review boundary while
preserving byte-for-byte parity at the top of the stack

## Linked Issues or Issue Description

- Related parity reference: #9534
- Problem: The governed access model needs additive persistence and
synchronized shared types before server enforcement can compile.
- Proposed solution: Adds migrations 0148–0169, tool-access and Smoke
Lab schema, shared types/validators/gallery helpers, and the minimal
compile-required contract consumers identified by boundary testing.
- Alternatives considered: keeping #9534 as one 403-file review, or
rewriting the feature to manufacture seams; both were rejected in favor
of path extraction plus compile-driven boundary moves.
- Roadmap alignment: this advances the existing governed MCP/tool-access
work already represented by #9534; it does not introduce a separate
roadmap initiative.
- Stack position: base branch is `pap10341-split/01-demo-servers`.
- Merge policy: merge bottom-up, in order, only after the complete
eight-PR stack has been reviewed and the top-of-stack parity gate
remains empty.
- Requested review: QA for migrations/validators; Greptile on every PR.

## What Changed

- Adds migrations 0148–0169, tool-access and Smoke Lab schema, shared
types/validators/gallery helpers, and the minimal compile-required
contract consumers identified by boundary testing.
- Keeps this PR below 100 changed files and independently typecheckable.
- Preserves the final tree from #9534 when combined with the other seven
stack levels.

## Verification

- `pnpm typecheck` — passed, including migration numbering and safety
checks
- `pnpm --filter @paperclipai/db test` — passed
- `pnpm --filter @paperclipai/shared test` — passed

## Risks

- Migration or contract mistakes could affect every upper layer; all
migrations are additive/idempotent and compile consumers are included in
this boundary.
- Stack risk: merging out of order can expose incomplete layers;
mitigate by following the documented bottom-up merge policy.
- Parity risk: later edits to an intermediate branch can drift from
#9534; mitigate by re-running the empty top-of-stack diff before merge.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, exact model ID `gpt-5.4`; runtime-managed context
window; medium reasoning with repository, shell, Git, GitHub CLI, and
code-execution tools enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] Internal references are omitted except the execution-plan link
explicitly required for this coordinated split stack
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge


## Stack Coordination

- Internal execution plan:
[PAP-13874](/PAP/issues/PAP-13874#document-plan)
- Parity reference: #9534
- Stack: #9556 → #9557 → #9558 → #9559 → #9560 → #9561 → #9562 → #9563
- Merge bottom-up only after full-stack review and an empty parity diff
at #9563.

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-14 12:57:20 -05:00
DottaandClaude Opus 4.8 f49a3f9924 fix(ui): cap live agent-run transcript buffers to bound tab memory (#9569)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents stream their run output live into the web UI, viewed per-run
in the `AgentDetail` transcript viewer
> - Browser tabs holding these views were sitting at 8–16 GB of memory
footprint while their JS heap stayed at ~256 MB — a 60×+ gap, meaning
the cost is in retained DOM / render objects, not JS objects
> - The `LogViewer` in `AgentDetail.tsx` kept every streamed
stdout/stderr line and structured event in unbounded React state and
rendered each into a rich DOM block (the default "nice" mode has no
virtualization), so a run streaming for hours grew an unbounded live DOM
tree
> - The sibling `useLiveRunTranscripts` hook (used by `IssueChatThread`)
already bounds its buffers and virtualizes; `LogViewer` bypassed it and
managed its own uncapped state — that inconsistency is the bug
> - This pull request caps the live buffers and bounds the live DOM
render, aligning `LogViewer` with the already-bounded path
> - The benefit is that long-lived streaming tabs no longer grow without
bound, cutting multi-GB tabs back to a bounded footprint

## Linked Issues or Issue Description

No public GitHub issue exists; describing inline per CONTRIBUTING.md →
"Link Issues or Describe Them In-PR", following the bug report template.

**What happened?**

Chrome's Task Manager showed multiple long-lived Paperclip tabs
(agent-run / task views) each consuming 8–16 GB of memory footprint,
while each tab's JS heap stayed at only ~150–256 MB. Memory grew
monotonically the longer a run streamed.

**Expected behavior**

A tab viewing a live agent run should hold a bounded amount of memory
regardless of how long the run streams.

**Steps to reproduce**

Open an agent run with a long-running / high-volume stream in
`AgentDetail`, leave the tab open while output streams for an extended
period, and watch the tab's memory footprint climb without bound in
Chrome's Task Manager.

**Paperclip version or commit**

`3991a19a` (branch `fix/agent-run-transcript-memory`, off `master`).

**Deployment mode**

Local dev (`pnpm dev`), web UI. Not adapter-specific — core UI bug in
the shared transcript viewer.

## What Changed

- Add `ui/src/lib/live-log-buffer.ts`: a pure `appendCapped(prev,
additions, max)` helper plus caps `MAX_LIVE_LOG_LINES=5000`,
`MAX_LIVE_EVENTS=2000`, and `LIVE_TRANSCRIPT_RENDER_LIMIT=1500`, with
rationale documented in the module.
- Add `ui/src/lib/live-log-buffer.test.ts`: 6 unit tests (append,
trim-to-cap, oversized batch, exact-cap, no-mutation, referential
bail-out).
- `ui/src/pages/AgentDetail.tsx` (`LogViewer`): route all four
live-append sites (WebSocket log / progress / event, plus the poll
fallback) through `appendCapped`, and pass
`limit={LIVE_TRANSCRIPT_RENDER_LIMIT}` to `RunTranscriptView` for live
runs so the "nice" view mounts only the most recent blocks.
- The terminated-run "Load more log" pagination is deliberately left
**uncapped** (guarded by `isLive`), so no historical output is lost —
older output remains on the server and reachable there.

## Verification

- `vitest run src/lib/live-log-buffer.test.ts` → 6/6 pass.
- Existing suites `RunTranscriptView.test.tsx`,
`AgentDetail.instructions.test.tsx`, `useLiveRunTranscripts.test.tsx` →
22/22 pass.
- `tsc -b` (UI) → clean.
- Manual/behavioral: live runs tail the last ~1500 blocks; terminated
runs still render full history via "Load more log". Follow-up planned to
profile before/after with the Chrome DevTools MCP.

## Risks

Low risk. Changes only bound **in-memory state for live runs**; the
terminated-run paginated path is untouched (still uncapped, guarded by
`isLive`). No API, schema, or persistence changes. Worst case for a live
run is that only the most recent 5000 lines / 1500 rendered blocks are
visible in the tab — which is the intended "tail" behavior, and full
history remains on the server.

## Model Used

- **Provider:** Anthropic, via the Claude Code CLI.
- **Model:** Claude Opus 4.8 (`claude-opus-4-8`).
- **Reasoning mode:** Extended thinking enabled.
- **Capabilities used:** tool use (shell execution, file editing),
sub-agent fan-out for the codebase memory sweep, and the Chrome DevTools
MCP for the diagnosis phase.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work (the ROADMAP "Memory" item is about company/agent
knowledge, unrelated to this browser-tab memory fix)
- [x] I have searched GitHub for duplicate or related PRs and linked
them above (none found among open PRs)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have considered and documented any risks above
- [ ] I have updated relevant documentation to reflect my changes (N/A —
no user-facing docs affected; rationale is documented inline in
`live-log-buffer.ts`)
- [ ] All Paperclip CI gates are green (in progress at time of writing)
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(the only open P2 was this missing template, which this update resolves;
awaiting re-review)
- [x] I will address all Greptile and reviewer comments before
requesting merge

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

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:43:05 -05:00
dependabot[bot] 2617bee422 build(deps-dev): bump @storybook/addon-docs from 10.4.6 to 10.5.0 (#9483)
Bumps
[@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs)
from 10.4.6 to 10.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">@​storybook/addon-docs's
releases</a>.</em></p>
<blockquote>
<h2>v10.5.0</h2>
<h2>10.5.0</h2>
<blockquote>
<p><em>Foundational changes for new AI workflows</em></p>
</blockquote>
<p>Storybook 10.5 contains hundreds of fixes and improvements:</p>
<ul>
<li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test
(preview)</li>
<li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li>
<li>🤖 Agentic review: AI-curated visual changesets and search results
(experimental)</li>
<li>⚛️ React docgen service: Unified metadata across MCP, Docs, and
Controls (experimental)</li>
<li>🧑‍💻 Claude / Codex plugins: One-click ADE integration
(experimental)</li>
</ul>
<!-- raw HTML omitted -->
<ul>
<li>A11y: Fix MDX heading anchors not keyboard accessible - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34368">#34368</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>A11y: Handle lang attribute throughout preview - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35321">#35321</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>A11y: Surface required args and keyboard-reachable Setup controls in
ArgsTable - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35306">#35306</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon A11y: Preserve disabled a11y rules with runOnly - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34649">#34649</a>,
thanks <a
href="https://github.com/cyphercodes"><code>@​cyphercodes</code></a>!</li>
<li>Addon Docs: DocsContent not filling available width when TOC is
enabled - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35043">#35043</a>,
thanks <a
href="https://github.com/k-utsumi"><code>@​k-utsumi</code></a>!</li>
<li>Addon Docs: Resolve CSF4 module exports without a default export -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34834">#34834</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Addon Docs: Resolve providerImportSource to a path instead of a
file:// URL - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34841">#34841</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Addon Vitest: Add an initialGlobals option to pin a project's
globals - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35226">#35226</a>,
thanks <a
href="https://github.com/lifeiscontent"><code>@​lifeiscontent</code></a>!</li>
<li>Addon Vitest: Avoid erroring out on benign Win process exits - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35287">#35287</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon Vitest: Fix dynamic import failure with Vitest 3 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34927">#34927</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon Vitest: Subscribe for run completion before triggering it - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35291">#35291</a>,
thanks <a
href="https://github.com/tsushanth"><code>@​tsushanth</code></a>!</li>
<li>Angular: Add versioned `@types/node` to packages installed during
`storybook init` - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34192">#34192</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Angular: Fix custom paths for stats.json on angular - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34551">#34551</a>,
thanks <a
href="https://github.com/mrginglymus"><code>@​mrginglymus</code></a>!</li>
<li>Angular: Fix zone.js drop in angular-to-angular-vite migration +
schema sync + transform widening - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35386">#35386</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Angular: Install <code>@​analogjs/vite-plugin-angular</code> in
angular-to-angular-vite automigration - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35432">#35432</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Angular: Introduce <code>@​storybook/angular-vite</code> package -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34202">#34202</a>,
thanks <a
href="https://github.com/brandonroberts"><code>@​brandonroberts</code></a>!</li>
<li>Angular: Support Angular 22 in Webpack framework - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35318">#35318</a>,
thanks <a
href="https://github.com/EtiennePasteur"><code>@​EtiennePasteur</code></a>!</li>
<li>Angular: Use future-proof API for component reflection - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35228">#35228</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Babel: Remove bugfixes from preset-env in v8 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35266">#35266</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Builder Vite: Fix empty external globals imports - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34348">#34348</a>,
thanks <a
href="https://github.com/raashish1601"><code>@​raashish1601</code></a>!</li>
<li>Builder Vite: Support configLoader via builder options - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34080">#34080</a>,
thanks <a
href="https://github.com/holvi-sebastian"><code>@​holvi-sebastian</code></a>!</li>
<li>CLI: Add `storybook ai <!-- raw HTML omitted -->` MCP passthrough
behind `STORYBOOK_FEATURE_AI_CLI` - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35125">#35125</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Add telemetry for the `storybook ai <!-- raw HTML omitted -->`
passthrough - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35138">#35138</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Allow -p shorthand to --port for ai command - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35390">#35390</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>CLI: Bundle the `ai` command in core so it never downloads
`@storybook/cli` - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35147">#35147</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Do not auto-open the browser in storybook dev under AI agents -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/35412">#35412</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Exit process after successful build - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34735">#34735</a>,
thanks <a
href="https://github.com/torleifhalseth"><code>@​torleifhalseth</code></a>!</li>
<li>CLI: Fix angular-to-angular-vite migration failing to configure
addon-vitest - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35404">#35404</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>CLI: Fix silent hang in deferred addon configuration during upgrade
- <a
href="https://redirect.github.com/storybookjs/storybook/pull/35423">#35423</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>CLI: Fix upgrade crash on Storybook latest version check - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35156">#35156</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>CLI: Handle nested array schema for AI help - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35424">#35424</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>CLI: Install MCP when upgrade is ran by agent - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35215">#35215</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>CLI: Load Storybook AI help from preset metadata - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35212">#35212</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Match `storybook ai` instances by config dir as well as cwd -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/35392">#35392</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@​storybook/addon-docs's
changelog</a>.</em></p>
<blockquote>
<h2>10.5.0</h2>
<blockquote>
<p><em>Foundational changes for new AI workflows</em></p>
</blockquote>
<p>Storybook 10.5 contains hundreds of fixes and improvements:</p>
<ul>
<li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test
(preview)</li>
<li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li>
<li>🤖 Agentic review: AI-curated visual changesets and search results
(experimental)</li>
<li>⚛️ React docgen service: Unified metadata across MCP, Docs, and
Controls (experimental)</li>
<li>🧑‍💻 Claude / Codex plugins: One-click ADE integration
(experimental)</li>
</ul>
<!-- raw HTML omitted -->
<ul>
<li>A11y: Fix MDX heading anchors not keyboard accessible - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34368">#34368</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>A11y: Handle lang attribute throughout preview - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35321">#35321</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>A11y: Surface required args and keyboard-reachable Setup controls in
ArgsTable - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35306">#35306</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon A11y: Preserve disabled a11y rules with runOnly - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34649">#34649</a>,
thanks <a
href="https://github.com/cyphercodes"><code>@​cyphercodes</code></a>!</li>
<li>Addon Docs: DocsContent not filling available width when TOC is
enabled - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35043">#35043</a>,
thanks <a
href="https://github.com/k-utsumi"><code>@​k-utsumi</code></a>!</li>
<li>Addon Docs: Resolve CSF4 module exports without a default export -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34834">#34834</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Addon Docs: Resolve providerImportSource to a path instead of a
file:// URL - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34841">#34841</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Addon Vitest: Add an initialGlobals option to pin a project's
globals - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35226">#35226</a>,
thanks <a
href="https://github.com/lifeiscontent"><code>@​lifeiscontent</code></a>!</li>
<li>Addon Vitest: Avoid erroring out on benign Win process exits - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35287">#35287</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon Vitest: Fix dynamic import failure with Vitest 3 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34927">#34927</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon Vitest: Subscribe for run completion before triggering it - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35291">#35291</a>,
thanks <a
href="https://github.com/tsushanth"><code>@​tsushanth</code></a>!</li>
<li>Angular: Add versioned <code>@types/node</code> to packages
installed during <code>storybook init</code> - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34192">#34192</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Angular: Fix custom paths for stats.json on angular - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34551">#34551</a>,
thanks <a
href="https://github.com/mrginglymus"><code>@​mrginglymus</code></a>!</li>
<li>Angular: Fix zone.js drop in angular-to-angular-vite migration +
schema sync + transform widening - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35386">#35386</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Angular: Install <code>@​analogjs/vite-plugin-angular</code> in
angular-to-angular-vite automigration - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35432">#35432</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Angular: Introduce <code>@​storybook/angular-vite</code> package -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34202">#34202</a>,
thanks <a
href="https://github.com/brandonroberts"><code>@​brandonroberts</code></a>!</li>
<li>Angular: Support Angular 22 in Webpack framework - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35318">#35318</a>,
thanks <a
href="https://github.com/EtiennePasteur"><code>@​EtiennePasteur</code></a>!</li>
<li>Angular: Use future-proof API for component reflection - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35228">#35228</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Babel: Remove bugfixes from preset-env in v8 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35266">#35266</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Builder Vite: Fix empty external globals imports - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34348">#34348</a>,
thanks <a
href="https://github.com/raashish1601"><code>@​raashish1601</code></a>!</li>
<li>Builder Vite: Support configLoader via builder options - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34080">#34080</a>,
thanks <a
href="https://github.com/holvi-sebastian"><code>@​holvi-sebastian</code></a>!</li>
<li>CLI: Add <code>storybook ai &lt;tool&gt;</code> MCP passthrough
behind <code>STORYBOOK_FEATURE_AI_CLI</code> - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35125">#35125</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Add telemetry for the <code>storybook ai &lt;command&gt;</code>
passthrough - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35138">#35138</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Allow -p shorthand to --port for ai command - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35390">#35390</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>CLI: Bundle the <code>ai</code> command in core so it never
downloads <code>@storybook/cli</code> - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35147">#35147</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Do not auto-open the browser in storybook dev under AI agents -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/35412">#35412</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Exit process after successful build - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34735">#34735</a>,
thanks <a
href="https://github.com/torleifhalseth"><code>@​torleifhalseth</code></a>!</li>
<li>CLI: Fix angular-to-angular-vite migration failing to configure
addon-vitest - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35404">#35404</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>CLI: Fix silent hang in deferred addon configuration during upgrade
- <a
href="https://redirect.github.com/storybookjs/storybook/pull/35423">#35423</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>CLI: Fix upgrade crash on Storybook latest version check - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35156">#35156</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>CLI: Handle nested array schema for AI help - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35424">#35424</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>CLI: Install MCP when upgrade is ran by agent - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35215">#35215</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>CLI: Load Storybook AI help from preset metadata - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35212">#35212</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Match <code>storybook ai</code> instances by config dir as well
as cwd - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35392">#35392</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
<li>CLI: Prefer agent-matched Storybook instances - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35235">#35235</a>,
thanks <a
href="https://github.com/kasperpeulen"><code>@​kasperpeulen</code></a>!</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/9dafcd22ed55947bc4c2fa1d5066b552baa0ebf4"><code>9dafcd2</code></a>
Bump version from &quot;10.5.0-beta.2&quot; to &quot;10.5.0&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/448db85e651a09ca55f978356c4f1593f261f82a"><code>448db85</code></a>
Bump version from &quot;10.5.0-beta.1&quot; to &quot;10.5.0-beta.2&quot;
[skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/a4ce9790a783d8e7720e9de980a08576de9555db"><code>a4ce979</code></a>
Bump version from &quot;10.5.0-beta.0&quot; to &quot;10.5.0-beta.1&quot;
[skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/f0bf138a0a83443c177f4b6882d74440829de42e"><code>f0bf138</code></a>
Bump version from &quot;10.5.0-alpha.11&quot; to
&quot;10.5.0-beta.0&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/fac05a57415eec36b0a72b383befd7ef5071572c"><code>fac05a5</code></a>
Bump version from &quot;10.5.0-alpha.10&quot; to
&quot;10.5.0-alpha.11&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/4057c4169f1e63d746d86349fcf4463e321b546e"><code>4057c41</code></a>
Bump version from &quot;10.5.0-alpha.9&quot; to
&quot;10.5.0-alpha.10&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/91b9c34e58bc91126baff5e184cefc20f9ada1ec"><code>91b9c34</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs/issues/35321">#35321</a>
from storybookjs/sidnioulz/fix-html-lang-refreshed</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/383d5905dbefbdbb673568ae06ea2afef07ce59e"><code>383d590</code></a>
Merge branch 'next' into sidnioulz/fix-html-lang-refreshed</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/520c70129d6fa0b5ede737ee0b1f16166096e6b8"><code>520c701</code></a>
UI: Add docs.lang and htmlLang parameters</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/d71aa77e16e650371a41f12f82cdc75e77d0ac1f"><code>d71aa77</code></a>
Merge origin/next into docgen/worker-threading</li>
<li>Additional commits viewable in <a
href="https://github.com/storybookjs/storybook/commits/v10.5.0/code/addons/docs">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>
2026-07-14 10:08:29 -07:00
dependabot[bot] d7961919f5 build(deps): bump react-i18next from 17.0.8 to 17.0.9 (#9481)
Bumps [react-i18next](https://github.com/i18next/react-i18next) from
17.0.8 to 17.0.9.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md">react-i18next's
changelog</a>.</em></p>
<blockquote>
<h2>17.0.9</h2>
<ul>
<li>fix: allow TypeScript 7 in the optional <code>typescript</code> peer
dependency range (<code>^5 || ^6 || ^7</code>). With
<code>typescript@7.0.2</code> in a project, <code>npm install</code>
failed with an <code>ERESOLVE</code> peer conflict. Fixes <a
href="https://redirect.github.com/i18next/react-i18next/issues/1927">#1927</a>,
thanks <a
href="https://github.com/andikapradanaarif"><code>@​andikapradanaarif</code></a>.</li>
<li>fix(types): <code>&lt;Trans t={t} ns=&quot;ns&quot; …&gt;</code>
with a <code>t</code> from <code>useTranslation(['ns'])</code> now
typechecks under TypeScript 7. TS7 intersects the <code>Ns</code>
inference candidates coming from the <code>t</code> prop (<code>readonly
['ns']</code>) and the <code>ns</code> prop (<code>'ns'</code>) into an
unsatisfiable <code>'ns' &amp; readonly ['ns']</code>, where TS6
resolved them. The <code>ns</code> prop on <code>TransProps</code>,
<code>TransSelectorProps</code> and
<code>IcuTransWithoutContextProps</code> now also accepts a single
namespace out of an array-typed <code>Ns</code> (<code>Ns | (Ns extends
readonly (infer S extends string)[] ? S : never)</code>) — which matches
runtime behavior and is unchanged under TS5/TS6.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/i18next/react-i18next/commit/8b4a9ea139b73309471737e5ba9c423f82d5c0cc"><code>8b4a9ea</code></a>
17.0.9</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/422bab13d4c9664e51c0c1025df2da37c0912075"><code>422bab1</code></a>
fix: support typescript 7 — widen peer range and fix Trans ns inference
under...</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/6e18aa95b5ff9257b477301283819697f249ea25"><code>6e18aa9</code></a>
README: mention npx i18next-cli localize as the zero-to-localized
path</li>
<li>See full diff in <a
href="https://github.com/i18next/react-i18next/compare/v17.0.8...v17.0.9">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 10:06:00 -07:00
dependabot[bot] ff09d8c1d8 build(deps): bump lexical from 0.46.0 to 0.47.0 (#9486)
Bumps
[lexical](https://github.com/facebook/lexical/tree/HEAD/packages/lexical)
from 0.46.0 to 0.47.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/lexical/releases">lexical's
releases</a>.</em></p>
<blockquote>
<p>v0.47.0 is a monthly release with a lot of bug fixes, particularly
related to IME and composition, and is headlined by two new experimental
packages:</p>
<ul>
<li><a
href="https://lexical.dev/docs/api/modules/lexical_mdast"><code>@lexical/mdast</code></a>
(<a
href="https://redirect.github.com/facebook/lexical/pull/8794">#8794</a>)
— a <a href="https://github.com/micromark/micromark">micromark</a>/<a
href="https://github.com/syntax-tree/mdast">mdast</a>-based alternative
to <code>@lexical/markdown</code>. Parsing, serialization, and markdown
shortcuts all go through the same parser used by <code>remark</code>, so
CommonMark + GFM compliance comes for free and there is no second
grammar to keep in sync. The original syntax of each construct is
preserved on the nodes, so re-serializing produces minimally different
Markdown. <code>@lexical/markdown</code> remains the supported default
for production apps. See the new <a
href="https://lexical.dev/docs/serialization/markdown-mdast">Markdown
with <code>@lexical/mdast</code> guide</a>.</li>
<li><a
href="https://lexical.dev/docs/api/modules/lexical_a11y"><code>@lexical/a11y</code></a>
(<a
href="https://redirect.github.com/facebook/lexical/pull/8591">#8591</a>)
— framework-agnostic accessibility helpers (ARIA live regions, focus
management, roving tab index, focus trap) usable from React, Svelte,
Vue, Solid, or vanilla DOM, with React wrappers shipping from
<code>@lexical/react</code>. The playground adopts them as part of a
WCAG AA reference pass, and the keyboard contracts Lexical follows are
documented in the new <a
href="https://lexical.dev/docs/concepts/keyboard-accessibility">Keyboard
Accessibility guide</a>.</li>
</ul>
<p>Beyond the headliners: React 18 is now the baseline (see Breaking
Changes), the playground gains Find and Replace and a Ruby annotation
node with a floating editor, tables learn to spread pasted TSV across
cells and get row/column header utilities, and there is a long list of
IME/composition, selection, and navigation fixes.</p>
<p>Special recognition once again goes to <a
href="https://github.com/mayrang"><code>@​mayrang</code></a> who has
been plowing through IME, accessibility, and other input related issues
as well as the really cool new Find and Replace and Ruby Annotations
playground features.</p>
<h2>Breaking Changes</h2>
<h3><code>@lexical/react</code> / <code>@lexical/devtools-core</code> —
React 17 support dropped (<a
href="https://redirect.github.com/facebook/lexical/pull/8782">#8782</a>)</h3>
<p>React 18 is now the minimum supported version; the <code>react</code>
/ <code>react-dom</code> peerDependencies require <code>&gt;=18</code>,
and React 17 compatibility code paths were removed. If you are already
on React 18 or 19, no changes are required.</p>
<h3><code>lexical</code> — DOM element preserved when composing on a
segmented TextNode (<a
href="https://redirect.github.com/facebook/lexical/pull/8784">#8784</a>)</h3>
<p>Starting IME composition in the middle of a segmented
<code>TextNode</code> (e.g. a mention) previously replaced the node —
destroying its DOM element and breaking the browser's composition
tracking (caret flashing and styling bleed on Chrome). The node now
temporarily switches to <code>normal</code> mode for the duration of
composition, keeping the same node key and DOM element, and is cleaned
up when composition ends. Subclass transforms or method overrides that
assume a segmented node is always in segmented mode must account for
this transient state — see the updated <a
href="https://lexical.dev/docs/api/classes/lexical.TextNode#setmode"><code>TextNode.setMode()</code>
documentation</a>.</p>
<h2>New APIs</h2>
<ul>
<li><a
href="https://lexical.dev/docs/api/modules/lexical"><code>lexical</code></a>
— <code>$getDocument()</code> returns the owner document of the active
editor (correct inside a <a
href="https://lexical.dev/docs/concepts/shadow-dom">Shadow DOM or
iframe</a>), falling back to the global document when there is no active
editor; a new <code>@lexical/eslint-plugin</code> rule enforces its use
over the <code>document</code> global (<a
href="https://redirect.github.com/facebook/lexical/pull/8788">#8788</a>,
<a
href="https://redirect.github.com/facebook/lexical/pull/8813">#8813</a>)</li>
<li><a
href="https://lexical.dev/docs/api/modules/lexical"><code>lexical</code></a>
— <code>registerEventListener</code> /
<code>registerEventListeners</code>, type-safe
<code>addEventListener</code> helpers that return cleanup functions, now
used throughout the codebase — see the updated <a
href="https://lexical.dev/docs/concepts/dom-events">Working with DOM
Events guide</a> (<a
href="https://redirect.github.com/facebook/lexical/pull/8767">#8767</a>)</li>
<li><a
href="https://lexical.dev/docs/api/modules/lexical"><code>lexical</code></a>
— <code>SET_TEXT_FORMAT_COMMAND</code> sets (rather than toggles) the
selection's text format (see <a
href="https://lexical.dev/docs/concepts/commands">Commands</a>); the
same PR fixes <code>formatText</code> toggle direction (<a
href="https://redirect.github.com/facebook/lexical/pull/8807">#8807</a>)</li>
<li><a
href="https://lexical.dev/docs/api/modules/lexical_markdown"><code>@lexical/markdown</code></a>
— <code>$generateNodesFromMarkdownString</code> parses a markdown string
into Lexical nodes without inserting them into the document or modifying
the selection (<a
href="https://redirect.github.com/facebook/lexical/pull/8789">#8789</a>)</li>
<li><a
href="https://lexical.dev/docs/api/modules/lexical_table"><code>@lexical/table</code></a>
— <code>$setTableRowIsHeader</code> and
<code>$setTableColumnIsHeader</code> utilities (<a
href="https://redirect.github.com/facebook/lexical/pull/8815">#8815</a>);
<code>$insertTableRowAtNode</code> and
<code>$insertTableColumnAtNode</code> are now exported (<a
href="https://redirect.github.com/facebook/lexical/pull/8791">#8791</a>)</li>
</ul>
<h2>Notable Fixes</h2>
<p><strong>IME, composition &amp; mobile</strong></p>
<ul>
<li>Prevent text duplication on iOS Safari when formatting during
composition (<a
href="https://redirect.github.com/facebook/lexical/pull/8755">#8755</a>)</li>
<li>Skip ZWSP insertion for format mismatch on Android Chrome (<a
href="https://redirect.github.com/facebook/lexical/pull/8769">#8769</a>);
deduplicate speech-to-text insertion on Android Chrome (<a
href="https://redirect.github.com/facebook/lexical/pull/8759">#8759</a>)</li>
<li>Event module globals moved into per-editor <code>InputState</code>
(<a
href="https://redirect.github.com/facebook/lexical/pull/8809">#8809</a>);
refactored IME composition test infrastructure with browser-level
coverage (<a
href="https://redirect.github.com/facebook/lexical/pull/8793">#8793</a>)</li>
</ul>
<p><strong>Selection &amp; navigation</strong></p>
<ul>
<li>ArrowUp/Down no longer skip block decorators (<a
href="https://redirect.github.com/facebook/lexical/pull/8775">#8775</a>);
<code>deleteLine</code> no longer removes adjacent block decorators (<a
href="https://redirect.github.com/facebook/lexical/pull/8744">#8744</a>)</li>
<li>Keep selection inside single-child inline elements (<a
href="https://redirect.github.com/facebook/lexical/pull/8772">#8772</a>);
fix navigation across unmergeable TextNode boundaries in inline-grid
containers (<a
href="https://redirect.github.com/facebook/lexical/pull/8797">#8797</a>)</li>
<li><code>$setBlocksType</code> properly handles block-end focus in
backward selections (<a
href="https://redirect.github.com/facebook/lexical/pull/8753">#8753</a>);
<code>insertNodes</code> re-resolves a detached firstBlock (<a
href="https://redirect.github.com/facebook/lexical/pull/8764">#8764</a>)</li>
<li>Place the block cursor between decorators and shadow roots (<a
href="https://redirect.github.com/facebook/lexical/pull/8758">#8758</a>);
clean up the trailing shadow root after select-all delete (<a
href="https://redirect.github.com/facebook/lexical/pull/8751">#8751</a>)</li>
<li><code>deleteCharacter</code> no longer overwrites the X11 PRIMARY
selection via <code>Selection.modify</code> (<a
href="https://redirect.github.com/facebook/lexical/pull/8774">#8774</a>)</li>
<li>Defer <code>onUpdate</code> callbacks during nested commits (<a
href="https://redirect.github.com/facebook/lexical/pull/8672">#8672</a>)</li>
</ul>
<p><strong>Markdown, code &amp; tables</strong></p>
<ul>
<li>Fence-like lines inside a code block stay content (<a
href="https://redirect.github.com/facebook/lexical/pull/8734">#8734</a>);
prevent formatting on <code>TabNode</code> inside code blocks (<a
href="https://redirect.github.com/facebook/lexical/pull/8752">#8752</a>)</li>
<li>Pasted TSV text spreads across table cells (<a
href="https://redirect.github.com/facebook/lexical/pull/8780">#8780</a>)</li>
</ul>
<p><strong>Playground &amp; website</strong></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/lexical/blob/main/CHANGELOG.md">lexical's
changelog</a>.</em></p>
<blockquote>
<h2>v0.47.0 (2026-07-10)</h2>
<ul>
<li>lexicallexical-rich-text Bug Fix Fix formatText toggle direction and
add SETTEXTFORMATCOMMAND (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8807">#8807</a>)
mayrang</li>
<li>scripts Bug Fix Let npm prompt for OTP when publishing bootstrap
stubs (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8820">#8820</a>)
Bob Ippolito</li>
<li>lexical-playground Bug Fix Clear inline font-size when converting to
heading (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8800">#8800</a>)
mayrang</li>
<li>lexical-tablelexical-playground Feature setTableRowIsHeader and
setTableColumnIsHeader utilities (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8815">#8815</a>)
mayrang</li>
<li>lexical-website Documentation Update Rewrite testing guide (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8811">#8811</a>)
mayrang</li>
<li>lexical-mdastlexical-rich-text Feature lexicalmdast, a
micromarkmdast-based alternative to lexicalmarkdown (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8794">#8794</a>)
Bob Ippolito</li>
<li>Make dependency-check resilient to transient registry errors (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8818">#8818</a>)
Gerard Rovira</li>
<li>lexical Refactor Move event module globals into per-editor
InputState (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8809">#8809</a>)
mayrang</li>
<li>lexical Bug Fix getDocument() should fall back to the global
document when there is no active editor (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8813">#8813</a>)
Sherry</li>
<li>lexical-playground Bug Fix Keep cell background color modal open on
first click (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8806">#8806</a>)
sahir</li>
<li>lexical-playground Bug Fix Use consistent default maxWidth for
markdown-imported images (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8810">#8810</a>)
mayrang</li>
<li>lexical-devtoolslexical-playground Chore Update flow, hermes, and
babel packages to latest (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8795">#8795</a>)
Bob Ippolito</li>
<li>Add a 7-day pnpm minimumReleaseAge to match the Dependabot cooldown
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8808">#8808</a>)
Gerard Rovira</li>
<li>lexical Chore Fix tmp package dependency vulnerability (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8802">#8802</a>)
vijay ojha</li>
<li>lexical Chore Add missing Flow type declarations (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8799">#8799</a>)
mayrang</li>
<li>lexical-markdown Feature Add generateNodesFromMarkdownString (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8789">#8789</a>)
mayrang</li>
<li>lexicallexical-playground Chore Refactor IME composition test
infrastructure and add browser-level coverage (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8793">#8793</a>)
mayrang</li>
<li>lexical-playground Bug Fix Use viewBox dimensions for unsized
Excalidraw output (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8798">#8798</a>)
mayrang</li>
<li>lexical-table Bug Fix Export insertTableRowAtNode and
insertTableColumnAtNode (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8791">#8791</a>)</li>
<li>lexical-playgroundlexical-website Feature Add Vercel Analytics and
Speed Insights (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8796">#8796</a>)
Gerard Rovira</li>
<li>lexicallexical-eslint-plugin Feature Add getDocument() API and
Shadow DOM lint enforcement (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8788">#8788</a>)
mayrang</li>
<li>scripts Bug Fix strip misplaced pure annotations from prod builds
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8786">#8786</a>)
Bob Ippolito</li>
<li>lexical Bug Fix deleteCharacter overwrites X11 PRIMARY selection via
Selection.modify (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8774">#8774</a>)
Bob Ippolito</li>
<li>lexical-playground Bug Fix Support Unicode URLs in autolink matcher
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8787">#8787</a>)
mayrang</li>
<li>lexical-table Feature Spread pasted TSV text across table cells (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8780">#8780</a>)
mayrang</li>
<li>Breaking Changelexical Bug Fix Preserve DOM element when composing
on segmented TextNode middle (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8784">#8784</a>)
mayrang</li>
<li>Breaking Changelexical-reactlexical-devtools-core Chore Drop React
17 support, baseline is now React 18 (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8782">#8782</a>)
Bob Ippolito</li>
<li>lexical-playgroundlexical Feature Ruby annotation node with floating
editor (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8741">#8741</a>)
mayrang</li>
<li>lexical-playground Feature Find and Replace (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8779">#8779</a>)
mayrang</li>
<li>lexical-playground Bug Fix restore RTL checkbox position in
checklist (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8783">#8783</a>)
Aldo Ryanda</li>
<li>lexical-rich-text Bug Fix Stop ArrowUpDown from skipping block
decorators (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8775">#8775</a>)
mayrang</li>
<li>lexical-playground Bug Fix Convert remaining icon glyphs to
mask-image for forced-colors support (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8781">#8781</a>)
mayrang</li>
<li>fix(lexical) use extends for type parameter bound in
registerEventListeners flow type (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8778">#8778</a>)
Sherry</li>
<li>lexical Bug Fix Keep selection inside single-child inline elements
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8772">#8772</a>)
mayrang</li>
<li>lexical Feature registerEventListener registerEventListeners DOM
helpers (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8767">#8767</a>)
Bob Ippolito</li>
<li>lexical-playground Bug Fix Restore floating toolbar comment icon
after mask-image conversion (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8773">#8773</a>)
mayrang</li>
<li>lexical Bug Fix Skip ZWSP insertion for format mismatch on Android
Chrome (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8769">#8769</a>)
mayrang</li>
<li>lexical-a11ylexical-reactlexical-playgroundlexical-website Feature
lexicala11y framework-agnostic accessibility helpers WCAG AA reference
adoption (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8591">#8591</a>)
mayrang</li>
<li>Add missing copyright headers to 4 source files (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8768">#8768</a>)
xiezhenjia-meta</li>
<li>lexical-website Bug Fix Remove horizontal scroll on homepage hero
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8760">#8760</a>)
Bakhtiyar</li>
<li>lexical-selection Bug Fix re-resolve detached firstBlock in insert
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8764">#8764</a>)
Olivier Chevallier</li>
<li>lexical Modernize InlineFormattableNode Flow stub syntax rejected by
fb-www flow strict (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8763">#8763</a>)
Sherry</li>
<li>lexical-utils Bug Fix positionNodeOnRange leaking orphan rect nodes
when rects shrink (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8762">#8762</a>)
Durvesh Pilankar</li>
<li>docs fix duplicated words in comments and docs (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8761">#8761</a>)
Durvesh Pilankar</li>
<li>lexical-selection Bug Fix Properly handle block end focus in
backward selections during setBlocksType (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8753">#8753</a>)
Olivier Chevallier</li>
<li>lexicallexical-extension Bug Fix Align DecoratorTextNode format with
TextNode in mixed selections (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8737">#8737</a>)
sahir</li>
<li>lexical Bug Fix Clean up trailing shadow root after select-all
delete (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8751">#8751</a>)
mayrang</li>
<li>lexicallexical-rich-text Bug Fix Place block cursor between
decorators and shadow roots (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8758">#8758</a>)
mayrang</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/facebook/lexical/commit/77ccc19b1e65dbd8a7a2e1c6f5628ee84551b0ef"><code>77ccc19</code></a>
v0.47.0</li>
<li><a
href="https://github.com/facebook/lexical/commit/18a0abf202786afc4dc23ef8aa8494f74e359422"><code>18a0abf</code></a>
[lexical][lexical-rich-text][lexical-selection] Bug Fix: Fix navigation
acros...</li>
<li><a
href="https://github.com/facebook/lexical/commit/02d2562c99028cf2c0494c8f1c7301bed0e1c558"><code>02d2562</code></a>
[lexical][lexical-rich-text] Bug Fix: Fix formatText toggle direction
and add...</li>
<li><a
href="https://github.com/facebook/lexical/commit/932aa67ec95dd86384d2e7e5ed80544e06f60e0f"><code>932aa67</code></a>
[lexical] Refactor: Move event module globals into per-editor InputState
(<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8809">#8809</a>)</li>
<li><a
href="https://github.com/facebook/lexical/commit/b00510c74a98fbc46dea13ef42afff2218ad7ea9"><code>b00510c</code></a>
[lexical] Bug Fix: $getDocument() should fall back to the global
document whe...</li>
<li><a
href="https://github.com/facebook/lexical/commit/a7666ab11f5e8c674a3f5ca8a83d2e92f1b171d0"><code>a7666ab</code></a>
[*][lexical-devtools][lexical-playground] Chore: Update flow, hermes,
and bab...</li>
<li><a
href="https://github.com/facebook/lexical/commit/c07e832ab8dfee640e5348335f7210a1edac5917"><code>c07e832</code></a>
[lexical] Chore: Add missing Flow type declarations (<a
href="https://github.com/facebook/lexical/tree/HEAD/packages/lexical/issues/8799">#8799</a>)</li>
<li><a
href="https://github.com/facebook/lexical/commit/38051a7498461da265a9b670ef1f3585319d4543"><code>38051a7</code></a>
[lexical][lexical-playground] Chore: Refactor IME composition test
infrastruc...</li>
<li><a
href="https://github.com/facebook/lexical/commit/e649ab28b7e2dd58c1b4798c446e611f54356518"><code>e649ab2</code></a>
[lexical][lexical-eslint-plugin] Feature: Add $getDocument() API and
Shadow D...</li>
<li><a
href="https://github.com/facebook/lexical/commit/69abb09cec921e73512d17d6a53bb5e2064d7b72"><code>69abb09</code></a>
[lexical] Bug Fix: deleteCharacter overwrites X11 PRIMARY selection via
Selec...</li>
<li>Additional commits viewable in <a
href="https://github.com/facebook/lexical/commits/v0.47.0/packages/lexical">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 10:02:57 -07:00
dependabot[bot] dcb7c323ed build(deps-dev): bump @storybook/react-vite from 10.4.6 to 10.5.0 (#9482)
Bumps
[@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite)
from 10.4.6 to 10.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">@​storybook/react-vite's
releases</a>.</em></p>
<blockquote>
<h2>v10.5.0</h2>
<h2>10.5.0</h2>
<blockquote>
<p><em>Foundational changes for new AI workflows</em></p>
</blockquote>
<p>Storybook 10.5 contains hundreds of fixes and improvements:</p>
<ul>
<li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test
(preview)</li>
<li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li>
<li>🤖 Agentic review: AI-curated visual changesets and search results
(experimental)</li>
<li>⚛️ React docgen service: Unified metadata across MCP, Docs, and
Controls (experimental)</li>
<li>🧑‍💻 Claude / Codex plugins: One-click ADE integration
(experimental)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@​storybook/react-vite's
changelog</a>.</em></p>
<blockquote>
<h2>10.5.0</h2>
<blockquote>
<p><em>Foundational changes for new AI workflows</em></p>
</blockquote>
<p>Storybook 10.5 contains hundreds of fixes and improvements:</p>
<ul>
<li>⚡️ Angular-vite framework: Modern, fast dev, docs, and test
(preview)</li>
<li>🌈 Vitest initialGlobals: Test across themes, viewports, locales</li>
<li>🤖 Agentic review: AI-curated visual changesets and search results
(experimental)</li>
<li>⚛️ React docgen service: Unified metadata across MCP, Docs, and
Controls (experimental)</li>
<li>🧑‍💻 Claude / Codex plugins: One-click ADE integration
(experimental)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/9dafcd22ed55947bc4c2fa1d5066b552baa0ebf4"><code>9dafcd2</code></a>
Bump version from &quot;10.5.0-beta.2&quot; to &quot;10.5.0&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/448db85e651a09ca55f978356c4f1593f261f82a"><code>448db85</code></a>
Bump version from &quot;10.5.0-beta.1&quot; to &quot;10.5.0-beta.2&quot;
[skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/a4ce9790a783d8e7720e9de980a08576de9555db"><code>a4ce979</code></a>
Bump version from &quot;10.5.0-beta.0&quot; to &quot;10.5.0-beta.1&quot;
[skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/f0bf138a0a83443c177f4b6882d74440829de42e"><code>f0bf138</code></a>
Bump version from &quot;10.5.0-alpha.11&quot; to
&quot;10.5.0-beta.0&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/fac05a57415eec36b0a72b383befd7ef5071572c"><code>fac05a5</code></a>
Bump version from &quot;10.5.0-alpha.10&quot; to
&quot;10.5.0-alpha.11&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/4057c4169f1e63d746d86349fcf4463e321b546e"><code>4057c41</code></a>
Bump version from &quot;10.5.0-alpha.9&quot; to
&quot;10.5.0-alpha.10&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/da84210b49cdbb1de724c6c5d590ae3d6945887f"><code>da84210</code></a>
Bump version from &quot;10.5.0-alpha.8&quot; to
&quot;10.5.0-alpha.9&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/c347410b9f96f3526cf72d20a7f3762153039694"><code>c347410</code></a>
Bump version from &quot;10.5.0-alpha.7&quot; to
&quot;10.5.0-alpha.8&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/d16ab3008ac721c8311f940183687cc86643a053"><code>d16ab30</code></a>
React: Align react-docgen versions</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/c9a1ac9f72fc5c03b70180a247d42691b26c6904"><code>c9a1ac9</code></a>
Bump version from &quot;10.5.0-alpha.6&quot; to
&quot;10.5.0-alpha.7&quot; [skip ci]</li>
<li>Additional commits viewable in <a
href="https://github.com/storybookjs/storybook/commits/v10.5.0/code/frameworks/react-vite">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@storybook/react-vite&package-manager=npm_and_yarn&previous-version=10.4.6&new-version=10.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 10:02:39 -07:00
dependabot[bot] 26bd07400b build(deps-dev): bump tailwindcss from 4.3.0 to 4.3.2 (#9477)
Bumps
[tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)
from 4.3.0 to 4.3.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">tailwindcss's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.2</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
<h2>v4.3.1</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Generate <code>0</code> instead of <code>calc(var(--spacing) *
0)</code> for spacing utilities like <code>m-0</code> and
<code>left-0</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">tailwindcss's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.2] - 2026-06-26</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
<h2>[4.3.1] - 2026-06-12</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/056a1550721d4bf79ff732d5ab9414fa83f7064f"><code>056a155</code></a>
4.3.2 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20281">#20281</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/c8b081d96376871acb0157923e894b7a929cad5b"><code>c8b081d</code></a>
Add suggestions for named opacity modifiers (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20287">#20287</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/c46f654fa0039ad4741c6ecefbe4e2a208a665c3"><code>c46f654</code></a>
Ensure <code>--alpha(…)</code> is seen as a <code>color</code>, and
<code>--spacing(…)</code> is seen as a `le...</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/5e9f66e4284164c62e80d74e69e0cbd8d9c645cc"><code>5e9f66e</code></a>
Ensure <code>@variant</code> can be used in JS based APIs (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20252">#20252</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/707c23b955bdfa7854a03195e503b95dd730b3d2"><code>707c23b</code></a>
Ensure custom variants can be used via <code>@variant</code> in
<code>addBase</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20247">#20247</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/127d17033a0518701dac8332667b12e0980870ec"><code>127d170</code></a>
Add bare value support for <code>auto-rows-*</code> and
<code>auto-cols-*</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20229">#20229</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/8a14a710102cae195f6811e8578bef9477bc6be9"><code>8a14a71</code></a>
4.3.1 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20226">#20226</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/12833aa4b3a8813fd32da74be7a2fd75aa706ab7"><code>12833aa</code></a>
Fix canonicalization bug where we end up with a high precision number
(<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20221">#20221</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/97a5b3abfb75ce9722266cd323a24eee057634fc"><code>97a5b3a</code></a>
docs: fix double word 'to to' in test comment (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20216">#20216</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/d01e103cc4741c29764afaa287d2fb21356f7eea"><code>d01e103</code></a>
Add missing <code>inset</code> keyword for
<code>inset-shadow-none</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20208">#20208</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/tailwindcss">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 10:02:37 -07:00
DottaandPaperclip 6f204605ad fix(ui): show source SHA for unreleased builds (#9508)
## Thinking Path

> - Paperclip is the open source control plane people use to manage
AI-agent companies
> - Operators need to identify the exact build running from the
persistent account menu
> - Formal releases already have a concise public version, but source
builds include a long derived version string
> - The derived version identifies a commit but does not expose the
source branch or a direct path to inspect the code
> - Server Git metadata is auth-sensitive, so the UI must also refresh
it when the current session changes
> - This pull request shows linked branch and commit metadata for source
builds while preserving `v<version>` for formal releases
> - The benefit is faster build diagnosis with correct metadata across
sign-in and sign-out transitions

## Linked Issues or Issue Description

### Pre-submission checklist

- [x] I searched existing open and closed issues and found no duplicate
implementing this exact account-menu behavior.
- [x] The behavior reproduces on `master`.
- [x] The behavior originates in Paperclip's core UI, not an adapter,
provider, or local configuration.

### What happened?

Source builds displayed the full derived version, such as
`2026.626.0+58.git.518fc71ce`, without linking the operator to the
corresponding source branch or commit.

### Expected behavior

Source builds should show the concise branch and short commit SHA with
links to GitHub, while formal releases should continue showing their
public version. Auth transitions should refresh the health metadata that
supplies those Git details.

### Steps to reproduce

1. Run Paperclip from a commit after a release tag.
2. Open the account menu.
3. Inspect the build label beneath the user identity.
4. Sign in or out and reopen the menu.

### Paperclip version or commit

Any source build whose server version uses the
`<version>+<count>.git.<sha>[.dirty]` format.

### Deployment mode

Local dev (`pnpm dev`) or authenticated deployments.

### Installation method

Built from source.

## What Changed

- Detect source-derived version strings and render the source branch
plus seven-character commit SHA in `SidebarAccountMenu`.
- Link source branches and commits to the canonical
`paperclipai/paperclip` GitHub repository.
- Extend server Git metadata with the full SHA and expose it through
health/OpenAPI contracts.
- Refresh auth-sensitive health metadata after sign-in and every
sign-out entry point.
- Preserve the existing `v<version>` label for formal releases and add
focused regression coverage.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run src/pages/Auth.test.tsx
src/components/SidebarAccountMenu.test.tsx
src/components/SidebarServerInfo.test.tsx`
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/health.test.ts src/__tests__/server-info.test.ts`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm check:token-gates`
- `git diff --check public/master...HEAD`

## Risks

- Low risk: formal release rendering retains the existing fallback
behavior when the source-version pattern does not match.
- Source links assume the build came from the canonical public
repository; fork-only branches or commits may not resolve there.
- Health metadata is invalidated after auth transitions, adding one
bounded refetch so the displayed Git details match the new session.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex using GPT-5.4 with medium reasoning, repository/tool
access, shell execution, and code editing; context-window size was not
exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-13 20:55:54 -05:00
Devin FoleyandCody b49d178c46 fix(ui): experiments auto-recovery dialog leaves UI dimmed and locked after enabling (#9513)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators tune instance behavior through Settings → Experiments,
where experimental features are toggled on and off
> - The task graph liveness auto-recovery experiment shows a
confirmation dialog (preview of what would be recovered) before it is
enabled
> - After confirming with "Enable only" or "Enable and run", the
dialog's Radix overlay and the `pointer-events: none` body lock were
left behind, dimming the page and blocking all interaction until a
refresh
> - The dialog was unconditionally mounted and only closed inside the
mutation's `onSuccess`, so the overlay teardown depended on the mutation
outcome and could race or never happen
> - This pull request closes the dialog before the mutation fires in
both confirm flows, clears the pending preview alongside the open flag,
and mounts the dialog conditionally so its overlay fully unmounts
> - The benefit is that enabling an experiment behaves like every other
settings change: the dialog goes away, the page stays interactive, and
errors surface in the page-level error banner instead of a dead UI

## Linked Issues or Issue Description

No public GitHub issue exists for this bug; description follows the bug
report template. Refs #4587 (the PR that introduced the configurable
liveness auto-recovery controls this dialog belongs to).

**What happened?** In Settings → Experiments, toggling on "Task graph
liveness auto-recovery" and confirming via "Enable only" left the whole
UI dimmed and unclickable. The dialog content disappeared, but the modal
overlay and the `pointer-events: none` lock on `<body>` remained until a
full page refresh.

**Expected behavior:** Confirming (or dismissing) the auto-recovery
dialog should close it completely and return the page to a fully
interactive state, with the toggle reflecting the new setting.

**Steps to reproduce:**
1. Open Settings → Experiments.
2. Toggle on "Task graph liveness auto-recovery"; the confirmation
dialog with the recovery preview appears.
3. Click "Enable only".
4. The dialog content disappears but the page stays dimmed and nothing
is clickable; refreshing restores the UI and shows the setting was
applied.

**Paperclip version or commit:** master @ 634ae12 · **Deployment mode:**
local instance · **Area:** UI only
(`ui/src/pages/InstanceExperimentalSettings.tsx`).

## What Changed

- Added a `closeRecoveryPreview()` helper that resets both
`previewDialogOpen` and `pendingPreview` together, and used it
everywhere the dialog closes (confirm flows, run-mutation success, and
user dismissal).
- "Enable only" and "Enable and run" now close the dialog *before*
firing the mutation, so overlay teardown no longer depends on the
mutation outcome; mutation errors roll back the optimistic toggle and
surface in the existing page-level error banner.
- The `RecoveryPreviewDialog` is now conditionally mounted
(`previewDialogOpen ? <RecoveryPreviewDialog … /> : null`), guaranteeing
the Radix overlay and body pointer-events lock are fully removed when
closed.
- Added a regression test that walks the real flow — toggle on → preview
dialog appears → "Enable only" — and asserts the update payload, that
the dialog text and `[data-slot="dialog-overlay"]` element are gone, and
that the toggle reads enabled.

Credit: the implementation commit was authored by Cody — thanks! This PR
packages that fix for upstream review.

## Verification

- `pnpm vitest run src/pages/InstanceExperimentalSettings.test.tsx` in
`ui/` — 17/17 tests pass, including the new regression test.
- Independently re-verified beyond the committed assertions: with a
temporary assertion (not committed), confirmed
`document.body.style.pointerEvents` is `none` while the dialog is open
and released after "Enable only" — the actual "can't interact with
anything" symptom, not just overlay DOM removal.
- Manual check: open Settings → Experiments, toggle the auto-recovery
feature, click "Enable only" — the dialog closes, the page stays
interactive, and the toggle shows enabled without a refresh.

## Risks

- Low risk: change is confined to one page component's dialog lifecycle;
no API, schema, or shared-package changes.
- Behavioral shift: the dialog now closes immediately on confirm instead
of staying open with a pending spinner until the mutation resolves.
Errors are still surfaced via the page-level error banner, and the
optimistic toggle rolls back on failure.

## Model Used

- Implementation commit authored by the AI coding agent "Cody"
(Anthropic Claude-based agent). Review, independent verification, and PR
preparation by Claude (Anthropic), model ID `claude-fable-5`, extended
thinking with tool use (code execution, test runs).

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Cody <noreply@paperclip.ing>
2026-07-13 11:52:59 -07:00