Commit Graph
3770 Commits
Author SHA1 Message Date
Devin Foley db4defdfbf feat: operator-configurable settings visibility via PAPERCLIP_HIDDEN_SETTINGS (#11823)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The instance settings surface (Access, Plugins, Adapters, General,
Experimental) assumes the person at the keyboard operates the whole
instance
> - Operators who host Paperclip for others — a managed cloud or an
internal shared server — expose settings pages and toggles that do not
apply to their deployment, and the related mutation APIs stay open
> - A hosted tenant can open Plugins or Adapters, try an action, and hit
a confusing failure, because only a few hardcoded platform floors exist
> - This pull request adds a generic, operator-configured visibility
mechanism: one env var hides declared settings surfaces in the UI and
floors their mutation routes with a stable 403 code
> - The benefit is a clean hosted-tenant settings surface for any
operator, with zero behavior change for normal self-hosted instances

## Linked Issues or Issue Description

**Subsystem affected**

Instance settings (server routes and UI), the shared settings registry
in `packages/shared`, and the `/api/health` bootstrap payload.

**Problem or motivation**

An operator who hosts Paperclip for other people cannot hide settings
surfaces that the platform manages. Tenants see Access, Plugins, and
Adapters pages, backup retention, and host-level experimental toggles
that do nothing useful for them. The mutation APIs behind these surfaces
also stay open, so a tenant admin can attempt actions the platform must
control. ROADMAP.md names a cleaner shared deployment story as a goal
("Teams should be able to run the same product in hosted or semi-hosted
environments without changing the mental model").

**Proposed solution**

Add a declarative registry of hideable settings surfaces and one env
var, `PAPERCLIP_HIDDEN_SETTINGS`. The server parses the list at boot,
reports it on `/api/health`, and rejects value-changing writes to hidden
surfaces with a stable `settings_operator_managed` 403 code. The UI
reads the list from the health payload and removes the hidden pages,
sections, and toggles from navigation, routes, and page content. Unknown
keys warn and are ignored, so one list can roll across a fleet with
mixed app versions. With the variable unset, behavior is byte-identical
to today.

**Alternatives considered**

- Hardcode the hidden set for cloud instances in this repo: rejected,
because each hosting operator needs a different policy, and policy does
not belong in shared code.
- Deliver the hidden set through the managed-config document: rejected,
because that channel is cloud-specific and fail-closed on unknown
fields; a plain env var works for any operator, including self-hosted
shared servers.
- Lock the controls with a badge instead of hiding them: rejected for
these surfaces, because they are meaningless to tenants, not merely
platform-controlled; the existing managed-overlay lock stays the right
tool for controlled flags.

**Roadmap alignment**

Supports the "shared deployment story" item in ROADMAP.md: hosted and
semi-hosted deployments keep the same product with a settings surface
that matches what the tenant can actually do.

## What Changed

- New `packages/shared/src/settings-visibility.ts`: registry of hideable
surfaces (every instance settings page — profile, environments, access,
heartbeats, experimental, plugins, adapters; every Instance → General
section; every experimental flag as `instance.experimental.<key>`), the
`PAPERCLIP_HIDDEN_SETTINGS` parser, and the `settings_operator_managed`
error code. The General page stays visible as the settings root and
redirect target.
- New `server/src/services/settings-visibility.ts`: parse-once accessor;
unknown keys log one warning and are ignored.
- `/api/health` reports `hiddenSettings` on every response shape; the
field is omitted when nothing is hidden.
- Server floors on hidden surfaces, with same-value echo tolerance (the
`executionMode` precedent): field-backed general sections and
experimental keys reject value-changing PATCHes, and hiding the whole
Experimental page floors every toggle; plugin lifecycle and config
writes, adapter management writes, and the Access admin routes (reads
included) return 403 `settings_operator_managed`. Reads the app itself
needs (plugin `ui-contributions`, adapter metadata, plugin job trigger)
stay open. Pages without instance-scoped mutation routes are hidden in
the UI only.
- UI: new `useHiddenSettings` hook and `HiddenSettingsPageGate` route
gate (hidden pages redirect to the settings root); the settings sidebar
and tab bar drop hidden entries; remembered settings paths remap to the
default page; `InstanceGeneralSettings` skips hidden sections; every
`ExperimentalToggleCard` now carries its flag key and renders nothing
when hidden.
- Removed the dead `InstanceSidebar` component (referenced only by its
own test).
- Docs: `docs/deploy/environment-variables.md` documents the variable
and the key registry.

## Verification

- `pnpm vitest run` over the new and extended suites: shared registry
and parser, representative floor tests per route class (changed-value
403, same-value echo 200, unset env 200, page-level Experimental
hiding), the health field, the route gate, nav filtering, and
section/card hiding with one hidden example per surface kind — 168 tests
pass.
- Full root `pnpm typecheck` passes.
- Manual: booted a server with the variable set. `/api/health` lists the
keys; an unknown key logs one warning and the server boots; hidden pages
redirect; hidden sections and cards do not render; hidden-field PATCH
returns 403 with `details.code = "settings_operator_managed"`; a
same-value echo returns 200. Unset the variable: the full settings
surface returns and responses are byte-identical to master.

## Risks

- Low risk for self-hosted instances: with the variable unset, the
hidden set is empty, the health field is omitted, and no floor
activates.
- Flooring plugin config writes assumes hosted deployments configure
plugins through the platform. If a future bundled plugin needs
tenant-entered config, the floor needs a narrow carve-out.
- Hidden-key floors tolerate same-value echoes, so API clients that
round-trip full GET responses keep working.
- Hiding a toggle does not change its value; operators pair hiding with
the desired default where the value matters.

## Model Used

Claude Fable 5 (Anthropic, `claude-fable-5`) with extended thinking and
agentic tool use, driven through the Claude Code CLI (file edits, test
execution, and live-server verification 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
- [ ] 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
2026-08-20 17:54:44 -07:00
Michael Nguyen 0fa318b8da feat(artifacts): bridge Markdown work products into the document review surface (#11822) 2026-08-20 17:28:01 -07:00
733ffbf7c3 build(deps-dev): bump @vitejs/plugin-react from 4.7.0 to 6.0.5 (#11710)
Bumps
[@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react)
from 4.7.0 to 6.0.5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/releases">@​vitejs/plugin-react's
releases</a>.</em></p>
<blockquote>
<h2>plugin-react@6.0.5</h2>
<h3>Fixed the react compiler preset filter to be linear (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1353">#1353</a>)</h3>
<p>The improved filter in v6.0.3 was non-linear and caused a performance
regression (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/issues/1349">#1349</a>).
The filter was changed to be linear to avoid that.</p>
<h2>plugin-react@6.0.4</h2>
<h3>Fixed <code>$RefreshSig$ is not defined</code> error when running
<code>vite dev</code> with <code>NODE_ENV=production</code></h3>
<p>When running <code>vite dev</code> with
<code>NODE_ENV=production</code>, the app errored with
<code>$RefreshSig$ is not defined</code>.
This error is now fixed.</p>
<h2>plugin-react@6.0.3</h2>
<p>No release notes provided.</p>
<h2>plugin-react@6.0.2</h2>
<h3>Allow all options in reactCompilerPreset (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1189">#1189</a>)</h3>
<p>This is a type only change. Only <code>compilationMode</code> and
<code>target</code> options were available for
<code>reactCompilerPreset</code>.</p>
<h2>plugin-react@6.0.1</h2>
<h3>Expand <code>@rolldown/plugin-babel</code> peer dep range (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1146">#1146</a>)</h3>
<p>Expanded <code>@rolldown/plugin-babel</code> peer dep range to
include <code>^0.2.0</code>.</p>
<h2>plugin-react@6.0.0</h2>
<h3>Remove Babel Related Features (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1123">#1123</a>)</h3>
<p>Vite 8+ can handle React Refresh Transform by Oxc and doesn't need
Babel for it. With that, there are no transform applied that requires
Babel. To reduce the installation size of this plugin, babel is no
longer a dependency of this plugin and the related features are
removed.</p>
<p>If you are using Babel, you can use
<code>@rolldown/plugin-babel</code> together with this plugin:</p>
<pre lang="diff"><code> import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'
+import babel from '@rolldown/plugin-babel'
<p>export default defineConfig({
plugins: [</p>
<ul>
<li>
<pre><code>react({
</code></pre>
</li>
<li>
<pre><code>  babel: {
</code></pre>
</li>
<li>
<pre><code>    plugins: ['@babel/plugin-proposal-throw-expressions'],
</code></pre>
</li>
<li>
<pre><code>  },
</code></pre>
</li>
<li>
<pre><code>}),
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code>react(),
</code></pre>
</li>
<li>
<pre><code>babel({
</code></pre>
</li>
<li>
<pre><code>  plugins: ['@babel/plugin-proposal-throw-expressions'],
</code></pre>
</li>
<li>
<pre><code>}),
</code></pre>
]
})
</code></pre></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md">@​vitejs/plugin-react's
changelog</a>.</em></p>
<blockquote>
<h2>6.0.5 (2026-07-30)</h2>
<h3>Fixed the react compiler preset filter to be linear (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1353">#1353</a>)</h3>
<p>The improved filter in v6.0.3 was non-linear and caused a performance
regression (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/issues/1349">#1349</a>).
The filter was changed to be linear to avoid that.</p>
<h2>6.0.4 (2026-07-22)</h2>
<h3>Fixed <code>$RefreshSig$ is not defined</code> error when running
<code>vite dev</code> with <code>NODE_ENV=production</code></h3>
<p>When running <code>vite dev</code> with
<code>NODE_ENV=production</code>, the app errored with
<code>$RefreshSig$ is not defined</code>.
This error is now fixed.</p>
<h2>6.0.3 (2026-06-23)</h2>
<h3>Improve the react compiler preset filter to reduce false-positives
(<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1138">#1138</a>)</h3>
<p>Improved the filter in the react compiler babel preset to reduce the
false-positives so that less modules are processed by the react
compiler.</p>
<h2>6.0.2 (2026-05-14)</h2>
<h3>Allow all options in reactCompilerPreset (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1189">#1189</a>)</h3>
<p>This is a type only change. Only <code>compilationMode</code> and
<code>target</code> options were available for
<code>reactCompilerPreset</code>.</p>
<h2>6.0.1 (2026-03-13)</h2>
<h3>Expand <code>@rolldown/plugin-babel</code> peer dep range (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1146">#1146</a>)</h3>
<p>Expanded <code>@rolldown/plugin-babel</code> peer dep range to
include <code>^0.2.0</code>.</p>
<h2>6.0.0 (2026-03-12)</h2>
<h2>6.0.0-beta.0 (2026-03-03)</h2>
<h3>Remove Babel Related Features (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1123">#1123</a>)</h3>
<p>Vite 8+ can handle React Refresh Transform by Oxc and doesn't need
Babel for it. With that, there are no transform applied that requires
Babel. To reduce the installation size of this plugin, babel is no
longer a dependency of this plugin and the related features are
removed.</p>
<p>If you are using Babel, you can use
<code>@rolldown/plugin-babel</code> together with this plugin:</p>
<pre lang="diff"><code> import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'
+import babel from '@rolldown/plugin-babel'
<p>export default defineConfig({
plugins: [</p>
<ul>
<li>
<pre><code>react({
</code></pre>
</li>
<li>
<pre><code>  babel: {
</code></pre>
</li>
</ul>
<p>&lt;/tr&gt;&lt;/table&gt;
</code></pre></p>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/68c0cb8796ce18bd049c3d05c5210eaf0617eac0"><code>68c0cb8</code></a>
release: plugin-react@6.0.5 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1362">#1362</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/555cdbc126506317b05404481374406771a41e70"><code>555cdbc</code></a>
fix(react): make the react compiler preset filter linear (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1353">#1353</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/a00a9f8240d5a7bb4062ee2a5bac68ea4f0defa6"><code>a00a9f8</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1327">#1327</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/f4b549822ec239799d746c030abb0b9a7d8f0a04"><code>f4b5498</code></a>
release: plugin-react@6.0.4</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/7a4065906e07e616aee23c4fcc76a76b74a7d694"><code>7a40659</code></a>
fix(react): <code>$RefreshSig$ is not defined</code> with
NODE_ENV=production vite dev ...</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/98b32d47a3f2517d52e8a51d8e28ff2ed13678a2"><code>98b32d4</code></a>
fix(deps): update react 19.2.8 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1298">#1298</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/8ae5449be23079dd17fdefc64064a3d94be6fc39"><code>8ae5449</code></a>
fix: babel-plugin-react-compiler cannot be imported when used in a
framework ...</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/f09ea01b0b66a4900c3e42cef2aa0147e78b097c"><code>f09ea01</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1282">#1282</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/640fd358a0e82393acfce4e92e19a6ac6e1641a7"><code>640fd35</code></a>
release: plugin-react@6.0.3</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/889efb02cdc4ec978a5e177a37e0213cfded38a4"><code>889efb0</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1249">#1249</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.5/packages/plugin-react">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​vitejs/plugin-react</code> since your current
version.</p>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-20 16:23:26 -07:00
3d6afde104 build(deps): bump @clack/prompts from 0.11.0 to 1.7.0 (#11724)
Bumps
[@clack/prompts](https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts)
from 0.11.0 to 1.7.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/bombshell-dev/clack/releases">@​clack/prompts's
releases</a>.</em></p>
<blockquote>
<h2><code>@​clack/prompts</code><a
href="https://github.com/1"><code>@​1</code></a>.7.0</h2>
<h3>Minor Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/bombshell-dev/clack/pull/574">#574</a>
<a
href="https://github.com/bombshell-dev/clack/commit/8f1c380683cfb5fb7a094610342046ae1603e28e"><code>8f1c380</code></a>
Thanks <a
href="https://github.com/dreyfus92"><code>@​dreyfus92</code></a>! - Add
<code>showInstructions</code> option to <code>select</code>,
<code>multiselect</code>, and <code>groupMultiselect</code>. Keyboard
hints remain shown by default; pass <code>showInstructions: false</code>
to hide them.</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/582">#582</a>
<a
href="https://github.com/bombshell-dev/clack/commit/4b249539e28eecc16c13b3a1bd0ba447e9f38d06"><code>4b24953</code></a>
Thanks <a href="https://github.com/43081j"><code>@​43081j</code></a>! -
Handle empty arrays in various prompts and utilities.</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/bombshell-dev/clack/commit/4b249539e28eecc16c13b3a1bd0ba447e9f38d06"><code>4b24953</code></a>]:</p>
<ul>
<li><code>@​clack/core</code><a
href="https://github.com/1"><code>@​1</code></a>.4.3</li>
</ul>
</li>
</ul>
<h2><code>@​clack/prompts</code><a
href="https://github.com/1"><code>@​1</code></a>.6.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/568">#568</a>
<a
href="https://github.com/bombshell-dev/clack/commit/f87933fb7b3f4c401b9e51a152b95cb8e7200fe5"><code>f87933f</code></a>
Thanks <a
href="https://github.com/florian-lefebvre"><code>@​florian-lefebvre</code></a>!
- Updates default formatter of <code>note()</code> to note dim lines
anymore</p>
<p>If you want the old behavior, provide a <code>format()</code>
function:</p>
<pre lang="diff"><code>import { note } from '@clack/prompts';
+import { styleText } from 'node:util';
<p>note(
'You can edit the file src/index.jsx',
'Next steps.'</p>
<ul>
<li>{ format: (text) =&gt; styleText('dim', text) }
);
</code></pre></li>
</ul>
</li>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/567">#567</a>
<a
href="https://github.com/bombshell-dev/clack/commit/cc6aab50186cff8a02dc98e9cfd3897c29a33b15"><code>cc6aab5</code></a>
Thanks <a
href="https://github.com/dreyfus92"><code>@​dreyfus92</code></a>! - Add
keyboard instruction footers to <code>select</code>,
<code>multiselect</code>, and <code>groupMultiselect</code> in the
active state, matching autocomplete. No option — always shown.</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [<a
href="https://github.com/bombshell-dev/clack/commit/2f2b52f77cbfa9af618c6d929249ab8395fc37a1"><code>2f2b52f</code></a>,
<a
href="https://github.com/bombshell-dev/clack/commit/e1b6ee71a76e17a3c33ba7ee6e5fb34e886233bb"><code>e1b6ee7</code></a>]:
<ul>
<li><code>@​clack/core</code><a
href="https://github.com/1"><code>@​1</code></a>.4.2</li>
</ul>
</li>
</ul>
<h2><code>@​clack/prompts</code><a
href="https://github.com/1"><code>@​1</code></a>.5.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/548">#548</a>
<a
href="https://github.com/bombshell-dev/clack/commit/2356e97c1f46007ead55133c3a26910404ef1cfb"><code>2356e97</code></a>
Thanks <a href="https://github.com/43081j"><code>@​43081j</code></a>! -
Remove sourcemaps and enable pretty-ish build output.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/546">#546</a>
<a
href="https://github.com/bombshell-dev/clack/commit/56e9d6707715bc858d9c2dbc444230b02813e809"><code>56e9d67</code></a>
Thanks <a
href="https://github.com/ghostdevv"><code>@​ghostdevv</code></a>! -
docs: add jsdoc for <code>date</code>, <code>limit-options</code>, and
<code>messages</code></p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/bombshell-dev/clack/commit/2356e97c1f46007ead55133c3a26910404ef1cfb"><code>2356e97</code></a>]:</p>
<ul>
<li><code>@​clack/core</code><a
href="https://github.com/1"><code>@​1</code></a>.4.1</li>
</ul>
</li>
</ul>
<h2><code>@​clack/prompts</code><a
href="https://github.com/1"><code>@​1</code></a>.5.0</h2>
<h3>Minor Changes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/bombshell-dev/clack/blob/main/packages/prompts/CHANGELOG.md">@​clack/prompts's
changelog</a>.</em></p>
<blockquote>
<h2>1.7.0</h2>
<h3>Minor Changes</h3>
<ul>
<li><a
href="https://redirect.github.com/bombshell-dev/clack/pull/574">#574</a>
<a
href="https://github.com/bombshell-dev/clack/commit/8f1c380683cfb5fb7a094610342046ae1603e28e"><code>8f1c380</code></a>
Thanks <a
href="https://github.com/dreyfus92"><code>@​dreyfus92</code></a>! - Add
<code>showInstructions</code> option to <code>select</code>,
<code>multiselect</code>, and <code>groupMultiselect</code>. Keyboard
hints remain shown by default; pass <code>showInstructions: false</code>
to hide them.</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/582">#582</a>
<a
href="https://github.com/bombshell-dev/clack/commit/4b249539e28eecc16c13b3a1bd0ba447e9f38d06"><code>4b24953</code></a>
Thanks <a href="https://github.com/43081j"><code>@​43081j</code></a>! -
Handle empty arrays in various prompts and utilities.</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/bombshell-dev/clack/commit/4b249539e28eecc16c13b3a1bd0ba447e9f38d06"><code>4b24953</code></a>]:</p>
<ul>
<li><code>@​clack/core</code><a
href="https://github.com/1"><code>@​1</code></a>.4.3</li>
</ul>
</li>
</ul>
<h2>1.6.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/568">#568</a>
<a
href="https://github.com/bombshell-dev/clack/commit/f87933fb7b3f4c401b9e51a152b95cb8e7200fe5"><code>f87933f</code></a>
Thanks <a
href="https://github.com/florian-lefebvre"><code>@​florian-lefebvre</code></a>!
- Updates default formatter of <code>note()</code> to note dim lines
anymore</p>
<p>If you want the old behavior, provide a <code>format()</code>
function:</p>
<pre lang="diff"><code>import { note } from '@clack/prompts';
+import { styleText } from 'node:util';
<p>note(
'You can edit the file src/index.jsx',
'Next steps.'</p>
<ul>
<li>{ format: (text) =&gt; styleText('dim', text) }
);
</code></pre></li>
</ul>
</li>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/567">#567</a>
<a
href="https://github.com/bombshell-dev/clack/commit/cc6aab50186cff8a02dc98e9cfd3897c29a33b15"><code>cc6aab5</code></a>
Thanks <a
href="https://github.com/dreyfus92"><code>@​dreyfus92</code></a>! - Add
keyboard instruction footers to <code>select</code>,
<code>multiselect</code>, and <code>groupMultiselect</code> in the
active state, matching autocomplete. No option — always shown.</p>
</li>
</ul>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [<a
href="https://github.com/bombshell-dev/clack/commit/2f2b52f77cbfa9af618c6d929249ab8395fc37a1"><code>2f2b52f</code></a>,
<a
href="https://github.com/bombshell-dev/clack/commit/e1b6ee71a76e17a3c33ba7ee6e5fb34e886233bb"><code>e1b6ee7</code></a>]:
<ul>
<li><code>@​clack/core</code><a
href="https://github.com/1"><code>@​1</code></a>.4.2</li>
</ul>
</li>
</ul>
<h2>1.5.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/548">#548</a>
<a
href="https://github.com/bombshell-dev/clack/commit/2356e97c1f46007ead55133c3a26910404ef1cfb"><code>2356e97</code></a>
Thanks <a href="https://github.com/43081j"><code>@​43081j</code></a>! -
Remove sourcemaps and enable pretty-ish build output.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/bombshell-dev/clack/pull/546">#546</a>
<a
href="https://github.com/bombshell-dev/clack/commit/56e9d6707715bc858d9c2dbc444230b02813e809"><code>56e9d67</code></a>
Thanks <a
href="https://github.com/ghostdevv"><code>@​ghostdevv</code></a>! -
docs: add jsdoc for <code>date</code>, <code>limit-options</code>, and
<code>messages</code></p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/bombshell-dev/clack/commit/2356e97c1f46007ead55133c3a26910404ef1cfb"><code>2356e97</code></a>]:</p>
<ul>
<li><code>@​clack/core</code><a
href="https://github.com/1"><code>@​1</code></a>.4.1</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/bombshell-dev/clack/commit/dc5bce8aae84a57b5863124adfaa839c1db1fa23"><code>dc5bce8</code></a>
[ci] release (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/575">#575</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/4b249539e28eecc16c13b3a1bd0ba447e9f38d06"><code>4b24953</code></a>
chore: enable strict index checks (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/582">#582</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/8f1c380683cfb5fb7a094610342046ae1603e28e"><code>8f1c380</code></a>
feat(prompts): add showInstructions opt-out (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/574">#574</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/06c16c7b65b69dee44301e7e6c8f1110c6da4149"><code>06c16c7</code></a>
chore: update license copyright to Bombshell contributors (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/572">#572</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/0e700562dfb54bd693d98c5b7e28d34213fcb226"><code>0e70056</code></a>
[ci] release (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/562">#562</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/f87933fb7b3f4c401b9e51a152b95cb8e7200fe5"><code>f87933f</code></a>
fix(prompts): do not dim note contents (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/568">#568</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/cc6aab50186cff8a02dc98e9cfd3897c29a33b15"><code>cc6aab5</code></a>
feat(prompts): add instructions footer for <code>select</code>,
<code>multi-select</code> &amp; `group-...</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/02ae19193ed1155a57fb3dfd830ecc356a1cc11a"><code>02ae191</code></a>
[ci] release (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/549">#549</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/56e9d6707715bc858d9c2dbc444230b02813e809"><code>56e9d67</code></a>
docs: add jsdoc for <code>date</code>, <code>limit-options</code>, and
<code>messages</code> (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/546">#546</a>)</li>
<li><a
href="https://github.com/bombshell-dev/clack/commit/030ba4d776e5985050c0e2712da7008bd93b8847"><code>030ba4d</code></a>
[ci] release (<a
href="https://github.com/bombshell-dev/clack/tree/HEAD/packages/prompts/issues/539">#539</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/bombshell-dev/clack/commits/@clack/prompts@1.7.0/packages/prompts">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​clack/prompts</code> since your current
version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@clack/prompts&package-manager=npm_and_yarn&previous-version=0.11.0&new-version=1.7.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>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-20 15:57:20 -07:00
nearfolk c2cfd55e97 fix: exclude thought text from automatic issue comments (#11801)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The heartbeat system records agent runs and can add a run summary to
an issue.
> - The ACPX engine receives output text and internal thought text as
separate streams.
> - The default summary strategy joined both streams and could publish
internal text in an issue comment.
> - Paperclip already has final-output segmentation for run summaries.
> - This pull request makes final-output-only summaries mandatory and
removes the configuration bypass.
> - The benefit is that automatic issue comments contain the intended
final message instead of internal execution text.

## Linked Issues or Issue Description

Refs #11761

**What happened?**

The ACPX engine used the full summary strategy when an adapter did not
set `summaryStrategy`. That strategy joined all text deltas, including
thought-stream text and intermediate narration. The heartbeat finalizer
could then store that summary as an issue comment.

**Expected behavior**

An automatic issue comment must use only the final output segment.
Configuration must not allow thought-stream text or intermediate
narration into that summary.

**Steps to reproduce**

1. Run an ACPX adapter without a configured `summaryStrategy`.
2. Emit an output delta, a thought delta, a tool call, and a final
output delta.
3. Read the generated run summary.
4. Observe that the old default included all text deltas.

**Paperclip version or commit**

`54b8bec44417511c623999613f9f1006f8af0517`

**Deployment mode**

Built from source with a local ACPX adapter.

## What Changed

- Limit ACPX run summaries to the final non-empty output segment.
- Ignore the legacy full-summary setting so configuration cannot bypass
containment.
- Update regression tests for the safe default and an attempted unsafe
override.

## Verification

- Observed the new guard fail before the implementation change because
the summary contained thought text.
- Ran `pnpm exec vitest run
packages/adapter-utils/src/acpx-engine/execute.test.ts -t "defaults run
summaries to the final output segment without thought text|does not
allow configuration to include thought text in run summaries"`. Result:
2 passed.
- Ran `pnpm exec vitest run
packages/adapter-utils/src/acpx-engine/execute.test.ts`. Result: 130
passed.
- Ran `pnpm --filter @paperclipai/adapter-utils typecheck`. Result:
passed.

## Risks

- Run summaries are shorter for adapters that relied on full text
aggregation.
- The old `summaryStrategy: "full"` setting no longer changes summary
behavior. This is an intentional containment change.
- The change does not alter run logs or tool events. It changes only the
summary selected for downstream use.

> This is a focused security and privacy bug fix. It does not add
roadmap scope.

## Model Used

- OpenAI Codex on the GPT-5 family. The runtime did not expose the exact
model ID or context-window size. Reasoning, tool use, terminal
execution, and code editing were 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 and contains no internal task
id
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant inline 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
2026-08-20 15:48:34 -07:00
dependabot[bot] 67ce516a84 build(deps): bump googleapis from 164.1.0 to 174.0.1 (#11723)
Bumps
[googleapis](https://github.com/googleapis/google-api-nodejs-client)
from 164.1.0 to 174.0.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-nodejs-client/releases">googleapis's
releases</a>.</em></p>
<blockquote>
<h2>googleapis: v174.0.1</h2>
<h2><a
href="https://github.com/googleapis/google-api-nodejs-client/compare/googleapis-v174.0.0...googleapis-v174.0.1">174.0.1</a>
(2026-08-05)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>generator:</strong> respect ignore.json when downloading
discovery docs and cleaning up old files (<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3965">#3965</a>)
(<a
href="https://github.com/googleapis/google-api-nodejs-client/commit/7c7bfdd9ce8aff2d8b590994d6bc56573554eb14">7c7bfdd</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/3285a2c50bb5b2b52127fdb5fdef41315fe87364"><code>3285a2c</code></a>
chore: release main (<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3966">#3966</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/51c4d51eecc2cc9c105a5b3aae0ec35d6030dae9"><code>51c4d51</code></a>
chore: ignore broken aiplatform:v1 discovery schema (<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3969">#3969</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/7c7bfdd9ce8aff2d8b590994d6bc56573554eb14"><code>7c7bfdd</code></a>
fix(generator): respect ignore.json when downloading discovery docs and
clean...</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/9967f25bc93acf8c0760796fa2a248fc61f74e83"><code>9967f25</code></a>
chore(generator): only commit index files if there are staged changes
(<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3962">#3962</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/8525611d9cec2017432eca8814a829353f5d8c73"><code>8525611</code></a>
chore: ignore broken aiplatform:v1beta1 and analytics:v3 discovery
schemas (#...</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/306daab95944d37590fa5bfe48ac7052aad85ecb"><code>306daab</code></a>
chore(test): increase kitchen sink system test timeout to 10m (<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3960">#3960</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/00487776c3500c407b031237be8de3e156380743"><code>0048777</code></a>
chore: release main (<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3952">#3952</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/ac153108d76743e8caaa0e4c013bb802d3f5121f"><code>ac15310</code></a>
feat: run the generator (<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3959">#3959</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/c429a9b6f8272f1a651084f83ffcf4b88124c59f"><code>c429a9b</code></a>
feat: run the generator (<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3955">#3955</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-nodejs-client/commit/5950a04a8c33944c5e594e48959868f288b0996e"><code>5950a04</code></a>
fix: prevent OOMs and HTTP 408 timeouts during API generation and push
(<a
href="https://redirect.github.com/googleapis/google-api-nodejs-client/issues/3954">#3954</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/googleapis/google-api-nodejs-client/compare/googleapis-v164.1.0...googleapis-v174.0.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=googleapis&package-manager=npm_and_yarn&previous-version=164.1.0&new-version=174.0.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-08-20 15:30:51 -07:00
f674f2ca31 build(deps): bump chokidar from 4.0.3 to 5.0.0 (#11720)
Bumps [chokidar](https://github.com/paulmillr/chokidar) from 4.0.3 to
5.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/paulmillr/chokidar/releases">chokidar's
releases</a>.</em></p>
<blockquote>
<h2>5.0.0</h2>
<ul>
<li>Make the package ESM-only. Reduces on-disk package size from ~150kb
to ~80kb</li>
<li>Increase minimum node.js version to v20.19. The versions starting
from it support loading esm files from cjs</li>
<li>fix: Make types more precise <a
href="https://redirect.github.com/paulmillr/chokidar/pull/1424">paulmillr/chokidar#1424</a></li>
<li>perf: re-use double slash regex <a
href="https://redirect.github.com/paulmillr/chokidar/pull/1435">paulmillr/chokidar#1435</a></li>
<li>Update readdirp to ESM-only v5</li>
<li>Lots of minor improvements in tests</li>
<li>Increase security of NPM releases. Switch to token-less Trusted
Publishing, with help of <a
href="https://github.com/paulmillr/jsbt">jsbt</a></li>
<li>Switch compilation mode to isolatedDeclaration-based typescript for
simplified auto-generated docs</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/mhkeller"><code>@​mhkeller</code></a>
made their first contribution in <a
href="https://redirect.github.com/paulmillr/chokidar/pull/1426">paulmillr/chokidar#1426</a></li>
<li><a href="https://github.com/btea"><code>@​btea</code></a> made their
first contribution in <a
href="https://redirect.github.com/paulmillr/chokidar/pull/1432">paulmillr/chokidar#1432</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/paulmillr/chokidar/compare/4.0.3...5.0.0">https://github.com/paulmillr/chokidar/compare/4.0.3...5.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/paulmillr/chokidar/commit/c0c8d20e49d337491891078d1081bf91bd178de6"><code>c0c8d20</code></a>
Release 5.0.0.</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/b211ceca34b1d30326334de21ed30b4a4ceb4c7e"><code>b211cec</code></a>
Remove src from npm</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/87422468fd353426a53a78788b8718979c8725cc"><code>8742246</code></a>
Upgrade dev deps, jsbt, ci files. Upgrade readdirp to v5.</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/de5a34c3cccf2d6fc812a6080e29fb4dd1583ec1"><code>de5a34c</code></a>
Merge pull request <a
href="https://redirect.github.com/paulmillr/chokidar/issues/1442">#1442</a>
from paulmillr/flaky-buns</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/c08a6c4ed6a67b2cb16f61592f763b33e6bce7d3"><code>c08a6c4</code></a>
fix: throttle based on dir + target</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/0c55ab3b049682fae9c1ee278ebc964dbfb92f08"><code>0c55ab3</code></a>
test: wait for explicit calls in directory test</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/ce81be5a51ae72920649e2a74aeba86688c2a5ee"><code>ce81be5</code></a>
perf: re-use double slash regex (<a
href="https://redirect.github.com/paulmillr/chokidar/issues/1435">#1435</a>)</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/7d9c1ed27d2b9150077601677a8a8bad27b8f3da"><code>7d9c1ed</code></a>
Merge pull request <a
href="https://redirect.github.com/paulmillr/chokidar/issues/1433">#1433</a>
from paulmillr/super-matrices</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/391554143f582fe78f7d37cf54b834c42f84652b"><code>3915541</code></a>
Merge pull request <a
href="https://redirect.github.com/paulmillr/chokidar/issues/1430">#1430</a>
from paulmillr/esm-only</li>
<li><a
href="https://github.com/paulmillr/chokidar/commit/9308bedee986abac912100e4bcc4823a1504a10f"><code>9308bed</code></a>
chore: use Nodejs 24 in CI (<a
href="https://redirect.github.com/paulmillr/chokidar/issues/1432">#1432</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/paulmillr/chokidar/compare/4.0.3...5.0.0">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for chokidar since your current version.</p>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-20 15:28:55 -07:00
cb0009b097 fix: preserve recovery retries across restarts (#11817)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The control plane must keep each active issue on a clear execution
or recovery path.
> - A missing issue disposition can require more than one bounded repair
attempt.
> - A server restart could lose that repair path or move source
ownership to the recovery owner.
> - A parked or expired retry could also make the user interface show a
false healthy state.
> - Concurrent recovery loops must not schedule the same repair attempt
twice.
> - This pull request keeps retry state durable, makes scheduling
atomic, and keeps source ownership stable.
> - The benefit is that recovery continues after a restart and operators
see the correct state.

## Linked Issues or Issue Description

**What happened?**

A run that ended without a valid issue disposition could lose its repair
path after a server restart. Manager recovery could also change the
source owner. In addition, a parked or expired retry could make the
issue look healthy when no active work existed. Concurrent
reconciliation could also schedule the same repair attempt twice.

**Expected behavior**

Paperclip must keep bounded source and manager repair attempts across
restarts. Recovery ownership must stay separate from source issue
ownership. The server and user interface must report only a live retry
as active work. Each repair attempt must be scheduled at most once per
company.

**Steps to reproduce**

1. Start an agent run on an issue.
2. End the run without a valid issue disposition.
3. Let the first repair attempt schedule a retry.
4. Restart the server, let the retry time pass without a live run, or
start two reconciliation loops together.
5. Observe that the repair path can stop, the issue can show a false
healthy state, or duplicate retries can be created.

**Paperclip version or commit**

The problem existed on `master` before candidate head
`d8e620fe86bade7df18decac332007f5821ae04f`.

**Deployment mode**

The problem affects self-hosted servers and local builds that use
automatic recovery.

## What Changed

- Persist bounded source-owner and manager repair lineages with stable
fingerprints and retry limits.
- Resume incomplete disposition repairs after a server restart.
- Keep recovery ownership separate from source issue ownership and
enforce source mutation authority.
- Project live retry evidence into issue and blocker summaries.
- Show recovery owner, return owner, attempt count, and retry state in
the board user interface.
- Treat expired or parked retries as attention states unless a queued or
running attempt exists.
- Atomically deduplicate disposition-repair wake requests with a
company-scoped partial unique index.
- Reuse the winning run when concurrent reconciliation loses the
uniqueness race, without duplicate scheduling activity.
- Honor disabled on-demand wake policy before recovery scheduling and
again before delayed retry promotion.
- Keep the new index migration safe for lagging seeded databases that
already contain the index.
- Add server and user interface tests for recovery, restart, ownership,
retry, concurrency, and blocker states.
- Update the implementation and execution semantics documents.

## Verification

- Focused server recovery and ownership suites: 282 tests passed on the
repaired base candidate.
- Focused user interface recovery suites: 128 tests passed on the
repaired base candidate.
- Atomic-deduplication schema and recovery suites: 111 tests passed on
the first Greptile repair.
- Recovery and scheduled-retry wake-policy suites: 126 tests passed at
`d8e620fe86bade7df18decac332007f5821ae04f`.
- The exact lagging-source migration-order test passed after the index
migration became idempotent: 1 test passed and 62 unrelated tests were
skipped.
- `@paperclipai/db` and `@paperclipai/server` typechecks passed at the
current head.
- Migration generation and migration safety checks passed for migration
`0226_tan_colossus.sql`.
- `pnpm check:token-gates` passed on the repaired base candidate.
- `pnpm -r typecheck` passed on the repaired base candidate.
- `pnpm build` passed on the repaired base candidate.
- `pnpm test:run` passed 4,540 tests on the repaired base candidate.
Four fixed-port cases met listeners that already existed on the host.
- The two unchanged fixed-port files passed in an isolated network
namespace: 129 tests passed and 27 tests were skipped.
- Independent Security and QA reviews approved
`63c0423aab54c66f2293a20b0fb3f3b013ee3ba8`; exact-head re-review is
required after automated checks settle on
`d8e620fe86bade7df18decac332007f5821ae04f`.

## Risks

- Recovery orchestration affects issue liveness and ownership. The new
paths use bounded attempts, stable fingerprints, row locks, authority
checks, and database uniqueness.
- A conservative attention state can show more warnings when a scheduled
retry has no queued or running attempt. It does not hide stopped work.
- Migration `0226_tan_colossus.sql` creates a partial unique index on a
known-large table. Migrations run transactionally, so `CONCURRENTLY` is
unavailable. The matching disposition-repair key namespace is introduced
by this release, so deployed databases have no matching rows before the
index is added.

> 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 from the GPT-5 model family used agentic reasoning, tool
use, and code execution. The runtime did not expose the exact model ID
or context window.
- Anthropic Claude Opus 5 used a 1M context window, tool use, and code
execution for part of the user interface repair, as recorded in the
commit history.

## 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 5 (1M context) <noreply@anthropic.com>
2026-08-20 17:09:42 -05:00
Devin Foley de9645ab73 fix(ui): surface live runtime status in the task-chat tail before the first transcript token (#11802)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Runs on sandbox execution targets spend their first minutes in
preparation phases — config seed, workspace and skills sync into the
sandbox — before the agent CLI produces its first transcript token
> - The engine already reports these phases through the runtime-progress
mechanism (`onRuntimeProgress` →
`recordCurrentHeartbeatRunRuntimeProgress` → `currentStatusMessage` on
the live run), and the pre-task-chat issue view surfaced them in its
live status line
> - The chat-style task view's live tail dropped that affordance: with
zero renderable transcript entries it shows an opaque "Waiting for
transcript..." for minutes, which reads as a hang (and prompted a real
is-this-broken investigation on a healthy run)
> - This pull request surfaces the live run's `currentStatusMessage` as
the tail's empty-state message, with the generic wait text as fallback
> - The benefit is that operators watching a sandbox run see "Syncing
workspace to sandbox" instead of wondering whether the run is stuck —
for every adapter, with no adapter identities involved

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The chat-style task view's live transcript tail (`TaskChatThread` →
`TaskChatLiveTail`), introduced with the experimental chat-style task
view.

**Current behavior**

While a live run has no renderable transcript entries yet — the normal
state for the multi-minute sandbox preparation window — the tail shows a
static "Waiting for transcript...". The run's live
`currentStatusMessage` (e.g. "Syncing workspace to sandbox", emitted by
the sandbox-managed runtime's progress reporting) is available on the
same live-run object but unused by this surface, although the earlier
issue-chat view did display it.

**Proposed behavior**

When the tail is streaming a live run and no transcript rows exist yet,
the empty-state message prefers the run's `currentStatusMessage`; the
generic wait text remains the fallback when no runtime status has been
reported (e.g. local runs that produce output immediately, or the brief
pre-status window).

**Reason and benefit**

The preparation phases are real, reportable progress that the engine
already emits. Showing them turns a minutes-long apparent hang into a
legible status, for every adapter and execution target, using data the
view already receives.

## What Changed

- `ui/src/components/TaskChatThread.tsx`: the live tail's `emptyMessage`
prefers `liveRun.currentStatusMessage` (guarded to the run the tail is
actually streaming) over the static "Waiting for transcript..."
fallback. Queued runs keep "Waiting to start...".
- `ui/src/components/TaskChatThread.test.tsx`: a test covering both
branches — a live run with a runtime status shows it (and not the wait
text), and a run without one keeps the generic message.

## Verification

- `vitest run ui/src/components/TaskChatThread.test.tsx
ui/src/components/task-chat/TaskChatLiveTail.test.tsx`: 22/22 pass
(including the new test)
- `pnpm --filter @paperclipai/ui typecheck`: clean
- Reproduced live: a `claude_local` run on a Daytona sandbox environment
showed "Waiting for transcript..." for the full sync window; with this
change the same window shows the streamed preparation statuses

## Risks

- Low: a one-expression change to an empty-state string, active only
while a live run has produced no renderable transcript rows. The
fallback path is byte-identical to today.
- `currentStatusMessage` is truncated/humanized upstream by the
runtime-progress reporter; this surface renders it verbatim in the same
muted style as the wait text.

## Model Used

- Anthropic, **Claude Fable 5** (`claude-fable-5`) via Claude Code, with
repository, shell, and Git tooling. It traced the runtime-progress
mechanism end-to-end (engine emitter → heartbeat recorder → live-run API
→ both thread views), identified the dropped affordance in the
chat-style view, and wrote the fix and test.

## 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
2026-08-20 12:47:20 -07:00
github-actions[bot]andlockfile-bot 726a3ee715 chore(lockfile): refresh pnpm-lock.yaml (#11786)
Auto-generated lockfile refresh after dependencies changed on master.
This PR only updates pnpm-lock.yaml.

Co-authored-by: lockfile-bot <lockfile-bot@users.noreply.github.com>
2026-08-20 12:16:11 -07:00
233c12f029 feat: add kimi-local adapter for Kimi Code CLI (CLI + ACP engines) (#9967)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Local agent adapters (`claude_local`, `gemini_local`, `grok_local`,
…) are the integration surface that lets Paperclip run coding CLIs on
the host machine
> - The Kimi Code CLI (`kimi`, Moonshot AI) has a documented
non-interactive mode, `kimi -p --output-format stream-json` with session
resume via `kimi -r`, but Paperclip has no built-in adapter for it
> - So Kimi users (especially Kimi membership / OAuth subscribers)
cannot onboard their CLI to Paperclip agent teams
> - This pull request adds a complete built-in `kimi_local` adapter
(both execution engines, session management, instructions + skills
delivery, thinking-effort control, environment test, UI and CLI modules,
docs) following the established `gemini_local`/`grok_local` package
pattern
> - Kimi Code ships an ACP server (`kimi acp`), so the adapter runs on
Paperclip's shared acpx engine by default (streaming transcript with
live tool status, like `claude_local`/`gemini_local`) and falls back to
a headless CLI lane (`kimi -p --output-format stream-json`) when ACP
prerequisites are unavailable
> - The benefit is that Kimi Code becomes a first-class Paperclip agent
lane: selectable in the UI, resumable across heartbeats, with the same
operating context (instruction bundle, skills, effort) and streaming
transcript the other local adapters get

## Linked Issues or Issue Description

- Supersedes #9880 (same branch; expanded from the CLI-only lane into a
complete adapter with the default ACP engine lane, control-plane skill
install, and live transcript wiring)
- Refs #9879 (adapter request for Kimi Code CLI, filed with this PR)
- Refs #163 (original Kimi support request)

Duplicate/related prior PRs, per the dedup search (both appear stale: no
updates or maintainer review since May 2026, and both target an older
Kimi CLI interface; calling them out for reviewer context per
CONTRIBUTING.md):

- Refs #6276 (`feat: add kimi-local adapter`): targets an older
array-based content format (`{type: think}`/`{type: text}` blocks), not
the current documented stream-json schema
- Refs #5202 (`feat(adapter): add Kimi CLI local adapter with Wire
protocol support`): builds on a `--wire` JSON-RPC interface that current
Kimi Code CLI (0.27.0) no longer documents; the current documented
headless interface is `-p --output-format stream-json`

This PR is a fresh implementation against current master and the
currently documented/verified Kimi CLI behavior (see Verification).
Happy to fold in anything useful from the earlier attempts if a reviewer
prefers.

## What Changed

- **New adapter package** `packages/adapters/kimi-local`
(`@paperclipai/adapter-kimi-local`), modeled on
`gemini-local`/`grok-local`:
- `src/server/execute.ts`: spawns `kimi -p <prompt> --output-format
stream-json` (argv array, no shell), `-m <model>` only when configured,
`-r <sessionId>` when the stored session cwd matches the run cwd,
automatic fresh-session retry on unrecoverable-session errors,
headless-safe env (`CI=1`, `NO_COLOR=1`, `KIMI_CODE_NO_AUTO_UPDATE=1`,
`TERM=dumb`; user-configured values win), full remote (ssh/sandbox)
execution lane with runtime install via `@moonshot-ai/kimi-code`
- **Instruction bundle delivery**: the prompt path directive now names
the sibling instruction files (`./HEARTBEAT.md`, `./SOUL.md`,
`./TOOLS.md`) alongside the prepended entry file, and local runs pass
`--add-dir <instructions-dir>` so Kimi can actually open them (matching
`claude_local`). Without this, only the entry file reached Kimi and
agents improvised the operating workflow that `HEARTBEAT.md` documents
- **Thinking effort**: a configured `effort` is forwarded as the
`KIMI_MODEL_THINKING_EFFORT` operational override (Kimi has no
per-invocation effort flag). It is only sent for models that advertise
`support_efforts` (currently `kimi-code/k3`) to avoid provider
rejections, and `medium` maps to `high` since Kimi has no medium tier
(`low`/`high`/`max` pass through)
- **Skills delivery**: desired Paperclip skills are delivered via Kimi's
`--skills-dir` flag from a dedicated per-run directory (a local
snapshot, or the synced snapshot on remote targets), so skills load
reliably and in isolation. Paperclip never overwrites the shared
`$KIMI_CODE_HOME/skills` home, so skills installed by the operator or
other agents are left intact. `--skills-dir` is only passed when at
least one skill is desired, so unconfigured agents keep Kimi's default
skill discovery
- **Live run status**: the adapter now forwards each streamed
stream-json line to `onEvent` (assistant `content` as an assistant
snippet, `tool_calls` as tool-name events), which drives the
issue-thread activity indicator (`currentToolName` /
`lastAssistantSnippet` / `lastEventAt`). Previously the adapter only
wrote the raw run log, so the issue thread showed a stale "no output for
N s" line with no tool or reasoning context while Kimi worked. Tool
results are omitted so the last meaningful "Using X" / snippet is not
overwritten by a generic label
- `src/server/parse.ts`: parses the verified Kimi stream-json event
shapes (`assistant` text, `assistant.tool_calls` with JSON-string
arguments, `tool` results, trailing `meta.session.resume_hint` for
session-id capture) plus failure classifiers (`kimi_auth_required`,
transient network, unrecoverable session). A signaled exit (null exit
code, not a timeout) is now reported as a failure rather than coalesced
to success, and the error message names the terminating signal
- `src/server/skills.ts`: lists/syncs Paperclip skills for the adapter's
skill-management surface
- `src/server/test.ts`: environment test covering CLI resolution + `kimi
--version`, cwd check, auth detection (OAuth credential dirs, keyed
`[providers.*]` in config.toml, or the `KIMI_MODEL_NAME` +
`KIMI_MODEL_API_KEY` env pair), and a live hello probe
- `src/ui/` (stdout-line parser for transcripts, config builder) and
`src/cli/` (stream event formatter) modules
- Root metadata: three managed model aliases
(`kimi-code/kimi-for-coding`, `kimi-code/kimi-for-coding-highspeed`,
`kimi-code/k3`), effort-capable-model metadata (`EFFORT_CAPABLE_MODELS`,
effort mapping helpers), `agentConfigurationDoc`
- Tests: 101 tests across parse, execute (args building, resume gating,
retry, auth error code, timeout, signaled-exit failure, effort
forwarding/gating/mapping, `--add-dir` instructions directive,
`--skills-dir` gating, `onEvent` runtime-event forwarding), ACP engine
(engine resolution, acpx config build, node-version gate), ACP
transcript delegation, environment test, UI parse/build-config
- **ACP engine lane (default)** (`src/server/acp.ts` + shared
`adapter-utils/acpx-engine`): Kimi Code ships an ACP server (`kimi
acp`), so `kimi_local` now runs on Paperclip's shared acpx engine by
default, matching `claude_local`/`codex_local`/`gemini_local`. The
issue-thread transcript streams live (assistant text deltas, tool calls
with a `pending`->`completed` status lifecycle) instead of the CLI
lane's bursty complete-message output. Registered `kimi_local -> "kimi"`
in `ACPX_ADAPTER_AGENT_IDS` and resolved the built-in agent command to
`kimi acp`; `execute.ts` dispatches to the ACP executor first with an
automatic CLI fallback when ACP prerequisites fail (`engine=acp`
requires ACP, `engine=cli` pins the headless lane); `index.ts` falls
back to the shared acpx session codec; the UI/CLI delegate `acpx.*`
events to the shared acpx transcript parser and event formatter. The
headless CLI lane (above) remains as the fallback
- **Registration** (one entry each, mirroring existing adapters): server
adapter registry + `BUILTIN_ADAPTER_TYPES`, `AGENT_ADAPTER_TYPES`
(shared), UI adapter registry + display registry (`Kimi Code`, Moon
icon) + capabilities defaults, CLI adapter registry, `Dockerfile`
(package copy + `npm install --global @moonshot-ai/kimi-code@latest`),
`vitest.config.ts` workspace, `scripts/release-package-manifest.json`
- **Behavioral sets** mirroring `gemini_local` (Kimi resumes sessions
the same way): `GIT_SENSITIVE_LOCAL_ADAPTER_TYPES`,
`SESSIONED_LOCAL_ADAPTERS` (heartbeat + recovery),
`REMOTE_MANAGED_ADAPTERS`, ssh/sandbox execution-target allow-lists,
`ADAPTER_DEFAULT_RULES_BY_TYPE` (`timeoutSec: 0`, `graceSec: 15`), and
`LEGACY_SESSIONED_ADAPTER_TYPES` + `ADAPTER_SESSION_MANAGEMENT` in
adapter-utils
- **UI touch-points**: New Agent default-model branch, AgentConfigForm
command map (`kimi_local: "kimi"`) + model defaults + a Kimi-specific
thinking-effort option list (`Low`/`High`/`Max`, reflecting Kimi's tiers
rather than borrowing Claude's), OnboardingWizard (command map, model
default, `kimi login` / `KIMI_MODEL_NAME + KIMI_MODEL_API_KEY` auth
hints, manual-debug command line), InviteLanding enabled adapters
- **Control-plane skill install** (`cli/src/commands/client/agent.ts`):
`paperclipai agent local-cli` seeded the Paperclip control-plane skills
into `~/.codex/skills` and `~/.claude/skills` so Codex/Claude agents
auto-discover the API reference every run. Kimi had no equivalent
target, so `kimi_local` agents began each session without the
control-plane skill and rediscovered routes (e.g. the company-scoped
`POST /api/companies/{companyId}/issues`) by trial and error. Added
`~/.kimi-code/skills` (honoring `KIMI_CODE_HOME`) as a third install
target for parity. Independent of the per-run `--skills-dir` delivery,
which only applies to explicitly configured skills.
- **Docs**: `docs/adapters/kimi-local.md` (prerequisites, auth options,
config fields including `effort`, session resume, instruction bundle,
skills delivery, control-plane skill install) + a row in
`docs/adapters/overview.md`

Out of scope (deliberately): model profiles, built-in agent
`allowedAdapterTypes` additions.

## Verification\n\nCurrent-master rebase verification (OpenAI Codex,
2026-08-03): 13 focused files / 231 tests pass; adapter-utils, server,
UI, CLI, and Kimi adapter typechecks pass; full repository build and UI
token gates pass. The branch is conflict-free against master at head
`1249df117c5e12e5771b9a570a6340866450619e`.\n\nAutomated (all from repo
root, pnpm 9.15.4, Node 22):

- `vitest run packages/adapters/kimi-local`: 89/89 pass (includes
coverage for the instruction `--add-dir` directive, effort
forwarding/gating/mapping, `--skills-dir` gating, the signaled-exit
failure path, and `onEvent` runtime-event forwarding with cross-chunk
line buffering)
- `vitest run server/src/__tests__/adapter-registry.test.ts
server/src/__tests__/adapter-routes.test.ts
server/src/services/heartbeat-stop-metadata.test.ts
ui/src/adapters/adapter-display-registry.test.ts`: 37/37 pass
- `vitest run cli/src/__tests__/skills.test.ts`: 13/13 pass (the
control-plane skill install target follows the existing Codex/Claude
install path, whose symlink logic is unchanged)
- `vitest run packages/shared`: 307/307 pass; `vitest run
packages/adapter-utils`: pass except one pre-existing, unrelated failure
(`mcp-isolation.integration.test.ts` requires Claude CLI ≥ 2.1.207; host
has 2.1.185, fails identically on unmodified master)
- `pnpm --filter @paperclipai/adapter-kimi-local typecheck|build`, plus
typecheck of `server`, `ui`, `cli`, `adapter-utils`: all clean
- `pnpm install --frozen-lockfile`: passes (the PR diff itself contains
no lockfile changes, per repo policy; verified against a locally
regenerated lockfile)
- `node scripts/check-no-git-push.mjs` and `node
scripts/check-forbidden-tokens.mjs`: pass
- CI note: the `policy` job's release-bootstrap step is expected to stay
red until a maintainer bootstraps the first npm publish of
`@paperclipai/adapter-kimi-local`; see the CI Note for Maintainers
comment. All other contributor-actionable checks are green.

Manual end-to-end (real Kimi CLI 0.27.0, OAuth login, dev server on an
isolated instance):

1. Server `GET /api/adapters` lists `kimi_local` as builtin with correct
capability flags; models endpoint returns the three Kimi models
2. `POST .../adapters/kimi_local/test-environment`: all checks pass,
including a live `kimi -p` hello probe
3. Created a `kimi_local` agent and invoked two heartbeats: run 1
spawned `kimi -p ... --output-format stream-json`, Kimi used its `Read`
tool, produced the expected answer, and the session id was captured from
the `session.resume_hint` meta event; run 2 resumed the **same** Kimi
session (`sessionIdBefore == sessionIdAfter`) via `-r`
4. UI: adapter appears in the New Agent dropdown; selecting it shows the
Kimi command placeholder, the three models, and the Kimi config fields;
the run transcript renders Kimi tool calls via the adapter's stdout
parser

The instruction-bundle, thinking-effort, and `--skills-dir` changes
landed after the manual run above. They are covered by the unit tests
listed under Automated, and the Kimi CLI flags they rely on
(`--add-dir`, `--skills-dir`, `KIMI_MODEL_THINKING_EFFORT`) were
confirmed against the installed Kimi Code CLI 0.27.0 (`kimi --help`,
config-file thinking-effort docs).

Screenshots (assets branch on the fork, not part of the diff):

![Kimi Code in the Add a new agent runtime
picker](https://raw.githubusercontent.com/hawikk/paperclip/assets/kimi-local-pr-screenshots/shots/00-kimicode.png)

![Adapter dropdown with Kimi
Code](https://raw.githubusercontent.com/hawikk/paperclip/assets/kimi-local-pr-screenshots/shots/01-adapter-dropdown-kimi.png)

![Kimi adapter selected: command, model, config
fields](https://raw.githubusercontent.com/hawikk/paperclip/assets/kimi-local-pr-screenshots/shots/02-kimi-adapter-selected.png)

![Kimi models in the model
dropdown](https://raw.githubusercontent.com/hawikk/paperclip/assets/kimi-local-pr-screenshots/shots/03-kimi-model-dropdown.png)

![Successful resumed heartbeat run (kimi_local invocation + parsed
transcript)](https://raw.githubusercontent.com/hawikk/paperclip/assets/kimi-local-pr-screenshots/shots/04-successful-resumed-run.png)

![Agents list showing the Kimi Code
label](https://raw.githubusercontent.com/hawikk/paperclip/assets/kimi-local-pr-screenshots/shots/05-agents-list.png)

## Risks

- Low risk to existing behavior: the change is additive, one new
workspace package plus single-entry registrations alongside existing
adapters; no existing adapter code paths are modified.
- The adapter invokes the locally installed `kimi` CLI; like other local
adapters, run behavior depends on the host's Kimi version. The parser is
written against the documented/verified 0.27.0 stream-json schema and
degrades gracefully (malformed lines are skipped, failures surface as
run errors).
- `--skills-dir` overrides Kimi's auto-discovery of user and project
skills for the run. This is intentional (paperclip-managed agents get a
reproducible, isolated skill set), and it is only passed when at least
one Paperclip skill is desired, so unconfigured agents keep default
discovery.
- Thinking effort is only forwarded to models that advertise
`support_efforts` (currently `kimi-code/k3`); `EFFORT_CAPABLE_MODELS`
must be extended when more Kimi models gain support, otherwise a
configured effort is silently ignored for them.
- `Dockerfile` now installs `@moonshot-ai/kimi-code@latest` globally
alongside the other agent CLIs, so image size increases slightly.
- Maintainer action needed for the npm bootstrap gate: the `policy`
job's release-bootstrap step fails until the first npm publish of
`@paperclipai/adapter-kimi-local` (the gate from #5146 that every new
adapter package has passed through). Enrollment with `publishFromCi:
true` is required by the manifest validator (dropping the entry,
`false`, or `private` are all rejected), so this is intentionally left
to a maintainer. Remaining CI lanes are expected to run once it is done.

## Model Used\n\n- **Current-master rebase, conflict adaptation, and
registry-parity coverage:** OpenAI, **GPT-5 Codex** (Codex agent; exact
serving model ID and context-window size were not exposed to the
runtime), with repository, shell, Git, and GitHub tooling. It preserved
Hawik’s commit authorship, reconciled ACPX and environment-capability
changes, added current registry tests, and ran the verification
above.\n- **Adapter implementation and initial review:** Moonshot AI,
**Kimi K3 Coding** (latest), via **Kimi Code CLI v0.27.0**
(`kimi-code/k3` alias, 1M-token context window, thinking mode, agentic
tool use). The CLI agent explored the repo, wrote the adapter
implementation (delegated to a coder sub-agent of the same model), ran
tests, and drafted the first version of this PR body. A second
model-driven review pass (read-only, same model) audited the diff for
security/correctness before submission; its findings (shell-quoting
hardening, auth-detection false positive, session-compaction
registration, test gaps) were fixed and are included.
- **Harness-context fixes and review responses:** Anthropic, **Claude
Opus 4.8** (`claude-opus-4-8`) via Claude Code. Diagnosed from run logs
that Kimi received only the entry instructions file (not the
`HEARTBEAT.md`/`SOUL.md`/`TOOLS.md` bundle) and that `effort` was never
wired, then implemented the instruction `--add-dir` delivery,
`KIMI_MODEL_THINKING_EFFORT` forwarding, and `--skills-dir` skill
delivery, added the accompanying tests and docs, and addressed the
automated review comments (preserving external skills on remote sync,
treating a signaled exit as a failure). Also extended the `paperclipai
agent local-cli` installer to seed the control-plane skills into
`~/.kimi-code/skills` for Codex/Claude parity, wired `onEvent` runtime
events so the issue-thread activity indicator reflects Kimi's tool and
reasoning output live, and built the ACP engine lane (`kimi acp` via the
shared acpx engine, default) so the transcript streams with live tool
status like the other ACP adapters. The Kimi CLI flags, subcommand, and
env var relied on here were verified against the installed Kimi Code CLI
0.27.0.
- All CLI behaviors claimed here (`-p`, `--output-format stream-json`,
`-r` resume, event shapes, `--add-dir`, `--skills-dir`,
`KIMI_MODEL_THINKING_EFFORT`) were verified empirically against the
installed Kimi CLI, not assumed.

## 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 *(only the release-bootstrap step
remains red, pending the maintainer npm publish described in Risks)*
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
*(will address all Greptile comments as they arrive)*
- [x] I will address all Greptile and reviewer comments before
requesting merge





---

## Maintainer Addendum (2026-08-20)

The shared acpx-engine and issue-chat changes (run-summary segmentation,
placeholder tool-event coalescing,
`ISSUE_CHAT_TRANSCRIPT_MAX_VISIBLE_ENTRIES` 30 → 400, live-reasoning UI)
have been **extracted to #11761** so the cross-adapter behavior changes
review and revert independently — both commits there preserve @hawikk's
authorship. This PR is now the kimi-specific adapter only (60 files,
+3,793/−8, essentially pure addition); the only shared-engine touch left
is the `kimi acp` command resolution. `publishFromCi` is `true` — the
package name is bootstrapped on npm.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Dotta <bippadotta@protonmail.com>
Co-authored-by: Devin Foley <devin@paperclip.ing>
2026-08-20 12:06:33 -07:00
Nicky LeachandPaperclip b83e14ad2c fix(runtime): stop the readiness probe from stealing the guest exposure port (#11788)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The workspace runtime starts guest processes and exposes their
ports.
> - The readiness wait bound the guest port to test whether it was
ready.
> - That bind could take the port before the guest process used it.
> - This pull request reads listener state without a competing bind and
recovers from a real port collision.
> - The benefit is stable runtime exposure and a clear recovery path for
a genuine collision.

## Linked Issues or Issue Description

**What happened?**

The managed HTTPS exposure test failed intermittently with `listen
EADDRINUSE` on `127.0.0.1:42000`. The readiness wait bound the guest
port before the guest process could bind it.

**Expected behavior**

The readiness wait must not hold the guest port. The runtime must
recover when an external process owns the assigned port.

**Steps to reproduce**

1. Run `npx vitest run
server/src/services/workspace-runtime-exposure.test.ts` from the
repository root.
2. Inject a delayed guest bind and a widened readiness-probe hold.
3. Observe the port collision before this fix and the successful retry
after this fix.

**Paperclip version or commit**

`b375bbd913cb2edc8e077f4339ce0745e53bd462`

**Deployment mode**

Built from source with the server test suite.

**Installation method**

Built from source with pnpm.

**Agent adapter(s) involved**

Not adapter-specific. This is a core runtime test.

**Database mode**

Not database-related.

**Relevant logs or output**

Before this fix, the test reported `listen EADDRINUSE: address already
in use 127.0.0.1:42000`.

## What Changed

- Read listener presence from `/proc` on Linux instead of binding the
guest port.
- Keep the bind probe as the fallback on non-Linux hosts.
- Capture the current port owner when an exposed guest exits with
`EADDRINUSE`.
- Quarantine the app and HMR pair, then allocate the next free port pair
within the existing range.
- Add a deterministic regression test for quarantine, re-allocation, and
self-diagnosis logging.

## Verification

- Run `npx vitest run
server/src/services/workspace-runtime-exposure.test.ts` from the
repository root.
- The target suite passes 19 tests locally.
- The related runtime suites pass 105, 128, and 21 tests locally.
- Run `tsc -p server/tsconfig.json` to check the changed server files.
- CI must pass the general server shard and all required checks.
- Greptile must report 5/5 with no open P2 comments, recommendations, or
follow-ups.

## Risks

The Linux readiness path now depends on `/proc` listener data. Non-Linux
hosts retain the existing bind-probe fallback. The port range and
allocation limit do not change.

## Model Used

OpenAI GPT-5. This agent used tool calls for repository checks and
GitHub PR management. Priya Raman authored the code change.

## 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-08-20 12:05:35 -07:00
Devin Foley 933749e01f test(server): deflake postgres teardown and pinned exposure port (#11667)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The server test suite gates every merge and every release cut.
> - Three server tests each failed exactly once on markdown-only or
unrelated diffs, then passed on rerun.
> - One of the three (the git-operation-scheduler owner/joiner race) was
fixed on master independently by
[#11671](https://github.com/paperclipai/paperclip/pull/11671) while this
PR was open, so after rebasing this pull request carries the remaining
two.
> - A flaky gate makes release operators rerun CI and stop trusting red
results.
> - Each remaining flake has a real nondeterminism: a teardown race and
a hard-coded host port.
> - This pull request removes the nondeterminism from the two tests
without weakening what they prove.
> - The benefit is a test gate that fails only when the product is
broken.

## Linked Issues or Issue Description

- [x] I searched open and closed issues and pull requests for these test
files and for these failures. I found no duplicate report or fix.

**What happened?**

Three one-off CI failures occurred during release operations, each on a
diff that could not have caused it, and each passed on rerun:

1. Run
[32086355930](https://github.com/paperclipai/paperclip/actions/runs/32086355930):
`server/src/__tests__/interaction-resolution-cross-issue-cap-postgres.test.ts`
— all 7 tests passed, but vitest recorded an Unhandled Error and failed
the run: `TypeError: Cannot read properties of null (reading 'write')`
at `postgres@3.4.9/src/connection.js:255 Immediate.nextWrite`.
2. Run
[32096743814](https://github.com/paperclipai/paperclip/actions/runs/32096743814):
`server/src/services/workspace-git-operation-scheduler.test.ts` — the
test "coalesces the same canonical key and cleans single-flight state
after success and failure" failed with an AssertionError: the two
concurrent calls came back with the `singleFlightJoined` values swapped.
*(Fixed on master by
[#11671](https://github.com/paperclipai/paperclip/pull/11671) with an
equivalent single-flight barrier while this PR was open; the fix was
dropped from this PR on rebase and the file is no longer touched here.)*
3. Run
[32196201529](https://github.com/paperclipai/paperclip/actions/runs/32196201529):
`server/src/services/workspace-runtime-exposure.test.ts` — the test
"keeps an existing runtime port that is already inside the dedicated
range" failed once out of 610 recorded runs because the runtime came
back on a relocated port instead of the pinned 42500.

**Expected behavior**

The tests pass on every run when the code under test is correct. A red
result means a product defect, not scheduling luck on the CI host.

**Steps to reproduce**

Each flake is a low-probability race, but both remaining mechanisms
reproduce deterministically:

1. Postgres teardown: the suite never ends the postgres.js pool behind
`createDb`; `afterAll` only stops the embedded server. postgres.js
batches small writes and flushes them with `setImmediate`
(`connection.js` `nextWrite`), and `close()` nulls the socket. Stop the
server while the pool is open and a pending flush can run after the
socket is gone.
2. Exposure pinned port: hold any loopback socket on 42500 or 52500
(both are inside the default Linux ephemeral port range, 32768–60999)
and run the test. The allocator correctly relocates, and the assertion
fails with `expected 42000 to be 42500`. The client side of any loopback
connection on the CI host can land on those ports.

**Paperclip version or commit**

Branched from `master` at `4b968d8c0`; rebased onto `5a1ce7aed`.

**Privacy checklist**

I reviewed this description and removed private instance URLs, internal
task identifiers, credentials, and user paths.

## What Changed

Both fixes are test-side. I found no product race.

- `interaction-resolution-cross-issue-cap-postgres.test.ts`: `afterAll`
now ends the drizzle/postgres.js pool (`db.$client.end()`) before it
stops the embedded Postgres server. `end()` waits for in-flight queries,
including a fire-and-forget wake that lands just after a response, and
closes the sockets from the client side first. Sibling suites (for
example `heartbeat-plugin-environment.test.ts`) already use this order;
this suite had skipped the pool shutdown.
- `workspace-runtime-exposure.test.ts`: the pinned-port test no longer
hard-codes 42500. It scans the dedicated range with the suite's real
loopback probe, finds the lowest free app/HMR pair, then pins the next
free pair strictly above it. If the keep-preferred-port path broke, the
ascending fallback scan would return the lower pair, so the assertion
keeps its discriminating power while no longer betting on one fixed host
port staying free.
- *(Dropped on rebase: the `workspace-git-operation-scheduler.test.ts`
coalescing fix, superseded by the equivalent barrier merged in
[#11671](https://github.com/paperclipai/paperclip/pull/11671).)*

## Verification

- Reproduced the exposure flake exactly: with a listener held on
`127.0.0.1:52500`, the pre-fix test fails with `expected 42000 to be
42500`; the fixed test passes with the port still held.
- The postgres flake is a probabilistic teardown race and I could not
trigger it on demand. The mechanism is established from `postgres@3.4.9`
source (`setImmediate`-batched `nextWrite` versus `close()` nulling the
socket) and the fix removes the whole class by closing the pool before
the server.
- Repeat runs after the fix: the pinned-port exposure test 20/20 green
while the Postgres suite looped concurrently for loopback churn;
`interaction-resolution-cross-issue-cap-postgres.test.ts` 15/15 green
with no unhandled errors.
- Re-verified after rebasing onto `5a1ce7aed`: both changed test files
pass and `tsc --noEmit` passes in `server/`.
- Environment note: three unrelated tests in
`workspace-runtime-exposure.test.ts` (the wildcard-bind diagnosis tests)
fail on macOS before and after this change because they read `/proc`;
they are untouched and pass on Linux CI.

## Risks

- Low risk: both changes are test-only; no product code changed.
- The pinned-port test keeps a tiny time-of-check/time-of-use window
between its own probe and the runtime's bind. The window shrinks from
"one fixed port must stay free across the whole CI fleet" to
milliseconds on a pair just verified free.

> 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

Claude Fable 5 (Claude Code) — model ID `claude-fable-5`, with
repository tools and local code execution for reproduction and
repeat-run verification.

## 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-08-20 11:27:39 -07:00
54b8bec444 build(deps): bump pino-http from 10.5.0 to 11.0.0 (#11716)
Bumps [pino-http](https://github.com/pinojs/pino-http) from 10.5.0 to
11.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pinojs/pino-http/releases">pino-http's
releases</a>.</em></p>
<blockquote>
<h2>v11.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>build(deps-dev): bump <code>@​types/node</code> from 22.15.32 to
24.0.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/pinojs/pino-http/pull/370">pinojs/pino-http#370</a></li>
<li>build(deps-dev): bump typescript from 5.8.3 to 5.9.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/pinojs/pino-http/pull/373">pinojs/pino-http#373</a></li>
<li>build(deps-dev): bump tsd from 0.32.0 to 0.33.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/pinojs/pino-http/pull/376">pinojs/pino-http#376</a></li>
<li>build(deps): bump actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/pinojs/pino-http/pull/380">pinojs/pino-http#380</a></li>
<li>build(deps): bump actions/setup-node from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/pinojs/pino-http/pull/382">pinojs/pino-http#382</a></li>
<li>Update for pino@10 by <a
href="https://github.com/jsumners"><code>@​jsumners</code></a> in <a
href="https://redirect.github.com/pinojs/pino-http/pull/383">pinojs/pino-http#383</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/pinojs/pino-http/compare/v10.5.0...v11.0.0">https://github.com/pinojs/pino-http/compare/v10.5.0...v11.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pinojs/pino-http/commit/6615953a8bfebf37c26e6438568724a091f80a82"><code>6615953</code></a>
v11.0.0</li>
<li><a
href="https://github.com/pinojs/pino-http/commit/da0442ea7306b0560eada975391d13853c72b119"><code>da0442e</code></a>
Update for pino@10 (<a
href="https://redirect.github.com/pinojs/pino-http/issues/383">#383</a>)</li>
<li><a
href="https://github.com/pinojs/pino-http/commit/c77bf2546d44dbe7381264955ae97ca76ff302e1"><code>c77bf25</code></a>
build(deps): bump actions/setup-node from 4 to 5 (<a
href="https://redirect.github.com/pinojs/pino-http/issues/382">#382</a>)</li>
<li><a
href="https://github.com/pinojs/pino-http/commit/5b06a223d3ad15f97b1e0f68416410776c47fdde"><code>5b06a22</code></a>
build(deps): bump actions/checkout from 4 to 5 (<a
href="https://redirect.github.com/pinojs/pino-http/issues/380">#380</a>)</li>
<li><a
href="https://github.com/pinojs/pino-http/commit/bc69ee95e184f882570c7a9d551288b5b077fe02"><code>bc69ee9</code></a>
build(deps-dev): bump tsd from 0.32.0 to 0.33.0 (<a
href="https://redirect.github.com/pinojs/pino-http/issues/376">#376</a>)</li>
<li><a
href="https://github.com/pinojs/pino-http/commit/c2ccdb31d8961033c976686102f7d6279f97a1c2"><code>c2ccdb3</code></a>
build(deps-dev): bump typescript from 5.8.3 to 5.9.2 (<a
href="https://redirect.github.com/pinojs/pino-http/issues/373">#373</a>)</li>
<li><a
href="https://github.com/pinojs/pino-http/commit/6dbe316bd5d8860a3efbc963e5b6fed7a4b45384"><code>6dbe316</code></a>
build(deps-dev): bump <code>@​types/node</code> from 22.15.32 to 24.0.3
(<a
href="https://redirect.github.com/pinojs/pino-http/issues/370">#370</a>)</li>
<li>See full diff in <a
href="https://github.com/pinojs/pino-http/compare/v10.5.0...v11.0.0">compare
view</a></li>
</ul>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
canary/v2026.820.0-canary.6
2026-08-20 10:51:54 -07:00
Devin FoleyandHawik 1d0e826767 feat(acpx/ui): adapter-declared capabilities for verbose streaming backends (no behavior change by default) (#11761)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Local agent adapters stream their work through the shared acpx
engine, which every ACP adapter (`claude_local`, `codex_local`,
`gemini_local`, custom ACP) runs on
> - Verbose streaming backends break two shared-engine behaviors: the
auto-posted run summary concatenates every text delta including the
thought stream (a long multi-tool run once auto-posted a ~50k character
monologue as an issue comment), and token-by-token tool-argument
streaming floods the run log with tens of thousands of
placeholder-titled in-progress events per run
> - These fixes were developed inside the `kimi_local` adapter PR, where
Kimi Code's streaming volume (~16,000 text deltas per run vs ~290 for a
comparable Claude run) surfaced both problems
> - Changing this behavior for all adapters at once is a fleet-wide
risk, and hardcoding adapter identities in shared code does not scale to
many adapters (or work at all for externally-shipped plugin adapters) —
so the behaviors become invocation-config parameters that an adapter's
own acpx config builder sets, with defaults preserving today's behavior
byte-for-byte
> - The benefit is that the machinery lands fully tested with zero
behavior change for existing adapters — pin tests prove it — the engine
carries no adapter identities, and any adapter (including `custom_acp`
configs for external backends) opts in declaratively

## Linked Issues or Issue Description

- Refs #9967 — extracted from the `kimi_local` adapter PR and
restructured to be inert by default; the commit preserves the original
author's (@hawikk) authorship.

**Current behavior**

When an acpx-engine run ends without the agent leaving a comment, the
auto-posted summary is every streamed text delta concatenated, thought
stream included. Backends that stream tool arguments emit tens of
thousands of placeholder-titled `in_progress` tool events into the
stored run log, pinning the live activity indicator to a generic "tool
call". There is no mechanism for an adapter to vary either behavior, and
shared code must never branch on adapter identities.

**Proposed behavior**

Two engine invocation-config parameters, read with behavior-preserving
defaults: `summaryStrategy` (`"full"` = existing concatenation, the
default; `"lastOutputSegment"` = segment output at tool starts, exclude
thought stream, post the last non-empty segment) and
`coalescePlaceholderToolUpdates` (`false` = never drop an event, the
default; `true` = coalesce placeholder-titled in-progress updates). An
adapter opts in from its own acpx config builder — the engine has no
per-adapter knowledge, no adapter identity appears anywhere in shared
code, and `custom_acp` agent configs can set the same knobs for external
verbose backends.

**Reason and benefit**

Existing adapters are provably unaffected — new pin tests assert the
default path's summary and tool-event output byte-for-byte, so any
future change that alters behavior for claude/codex/gemini/custom fails
the suite. The verbose-backend handling still lands fully tested,
activated declaratively by the adapter that needs it (the `kimi_local`
adapter PR sets both knobs in its config builder).

## What Changed

- `packages/adapter-utils/src/acpx-engine/execute.ts`: the run
preparation parses `summaryStrategy` and
`coalescePlaceholderToolUpdates` from the invocation config (validated,
defaulted); summary accumulation and `emitRuntimeEvent` branch on the
prepared values. The default path is the pre-existing code
(`textParts.join("")`, no event filtering). `buildAcpxRunSummary` is the
exported last-segment strategy.
- `packages/adapter-utils/src/acpx-engine/execute.test.ts`: a pin test
asserting the default path's exact summary (thought stream included) and
full tool-event stream (placeholder-titled in-progress updates present,
names restored); opt-in tests for each knob; a `buildAcpxRunSummary`
unit test.

- `ui/src/adapters/types.ts`: `UIAdapterModule` gains an optional
`transcriptPresentation` capability — `maxVisibleEntries` (issue-chat
transcript window, default 30) and `liveReasoningView` (`"ticker"`
default; `"scrollLog"` renders live reasoning in a scrollable
auto-following box with one entry per tool call).
- `ui/src/lib/issue-chat-messages.ts` and
`ui/src/components/IssueChatThread.tsx`: shared code resolves the hints
via `findUIAdapter(adapterType)` with today's defaults as fallback — no
adapter identities anywhere. The `scrollLog` rendering component ships
here but is unreachable until an adapter declares it.
- `ui/src/lib/issue-chat-messages.test.ts`: a capability test registers
a synthetic verbose adapter and asserts the wider window; the
pre-existing test keeps pinning the default 30-entry window.

No adapter declares any of this in this PR — every adapter renders and
summarizes exactly as before, and there is no per-adapter data anywhere.
The `kimi_local` adapter PR (#9967, stacked on this branch) is the first
consumer: it declares `transcriptPresentation` in its own UI module and
sets the engine knobs in its own acpx config builder.

## Verification

- Engine suite: 130/130 pass (126 existing + 4 new); chat suites
(`issue-chat-messages`, `IssueChatThread`, `RunChatSurface`): all pass
including the new synthetic-adapter capability test — 237 tests across
the touched surfaces
- The pin tests are the regression guard: the engine test encodes
today's summary text and tool-event sequence for a default-config run,
and the existing 30-entry-window test pins the default transcript
window, so "nothing changed for Claude/Codex users" is an executable
assertion, not a review judgment
- `pnpm --filter @paperclipai/adapter-utils --filter @paperclipai/ui
typecheck`: clean

## Risks

- Low: with no adapter setting the knobs, every code path taken in
production is the existing one. The only behavioral surface is additive
(an unused strategy and an unused filter), exercised by tests.
- The knobs are ordinary invocation-config keys, so a `custom_acp` agent
config can also set them — intended: an external verbose backend gets
the same handling without code changes. Both knobs only affect that
agent's own run summaries and run-log verbosity.

## Model Used

- Original implementation authored in #9967 by @hawikk (models
documented there: Moonshot AI Kimi K3 Coding via Kimi Code CLI 0.27.0,
OpenAI GPT-5 Codex, Anthropic Claude Opus 4.8). The commit preserves
that authorship.
- Extraction, restructuring into config-declared parameters, pin tests,
and verification: Anthropic, **Claude Fable 5** (`claude-fable-5`) via
Claude Code, with repository, shell, and Git tooling.

## 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: Hawik <davapa@gmail.com>
canary/v2026.820.0-canary.5
2026-08-20 10:37:58 -07:00
DottaandPaperclip e826188e82 refactor(settings): unify settings and speed up exports (#11789)
## Thinking Path

> - Paperclip is the open source app that people use to manage AI agents
for work.
> - Operators use the settings area to control a company and its
Paperclip instance.
> - The current navigation separates related settings and uses duplicate
instance pages.
> - Company exports also do independent reads in sequence and do extra
work for previews.
> - Hardened workspace commands can differ from their saved command
after loopback binding.
> - This pull request makes these related operator workflows consistent
and faster.
> - The benefit is one clear settings area, faster exports, and stable
runtime command matching.

## Linked Issues or Issue Description

Refs #338

Related: #9834

**What existing behavior does this improve?**

This improves the company settings UI, company export preparation, and
workspace runtime command matching.

**Current behavior**

Company and instance settings use separate navigation and duplicate
pages. Export preparation reads many independent records in sequence.
Preview generation can also build an unused organization image. A
command with a forced loopback bind can fail to match its saved runtime
command.

**Proposed behavior**

Use one settings navigation and put general instance controls on the
company General page. Load independent export data with bounded
concurrency, skip unused preview image work, and load the export page
only when it is needed. Treat the loopback-bound form of a command as
the same runtime command.

**Reason and benefit**

Operators get one clear settings area. Large company exports need fewer
serialized reads. Export previews and initial UI loads do less work.
Hardened runtime services remain linked to their saved command
definitions.

**Breaking changes**

The obsolete instance General URL redirects to the unified settings
page. Access and Heartbeats remain available, and legacy bookmarks keep
their destinations. No API response shape or database schema changes.

## What Changed

- Unified company and instance settings navigation and removed duplicate
instance settings pages.
- Embedded general instance controls in the company General page and
kept access-sensitive navigation behavior.
- Preserved instance Access and Heartbeats controls in the unified
navigation and normalized old bookmarks to those destinations.
- Improved environment and access-state handling when workspace seed
requests overlap.
- Added bounded export reads, a lighter preview path, deferred export
preparation, and lazy export-page loading.
- Matched loopback-bound runtime commands to their saved command
definitions.
- Added focused shared, server, and UI regression tests.

## Verification

- `pnpm exec vitest run <18 changed test files>`: 18 files and 256 tests
passed.
- `pnpm check:token-gates`: passed all four token gates.
- `pnpm -r typecheck`: passed for all workspace projects.
- `pnpm build`: passed for all workspace projects.
- `pnpm test:run`: tests ran without a reported failure, but the runner
did not close after the server handoff tests. The process closed with
status 0 after an interrupt.
- Focused latest-head route tests: 2 files and 4 tests passed.
- GitHub latest-head checks: all completed without failure.
- Greptile: 5/5 with no unresolved review threads.

## Risks

- Medium risk: settings routes and navigation changed across several
operator roles.
- Medium risk: bounded export concurrency increases simultaneous
database reads. The limits stay below the normal pool size.
- Low risk: runtime command matching accepts only the known Tailscale
HTTPS loopback transformation.
- No migrations 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

- OpenAI Codex with a GPT-5-family coding model. The runtime does not
expose the exact deployed model ID or context-window size. Reasoning,
tool use, and local code execution were 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)
- [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details

Exception: This task requires the existing execution branch. The harness
does not permit a branch rename.
- [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>
canary/v2026.820.0-canary.4
2026-08-20 12:15:16 -05:00
416a273366 build(deps): bump jsdom and @types/jsdom (#11717)
Bumps [jsdom](https://github.com/jsdom/jsdom) and
[@types/jsdom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jsdom).
These dependencies needed to be updated together.
Updates `jsdom` from 28.1.0 to 30.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jsdom/jsdom/releases">jsdom's
releases</a>.</em></p>
<blockquote>
<h2>v30.0.1</h2>
<ul>
<li>Fixed <code>getComputedStyle()</code> with <code>calc()</code> and
other functions throwing an exception, which regressed in v30.0.0. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Sped up up range operations on large documents (<a
href="https://github.com/leonidaz"><code>@​leonidaz</code></a>)</li>
</ul>
<h2>v30.0.0</h2>
<p>Breaking changes:</p>
<ul>
<li>Node.js minimum version raised to <code>^22.22.2 || ^24.15.0 ||
&gt;=26.0.0</code>.</li>
</ul>
<p>Other changes:</p>
<ul>
<li>Added <code>CSS.escape()</code> and <code>CSS.supports()</code>
functions. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Added <code>'background-position-x'</code> and
<code>'background-position-y'</code> CSS properties. (<a
href="https://github.com/olagokemills"><code>@​olagokemills</code></a>)</li>
<li>Fixed <code>getComputedStyle()</code> to convert length values into
pixels. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Fixed CSS function serialization, e.g., in the return value of
<code>getPropertyValue()</code>. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Fixed the type of error thrown by <code>document.evaluate()</code>
(<a href="https://github.com/dokson"><code>@​dokson</code></a>)</li>
</ul>
<h2>v29.1.1</h2>
<ul>
<li>Fixed <code>'border-radius'</code> computed style serialization. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Fixed computed style computation when using
<code>'background-origin'</code> and <code>'background-clip'</code> CSS
properties. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Significantly optimized initial calls to
<code>getComputedStyle()</code>, before the cache warms up. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
</ul>
<h2>v29.1.0</h2>
<ul>
<li>Added basic support for the ratio CSS type. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Fixed <code>getComputedStyle()</code> sometimes returning outdated
results after CSS was modified. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
</ul>
<h2>v29.0.2</h2>
<ul>
<li>Significantly improved and sped up <code>getComputedStyle()</code>.
Computed value rules are now applied across a broader set of properties,
and include fixes related to inheritance, defaulting keywords, custom
properties, and color-related values such as <code>currentcolor</code>
and system colors. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Fixed CSS <code>'background</code>' and <code>'border'</code>
shorthand parsing. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
</ul>
<h2>v29.0.1</h2>
<ul>
<li>Fixed CSS parsing of <code>'border'</code>,
<code>'background'</code>, and their sub-shorthands containing keywords
or <code>var()</code>. (<a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a>)</li>
<li>Fixed <code>getComputedStyle()</code> to return a more functional
<code>CSSStyleDeclaration</code> object, including indexed access
support, which regressed in v29.0.0.</li>
</ul>
<h2>v29.0.0</h2>
<p>Breaking changes:</p>
<ul>
<li>Node.js v22.13.0+ is now the minimum supported v22 version (was
v22.12.0+).</li>
</ul>
<p>Other changes:</p>
<ul>
<li>Overhauled the CSSOM implementation, replacing the <a
href="https://www.npmjs.com/package/@acemir/cssom"><code>@acemir/cssom</code></a>
and <a
href="https://github.com/jsdom/cssstyle"><code>cssstyle</code></a>
dependencies with fresh internal implementations built on webidl2js
wrappers and the <a
href="https://www.npmjs.com/package/css-tree"><code>css-tree</code></a>
parser. Serialization, parsing, and API behavior is improved in various
ways, especially around edge cases.</li>
<li>Added <code>CSSCounterStyleRule</code> and
<code>CSSNamespaceRule</code> to jsdom <code>Window</code>s.</li>
<li>Added <code>cssMediaRule.matches</code> and
<code>cssSupportsRule.matches</code> getters.</li>
<li>Added proper media query parsing in <code>MediaList</code>, using
<code>css-tree</code> instead of naive comma-splitting. Invalid queries
become <code>&quot;not all&quot;</code> per spec.</li>
<li>Added <code>cssKeyframeRule.keyText</code> getter/setter
validation.</li>
<li>Added <code>cssStyleRule.selectorText</code> setter validation:
invalid selectors are now rejected.</li>
<li>Added <code>styleSheet.ownerNode</code>,
<code>styleSheet.href</code>, and <code>styleSheet.title</code>.</li>
<li>Added bad port blocking per the <a
href="https://fetch.spec.whatwg.org/#bad-port">fetch specification</a>,
preventing fetches to commonly-abused ports.</li>
<li>Improved <code>Document</code> initialization performance by lazily
initializing the CSS selector engine, avoiding ~0.5 ms of overhead per
<code>Document</code>. (<a
href="https://github.com/thypon"><code>@​thypon</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jsdom/jsdom/commit/6584485f094d5b271553005b68804c93a455c002"><code>6584485</code></a>
30.0.1</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/0c51df6d80567202e969ba273c32db01de43c26e"><code>0c51df6</code></a>
Update dependencies and dev dependencies</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/32adb340bf3782194099c6a7b0e0a34c05aa8f24"><code>32adb34</code></a>
Bump <code>@​asamuzakjp/dom-selector</code></li>
<li><a
href="https://github.com/jsdom/jsdom/commit/70f014aa1de06a684b4f7d123bdb832ae8c63c53"><code>70f014a</code></a>
Speed up range operations on large documents</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/250d7ee387109d9674d3e4a79fe1edac96e45476"><code>250d7ee</code></a>
Partially fix getComputedStyle with calc()</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/20a01fc4a5ca1b2a48ec9c546d230624964d2f83"><code>20a01fc</code></a>
30.0.0</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/8c8e583c4f0130f09a1f0ba2728c9aebc4f709c5"><code>8c8e583</code></a>
Precompute WPT expectation matches</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/f32245cfedf894b933bf4625b5649c284422da45"><code>f32245c</code></a>
Bump Node.js floor and dependencies</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/03ef23b4513af92d89d59b2383c5697a0a260111"><code>03ef23b</code></a>
Add background-position longhands</li>
<li><a
href="https://github.com/jsdom/jsdom/commit/ded056f38de1a1e3709feafd0acea57377f85f35"><code>ded056f</code></a>
Test CSS.escape() with numeric IDs</li>
<li>Additional commits viewable in <a
href="https://github.com/jsdom/jsdom/compare/v28.1.0...v30.0.1">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for jsdom since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version modifies <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />

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

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-20 10:11:28 -07:00
dependabot[bot] e1ce7a553c build(deps): bump @assistant-ui/react from 0.14.14 to 0.15.14 (#11725)
Bumps
[@assistant-ui/react](https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react)
from 0.14.14 to 0.15.14.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/assistant-ui/assistant-ui/releases">@​assistant-ui/react's
releases</a>.</em></p>
<blockquote>
<h2><code>@​assistant-ui/react</code><a
href="https://github.com/0"><code>@​0</code></a>.15.14</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5760">#5760</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/a4ac7dd94e9992070310acddff5e29f4e0693340"><code>a4ac7dd</code></a>
- fix: release replay response readers after completion, cancellation,
and errors (<a
href="https://github.com/Kinfe123"><code>@​Kinfe123</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5764">#5764</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/47b9256d417acda832cf93cd76f2c2714dd8ed6a"><code>47b9256</code></a>
- fix: generate unique in-memory thread IDs (<a
href="https://github.com/Kinfe123"><code>@​Kinfe123</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5789">#5789</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/d3fece3b17487edbbeeedb903f0e8075f82b2dd7"><code>d3fece3</code></a>
- feat: give the composer its draft back when a send never reached the
backend. a runtime that rejects <code>onNew</code> with the new
<code>MessageNotSentError</code> restores the text, quote, and
attachments the composer cleared at dispatch time, as long as nothing
has claimed the composer since. that guard and that outcome are the ones
<code>cancelRun</code> already applies to a trailing user message, so
whichever fires first keeps the composer, and of several drafts queued
behind one turn only the most recent is still restorable. an edit
composer closes at dispatch, so a rejected edit is not restored. (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5828">#5828</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/685a06939edb9478d68258cab632f389c2742a05"><code>685a069</code></a>
- feat: wire <code>threads.reloadMainThread()</code> through the tap
<code>ExternalThread</code> path via a new <code>onRefetchThread</code>
callback, with the <code>refetchThread</code> capability derived from
its presence (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5757">#5757</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/092585b6859eeca4d2947cbe858019f5a9d9e101"><code>092585b</code></a>
- fix: derive the suggestions scope from the thread so runtime-provided
suggestions render through <code>ThreadPrimitive.Suggestions</code> (<a
href="https://redirect.github.com/assistant-ui/assistant-ui/issues/5529">#5529</a>)
(<a href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/a90db30dbf1c73eb2ba8cc587cf157b1a04ce541"><code>a90db30</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/cfb5fab251784ce20722ec9371fd66137a9727f8"><code>cfb5fab</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/65e03a697366c62cc5295c28ae528634baaf2901"><code>65e03a6</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/d3fece3b17487edbbeeedb903f0e8075f82b2dd7"><code>d3fece3</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/4b75b8f96729314a369879d26d8e4cd8321eac36"><code>4b75b8f</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/1e98bcf3f406385f3c924521b73300c12898fea6"><code>1e98bcf</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/82cbc1560b069ba1dd7e9b068585f5c647629b36"><code>82cbc15</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/e28a62d84439e93a32b64f166196cef2cb02e5db"><code>e28a62d</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/8bba3aaadcae042b4750436e6aa62bbba4815dde"><code>8bba3aa</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/48af3c5c4198b9f3fe015e77580922b2e4733e7a"><code>48af3c5</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/22fa20ffd1f0d192c417b12d4512dcffeab5161b"><code>22fa20f</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/00a630aa93ce0a5e40f81fbf6ff1886275f72356"><code>00a630a</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/417efee92b48f3fac057d65200f85d4df8657fa0"><code>417efee</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/1e1d52bd2f08b8712764792a9d95b608cb365b64"><code>1e1d52b</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/c98699d83b1fcc98511ca00e810e1c3d2ba019ba"><code>c98699d</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/685a06939edb9478d68258cab632f389c2742a05"><code>685a069</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/f59d24b3ee7036c94bce7bc0a38f018574f50a69"><code>f59d24b</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/092585b6859eeca4d2947cbe858019f5a9d9e101"><code>092585b</code></a>]:</p>
<ul>
<li><code>@​assistant-ui/core</code><a
href="https://github.com/0"><code>@​0</code></a>.3.13</li>
<li><code>@​assistant-ui/store</code><a
href="https://github.com/0"><code>@​0</code></a>.3.9</li>
<li>assistant-cloud@0.1.40</li>
<li><code>@​assistant-ui/tap</code><a
href="https://github.com/0"><code>@​0</code></a>.9.12</li>
</ul>
</li>
</ul>
<h2><code>@​assistant-ui/react</code><a
href="https://github.com/0"><code>@​0</code></a>.15.13</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5745">#5745</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/1df4327dc915103bb1b64e01ee8d888c08de9f59"><code>1df4327</code></a>
- refactor: move ExternalThread, SingleThreadList, and the Assistant
augmentation namespace into <code>@​assistant-ui/core</code> (<a
href="https://github.com/Yonom"><code>@​Yonom</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/1df4327dc915103bb1b64e01ee8d888c08de9f59"><code>1df4327</code></a>]:</p>
<ul>
<li><code>@​assistant-ui/core</code><a
href="https://github.com/0"><code>@​0</code></a>.3.12</li>
</ul>
</li>
</ul>
<h2><code>@​assistant-ui/react</code><a
href="https://github.com/0"><code>@​0</code></a>.15.12</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5730">#5730</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/6c9560d145d8cd4699002ad305005e8b83a94342"><code>6c9560d</code></a>
- chore: drop dependencies that are never imported (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/f551562162f43b2bbeb2bb46d39b68243ca1d35a"><code>f551562</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/dc7b77dca65ad8d0384e8aec268a4141dc8bd0da"><code>dc7b77d</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/0ae51a8e8c4c49c4b8810b9c64845eeeded8b9bc"><code>0ae51a8</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/d1b7097ca86e84698fcfaabd1b310e30612dd32c"><code>d1b7097</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/e319574df10df2dbf2d57fc2bcf7cb92d3c6a2e6"><code>e319574</code></a>]:</p>
<ul>
<li><code>@​assistant-ui/core</code><a
href="https://github.com/0"><code>@​0</code></a>.3.11</li>
<li>assistant-stream@0.3.37</li>
</ul>
</li>
</ul>
<h2><code>@​assistant-ui/react-langgraph</code><a
href="https://github.com/0"><code>@​0</code></a>.14.23</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5730">#5730</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/6c9560d145d8cd4699002ad305005e8b83a94342"><code>6c9560d</code></a>
- chore: drop dependencies that are never imported (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5742">#5742</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/f551562162f43b2bbeb2bb46d39b68243ca1d35a"><code>f551562</code></a>
- fix: skip RemoveMessage explicitly in convertLangChainMessages (<a
href="https://github.com/Yonom"><code>@​Yonom</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/f551562162f43b2bbeb2bb46d39b68243ca1d35a"><code>f551562</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/dc7b77dca65ad8d0384e8aec268a4141dc8bd0da"><code>dc7b77d</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/0ae51a8e8c4c49c4b8810b9c64845eeeded8b9bc"><code>0ae51a8</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/d1b7097ca86e84698fcfaabd1b310e30612dd32c"><code>d1b7097</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/e319574df10df2dbf2d57fc2bcf7cb92d3c6a2e6"><code>e319574</code></a>]:</p>
<ul>
<li><code>@​assistant-ui/core</code><a
href="https://github.com/0"><code>@​0</code></a>.3.11</li>
<li>assistant-stream@0.3.37</li>
</ul>
</li>
</ul>
<h2><code>@​assistant-ui/react-langgraph</code><a
href="https://github.com/0"><code>@​0</code></a>.14.22</h2>
<h3>Patch Changes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/assistant-ui/assistant-ui/blob/main/packages/react/CHANGELOG.md">@​assistant-ui/react's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.14</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5760">#5760</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/a4ac7dd94e9992070310acddff5e29f4e0693340"><code>a4ac7dd</code></a>
- fix: release replay response readers after completion, cancellation,
and errors (<a
href="https://github.com/Kinfe123"><code>@​Kinfe123</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5764">#5764</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/47b9256d417acda832cf93cd76f2c2714dd8ed6a"><code>47b9256</code></a>
- fix: generate unique in-memory thread IDs (<a
href="https://github.com/Kinfe123"><code>@​Kinfe123</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5789">#5789</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/d3fece3b17487edbbeeedb903f0e8075f82b2dd7"><code>d3fece3</code></a>
- feat: give the composer its draft back when a send never reached the
backend. a runtime that rejects <code>onNew</code> with the new
<code>MessageNotSentError</code> restores the text, quote, and
attachments the composer cleared at dispatch time, as long as nothing
has claimed the composer since. that guard and that outcome are the ones
<code>cancelRun</code> already applies to a trailing user message, so
whichever fires first keeps the composer, and of several drafts queued
behind one turn only the most recent is still restorable. an edit
composer closes at dispatch, so a rejected edit is not restored. (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5828">#5828</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/685a06939edb9478d68258cab632f389c2742a05"><code>685a069</code></a>
- feat: wire <code>threads.reloadMainThread()</code> through the tap
<code>ExternalThread</code> path via a new <code>onRefetchThread</code>
callback, with the <code>refetchThread</code> capability derived from
its presence (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5757">#5757</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/092585b6859eeca4d2947cbe858019f5a9d9e101"><code>092585b</code></a>
- fix: derive the suggestions scope from the thread so runtime-provided
suggestions render through <code>ThreadPrimitive.Suggestions</code> (<a
href="https://redirect.github.com/assistant-ui/assistant-ui/issues/5529">#5529</a>)
(<a href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/a90db30dbf1c73eb2ba8cc587cf157b1a04ce541"><code>a90db30</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/cfb5fab251784ce20722ec9371fd66137a9727f8"><code>cfb5fab</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/65e03a697366c62cc5295c28ae528634baaf2901"><code>65e03a6</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/d3fece3b17487edbbeeedb903f0e8075f82b2dd7"><code>d3fece3</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/4b75b8f96729314a369879d26d8e4cd8321eac36"><code>4b75b8f</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/1e98bcf3f406385f3c924521b73300c12898fea6"><code>1e98bcf</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/82cbc1560b069ba1dd7e9b068585f5c647629b36"><code>82cbc15</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/e28a62d84439e93a32b64f166196cef2cb02e5db"><code>e28a62d</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/8bba3aaadcae042b4750436e6aa62bbba4815dde"><code>8bba3aa</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/48af3c5c4198b9f3fe015e77580922b2e4733e7a"><code>48af3c5</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/22fa20ffd1f0d192c417b12d4512dcffeab5161b"><code>22fa20f</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/00a630aa93ce0a5e40f81fbf6ff1886275f72356"><code>00a630a</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/417efee92b48f3fac057d65200f85d4df8657fa0"><code>417efee</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/1e1d52bd2f08b8712764792a9d95b608cb365b64"><code>1e1d52b</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/c98699d83b1fcc98511ca00e810e1c3d2ba019ba"><code>c98699d</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/685a06939edb9478d68258cab632f389c2742a05"><code>685a069</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/f59d24b3ee7036c94bce7bc0a38f018574f50a69"><code>f59d24b</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/092585b6859eeca4d2947cbe858019f5a9d9e101"><code>092585b</code></a>]:</p>
<ul>
<li><code>@​assistant-ui/core</code><a
href="https://github.com/0"><code>@​0</code></a>.3.13</li>
<li><code>@​assistant-ui/store</code><a
href="https://github.com/0"><code>@​0</code></a>.3.9</li>
<li>assistant-cloud@0.1.40</li>
<li><code>@​assistant-ui/tap</code><a
href="https://github.com/0"><code>@​0</code></a>.9.12</li>
</ul>
</li>
</ul>
<h2>0.15.13</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5745">#5745</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/1df4327dc915103bb1b64e01ee8d888c08de9f59"><code>1df4327</code></a>
- refactor: move ExternalThread, SingleThreadList, and the Assistant
augmentation namespace into <code>@​assistant-ui/core</code> (<a
href="https://github.com/Yonom"><code>@​Yonom</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/1df4327dc915103bb1b64e01ee8d888c08de9f59"><code>1df4327</code></a>]:</p>
<ul>
<li><code>@​assistant-ui/core</code><a
href="https://github.com/0"><code>@​0</code></a>.3.12</li>
</ul>
</li>
</ul>
<h2>0.15.12</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5730">#5730</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/6c9560d145d8cd4699002ad305005e8b83a94342"><code>6c9560d</code></a>
- chore: drop dependencies that are never imported (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/f551562162f43b2bbeb2bb46d39b68243ca1d35a"><code>f551562</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/dc7b77dca65ad8d0384e8aec268a4141dc8bd0da"><code>dc7b77d</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/0ae51a8e8c4c49c4b8810b9c64845eeeded8b9bc"><code>0ae51a8</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/d1b7097ca86e84698fcfaabd1b310e30612dd32c"><code>d1b7097</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/e319574df10df2dbf2d57fc2bcf7cb92d3c6a2e6"><code>e319574</code></a>]:</p>
<ul>
<li><code>@​assistant-ui/core</code><a
href="https://github.com/0"><code>@​0</code></a>.3.11</li>
<li>assistant-stream@0.3.37</li>
</ul>
</li>
</ul>
<h2>0.15.11</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5723">#5723</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/94dc3e509fa2b4fae1a14c88ec34b910c8d95af8"><code>94dc3e5</code></a>
- chore: update dependencies (<a
href="https://github.com/okisdev"><code>@​okisdev</code></a>)</p>
</li>
<li>
<p><a
href="https://redirect.github.com/assistant-ui/assistant-ui/pull/5722">#5722</a>
<a
href="https://github.com/assistant-ui/assistant-ui/commit/7faf0fb1fbc3e36f14ba4822446f95bf730c452b"><code>7faf0fb</code></a>
- fix: ExternalThread edit composer reads editing state live, so a
same-tick beginEdit + setText + send dispatches the edit; send before
beginEdit and double beginEdit now throw (legacy runtime parity) (<a
href="https://github.com/Yonom"><code>@​Yonom</code></a>)</p>
</li>
<li>
<p>Updated dependencies [<a
href="https://github.com/assistant-ui/assistant-ui/commit/94dc3e509fa2b4fae1a14c88ec34b910c8d95af8"><code>94dc3e5</code></a>,
<a
href="https://github.com/assistant-ui/assistant-ui/commit/ab5796932c97bc5bade19022e2ac8762949d2967"><code>ab57969</code></a>]:</p>
<ul>
<li>assistant-stream@0.3.36</li>
<li>assistant-cloud@0.1.39</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/6b73c5053829c8ec59b35422af4ac29869cc19e4"><code>6b73c50</code></a>
chore: update versions (<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5754">#5754</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/685a06939edb9478d68258cab632f389c2742a05"><code>685a069</code></a>
feat(core,react): wire reloadMainThread through the tap external thread
(<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5828">#5828</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/d3fece3b17487edbbeeedb903f0e8075f82b2dd7"><code>d3fece3</code></a>
fix(core,eve): return an undispatched send to the composer (<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5789">#5789</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/a4ac7dd94e9992070310acddff5e29f4e0693340"><code>a4ac7dd</code></a>
fix(react): release replay boundary stream readers (<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5760">#5760</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/47b9256d417acda832cf93cd76f2c2714dd8ed6a"><code>47b9256</code></a>
fix(react): generate unique in-memory thread ids (<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5764">#5764</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/092585b6859eeca4d2947cbe858019f5a9d9e101"><code>092585b</code></a>
fix(core): derive the suggestions scope from the thread's suggestions
(<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5757">#5757</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/fb4025e93aaaa2383fdda2c3b4fc69303587a1ed"><code>fb4025e</code></a>
chore: update versions (<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5746">#5746</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/1df4327dc915103bb1b64e01ee8d888c08de9f59"><code>1df4327</code></a>
refactor(core,react): move ExternalThread and SingleThreadList into <a
href="https://github.com/assistan"><code>@​assistan</code></a>...</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/21d8d6526382fc0e71c357efd98f3b9d573eda7a"><code>21d8d65</code></a>
chore: update versions (<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5732">#5732</a>)</li>
<li><a
href="https://github.com/assistant-ui/assistant-ui/commit/6c9560d145d8cd4699002ad305005e8b83a94342"><code>6c9560d</code></a>
chore: drop dependencies that are never imported (<a
href="https://github.com/assistant-ui/assistant-ui/tree/HEAD/packages/react/issues/5730">#5730</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/assistant-ui/assistant-ui/commits/@assistant-ui/react@0.15.14/packages/react">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>
canary/v2026.820.0-canary.3
2026-08-20 08:59:37 -07:00
Nicky LeachandClaude Opus 5 a9d1f740f0 fix(workspaces): seed managed worktrees when the base checkout has no config (#11752)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents do that work in isolated git worktrees, and a managed
worktree runs its own Paperclip instance with a cloned database
> - That clone needs a seed source, and the source must come from
server-owned registration, never from state the workspace itself can
rewrite
> - The seed-source resolver requires the registered base project
workspace to hold its own `.paperclip/config.json`
> - A managed project workspace is a plain `git clone`, and no code
writes that file into it
> - Every isolated worktree provision, deferred seed, and workspace
repair therefore fails on a managed checkout
> - This pull request lets a named source supply the config when the
base checkout has none
> - The benefit is that managed worktrees provision again, and the seed
source stays server-owned

## Linked Issues or Issue Description

No public GitHub issue exists for this problem. It is described below.

**What happened?**

Agent runs that need an isolated worktree fail during provisioning. The
provision command exits with this error (paths redacted):

```
Execution workspace provision command "bash ./scripts/provision-worktree.sh" failed:
Registered base project workspace has no canonical Paperclip config:
<instance-home>/instances/default/projects/<company-id>/<project-id>/<repo>/.paperclip/config.json
```

`resolveRegisteredWorktreeSeedSource` sets `registeredConfigPath` to
`<baseCwd>/.paperclip/config.json` whenever the caller names a
registered base workspace. It then requires that file to exist.
`scripts/provision-worktree.sh` applies the same rule.

A managed project workspace never has that file.
`materializeManagedProjectWorkspace` creates it with `git clone` and a
rename, so the checkout holds repository content only. The control plane
keeps its config at `<home>/instances/<id>/config.json` instead.

The failure reaches three paths: worktree provisioning, deferred seeding
through `worktree ensure-seeded`, and workspace repair.

The behavior changed in #11671. That pull request replaced a fallback
chain with a single hard requirement. Fixture code in
`scripts/__tests__/provision-worktree-self-heal.test.mjs` writes a
config into the fake base workspace, so tests kept passing.

**Expected behavior**

A managed worktree provisions and seeds from the registered source. The
seed manifest still never selects that source.

**Steps to reproduce**

1. Register the Paperclip repository as a project with a `repoUrl`, so
the server materializes a managed checkout.
2. Assign an issue to an agent whose workspace strategy is
`git_worktree`.
3. Watch the workspace operation log for the provision command.
4. The command exits non-zero with the error above.

**Paperclip version or commit**

Reproduced on `master` at 01ddc26a3.

**Deployment mode**

`local_trusted`, single instance.

**Database mode**

Embedded PostgreSQL.

**Operating system**

Linux, Node.js 22.

**Related pull requests**

- Refs #11671 — introduced the requirement this pull request relaxes.
- Refs #11733 — open work on seed-source preflight. It reads the same
base-workspace config path and skips when the file is absent. It does
not change source selection.
- Refs #11735 — open work on provisioning reliability. It edits the same
four files and will need a rebase after either lands.

## What Changed

- `resolveRegisteredWorktreeSeedSource` sets the registered config path
only when `<baseCwd>/.paperclip/config.json` exists. This makes the
existing `registeredConfigPath ?? explicitSource` branch reachable for a
plain checkout.
- A base workspace that does hold its own config stays authoritative. A
mismatched explicit source is still rejected.
- The resolver throws a named error when the base workspace has no
config and no source is named.
- `readInstanceId` accepts an instance-root config at
`<home>/instances/<id>/config.json`. That layout names its instance by
directory and has no adjacent `.env`. Validation reuses
`resolvePaperclipInstanceId`.
- `scripts/provision-worktree.sh` and
`scripts/provision-worktree-runtime.sh` name the control plane's
instance config as the source when the base workspace has none. The
canonical-path and symlink checks stay.
- The workspace repair route supplies the same fallback, and only when
the base workspace has no config of its own.
- `doc/DEVELOPING.md` records the two source layouts.

## Verification

- `node --test scripts/__tests__/provision-worktree-self-heal.test.mjs`
— 10 tests pass. The fixture no longer writes a config into the base
workspace, so it models a real managed checkout. One test now creates
that config mid-test, which covers both layouts.
- `npx vitest run src/worktree-seed-source.test.ts` in `packages/shared`
— 4 tests pass. Two are new: one resolves an instance-root source, and
one still fails closed when no source exists.
- `npx vitest run src/__tests__/workspace-runtime.test.ts
src/__tests__/execution-workspaces-routes.test.ts
src/__tests__/execution-workspace-runtime-control-conflict.test.ts
src/__tests__/workspace-operations-reconciliation.test.ts
src/__tests__/worktree-seed-server-spawn.test.ts` in `server` — all
pass. Run them one file at a time. They share one test database, and
concurrent runs fail teardown.
- `npx vitest run src/__tests__/worktree.test.ts` in `cli` — 63 tests
pass.
- `pnpm --filter @paperclipai/shared typecheck` — clean.
- Manual check on a live instance: the resolver now returns the instance
config as the source for a managed checkout, with the source instance
`default` and a distinct target instance.

## Risks

Low to moderate.

- The relaxed rule applies only when the base workspace holds no config.
A base workspace that holds one keeps full authority, so the trust model
from #11671 is unchanged. The seed manifest still never selects the
source.
- The instance-id fallback reads a directory name. It applies only to
the `<home>/instances/<id>/config.json` layout, and
`resolvePaperclipInstanceId` rejects an unsafe segment.
- #11735 edits the same four files. Whichever pull request lands second
needs a rebase.
- `pnpm --filter @paperclipai/server typecheck` currently fails on this
checkout with duplicate `drizzle-orm` type instantiations. The failure
is present with and without this change, and the error count is
identical. It comes from an unrelated lockfile state, not from this pull
request.

## Model Used

Claude Opus 5 (`claude-opus-5`), by Anthropic, running in Claude Code.
Extended thinking was on. The model used file, search, and shell tools
to diagnose the failure on a live instance and to run the test suites.

## 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
- [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 5 <noreply@anthropic.com>
2026-08-20 08:42:16 -07:00
dependabot[bot] ed1db310a7 build(deps): bump @agentclientprotocol/claude-agent-acp from 0.66.0 to 0.69.0 (#11728)
Bumps
[@agentclientprotocol/claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp)
from 0.66.0 to 0.69.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/claude-agent-acp/releases">@​agentclientprotocol/claude-agent-acp's
releases</a>.</em></p>
<blockquote>
<h2>v0.69.0</h2>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.68.0...v0.69.0">0.69.0</a>
(2026-08-16)</h2>
<h3>Features</h3>
<ul>
<li>report changed files to AIR (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/1001">#1001</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/450d6b19dc46a041128356a6fa3cfa3ce6a5a382">450d6b1</a>)</li>
</ul>
<h2>v0.68.0</h2>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.67.0...v0.68.0">0.68.0</a>
(2026-08-14)</h2>
<h3>Features</h3>
<ul>
<li>align typed session failures with AIR protocol (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/992">#992</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/0581b9cf397ffd88f2830db721c2d8e3689045e4">0581b9c</a>)</li>
</ul>
<h2>v0.67.0</h2>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.66.0...v0.67.0">0.67.0</a>
(2026-08-14)</h2>
<h3>Features</h3>
<ul>
<li><strong>deps:</strong> Update to
<code>@​anthropic-ai/claude-agent-sdk</code> v0.3.232 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/993">#993</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/de0d0e2b7d185c521c3d1ac7b86e4312c919abfe">de0d0e2</a>)</li>
<li>expose typed session failures for AIR (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/979">#979</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/8157ee113e705750be4eb6cc787bdd12f1db84ff">8157ee1</a>)</li>
<li>publish the model fallback as a warning advisory (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/990">#990</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/35aaddb3d5b14eca316582ab285af8a660150dae">35aaddb</a>)</li>
<li>surface resolved model name in default model option description (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/982">#982</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/ec73cd8560be7d5e8b9741e404d7d45e17336996">ec73cd8</a>)</li>
<li>surface Skill tool calls with name and kind in _meta (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/986">#986</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/1f09e9a3cae787b0effdfae0e7205ef7fe22b9dc">1f09e9a</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>preserve task plans across prompts (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/974">#974</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/1afa940a2c8c0f4c610f4f64d30c0961642907b0">1afa940</a>)</li>
<li>show a pending title while Claude prepares a file (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/978">#978</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/3df1ede89f217312bc237124dc1eccc10c860f99">3df1ede</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/claude-agent-acp/blob/main/CHANGELOG.md">@​agentclientprotocol/claude-agent-acp's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.68.0...v0.69.0">0.69.0</a>
(2026-08-16)</h2>
<h3>Features</h3>
<ul>
<li>report changed files to AIR (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/1001">#1001</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/450d6b19dc46a041128356a6fa3cfa3ce6a5a382">450d6b1</a>)</li>
</ul>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.67.0...v0.68.0">0.68.0</a>
(2026-08-14)</h2>
<h3>Features</h3>
<ul>
<li>align typed session failures with AIR protocol (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/992">#992</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/0581b9cf397ffd88f2830db721c2d8e3689045e4">0581b9c</a>)</li>
</ul>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.66.0...v0.67.0">0.67.0</a>
(2026-08-14)</h2>
<h3>Features</h3>
<ul>
<li><strong>deps:</strong> Update to
<code>@​anthropic-ai/claude-agent-sdk</code> v0.3.232 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/993">#993</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/de0d0e2b7d185c521c3d1ac7b86e4312c919abfe">de0d0e2</a>)</li>
<li>expose typed session failures for AIR (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/979">#979</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/8157ee113e705750be4eb6cc787bdd12f1db84ff">8157ee1</a>)</li>
<li>publish the model fallback as a warning advisory (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/990">#990</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/35aaddb3d5b14eca316582ab285af8a660150dae">35aaddb</a>)</li>
<li>surface resolved model name in default model option description (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/982">#982</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/ec73cd8560be7d5e8b9741e404d7d45e17336996">ec73cd8</a>)</li>
<li>surface Skill tool calls with name and kind in _meta (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/986">#986</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/1f09e9a3cae787b0effdfae0e7205ef7fe22b9dc">1f09e9a</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>preserve task plans across prompts (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/974">#974</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/1afa940a2c8c0f4c610f4f64d30c0961642907b0">1afa940</a>)</li>
<li>show a pending title while Claude prepares a file (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/978">#978</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/3df1ede89f217312bc237124dc1eccc10c860f99">3df1ede</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/59a7e9367b3931a50178de4783cf6074b20060cd"><code>59a7e93</code></a>
chore(main): release 0.69.0 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/1007">#1007</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/450d6b19dc46a041128356a6fa3cfa3ce6a5a382"><code>450d6b1</code></a>
feat: report changed files to AIR (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/1001">#1001</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/5de5d4a2c8363e6462c231380c9fc17d80c568cc"><code>5de5d4a</code></a>
chore(main): release 0.68.0 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/1000">#1000</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/0581b9cf397ffd88f2830db721c2d8e3689045e4"><code>0581b9c</code></a>
feat: align typed session failures with AIR protocol (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/992">#992</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/11dd73b87146478d3d99ed62c2728289db5dff5d"><code>11dd73b</code></a>
Restore native provider state after overrides (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/996">#996</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/e4dba808eaf280379a1218280081fdf0346632e1"><code>e4dba80</code></a>
chore(main): release 0.67.0 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/975">#975</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/de0d0e2b7d185c521c3d1ac7b86e4312c919abfe"><code>de0d0e2</code></a>
feat(deps): Update to <code>@​anthropic-ai/claude-agent-sdk</code>
v0.3.232 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/993">#993</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/35aaddb3d5b14eca316582ab285af8a660150dae"><code>35aaddb</code></a>
feat: publish the model fallback as a warning advisory (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/990">#990</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/1f09e9a3cae787b0effdfae0e7205ef7fe22b9dc"><code>1f09e9a</code></a>
feat: surface Skill tool calls with name and kind in _meta (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/986">#986</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/ec73cd8560be7d5e8b9741e404d7d45e17336996"><code>ec73cd8</code></a>
feat: surface resolved model name in default model option description
(<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/982">#982</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.66.0...v0.69.0">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-08-20 08:40:49 -07:00
dependabot[bot] 6bf8f1d194 build(deps): bump react-dom and @types/react-dom (#11712)
Bumps
[react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom)
and
[@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).
These dependencies needed to be updated together.
Updates `react-dom` from 19.2.7 to 19.2.8
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/react/react/releases">react-dom's
releases</a>.</em></p>
<blockquote>
<h2>19.2.8 (July 21st, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Performance improvements when decoding
(<a
href="https://redirect.github.com/facebook/react/pull/37087">#37087</a>
by <a href="https://github.com/eps1lon"><code>@​eps1lon</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/react/react/commit/1dd4ecbdabf826f527fc9a58c05ea70375b7d170"><code>1dd4ecb</code></a>
[FlightReply] Performance improvements when decoding (<a
href="https://github.com/react/react/tree/HEAD/packages/react-dom/issues/37087">#37087</a>)</li>
<li><a
href="https://github.com/react/react/commit/b0d2fdb78bdfae075a7fa02ddcebbf25f90952c2"><code>b0d2fdb</code></a>
[19.2.x] Update required references to GitHub repo (<a
href="https://github.com/react/react/tree/HEAD/packages/react-dom/issues/36753">#36753</a>)</li>
<li>See full diff in <a
href="https://github.com/react/react/commits/v19.2.8/packages/react-dom">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/react-dom` from 19.2.3 to 19.2.4
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom">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-08-20 08:38:47 -07:00
b4953985c1 build(deps): bump react and @types/react (#11721)
Bumps [react](https://github.com/react/react/tree/HEAD/packages/react)
and
[@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).
These dependencies needed to be updated together.
Updates `react` from 19.2.7 to 19.2.8
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/react/react/releases">react's
releases</a>.</em></p>
<blockquote>
<h2>19.2.8 (July 21st, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Performance improvements when decoding
(<a
href="https://redirect.github.com/facebook/react/pull/37087">#37087</a>
by <a href="https://github.com/eps1lon"><code>@​eps1lon</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/react/react/commit/1dd4ecbdabf826f527fc9a58c05ea70375b7d170"><code>1dd4ecb</code></a>
[FlightReply] Performance improvements when decoding (<a
href="https://github.com/react/react/tree/HEAD/packages/react/issues/37087">#37087</a>)</li>
<li><a
href="https://github.com/react/react/commit/b0d2fdb78bdfae075a7fa02ddcebbf25f90952c2"><code>b0d2fdb</code></a>
[19.2.x] Update required references to GitHub repo (<a
href="https://github.com/react/react/tree/HEAD/packages/react/issues/36753">#36753</a>)</li>
<li>See full diff in <a
href="https://github.com/react/react/commits/v19.2.8/packages/react">compare
view</a></li>
</ul>
</details>
<br />

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

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
canary/v2026.820.0-canary.2
2026-08-20 08:20:34 -07:00
cbe6395cc5 fix(ui): task chat composer clears on send; align carets and composer with thread (#11772)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The task detail view uses a chat-style thread: agent turns, activity
phases, and a message composer.
> - A colleague's UX review found three defects: the composer draft
stayed visible after send, disclosure carets in turns and status pills
were misaligned, and the composer was not horizontally aligned with the
thread column.
> - These defects make the chat surface feel unpolished and cause
confusion about whether a message was sent.
> - This pull request fixes all three defects with small, targeted UI
changes and adds regression tests for each.
> - The benefit is a chat surface that behaves and aligns like users
expect from a messaging UI.

## Linked Issues or Issue Description

No public GitHub issue exists for this. Description of the underlying
problems:

**What happened?**

Three UI defects in the chat-style task view:

1. After a user pressed send, the composer kept the draft text until the
server round-trip finished. Fast typers could see stale text and doubt
the message was sent.
2. The disclosure carets on collapsed agent turns and the caret inside
the status pill did not share one alignment axis. They rendered at
different x-offsets and sizes.
3. The composer container had different horizontal padding than the
thread column above it, so the input box did not line up with the
message bubbles.

**Expected behavior**

The composer clears the instant a send starts. All disclosure carets sit
on one vertical axis with one size. The composer's left and right edges
align with the thread column.

**Steps to reproduce**

Open any task in the chat-style task view. Type a message and press
Enter — watch the composer text. Collapse and expand agent turns —
compare caret positions. Compare the composer's horizontal edges with
the message bubbles above it.

## What Changed

- `TaskChatComposer.tsx`: clear the draft synchronously when a send
starts instead of after the request resolves; restore the draft if the
send fails.
- `TaskChatTurn.tsx` and `TaskChatStatusPill.tsx`: use one shared caret
alignment (size, x-offset) for turn disclosure and status pill carets,
with supporting utility styles in `ui/src/index.css`.
- `TaskChatThread.tsx`: align the composer container with the thread
column padding.
- Added or updated unit tests in `TaskChatComposer.test.tsx`,
`TaskChatTurn.test.tsx`, `TaskChatActivityPhase.test.tsx`, and
`TaskChatThread.test.tsx`.

## Verification

- Run `pnpm vitest run
src/components/task-chat/TaskChatComposer.test.tsx
src/components/task-chat/TaskChatActivityPhase.test.tsx
src/components/task-chat/TaskChatTurn.test.tsx
src/components/TaskChatThread.test.tsx` in `ui/` — 4 files, 64 tests,
all pass.
- Manual: open a task in the chat view, send a message, and confirm the
composer clears immediately. Collapse/expand turns and confirm the
carets align. Compare composer edges with the thread column; the
alignment fixes were also pixel-verified with screenshots during local
review.

## Risks

- Low risk. All changes are render-layer only; no server or data
changes.
- The composer now clears optimistically. If a send fails, the draft is
restored, so no user text is lost.
- Caret alignment uses shared CSS utilities; visual regressions would
show in the existing component tests and in any screenshot diff.

## Model Used

- Implementation: OpenAI Codex CLI coding agent (Codex model family,
agentic tool use) via Paperclip's Codex adapter.
- Review, verification, rebase, and PR preparation: Anthropic Claude,
model id `claude-fable-5` (extended thinking, tool use), via Claude
Code.

## 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

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 00:17:55 -07:00
Nicky LeachandPaperclip 5a1ce7aed8 fix(server): stamp built commit into service.version (#11748)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The server emits OpenTelemetry spans so operators can trace agent
work
> - Each span needs a service version that identifies the code that
produced it
> - The current service version comes from a static environment value
and can become stale after a rebuild
> - This pull request records the built commit and resolves the service
version from the build stamp, runtime Git, the environment, or an
unknown fallback
> - The benefit is trace data that identifies the correct built commit
during development and deployment

## Linked Issues or Issue Description

**What happened?**

The server used a static `OTEL_SERVICE_VERSION` value for every
OpenTelemetry span. Rebuilds could produce traces with an old commit
value.

**Expected behavior**

The server should report the built commit when a build stamp exists. It
should use runtime Git, the environment value, or `unknown` as fallback.

**Steps to reproduce**

1. Set `OTEL_SERVICE_VERSION` to an old commit value.
2. Build the server at a different commit.
3. Start the server and inspect the OpenTelemetry service version.
4. Confirm that the built commit takes precedence over the old
environment value.

## What Changed

- Add a build script that writes the short Git commit to
`dist/build-info.json`.
- Resolve `service.version` from the build stamp, runtime Git, the
environment, or `unknown`.
- Log the resolved service version once during server startup.
- Add tests for the resolution order and safe behavior without Git.
- Document the resolution order in `doc/observability.md`.

## Verification

- `pnpm --filter @paperclipai/server build`
- `npx vitest run server/src/__tests__/service-version.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- Confirm that the build stamp contains the short commit.
- Confirm that the stamp wins over the environment value.
- Confirm that a build without Git exits successfully without a stamp.

## Risks

The server now prefers the built commit over `OTEL_SERVICE_VERSION`. A
build without Git uses the existing environment value or `unknown`. The
change needs no schema migration and has a single-commit rollback path.

## Model Used

OpenAI Codex, GPT-5, tool use and code execution. The runtime does not
expose the context window size or reasoning mode.

## 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>
nightly/v2026.820.0-nightly.0 canary/v2026.820.0-canary.1
2026-08-19 21:20:40 -07:00
Nicky LeachandPaperclip 7c8064da1b test(runtime): assert order-independent port invariants for concurrent siblings (#11754)
## Thinking Path

> - Paperclip manages work for AI agents.
> - The workspace runtime starts isolated services for concurrent
workspaces.
> - A runtime test assumed that one concurrent lane always received the
base port.
> - The allocator guarantees distinct ports, but scheduling decides
which lane receives the base port.
> - This pull request changes the test to assert allocator guarantees
without lane-order assumptions.
> - The benefit is a stable test that still checks the complete bounded
port range.

## Linked Issues or Issue Description

**What happened?**

The concurrent sibling workspace runtime test failed intermittently
because it assumed array index 0 received the base port.

**Expected behavior**

The test must accept either lane as the base-port owner while it checks
the allocator invariants.

**Steps to reproduce**

1. Start two isolated workspace runtimes with `Promise.all`.
2. Force the second lane to start first.
3. Run the old assertions.
4. Observe that the test expects the wrong lane to receive the base
port.

**Paperclip version or commit**

This change targets the current `master` branch.

**Deployment mode**

Built from source test suite.

**Installation method**

Built from source with pnpm.

**Database mode**

Not database-related.

## What Changed

- Replace lane-order assertions with order-independent port invariants.
- Assert distinct ports, the base lower port, and the bounded upper
port.
- Keep concurrent startup, service URL checks, and persisted-row checks.

## Verification

- The target test passed 12 consecutive runs.
- The full test file passed 128 of 128 tests.
- Both forced lane orderings passed with the new invariants.
- TypeScript reported no errors in the changed file.
- CI will run after this pull request opens.

## Risks

Low risk. This pull request changes one test file and does not change
runtime code.

## Model Used

OpenAI Codex, GPT-5, tool use and code execution enabled. The model
reviewed and prepared the pull request metadata.

## 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-08-19 19:59:40 -07:00
Devin Foley b5a3a863c3 feat(release): bootstrap new npm packages with a placeholder publish (#11757)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its release pipeline publishes a set of npm packages from CI with
npm trusted publishing (GitHub OIDC), gated by
`scripts/release-package-manifest.json`
> - A brand-new package name cannot be published by CI directly: the PR
bootstrap gate requires the name to resolve on npm, and a
trusted-publisher rule can only be configured after the package page
exists
> - The current bootstrap helper closes that gap by building the package
locally and publishing its real output from a maintainer machine —
before the PR that adds the package has passed CI or review
> - This pull request replaces that flow: the helper now publishes a
minimal deprecated placeholder at version `0.0.0` that only reserves the
name, so every real version ships from CI
> - The benefit is that unreviewed build output never reaches npm, and
the bootstrap runs from any checkout (including `master`, before the new
package's PR merges) with no local build

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The one-time npm bootstrap for a brand-new release package (`pnpm run
release:bootstrap-package`).

**Current behavior**

The helper builds the target package locally and publishes the real
build output from a maintainer machine. That content has not passed
repository CI or review at publish time. The helper also requires the
new package to exist in the local workspace, so it must run from the
(unmerged) PR branch that adds the package.

**Proposed behavior**

The helper publishes a three-file placeholder at version `0.0.0`
(manifest, README, and an `index.js` that throws a descriptive error),
waits for the registry to show the package, then deprecates it. The PR
bootstrap gate (`scripts/check-release-package-bootstrap.mjs`) only
requires the name to resolve on the registry, so the placeholder
satisfies it. The first real calver release from CI supersedes the
placeholder, and a stable release moves `latest` off it — the same
`latest` window that existed under the old flow, but containing an
explicit inert stub instead of unreviewed code.

**Reason and benefit**

Real package content only ever reaches npm from CI, after review and
merge. The bootstrap becomes safer (scope guard refuses names outside
`@paperclipai/`, already-published names are rejected) and simpler (no
local build, no workspace state, runs from any checkout).

**Breaking changes**

None at runtime. The helper's CLI surface changes: it now takes a
package name only (no directory selector) and drops `--skip-build`.
`doc/PUBLISHING.md` is updated to match.

## What Changed

- `scripts/bootstrap-npm-package.mjs`: replaced the build-and-publish
flow with a placeholder publish — stages `package.json` + `README.md` +
throwing `index.js` at version `0.0.0` in a temp directory, previews
with `npm publish --dry-run`, and publishes only with `--publish`.
One-time passwords are prompted interactively (never passed as
arguments, since they are single-use and would land in shell history),
with re-prompt on a rejected or expired code. After publishing, the
helper polls the registry until the package is visible (a first publish
can lag by minutes; verified live at ~5 minutes), requiring two
consecutive sightings before prompting for a second code and deprecating
the placeholder so accidental installs warn loudly; on timeout or
failure it prints the exact manual `npm deprecate` command. Added an
`@paperclipai/`-scope guard and a fail-fast error when `--publish` runs
without an interactive terminal. Removed the workspace-plan dependency
so it runs from any checkout.
- `scripts/bootstrap-npm-package.test.mjs`: rewrote for the new
interface — argument parsing, scope validation, the generated
placeholder files (manifest shape, throwing entry point, README), the
OTP re-prompt loop, and the registry poll (consecutive-sighting
requirement, timeout, transient-error tolerance) via injected fakes.
- `doc/PUBLISHING.md`: rewrote the "One-time bootstrap sequence for a
new package" section for the placeholder flow, including the `latest`
dist-tag window and the trusted-publishing setup ordering (placeholder
publish → trusted publisher rule → `"publishFromCi": true`).
- `.github/scripts/check-pr-release-bootstrap.mjs` (+ test, + wiring in
`run-quality-gates.mjs`): new informational commitperclip notice on PRs
that need this bootstrap. It fires when the PR newly release-enables a
package that is missing from npm, or adds an unpublished `publishFromCi:
false` package that published packages declare a `workspace:*`
dependency on, and names the exact maintainer command — so contributors
know the red `policy` check is not theirs to fix. It never fails the
gate (the `policy` job remains the enforcer), only looks up
scope-validated names on the registry, and stays quiet on registry
errors.

## Verification

- `node --test scripts/bootstrap-npm-package.test.mjs`: 13/13 pass
- `node --test .github/scripts/tests/*.test.mjs`: 147/147 pass (10 new
for the PR notice)
- `pnpm run test:release-registry`: 82/82 pass
- Replayed the new PR notice against a real historical PR's live API
data (files, manifest at base and head refs): with the registry in its
pre-bootstrap state it produces the exact maintainer instruction; with
the package bootstrapped it stays silent
- Full live end-to-end run: the flow bootstrapped
`@paperclipai/adapter-kimi-local` for real — dry-run preview (634-byte,
3-file tarball), publish, registry visibility after ~5 minutes of
propagation lag, deprecation confirmed via `npm view ... deprecated`
- Guards verified live: an already-published name is rejected, an
out-of-scope name (`left-pad`) is rejected, unknown options (including
the removed `--otp`) are rejected, and `--publish` in a non-interactive
shell fails fast before any network call

## Risks

- The `latest` dist-tag points at the deprecated `0.0.0` placeholder
until the first stable release supersedes it. This window also existed
under the old flow (which parked `latest` at a locally built version);
internal consumers are unaffected because release version rewrites pin
exact calver versions.
- The registry poll caps at ~10 minutes. If propagation is slower than
that, the helper prints the exact `npm deprecate ... --otp <code>`
command to run manually once `npm view` resolves.
- The helper no longer validates the name against the workspace release
plan, so a typo within the `@paperclipai/` scope would reserve a wrong
name. The dry-run preview shows the exact name before any publish.

## Model Used

- Anthropic, **Claude Fable 5** (`claude-fable-5`) via Claude Code, with
repository, shell, and Git tooling. It analyzed the existing bootstrap
flow and the release scripts (`release-package-map.mjs`,
`check-release-package-bootstrap.mjs`, `release.sh` dist-tag handling),
wrote the replacement script and tests, updated the documentation, and
ran the verification above.

## 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
2026-08-19 19:38:17 -07:00
Nicky LeachandPaperclip faab2620ad feat(sandbox): add a duplex transport for Daytona behind a default-off kill switch (#11750)
## Thinking Path

> - Paperclip is an open source app that manages AI agents for work
> - Paperclip runs agents in local and remote sandbox environments
> - A sandbox needs a bounded channel for commands and asynchronous
input
> - Daytona needs a real pseudo-terminal transport for this channel
> - The sandbox gateway also needs a mode that handles channel loss
safely
> - This pull request adds the Daytona transport and gateway mode behind
a default-off kill switch
> - The benefit is a tested foundation for later transport selection

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting (multiple of the above): sandbox providers, plugin SDK,
server settings, and shared types.

**Problem or motivation**

The merged sandbox protocol has no runtime transport for Daytona. The
generated sandbox gateway also has no duplex mode. A later
transport-selection change needs both parts and a safe per-run gate.

**Proposed solution**

Add a Daytona `duplexCommandStream` transport over a raw
pseudo-terminal. Add a generated gateway mode named `duplex_v1`. Add the
`enableSandboxDuplexBridge` setting with a default value of `false`.
Keep transport selection disabled until a later pull request.

**Alternatives considered**

Keep the protocol unused until the transport-selection change. This
would delay provider tests and leave the gateway path without direct
coverage.

**Roadmap alignment**

This change supports the completed Roadmap item for cloud and sandbox
agents. It extends the merged sandbox channel foundation in pull request
#11738.

**Additional context**

The Daytona provider remains an untrusted boundary. Deployments must use
least-privilege provider credentials and provider-side quota controls.
Operators must name an owner for duplex telemetry retention before
rollout.

## What Changed

- Add the Daytona `duplexCommandStream` capability over a raw
pseudo-terminal.
- Add a launch wrapper that disables echo and newline translation for
NDJSON frames.
- Close channels on lease release, destroy, resume of a stopped worker,
and worker shutdown.
- Declare the capability in the Daytona manifest and set
`PLUGIN_VERSION` to `0.1.5`.
- Add the worker-to-host notification sink at `ctx.duplexChannel.data`
and `ctx.duplexChannel.exit`.
- Add the generated sandbox gateway mode
`PAPERCLIP_API_BRIDGE_MODE=duplex_v1`.
- Add channel-loss results of `409 outcome_indeterminate` and `503
bridge_unavailable`.
- Add the per-run setting `enableSandboxDuplexBridge`, with a default
value of `false`.
- Add unit tests, generated-source codec tests, lifecycle tests, and a
credential-gated live Daytona test.

## Verification

- Daytona suite: 185 tests pass.
- Adapter utilities: 754 tests pass and 4 tests skip.
- Plugin SDK: 62 tests pass.
- Shared package: 28 tests pass.
- Server duplex tests pass.
- Shared, plugin SDK, server, and Daytona TypeScript checks pass.
- The live Daytona test passes 3 cases when `DAYTONA_API_KEY` is set.
- The live Daytona test skips 3 cases without `DAYTONA_API_KEY`.
- CI must run the full workspace typecheck, test, and build gates after
PR creation.

## Risks

- The Daytona control plane and pseudo-terminal remain untrusted
boundaries.
- The duplex gateway changes behavior only when the mode and per-run
setting enable it.
- A lost channel fails requests without replay, so callers must handle
indeterminate outcomes.
- The transport-selection change must require both `duplexCommandStream
=== true` and `enableSandboxDuplexBridge === true`.
- The provider credential and quota limits need operator control before
rollout.

## Model Used

OpenAI Codex, GPT-5, tool use 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
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-08-19 17:14:47 -07:00
Nicky LeachandPaperclip d5416fde9a fix(runtime): route sandbox git-bundle export through native syncOut (#11749)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Sandbox-managed runtimes move files between a host and an isolated
sandbox
> - The git-bundle export path reads the full bundle into host memory
> - The workspace restore path already uses the provider native
`syncOut` transfer
> - This pull request uses `syncOut` for bundle export and keeps
`readFile` as a fallback
> - The change reduces host buffering and exposes the transfer to
provider tracing

## Linked Issues or Issue Description

**What happened?**

The sandbox git-bundle export used `client.readFile` even when the
provider supported native `syncOut`. The path buffered the full bundle
in host memory and used a chunked base64 command loop.

**Expected behavior**

The export should use one confined native file transfer when the
provider supports `syncOut`. Providers without that capability should
keep the existing `readFile` fallback.

**Steps to reproduce**

1. Prepare a sandbox-managed runtime with native `syncOut` support.
2. Export the sandbox git bundle.
3. Inspect the sync operations and file reads.
4. Confirm that the bundle uses one native file mapping and that the
status file still uses `readFile`.

**Paperclip version or commit**

Commit `3fc88d14be7133867897e87838276e15aba675fd`.

**Deployment mode**

Built from source. The change applies to sandbox-managed runtime
execution.

**Additional context**

This PR contains a focused bug fix. No public issue matched this change
during the duplicate search.

## What Changed

- Route bundle export through `nativeSyncOut` when the provider supports
it.
- Keep the existing `readFile` fallback for providers without native
sync support.
- Confine the native bundle mapping with `assertSyncOperationsConfined`.
- Cover the native path, fallback path, retry path, and confinement
checks with unit tests.

## Verification

- `npx vitest run
packages/adapter-utils/src/sandbox-managed-runtime.test.ts` — 52 tests
passed.
- `npx tsc --noEmit` in `packages/adapter-utils` — passed.
- The PR CI workflow must pass before merge.

## Risks

Low risk. The native path runs only when the provider advertises
`syncOut`. The existing `readFile` path remains available as a fallback.
Native transfer progress reports only start and finish events.

## Model Used

OpenAI GPT-5 Codex. Exact runtime model ID: GPT-5 Codex. Context window:
not exposed in this run. Capabilities used: code review, shell tools,
GitHub CLI, and Paperclip API coordination.

## 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>
canary/v2026.820.0-canary.0
2026-08-19 16:50:04 -07:00
Nicky LeachandPaperclip b8a76081ec feat(environments): expose boot-relevant drift attribution in the custom-image overview (#11751)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip lets operators prepare and use custom images for sandbox
environments
> - The custom-image overview detected drift but did not show which boot
source changed
> - Operators need the changed field and values to understand why a
template no longer matches
> - This pull request adds safe drift attribution to the overview API
and the out-of-sync banner
> - The benefit is faster diagnosis without exposing secrets or internal
snapshot data

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting (server and UI).

**Problem or motivation**

The custom-image overview reported drift without identifying the changed
boot source. Operators had to inspect other data to find the cause.

**Proposed solution**

Return a classified drift summary with changed paths and their prior and
current values. Show the boot-source field in the UI banner. Keep legacy
templates and unclassified drift on the generic message.

**Alternatives considered**

The change does not expose the full snapshot or fingerprint. This keeps
the overview contract small and avoids secret disclosure.

**Roadmap alignment**

The change supports the existing custom-image environment workflow and
does not duplicate a roadmap item.

## What Changed

- Add `activeTemplateDrift` to the custom-image overview response.
- Classify drift as `boot_source_drift`, `knob_only`, or `unclassified`.
- Return drifted paths with safe `from` and `to` values.
- Show the changed boot-source field and values in the out-of-sync
banner.
- Keep legacy templates fail-closed and exclude secrets, fingerprints,
and raw snapshots.
- Add server and UI tests for the new behavior.

## Verification

- `npx vitest run
server/src/__tests__/environment-custom-images-service.test.ts` passes
with 27 tests.
- `npx vitest run ui/src/pages/CompanyEnvironments.test.tsx` passes with
27 tests.
- `pnpm --filter @paperclipai/ui exec tsc --noEmit` passes.
- Review the overview response and banner cases for boot-source,
knob-only, and legacy drift.

## Risks

The overview response gains one optional field. Legacy templates remain
compatible because they return `unclassified` and keep the generic
banner. The service excludes secret values, fingerprints, and raw
snapshots.

## Model Used

OpenAI Codex, GPT-5, tool use and code execution enabled. The model
reviewed the handoff and managed the pull request.

## 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] All Paperclip CI gates are green
- [x] 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: Paperclip <noreply@paperclip.ing>
canary/v2026.819.0-canary.9
2026-08-19 16:36:18 -07:00
DottaandPaperclip 2eb9a09c0c fix(runtime): adopt surviving shell-command services (#11744)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Managed workspace services must continue after a control-plane
restart
> - A service command can use shell control operators before it starts
the final process
> - The final process command line then differs from the stored shell
expression
> - Paperclip rejected that valid process even when its listener,
process group, and workspace matched
> - This pull request uses the stronger ownership checks for shell
expressions
> - The benefit is that Paperclip can adopt a valid service after a
restart

## Linked Issues or Issue Description

Refs #11740

**What happened?**

A managed service could use a command such as `env | sort > file; exec
pnpm dev`. After a control-plane restart, the surviving process command
line contained only the final program. Paperclip compared it with the
complete shell expression and rejected the service.

**Expected behavior**

Paperclip must adopt the surviving service when the listener, process
group, and workspace directory prove ownership.

**Steps to reproduce**

1. Configure a managed workspace service with a shell pipeline or
command sequence.
2. Start the service.
3. Restart the control plane while the service stays alive.
4. Observe that Paperclip starts a replacement instead of adopting the
live service.

**Paperclip version or commit**

`bd059a073d`

**Deployment mode**

Local dev with managed workspace services.

## What Changed

- Detect shell control syntax outside quoted strings.
- Skip the weak command-line comparison for these shell expressions.
- Require the live port owner to remain in the recorded process group.
- Keep the existing workspace directory check.
- Add unit and restart-adoption regression tests.

## Verification

- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/local-service-supervisor.test.ts
src/__tests__/workspace-runtime.test.ts -t 'does not compare shell
expressions|re-adopts a live service whose shell command differs'
--reporter=verbose` — 2 passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- `git diff --check origin/master...HEAD` — passed.

## Risks

- Low risk. The relaxed command comparison applies only to shell
expressions.
- Listener ownership, process-group ownership, and workspace directory
checks still fail closed.
- This change does not change the database schema, lockfile, workflow
files, or user interface.

> 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. The serving suffix and context-window size are
not exposed. The model used agentic reasoning, repository tools, code
execution, test execution, and GitHub 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-08-19 16:42:43 -05:00
1b259d7be4 build(deps): bump radix-ui from 1.6.4 to 1.6.7 (#11726)
Bumps
[radix-ui](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/radix-ui)
from 1.6.4 to 1.6.7.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/radix-ui/primitives/blob/main/packages/react/radix-ui/CHANGELOG.md">radix-ui's
changelog</a>.</em></p>
<blockquote>
<h2>1.6.6, 1.6.7</h2>
<ul>
<li>Reverted breaking changes that caused compatibility issues with
React Server Components.</li>
</ul>
<h2>1.6.5</h2>
<ul>
<li>Republish through CI to attach provenance attestations. The previous
versions of these packages were published manually outside of CI and
therefore shipped without provenance; this patch re-releases the same
code through the CI pipeline so every package includes an
attestation.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/radix-ui/primitives/commits/1.6.7/packages/react/radix-ui">compare
view</a></li>
</ul>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
canary/v2026.819.0-canary.8
2026-08-19 14:28:35 -07:00
DottaandPaperclip 01ddc26a37 fix(routines): clear transient execution failures (#9689)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Scheduled routines track each dispatch in `routine_runs` and link it
to an execution issue
> - Moving an execution issue to `blocked` or `cancelled` correctly
records a failed run state for operator visibility
> - When that issue later resumes or completes, the run can retain the
earlier failure reason and completion timestamp
> - That stale state makes an active or successfully completed routine
appear failed
> - This pull request reconciles the run back to a live state on resume
and preserves cleared failure details as completion context
> - The benefit is that routine run status consistently reflects the
current execution issue lifecycle without losing useful recovery history

## Linked Issues or Issue Description

Refs #9201

### What happened?

A routine execution issue that temporarily moved to `blocked` or
`cancelled` caused its linked routine run to become `failed`. If the
issue later returned to an active status or reached `done`, the routine
run could keep the stale failure reason and terminal timestamp.

### Expected behavior

Active execution issues should have an `issue_created` run with no
failure or completion timestamp. Completed execution issues should have
a `completed` run with no active failure reason, while retaining any
earlier transient failure in structured trigger context for diagnosis.

### Steps to reproduce

1. Create a routine run linked to a routine execution issue.
2. Move the issue to `blocked` and synchronize the run state.
3. Move the issue back to `in_progress` or forward to `done` and
synchronize again.
4. Observe that the run previously retained stale failed-state fields.

### Environment

- Reproduced on `master` at `da549123cc`.
- Core server behavior; not adapter-specific.
- Covered with the embedded PostgreSQL routines service test harness.

## What Changed

- Load the linked routine run while synchronizing execution issue
status.
- Restore transiently failed runs to `issue_created` when their
execution issue resumes active work.
- Clear stale failure state when an execution issue completes and retain
the earlier failure under `triggerPayload.transientFailure`.
- Add regression coverage for both resumed and completed execution
issues.

## Verification

- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/routines-service.test.ts` — 57 tests passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.

## Risks

- Low risk: the change is limited to routine execution issue/run
reconciliation.
- A completed run now stores a prior failed-state reason as structured
transient context instead of leaving `failureReason` populated.
- No schema, migration, API contract, or UI behavior 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

- OpenAI Codex using GPT-5.4 with reasoning, repository tools, GitHub
CLI access, code execution, and focused test execution. 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-08-19 15:43:26 -05:00
Nicky LeachandPaperclip 8161244284 feat(sandbox): add opt-in duplex command-stream foundation (capability, protocol, bounded host route, frame codec) (#11738)
## Thinking Path

> - Paperclip provides a control plane for companies that run AI agents.
> - Sandboxed agents need a safe execution path for persistent command
streams.
> - The existing callback transport does not provide a bounded, generic
duplex route.
> - The host must control capability access, route identity, protocol
limits, and close behavior.
> - This pull request adds an opt-in duplex command-stream foundation
across the sandbox layers.
> - The feature stays inert because no current provider declares the
capability.

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting (multiple of the above)

**Problem or motivation**

Sandbox command execution needs a persistent host-to-sandbox stream. The
current callback bridge uses a file transport and does not provide this
generic route.

**Proposed solution**

Add a fail-closed provider capability, generic worker protocol messages,
a host-owned bounded route, cross-layer service mediation, and a
versioned newline-delimited frame codec.

**Alternatives considered**

Keep the file transport and add feature-specific commands. This does not
provide one reusable duplex contract or host-owned route bounds.

**Roadmap alignment**

This work supports the completed Cloud / Sandbox agents roadmap area and
the safe autonomy goal in the product definition.

**Additional context**

The change passed a two-stage security review. The final code review
verdict was approve after fixes for active-stream bounds and
service-layer capability mediation.

## What Changed

- Add the opt-in `duplexCommandStream` provider capability with
fail-closed narrowing.
- Add duplex open, write, stop, and close requests and data and exit
notifications to the plugin worker protocol.
- Add a host-owned route with bounds for chunk size, cumulative bytes,
lifetime, protocol errors, pending requests, and pre-bind buffering.
- Add close acknowledgement handling with worker retirement when the
close remains unconfirmed.
- Wire `openDuplexChannel` through the execution target, runtime
service, and plugin worker.
- Add a versioned frame codec with shared wire-compatibility vectors and
split UTF-8 handling.

## Verification

- `server/src/__tests__/plugin-worker-manager-duplex.test.ts` passes 18
tests.
- `server/src/__tests__/environment-execution-target-duplex.test.ts`
passes 11 tests.
- `packages/adapter-utils/src/duplex-frame-codec.test.ts` passes 38
tests.
- `server/src/__tests__/sandbox-capability-contract.test.ts` passes 15
tests.
- Setup-token pseudo-terminal regression tests pass 47 tests.
- Server TypeScript check passes.
- Continuous integration will run the full required test, typecheck,
build, and policy checks.

## Risks

- Providers that opt into the capability must implement the complete
worker protocol.
- Route limit defaults can close a stream when a workload exceeds the
configured bounds.
- The capability remains disabled for current providers, so current
production behavior does not change.

## Model Used

OpenAI GPT-5 (`gpt-5`), with tool use and code execution. The model
reviewed and prepared this pull request from the supplied implementation
and verification record.

## 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>
canary/v2026.819.0-canary.7
2026-08-19 13:39:13 -07:00
bd059a073d fix(workspaces): make managed runtimes reliable across restarts (#11740)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Execution workspaces need isolated databases, ports, and runtime
services
> - Concurrent workspaces could reuse ports or lose service ownership
after a restart
> - A markerless worktree also needed seed recovery, but normal
markerless instances still needed to boot
> - This pull request makes seed, port, and service ownership state
explicit and recoverable
> - It also checks live process and listener identity before it reclaims
shared resources
> - The benefit is reliable workspace startup, restart, adoption, and
concurrent provisioning

## Linked Issues or Issue Description

**What happened?**

Managed workspaces could lose runtime service ownership after a
control-plane restart. Concurrent worktrees could also reuse a port when
their parent paths differed. A seed recovery change made every
markerless instance resolve a worktree seed source, so normal instances
without a source could not start.

**Expected behavior**

Paperclip must preserve healthy managed services across restarts. It
must reserve unique ports across worktree parents. It must provision a
registered markerless worktree, but it must skip seed work for a normal
markerless instance.

**Steps to reproduce**

1. Start two managed worktrees under different parent paths at the same
time.
2. Restart the control plane while a managed service stays alive.
3. Start Paperclip with a config that has no seed markers and no
registered worktree source.
4. Observe duplicate port selection, lost service adoption, or a
seed-source startup error.

**Paperclip version or commit**

Current `master` plus the workspace runtime reliability changes in this
pull request.

**Deployment mode**

Local development with managed execution workspaces and embedded
Postgres.

## What Changed

- Added a shared port registry with lease heartbeats, process identity
checks, and live listener probes.
- Reserved worktree ports across custom parent paths and repaired
duplicate legacy assignments.
- Preserved and adopted healthy managed services across control-plane
restarts.
- Reconciled guest bind modes and verified listener ownership before
termination or reuse.
- Provisioned registered markerless worktree databases and kept normal
markerless instance startup as a no-op.
- Added CLI, shared, server, and shell regression tests for seed, port,
listener, restart, and adoption behavior.
- Updated the worktree development documentation.

## Verification

- `pnpm exec vitest run cli/src/__tests__/worktree.test.ts
--reporter=verbose` — 63 tests passed.
- `pnpm exec vitest run
packages/shared/src/worktree-port-registry.test.ts --reporter=verbose` —
5 tests passed.
- Focused runtime Vitest set — 199 tests passed across 37 suites.
- `node --test scripts/__tests__/provision-worktree-self-heal.test.mjs`
— 10 tests passed.
- `git diff --check` passed.

## Risks

- Port reservation now depends on lease and process identity data. The
fallback listener probe prevents early reclamation when process metadata
is incomplete.
- Runtime adoption is stricter about bind and owner identity. The tests
cover healthy adoption, stale records, PID reuse, and unrelated
listeners.
- Markerless seed detection now separates registered worktrees from
normal instances. The tests cover both paths.
- There are no database schema migrations.

> 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 the `gpt-5` model family. The serving snapshot and
context-window size are not exposed. The agent used reasoning,
repository tools, 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>
Co-authored-by: Dev Agent <dev@paperclip.ing>
2026-08-19 14:55:16 -05:00
dependabot[bot] 433b1eb099 build(deps): bump @aws-sdk/client-s3 from 3.1106.0 to 3.1111.0 (#11714)
Bumps
[@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)
from 3.1106.0 to 3.1111.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/releases">@​aws-sdk/client-s3's
releases</a>.</em></p>
<blockquote>
<h2>v3.1111.0</h2>
<h4>3.1111.0(2026-08-14)</h4>
<h5>Chores</h5>
<ul>
<li>upgrade to typescript 7 (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8264">#8264</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/ca81fbb7398345aa31482dd7aa1971bccf278989">ca81fbb7</a>)</li>
<li>remove jest, use vitest for remaining test suites (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8263">#8263</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/3a88aada579866331fe642d4b8147ede799deafa">3a88aada</a>)</li>
</ul>
<h5>Documentation Changes</h5>
<ul>
<li><strong>client-redshift:</strong> Amazon Redshift now unlocks a
locked admin user account and resets the failed-login counter when you
update the admin password using the ModifyCluster API. This option is
available only when account lockout security is enabled. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/b93cb20c99c76c43369ffe2fb633577971c93236">b93cb20c</a>)</li>
<li><strong>client-redshift-serverless:</strong> Amazon Redshift now
unlocks a locked admin user account and resets the failed-login counter
when you update the admin password using the UpdateNamespace API. This
option is available only when account lockout security is enabled. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/197b4aa6163ac76eef6c7dce29b922fafdab395d">197b4aa6</a>)</li>
</ul>
<h5>New Features</h5>
<ul>
<li><strong>clients:</strong> update client endpoints as of 2026-08-14
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/1e7a28061dde539727980cb25689db3c50d1507e">1e7a2806</a>)</li>
<li><strong>client-bedrock-agentcore-control:</strong> Adds AgentCore
Payments support for CMK, Marketplace Subscriptions and QuickCreate (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/39108eb0d601bb5916971f56dc8573ec17842cf8">39108eb0</a>)</li>
<li><strong>client-sagemaker:</strong> Release support for g7.2xlarge,
g7.4xlarge, g7.8xlarge, g7.12xlarge, g7.24xlarge, and g7.48xlarge
instance types for SageMaker HyperPod (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/7198c1938d7897dc4f3839b04d8a55dba0f75c4b">7198c193</a>)</li>
<li><strong>client-mwaa-serverless:</strong> Adds support for Consuming
code for MWAA Serverless (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/e3edae27ddc8bcaf3e30f5ec93abdae0e013fae2">e3edae27</a>)</li>
<li><strong>client-bedrock-agent-runtime:</strong> Adds
CheckIngestedDocumentAcl and GetIngestedDocumentAcl APIs to Amazon
Bedrock Knowledge Bases. Customers can verify user access to documents
based on ingested ACLs and retrieve full ACL details including allow and
deny entries, enabling validation of ACL ingestion without test
retrievals. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/e86c42049cc69793f80c332bd9829ba6871153ad">e86c4204</a>)</li>
<li><strong>client-observabilityadmin:</strong> CloudWatch Logs
centralization rules now support tag propagation. You can configure a
TagPropagationConfiguration on your centralization rule to automatically
sync resource tags from source to destination log groups, with
configurable conflict resolution strategies. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/c57d7a4cd3b279d750cc035e8861f1b2c8857da7">c57d7a4c</a>)</li>
<li><strong>client-bedrock-agentcore:</strong> Add support for the
Machine Payments Protocol (MPP) and x402 upto scheme payments protocol
in Amazon Bedrock AgentCore Payments. Customers can now pay for
MPP-gated resources and also pay services which requires upto scheme in
x402 (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/7fdf457a8a7ff25eb019ef61c074158a3630816a">7fdf457a</a>)</li>
<li><strong>client-glue:</strong> Added support for associating glossary
terms with iterable form items, such as table columns. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/4c2e27d138f73f804774572c7772bcfd6a44006c">4c2e27d1</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1111.0.zip</strong></p>
<h2>v3.1110.0</h2>
<h4>3.1110.0(2026-08-13)</h4>
<h5>New Features</h5>
<ul>
<li><strong>client-auto-scaling:</strong> Amazon EC2 Auto Scaling now
supports terminating multiple instances in a single
TerminateInstanceInAutoScalingGroup call via the new InstanceIds
parameter, returning an Activities list. LaunchInstances now returns
IdempotentCallInProgressFault for duplicate client tokens. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/ee707980d238c2b5028e03084914a3398ce92709">ee707980</a>)</li>
<li><strong>client-cleanrooms:</strong> This release adds support for
minimum aggregation thresholds and comparison controls to the Custom
analysis rule type. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/1f84f2ae77a1cf4aed0b61dafba5da358894d61f">1f84f2ae</a>)</li>
<li><strong>client-codecommit:</strong> Added the GetBlobDifferences API
operation, which returns line-level diffs between two blob versions
without requiring a local clone. Returns structured hunks with context,
additions, and deletions. Supports pagination for large diffs. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/f1165c620804c3e7e1b035ecb9e083c723b8fba3">f1165c62</a>)</li>
<li><strong>client-securityagent:</strong> Add support for setting a
maximum task-hour budget cap on penetration tests and code reviews, and
for revalidating previously reported findings via a new REVALIDATION job
type. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/aba75d728bf5a19eebc7afa1c78df8f18d9ae8d0">aba75d72</a>)</li>
<li><strong>client-connect:</strong> Adds the StartAssistantContact API
to start chat contacts handled by an AI agent. Adds SegmentAttributes to
StartWebRTCContact, and corrects its error response to now receive
AccessDeniedException (previously returned as an internal server error
due to a missing error declaration). (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/67f9b7bb9bed253cc03580527faf7a94a2ebb2bf">67f9b7bb</a>)</li>
<li><strong>client-acm:</strong> This change allows customers to update
their existing email-validated certificates to use the DNS validation
method. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/71c194a4678abd7a368925a38c5b63f411fbd483">71c194a4</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1110.0.zip</strong></p>
<h2>v3.1109.0</h2>
<h4>3.1109.0(2026-08-12)</h4>
<h5>Documentation Changes</h5>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md">@​aws-sdk/client-s3's
changelog</a>.</em></p>
<blockquote>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1110.0...v3.1111.0">3.1111.0</a>
(2026-08-14)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1109.0...v3.1110.0">3.1110.0</a>
(2026-08-13)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1108.0...v3.1109.0">3.1109.0</a>
(2026-08-12)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1107.0...v3.1108.0">3.1108.0</a>
(2026-08-11)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1106.0...v3.1107.0">3.1107.0</a>
(2026-08-10)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/c41e9a98d4227b06099fdc7ea42bcf6fc5a1029f"><code>c41e9a9</code></a>
Publish v3.1111.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/ca81fbb7398345aa31482dd7aa1971bccf278989"><code>ca81fbb</code></a>
chore: upgrade to typescript 7 (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8264">#8264</a>)</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/4efe5bc67b71dc5ec652fe77130f3bae9efe0173"><code>4efe5bc</code></a>
Publish v3.1110.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/d2ee371d0cc488521fbb8a2304f941a4a0b53d1a"><code>d2ee371</code></a>
Publish v3.1109.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/26b0eb790ff86399b7af7b74ce8c188f25512cc6"><code>26b0eb7</code></a>
Publish v3.1108.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/785d467fbde2fe2f3720bbb944caefcb198039ed"><code>785d467</code></a>
chore(codegen): update smithy-ts commit to bring in TS6 change (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8262">#8262</a>)</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/edabd4a5228e259e9f3352cd47414069db755188"><code>edabd4a</code></a>
chore: upgrade to typescript 6 (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8257">#8257</a>)</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/d87c82ba2021a598a478383ae50647e7c1af45e0"><code>d87c82b</code></a>
Publish v3.1107.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/2e4482a67896a98b3fc23933c5cf2ad7c1d61f10"><code>2e4482a</code></a>
chore(codegen): smithy-aws-typescript-codegen 0.52.0 (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8255">#8255</a>)</li>
<li>See full diff in <a
href="https://github.com/aws/aws-sdk-js-v3/commits/v3.1111.0/clients/client-s3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@aws-sdk/client-s3&package-manager=npm_and_yarn&previous-version=3.1106.0&new-version=3.1111.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-08-19 12:53:30 -07:00
Nicky LeachandPaperclip e0e503e1bc fix(server): make blockers-resolved wake dedup level-triggered (#11732)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Paperclip uses issue dependencies to pause work until blockers reach
a ready state.
> - A blocked issue with several blockers can miss its wake when the
final blocker completes.
> - The wake deduplication used a historical per-edge key, so an old
completed wake hid the current ready state.
> - This pull request adds a level-triggered key for the sorted set of
blocker issue ids and uses one helper for all wake paths.
> - The benefit is that the final blocker wake can repair a missed wake,
while repeated reconciliation stays bounded.

## Linked Issues or Issue Description

Refs #8009, #7853, and #6719. These public pull requests cover related
dependency-wake and deduplication behavior. This pull request fixes a
separate multi-blocker state-key gap.

**What happened?**
A blocked issue with multiple blockers received no
`issue_blockers_resolved` wake when the final blocker completed. An
earlier completed per-edge wake suppressed the wake for the current
all-ready state.

**Expected behavior**
The final blocker completion must emit one wake for the current ready
state. A later reconciliation pass must not emit a second wake for the
same state.

**Steps to reproduce**
1. Create a blocked issue with at least two blocker issues.
2. Complete one blocker and record its completed per-edge wake.
3. Complete the final blocker.
4. Run the route-time or reconciliation wake path.
5. Confirm that one level-triggered wake exists for the sorted blocker
set.

**Paperclip version or commit**
`eed1e5cad91a37547e1b521232da04b9ddb316f0`

**Deployment mode**
Local dev from source.

## What Changed

- Add a SHA-256 level-triggered idempotency key from the sorted blocker
issue ids.
- Share one deduplication helper across route-time, finalize-time, and
periodic wake paths.
- Treat state-key rows with idempotent statuses as duplicates.
- Treat legacy per-edge rows as duplicates only while they remain in
flight.
- Record skipped route-time wakes without suppressing later
finalize-time or periodic wakes.
- Add regression coverage for a completed earlier-blocker wake and a
second reconciliation pass.

## Verification

- Run `npx vitest run
server/src/__tests__/issue-dependency-wakeups-routes.test.ts`.
- Run `npx vitest run
server/src/__tests__/heartbeat-issue-liveness-escalation.test.ts`.
- Run `npx vitest run
server/src/__tests__/heartbeat-dependency-scheduling.test.ts`.
- Run `npx vitest run server/src/__tests__/issue-rewake-throttle.test.ts
server/src/__tests__/recovery-stale-issue-lock-sweep.test.ts`.
- Run `tsc --noEmit` on the touched files.

## Risks

The change alters wake deduplication for dependency reconciliation. The
new key uses the full sorted blocker set, so a change in that set
permits a new wake. The regression tests cover the missed-final-blocker
case and repeated reconciliation.

## Model Used

OpenAI Codex, GPT-5, tool-use model with code execution and repository
review support.

## 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-08-19 12:52:50 -07:00
Nicky LeachandPaperclip 233be4b36c feat: parallelize sandbox file-sync behind a provider opt-in capability (#11736)
## Thinking Path

> - Paperclip runs AI agents through local and remote execution
adapters.
> - Sandbox providers move workspace and asset files before and after
agent runs.
> - Serial file transfers delay startup and teardown when several
operations do not depend on each other.
> - Providers need an opt-in contract so existing providers keep their
serial behavior.
> - This pull request adds a bounded scheduler and routes inbound and
outbound sync operations through it.
> - The benefit is shorter sandbox setup and teardown with stable
errors, clear telemetry, and a safe opt-in path.

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting (multiple of the above): packages/shared,
packages/adapter-utils, packages/plugins, and server.

**Problem or motivation**

Sandbox sync processes the workspace, assets, and referenced projects in
series. This adds avoidable wait time to agent startup and teardown.

**Proposed solution**

Add a fail-closed provider capability named concurrentSyncOperations.
Use a bounded scheduler with a limit of four operations. Preserve
operation order for error reporting. Keep non-opted-in providers on the
serial path.

**Alternatives considered**

Increase the serial transfer speed or add provider-specific schedulers.
Those options do not provide one shared contract or stable behavior
across providers.

**Roadmap alignment**

ROADMAP.md lists cloud and sandbox agents as a product area. This change
improves sandbox execution without changing the control-plane contract.

**Additional context**

The Daytona provider opts in. Board trials on this commit showed overlap
for inbound sync and outbound restore, with no referenced-project
staging failures.

## What Changed

- Add the concurrentSyncOperations sandbox capability and fail-closed
parsing.
- Add a bounded settle-all scheduler with stable input-order errors.
- Parallelize inbound workspace, asset, and referenced-project sync
operations when the provider opts in.
- Parallelize outbound workspace and asset restore operations when the
provider opts in.
- Surface referenced-project failure text in run logs and server
telemetry.
- Add Daytona sync spans and the capability declaration.
- Preserve in-flight upload scratch tarballs during workspace wipe.
- Add unit and regression tests for the scheduler, coordinators,
provider behavior, telemetry, and wipe race.

## Verification

- Run the adapter-utils and server type checks.
- Run the targeted adapter-utils, server, and Daytona test suites.
- Run the full automated sweep.
- Review six cold Daytona trials, with three serial and three parallel
runs.
- Confirm that parallel trials show inbound overlap and outbound restore
overlap.
- Confirm that providers without the capability keep serial behavior.

## Risks

- Providers must opt in only when their file operations can run safely
at the same time.
- A provider that declares the capability incorrectly can expose
transfer races.
- The scheduler keeps a limit of four to bound resource use.
- Providers without the capability keep the prior serial behavior.

## Model Used

OpenAI GPT-5 in the Codex runtime. The model used tool calls, code
inspection, and GitHub workflow support. The model did not author the
implementation commits.

## 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 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>
canary/v2026.819.0-canary.6
2026-08-19 12:34:11 -07:00
github-actions[bot]andlockfile-bot a5f3ac6b48 chore(lockfile): refresh pnpm-lock.yaml (#11737)
Auto-generated lockfile refresh after dependencies changed on master.
This PR only updates pnpm-lock.yaml.

Co-authored-by: lockfile-bot <lockfile-bot@users.noreply.github.com>
2026-08-19 12:18:50 -07:00
Nicky LeachandPaperclip e0b64529b3 feat(auth): normalize agent login in the sandbox onto one session table and a capability contract (#11730)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Sandbox agents need a safe login path for each supported adapter
> - Codex device login and Claude setup-token login used separate
session stores and route logic
> - Separate stores made session lookup, expiry, and login capability
checks harder to keep consistent
> - This pull request unifies both flows on one session table and one
capability contract
> - The benefit is one company-scoped login model with public session
identifiers and shared lifecycle rules

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting (multiple of the above)

**Problem or motivation**

Codex and Claude sandbox login used separate session stores and
different route paths. This split increased the risk of inconsistent
company scoping, session lookup, and cleanup.

**Proposed solution**

Use `adapter_auth_sessions` for both login flows. Use public session
identifiers for API access. Select login behavior from projected adapter
capability data. Share the route spine, lease arguments, runner
lifecycle, and reaper rules.

**Alternatives considered**

Keep two session tables and add matching fixes to both routes. This
keeps duplicate logic and does not provide one capability contract, so
this pull request uses shared infrastructure.

**Roadmap alignment**

This change supports the shipped Cloud / Sandbox agents milestone in
`ROADMAP.md`.

## What Changed

- Unify Codex device login and Claude setup-token login on
`adapter_auth_sessions`.
- Return and look up sessions with company-scoped public session
identifiers.
- Enforce one active session for each company, owner, and adapter.
- Share the login route spine, sandbox lease arguments, runner
lifecycle, and missing-auth check.
- Add a standalone setup-token reaper with adapter-specific row
selection.
- Add optional login capability projection for adapters and drive route
and UI selection from that data.
- Rename the provider flag to `supportsLoginPty` and validate its
deprecated alias.
- Remove the old Claude setup-token session table and add the required
migrations.

## Verification

- Server typecheck passed with `tsc`.
- Database typecheck passed.
- UI typecheck passed with `tsc -b`.
- Codex login service and route suites passed.
- Setup-token session, route, and reaper suites passed.
- Adapter session schema, plugin validator, capability projection, UI
render, and Daytona suites passed.
- GitHub Actions must confirm the complete CI gate after pull request
creation.

## Risks

- The migrations remove short-lived in-flight login rows during
deployment. A login that spans the migration can continue until its
provider lease expires.
- The Codex credential store remains company-scoped. A cross-owner
credential race remains a documented, board-accepted risk.
- API clients that use internal session row identifiers no longer work.
The API accepts only public session identifiers.

## Model Used

Codex, GPT-5, exact runtime model ID not exposed in this handoff, large
context window, reasoning, and repository tool use. The implementing
engineer produced the code with AI assistance.

## 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-08-19 11:51:31 -07:00
dependabot[bot] 61b4fc02d4 build(deps-dev): bump @storybook/addon-a11y from 10.5.4 to 10.5.8 (#11713)
Bumps
[@storybook/addon-a11y](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y)
from 10.5.4 to 10.5.8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">@​storybook/addon-a11y's
releases</a>.</em></p>
<blockquote>
<h2>v10.5.8</h2>
<h2>10.5.8</h2>
<ul>
<li>React: Fix RDT tsconfig selection for Vite project references - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35743">#35743</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>Tanstack React: Remove <code>@​cloudflare/vite-plugin</code> from
the inherited Vite config - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35706">#35706</a>,
thanks <a
href="https://github.com/FrancoKaddour"><code>@​FrancoKaddour</code></a>!</li>
<li>Tanstack: Wait for router to load before rendering - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35784">#35784</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>Test: Fix Illegal invocation when reading prototype.focus - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35528">#35528</a>,
thanks <a
href="https://github.com/FrancoKaddour"><code>@​FrancoKaddour</code></a>!</li>
</ul>
<h2>v10.5.7</h2>
<h2>10.5.7</h2>
<ul>
<li>Angular: Serve ancestor node_modules for addon-vitest in browser
mode - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35600">#35600</a>,
thanks <a
href="https://github.com/brandonroberts"><code>@​brandonroberts</code></a>!</li>
<li>Refactor: Update getVersionedPackages method to handle non-Storybook
packages correctly - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35769">#35769</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
</ul>
<h2>v10.5.6</h2>
<h2>10.5.6</h2>
<ul>
<li>Dependencies: Pin `@testing-library/jest-dom` to `6.9.1` - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35614">#35614</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>ESLint Plugin: Add plugin meta and document oxlint usage - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35655">#35655</a>,
thanks <a
href="https://github.com/yannbf"><code>@​yannbf</code></a>!</li>
<li>Vue: Skip docgen for module ids carrying a query - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35598">#35598</a>,
thanks <a
href="https://github.com/seanogdev"><code>@​seanogdev</code></a>!</li>
</ul>
<h2>v10.5.5</h2>
<h2>10.5.5</h2>
<ul>
<li>CLI: Update AI setup instructions to msw-storybook-addon v3 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35512">#35512</a>,
thanks <a
href="https://github.com/yannbf"><code>@​yannbf</code></a>!</li>
<li>Core: Upgrade `ws` to fix security advisories - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35584">#35584</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>ReactNative: Telemetry framework detection fix - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>,
thanks <a
href="https://github.com/hxy-asdw"><code>@​hxy-asdw</code></a>!</li>
<li>TanStack: Preserve explicit route ids on pathful clones - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35499">#35499</a>,
thanks <a
href="https://github.com/unpunnyfuns"><code>@​unpunnyfuns</code></a>!</li>
<li>TanStack: Resolve mock redirects through Vite's resolver - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35501">#35501</a>,
thanks <a
href="https://github.com/unpunnyfuns"><code>@​unpunnyfuns</code></a>!</li>
<li>TanStack: Respect routeOverrides component overrides in stories - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35497">#35497</a>,
thanks <a
href="https://github.com/unpunnyfuns"><code>@​unpunnyfuns</code></a>!</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@​storybook/addon-a11y's
changelog</a>.</em></p>
<blockquote>
<h2>10.5.8</h2>
<ul>
<li>React: Fix RDT tsconfig selection for Vite project references - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35743">#35743</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>Tanstack React: Remove <code>@​cloudflare/vite-plugin</code> from
the inherited Vite config - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35706">#35706</a>,
thanks <a
href="https://github.com/FrancoKaddour"><code>@​FrancoKaddour</code></a>!</li>
<li>Tanstack: Wait for router to load before rendering - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35784">#35784</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>Test: Fix Illegal invocation when reading prototype.focus - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35528">#35528</a>,
thanks <a
href="https://github.com/FrancoKaddour"><code>@​FrancoKaddour</code></a>!</li>
</ul>
<h2>10.5.7</h2>
<ul>
<li>Angular: Serve ancestor node_modules for addon-vitest in browser
mode - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35600">#35600</a>,
thanks <a
href="https://github.com/brandonroberts"><code>@​brandonroberts</code></a>!</li>
<li>Refactor: Update getVersionedPackages method to handle non-Storybook
packages correctly - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35769">#35769</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
</ul>
<h2>10.5.6</h2>
<ul>
<li>Dependencies: Pin <code>@testing-library/jest-dom</code> to
<code>6.9.1</code> - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35614">#35614</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>ESLint Plugin: Add plugin meta and document oxlint usage - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35655">#35655</a>,
thanks <a
href="https://github.com/yannbf"><code>@​yannbf</code></a>!</li>
<li>Vue: Skip docgen for module ids carrying a query - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35598">#35598</a>,
thanks <a
href="https://github.com/seanogdev"><code>@​seanogdev</code></a>!</li>
</ul>
<h2>10.5.5</h2>
<ul>
<li>CLI: Update AI setup instructions to msw-storybook-addon v3 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35512">#35512</a>,
thanks <a
href="https://github.com/yannbf"><code>@​yannbf</code></a>!</li>
<li>Core: Upgrade <code>ws</code> to fix security advisories - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35584">#35584</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>ReactNative: Telemetry framework detection fix - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35560">#35560</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>SyntaxHighlighter: Fix PrismJS dark mode mismatch - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35541">#35541</a>,
thanks <a
href="https://github.com/hxy-asdw"><code>@​hxy-asdw</code></a>!</li>
<li>TanStack: Preserve explicit route ids on pathful clones - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35499">#35499</a>,
thanks <a
href="https://github.com/unpunnyfuns"><code>@​unpunnyfuns</code></a>!</li>
<li>TanStack: Resolve mock redirects through Vite's resolver - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35501">#35501</a>,
thanks <a
href="https://github.com/unpunnyfuns"><code>@​unpunnyfuns</code></a>!</li>
<li>TanStack: Respect routeOverrides component overrides in stories - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35497">#35497</a>,
thanks <a
href="https://github.com/unpunnyfuns"><code>@​unpunnyfuns</code></a>!</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/6ef7d1ae816ebd5fb8bf84b8dec7d4a92410d73c"><code>6ef7d1a</code></a>
Bump version from &quot;10.5.7&quot; to &quot;10.5.8&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/7c6fb3a5ecf4495d73de6d70f802251934e079bd"><code>7c6fb3a</code></a>
Bump version from &quot;10.5.6&quot; to &quot;10.5.7&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/80195a019c8fc3c2d3554005c8c61fa2d97b319b"><code>80195a0</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/addons/a11y/issues/35486">#35486</a>
from storybookjs/valentin/cli-local-postinstall-aut...</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/3126f0a14a351e971679f61cd0bd5609d086ed57"><code>3126f0a</code></a>
Bump version from &quot;10.5.5&quot; to &quot;10.5.6&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/05a52b7a888c6b85c3f8aa6765ed9a0a69a79e4c"><code>05a52b7</code></a>
Bump version from &quot;10.5.4&quot; to &quot;10.5.5&quot; [skip
ci]</li>
<li>See full diff in <a
href="https://github.com/storybookjs/storybook/commits/v10.5.8/code/addons/a11y">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@storybook/addon-a11y&package-manager=npm_and_yarn&previous-version=10.5.4&new-version=10.5.8)](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-08-19 10:40:11 -07:00
dependabot[bot] 05e89db1d0 build(deps): bump react-i18next from 17.0.10 to 17.0.11 (#11711)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps [react-i18next](https://github.com/i18next/react-i18next) from
17.0.10 to 17.0.11.
<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.11</h2>
<ul>
<li>chore: <code>html-parse-stringify</code> updated to
<code>^4.0.1</code>. The parser powering <code>&lt;Trans&gt;</code> is
now actively maintained under the i18next org (<a
href="https://github.com/i18next/html-parse-stringify">i18next/html-parse-stringify</a>)
after years without upstream releases. 4.x brings modern dual ESM/CJS
packaging with an <code>exports</code> map, zero runtime dependencies,
reworked TypeScript types and a long list of parser fixes (literal
<code>&lt;</code> in text, multiline/CRLF attribute values, comments
containing <code>&gt;</code>, doctype handling, quote-aware bracket
handling).</li>
<li>refactor(Trans): the internal <code>escapeLiteralLessThan</code>
scanner (~80 lines) is replaced by the parser's new
<code>allowedTags</code> option with identical semantics: only numbered
tags, kept basic HTML tags and known component names are parsed as
markup, any other tag-shaped sequence in the translation stays literal
text. Rendered output is unchanged (all 493 tests pass, including the <a
href="https://redirect.github.com/i18next/react-i18next/issues/1880">#1880</a>
and <a
href="https://redirect.github.com/i18next/react-i18next/issues/1893">#1893</a>
escaping cases).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/i18next/react-i18next/commit/274e2e60785514388495466137c195c72d6749fb"><code>274e2e6</code></a>
17.0.11</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/3c4c5631150080453d5f63aac71575694fabef7c"><code>3c4c563</code></a>
build</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/1e7ccae22a755ea8471f0cab5cd3d94c925c527c"><code>1e7ccae</code></a>
chore: html-parse-stringify ^4.0.1 + 17.0.11 changelog</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/4412e25621ec9d0f45f7137e3a5cb7207bcfd8b0"><code>4412e25</code></a>
html-parse-stringify ^4.0.0: replace escapeLiteralLessThan with the
parser's ...</li>
<li><a
href="https://github.com/i18next/react-i18next/commit/5787979e38d03c2affb05cec0bf23daa6f2ad3ec"><code>5787979</code></a>
ci: types-compat falls back to latest when no <code>@​types/react</code>
pre-release tag ex...</li>
<li>See full diff in <a
href="https://github.com/i18next/react-i18next/compare/v17.0.10...v17.0.11">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.10&new-version=17.0.11)](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-08-19 10:38:23 -07:00
dependabot[bot] 81c9fdc5aa build(deps): bump react-router-dom from 7.18.1 to 7.18.2 (#11715)
Bumps
[react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom)
from 7.18.1 to 7.18.2.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/react-router-dom@7.18.2/packages/react-router-dom/CHANGELOG.md">react-router-dom's
changelog</a>.</em></p>
<blockquote>
<h2>v7.18.2</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.2"><code>react-router@7.18.2</code></a></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/remix-run/react-router/commit/69a653ee6ab1ac95b13c917ec56c5f3dc17ca9c1"><code>69a653e</code></a>
Release v7.18.2 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15354">#15354</a>)</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router-dom@7.18.2/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.18.1&new-version=7.18.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-08-19 10:36:08 -07:00
dependabot[bot] 6eb0739ff5 build(deps-dev): bump tailwindcss from 4.3.2 to 4.3.3 (#11718)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps
[tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)
from 4.3.2 to 4.3.3.
<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.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>
</blockquote>
</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.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>
</blockquote>
</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/issues/20334">#20334</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/e48c5e80473c25fe5a27fe267fbaf4f6512424a3"><code>e48c5e8</code></a>
Fix weird character rendering on Windows with Japanese locale (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20318">#20318</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/35a3e9c5159bea77af0d48f0c8849279211cc7e9"><code>35a3e9c</code></a>
Always produce <code>\&lt;length&gt;</code> value when optimizing
<code>--spacing(0)</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20319">#20319</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/4af47fbe942245fd05ad8cd4776c2dbd27237bee"><code>4af47fb</code></a>
Fix hues in achromatic theme colors to be <code>none</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20314">#20314</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/5835691d210b1c530160c844a562c36fa5fcbdb3"><code>5835691</code></a>
Handle CSS nesting natively (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20124">#20124</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/67c745efde4c6b36879e812b4c3d9250f7e0b31e"><code>67c745e</code></a>
Fix bug in attribute selector parsing (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20303">#20303</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/2683903b86d695f9c2647a06eb58bd96ade1eaee"><code>2683903</code></a>
Support fractional opacity modifiers for named shadow sizes (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20302">#20302</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/04588b1e8f3dbc856d8a3fad97c460bee689dbf3"><code>04588b1</code></a>
Fix theme() in JS plugins returning unresolved object instead of DEFAULT
valu...</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/b53fa096c92d830fc64b7cf69581496242583446"><code>b53fa09</code></a>
fix: exclude iframes from focus-visible auto outline in Preflight (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20292">#20292</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/ef79119d4e2b8b0f37710e736605bd0b3419afb7"><code>ef79119</code></a>
Bump dependencies (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20300">#20300</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/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.2&new-version=4.3.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-19 10:34:15 -07:00
dependabot[bot] 98298cb7ff build(deps-dev): bump tsx from 4.23.1 to 4.23.12 (#11722)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.23.1 to
4.23.12.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/privatenumber/tsx/releases">tsx's
releases</a>.</em></p>
<blockquote>
<h2>v4.23.12</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.23.11...v4.23.12">4.23.12</a>
(2026-08-10)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>shim <code>import.meta</code> when tokens are split by comments or
newlines (<a
href="https://redirect.github.com/privatenumber/tsx/issues/829">#829</a>)
(<a
href="https://github.com/privatenumber/tsx/commit/ed9d33046a135de13a35fdfce12368b79d1b1518">ed9d330</a>),
closes <a
href="https://redirect.github.com/privatenumber/tsx/issues/828">#828</a></li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.23.12"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.23.11</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.23.10...v4.23.11">4.23.11</a>
(2026-08-07)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>preserve async ESM require fallback (<a
href="https://github.com/privatenumber/tsx/commit/55cbecef8ebe839c7110e8c141a1c3bc4da326cd">55cbece</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.23.11"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.23.10</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.23.9...v4.23.10">4.23.10</a>
(2026-08-07)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>support nyc coverage discovery (<a
href="https://redirect.github.com/privatenumber/tsx/issues/710">#710</a>)
(<a
href="https://github.com/privatenumber/tsx/commit/ec1bcd5f711e5159b67cb0aea211f06cf2cfce8a">ec1bcd5</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.23.10"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.23.9</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.23.8...v4.23.9">4.23.9</a>
(2026-08-06)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>map Node test locations (<a
href="https://github.com/privatenumber/tsx/commit/2f55884195a8c745fbe64a0288de69bc062ed876">2f55884</a>)</li>
<li>support data URLs in tsImport (<a
href="https://github.com/privatenumber/tsx/commit/b94f46f6b6a7e6dc575624b0ecc7124318723056">b94f46f</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.23.9"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.23.8</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/privatenumber/tsx/commit/ed9d33046a135de13a35fdfce12368b79d1b1518"><code>ed9d330</code></a>
fix: shim <code>import.meta</code> when tokens are split by comments or
newlines (<a
href="https://redirect.github.com/privatenumber/tsx/issues/829">#829</a>)</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/651f5bec70d9a116d1fe1706000b7ca011a516fc"><code>651f5be</code></a>
test: cover CommonJS TypeScript import.meta paths</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/bd3bc6448e957c1172eb91a0584ec7fec2d6a7ad"><code>bd3bc64</code></a>
test: cover CommonJS loader source fallback</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/55cbecef8ebe839c7110e8c141a1c3bc4da326cd"><code>55cbece</code></a>
fix: preserve async ESM require fallback</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/6c5ba85f7a1e57f06bcb760718d6ba3b978e5a05"><code>6c5ba85</code></a>
docs: document CommonJS default interop</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/ec1bcd5f711e5159b67cb0aea211f06cf2cfce8a"><code>ec1bcd5</code></a>
fix: support nyc coverage discovery (<a
href="https://redirect.github.com/privatenumber/tsx/issues/710">#710</a>)</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/b6e5b48a7b0fa4639e67119c8b02150ec8c6cef7"><code>b6e5b48</code></a>
docs: clarify CommonJS default imports</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/2f55884195a8c745fbe64a0288de69bc062ed876"><code>2f55884</code></a>
fix: map Node test locations</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/de935d588b6c0959ac8af71e2cf40d1a61e659e7"><code>de935d5</code></a>
docs: document Node source-map stack formatting</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/b94f46f6b6a7e6dc575624b0ecc7124318723056"><code>b94f46f</code></a>
fix: support data URLs in tsImport</li>
<li>Additional commits viewable in <a
href="https://github.com/privatenumber/tsx/compare/v4.23.1...v4.23.12">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=tsx&package-manager=npm_and_yarn&previous-version=4.23.1&new-version=4.23.12)](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-08-19 10:32:04 -07:00
dependabot[bot] ec8d7dd21f build(deps): bump ws from 8.21.1 to 8.21.3 (#11729)
Bumps [ws](https://github.com/websockets/ws) from 8.21.1 to 8.21.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/websockets/ws/releases">ws's
releases</a>.</em></p>
<blockquote>
<h2>8.21.3</h2>
<h1>Bug fixes</h1>
<ul>
<li>The server now correctly rejects permessage-deflate offers if the
incoming
<code>client_max_window_bits</code> parameter value is smaller than its
configured
<code>clientMaxWindowBits</code> (e97a20ea).</li>
</ul>
<h2>8.21.2</h2>
<h1>Bug fixes</h1>
<ul>
<li>Fixed a test for <a href="https://github.com/nodejs/citgm">CITGM</a>
(2eb3be0b).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/websockets/ws/commit/c791e707eab3c13dd9a261d2479c3cc4a49a6fed"><code>c791e70</code></a>
[dist] 8.21.3</li>
<li><a
href="https://github.com/websockets/ws/commit/e97a20eaa6f2ad7969419eed732a506453251eb9"><code>e97a20e</code></a>
[fix] Reject offers with <code>client_max_window_bits</code> below
config</li>
<li><a
href="https://github.com/websockets/ws/commit/787ebf22ce3d091fb6f931d20b4c7e914ba7cf85"><code>787ebf2</code></a>
[dist] 8.21.2</li>
<li><a
href="https://github.com/websockets/ws/commit/b4d62ebad40c3b925c84ff305a47975406015422"><code>b4d62eb</code></a>
Revert &quot;[ci] Trust Coveralls Homebrew tap&quot;</li>
<li><a
href="https://github.com/websockets/ws/commit/e4bb883723a0c18452eea10a74139901ae33c61d"><code>e4bb883</code></a>
[security] Use GitHub PVR as main reporting channel</li>
<li><a
href="https://github.com/websockets/ws/commit/2eb3be0bff2453e2654b1315c5872e8d5d424a50"><code>2eb3be0</code></a>
[test] Skip test on Node.js versions where it does not apply</li>
<li>See full diff in <a
href="https://github.com/websockets/ws/compare/8.21.1...8.21.3">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
canary/v2026.819.0-canary.5
2026-08-19 10:30:13 -07:00
Nicky LeachandPaperclip 8b2dbd9d87 chore(deps): open one dependabot PR per major update (#11709)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Dependabot keeps the project dependencies current.
> - The npm update rule groups all major updates into one pull request.
> - One blocked major update can stop that grouped pull request.
> - This pull request gives each major update its own pull request.
> - The higher limit keeps the initial major updates and normal updates
visible.

## Linked Issues or Issue Description

**What happened?**

Dependabot grouped all npm major updates into one weekly pull request. A
blocked upgrade stopped the grouped pull request and hid other ready
updates.

**Expected behavior**

Dependabot should open one pull request for each npm major update.

**Steps to reproduce**

1. Read the npm entry in `.github/dependabot.yml`.
2. Run the weekly Dependabot update.
3. Inspect the pull requests for major npm updates.

**Paperclip version or commit**

`master` at the base commit for this pull request.

**Deployment mode**

Not applicable. This change affects repository configuration.

**Installation method**

Not applicable. This change affects repository configuration.

**Agent adapter(s) involved**

Not adapter-specific (repository configuration).

**Database mode**

Not database-related.

**Additional context**

The grouped major update included a blocked `js-yaml` upgrade. Separate
pull requests let other major updates proceed independently.

## What Changed

- Remove the `major-updates` group from the npm Dependabot entry.
- Raise the npm `open-pull-requests-limit` from 10 to 20.
- Keep the GitHub Actions Dependabot entry unchanged.

## Verification

- Run `python3 -c "import yaml;
yaml.safe_load(open('.github/dependabot.yml'))"`.
- Confirm the diff changes only `.github/dependabot.yml`.
- Confirm CI passes on this pull request.

## Risks

This change can open more Dependabot pull requests. The limit of 20
bounds the number of open npm update pull requests. No application code
changes.

## Model Used

OpenAI GPT-5. Tool use and code repository inspection assisted this
change.

## 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>
canary/v2026.819.0-canary.4
2026-08-19 09:13:27 -07:00
DottaandPaperclip e0d46d1375 test(workspaces): fix runtime provision metadata assertion (#11707)
## Thinking Path

> - Paperclip manages agent work in isolated execution workspaces.
> - Workspace operations record operation metadata and command-result
metadata separately.
> - Runtime provisioning records its provision kind in the operation
metadata.
> - One merged regression test checked that value in the command-result
metadata.
> - The production behavior was correct, but the test failed.
> - This pull request checks the provision kind in the operation
metadata.
> - The benefit is that the regression test now matches the recorder
contract.

## Linked Issues or Issue Description

Related pull request: #11706

**What happened?**

The runtime provisioning regression test expected `provisionKind` in
`result.metadata`. The recorder stores this value in the operation's
top-level `metadata`. The command-result metadata is `null` for this
case.

**Expected behavior**

The test must check `metadata.provisionKind`. It must continue to check
`result.status`.

**Steps to reproduce**

1. Check out commit `e1df4c6068fea684a1e9714ebd64bce95f3db19a`.
2. Run the focused runtime provisioning test.
3. Observe that the assertion checks the wrong metadata object.

**Paperclip version or commit**

`e1df4c6068fea684a1e9714ebd64bce95f3db19a`

**Deployment mode**

Local development.

## What Changed

- Move the `provisionKind` assertion from `result.metadata` to the
operation's top-level `metadata`.
- Keep the `result.status` assertion unchanged.

## Verification

- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/workspace-runtime.test.ts -t "keeps an explicit command
matching the built-in seed command as runtime provisioning"`
- Result: 1 test passed and 125 tests skipped.

## Risks

- Low risk. This pull request changes one test assertion and does not
change production code.

> 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, high-reasoning mode, with repository, shell, Git,
GitHub, and code execution tools. The runtime does not expose a
context-window value.

## 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>
canary/v2026.819.0-canary.3
2026-08-19 11:01:24 -05:00
DottaandPaperclip e1df4c6068 fix(workspaces): keep deferred seed databases reliable (#11706)
## Thinking Path

> - Paperclip manages agent work in isolated execution workspaces.
> - A workspace depends on a valid database seed before it can run.
> - Deferred seed failures were hidden behind a successful provision
status.
> - The seed restore also had two possible owners for the embedded
PostgreSQL process.
> - That allowed the target database to stop while the restore was still
running.
> - This pull request makes seed failures visible and gives the seed
process sole lifecycle ownership.
> - The benefit is that workspace provisioning reports the real result
and does not stop its own target database.

## Linked Issues or Issue Description

Related: #11684

**What happened?**

Initial worktree provisioning could report success before its deferred
database seed completed. The seed restore could also reuse a target
embedded PostgreSQL process with another shutdown owner. This could stop
the target database during the restore.

**Expected behavior**

Workspace status must show a failed deferred seed as a failure. The seed
restore must own the target embedded PostgreSQL process until restore,
migration, and validation finish.

**Steps to reproduce**

1. Provision a worktree with deferred database seeding.
2. Make the seed manifest end in a failed state while the command exits
with code 0.
3. Observe that the provision status remains successful on `master`.
4. Start a seed restore against an already-running target embedded
PostgreSQL process.
5. Observe that another lifecycle owner can stop the target during
restore.

**Paperclip version or commit**

`51a843e135`

**Deployment mode**

Local dev with execution workspaces and embedded PostgreSQL.

## What Changed

- Add a first-class `workspace_seed` operation for deferred database
seeds.
- Require terminal, verified seed evidence before the seed operation
succeeds.
- Surface the seed phase and failure metadata in workspace status and UI
state.
- Give the seed process exclusive lifecycle ownership of the target
embedded PostgreSQL process.
- Suppress imported embedded-Postgres exit hooks without removing
existing host listeners.
- Record a credential-safe shutdown diagnostic in failed seed manifests.

## Verification

- The original deferred-seed commit passed 4 server tests, 24
workspace-status UI tests, shared/server/UI typechecks, and the UI token
gate.
- The original PostgreSQL-lifecycle commit passed 3 lifecycle tests, 3
ownership/diagnostic tests, 1 real embedded-Postgres seed integration,
and the affected package typechecks.
- No local tests were rerun after the clean cherry-pick because the
operator requested the shortest landing path.
- Review the automatic PR checks for the clean `origin/master` replay.

## Risks

- A live target database now causes an early error instead of being
reused. The error includes recovery guidance.
- Workspace consumers must handle the new `workspace_seed` operation
type. Shared types and UI state handling are updated in this pull
request.

> 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, high-reasoning mode, with repository, shell, and
GitHub tool use. The runtime does not expose a more specific deployment
suffix or context-window value.

## 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-08-19 10:41:29 -05:00
DottaandPaperclip 51a843e135 fix(cli): accept renumbered migration journal order (#11684)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Worktree provisioning clones a source database into an isolated
workspace
> - Source validation must accept a migration journal that matches a
prefix of the checkout journal
> - Long-lived instances can apply migrations in a different order after
migration files are renumbered
> - The validator compared application order with filename order and
rejected a valid source
> - This pull request compares the resolved migration names as a set and
records the checkout-prefix revision
> - The benefit is that valid renumbered migration histories can pass
source validation without allowing divergent histories

## Linked Issues or Issue Description

**What happened?**

Worktree seed source validation compared applied migrations in database
application order with available migration files in filename order. A
current source with the same migration set failed with `Migration
journal is not a prefix` after migration files were renumbered.

**Expected behavior**

Source validation must accept a source when its resolved applied
migration set equals a prefix of the checkout migration files. It must
still reject a source that contains a resolved migration outside that
prefix.

**Steps to reproduce**

1. Apply migrations before a migration-file renumber operation.
2. Update the checkout so the same migration files have a different
filename order.
3. Run worktree seed source validation against the long-lived source.
4. Observe that positional comparison rejects the source even though the
sets are equal.

**Paperclip version or commit**

The bug reproduces on the master-equivalent worktree-seeding
implementation before this commit.

**Deployment mode**

Local dev with embedded PostgreSQL.

## What Changed

- Compare resolved applied migration names with the expected checkout
prefix as an order-independent set.
- Derive the reported source revision from the checkout prefix instead
of database application order.
- Add unit and embedded-PostgreSQL regressions for shuffled application
order, stale unresolved rows, lagging sources, and true divergence.

## Verification

- `pnpm exec vitest run cli/src/__tests__/worktree.test.ts` — 54 tests
passed.
- `pnpm --filter paperclipai typecheck` — passed.
- The focused suite includes the real embedded-PostgreSQL seed path.

## Risks

- Low risk. The change is limited to source migration-prefix validation.
- The validator still rejects missing or unknown resolved migrations.
- Duplicate resolved names remain set-equivalent by design. Raw stale
journal rows remain tolerated.
- Existing documentation already specifies order-independent
checkout-prefix behavior, so no documentation change is required.

> 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.6-sol`. The Codex runtime manages
the context window. The model used reasoning, shell tools, 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>
canary/v2026.819.0-canary.2
2026-08-19 09:53:15 -05:00
dependabot[bot] 536d5880c5 build(deps): bump @cursor/sdk from 1.0.24 to 1.0.28 (#11520)
Bumps [@cursor/sdk](https://github.com/cursor/cursor) from 1.0.24 to
1.0.28.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/cursor/cursor/commits">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@cursor/sdk&package-manager=npm_and_yarn&previous-version=1.0.24&new-version=1.0.28)](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>
canary/v2026.819.0-canary.1 nightly/v2026.819.0-nightly.0
2026-08-19 00:48:17 -07:00