Commit Graph

4326 Commits

Author SHA1 Message Date
Dotta 5ecb2a505c Merge commit '1a74719309130e2f04954e263be5baa57c3bf2ed' into fix/runner-paid-matrix-integrity
* commit '1a74719309130e2f04954e263be5baa57c3bf2ed':
  feat(onboarding): the connect step signs in from its own button (#12801)
2026-09-03 23:59:00 -05:00
Tonio 1a74719309
feat(onboarding): the connect step signs in from its own button (#12801)
Connect starts the sign-in; the card that appears is the sign-in rather
than an offer of one; success advances to Review rather than reporting
itself. The two logins end in different places and the button says which:
Claude submits a code back here, so it spins on "Connecting"; OpenAI
finishes in another tab, so it stays a still, disabled Next until the
poll lands.

AdapterLoginPanel grows autoStart / onCancel / onConnected / chrome
rather than a second implementation — the session start, both polls, the
server deadline, the one-shot completion read and the unmount release are
the parts onboarding needs unchanged. Every prop is off by default, so
the agent form and the new-agent page render what they did before.

Claude's code auto-submits on the paste, not on every change:
isValidBrowserCode accepts any printable ASCII from one character up, so
a value-driven submit fired on the first keystroke of anyone who typed.

Also orders the OpenAI card and the settings displayed-code panel
code-above-link, with the instruction worded to match, and releases the
displayed-code session on unmount so an abandoned login stops holding the
one-per-owner reservation.
2026-09-03 21:45:45 -07:00
Dotta 556785beab fix(opencode): refresh isolated model cache 2026-09-03 23:45:37 -05:00
Dotta 24917f8293 Merge commit '9ef3b087c14686327e4915705ae1fe4537fccc33' into fix/runner-paid-matrix-integrity
* commit '9ef3b087c14686327e4915705ae1fe4537fccc33':
  feat(onboarding): round-4 corrections to the connect and agent steps (#12796)
  chore(docker): pass PAPERCLIP_ALLOWED_HOSTNAMES through to quickstart (#6846)
  fix(recovery): exclude hidden issues from stranded recovery and continuation wakes (#5648)
2026-09-03 22:57:27 -05:00
Tonio 9ef3b087c1
feat(onboarding): round-4 corrections to the connect and agent steps (#12796)
Reads the connect and agent steps from the design's own values through the
Figma MCP rather than measuring an export, which corrected the arc column
inset (433px content, 64px inset — `--sz-68px` goes with the mismeasurement
it was minted for) and restored the selected tile's border alongside its
fill.

Round-4 items: sources named for the provider you sign in with, OpenAI's
mark inlined so it can take `currentColor` on a light tile, monochrome
autofill via `box-shadow` (Chrome ignores `background-color`), and the
agent step's placeholder.

Also wires `MODEL_SOURCE_NAMES`, which was added for the rename and never
read — the tiles kept passing the display registry's label, so the step
still showed "Claude Code" and "Codex" under a heading asking which
provider you are signing in to. Covered by a test that fails on the
unwired version.
2026-09-03 20:52:31 -07:00
Dotta 8961aee0de ci(runner): skip Daytona setup for local cells 2026-09-03 22:35:46 -05:00
Ross Sclafani 82ee0a68d4
chore(docker): pass PAPERCLIP_ALLOWED_HOSTNAMES through to quickstart (#6846)
## Thinking Path

> - Operators run Paperclip in many places: localhost dev, LAN servers,
Tailscale meshes, cloud VMs
> - The server already supports a `PAPERCLIP_ALLOWED_HOSTNAMES` env var
for hostname allow-listing (`server/src/config.ts`)
> - But `docker/docker-compose.quickstart.yml` did not forward that env
var from the host to the container
> - So an operator running quickstart on a LAN gets "Hostname '<lan-ip>'
is not allowed for this Paperclip instance" with no env-only escape
hatch — they're forced to run the CLI inside the container to write
`config.json`
> - This PR adds a one-line passthrough so the existing env var works
end-to-end with the quickstart compose file
> - The benefit is parity with the server's documented config surface:
anything settable via env on a bare-metal run is now settable via env on
a quickstart docker run

## Linked Issues or Issue Description

**What happened?**

Running the quickstart compose file on a LAN host and opening the UI by
the machine's LAN address fails with "Hostname '<lan-ip>' is not allowed
for this Paperclip instance". The server supports
`PAPERCLIP_ALLOWED_HOSTNAMES` for exactly this case and `doc/DOCKER.md`
tells operators to set it, but `docker/docker-compose.quickstart.yml`
never forwards the variable into the container, so setting it on the
host has no effect.

**Expected behavior**

Setting `PAPERCLIP_ALLOWED_HOSTNAMES` on the host before `docker compose
up` reaches the server, the same way `PAPERCLIP_PUBLIC_URL` and the
provider keys do.

**Steps to reproduce**

1. `export PAPERCLIP_ALLOWED_HOSTNAMES=my-lan-host` alongside the other
quickstart variables.
2. `docker compose -f docker-compose.quickstart.yml up --build`.
3. Open `http://my-lan-host:3100` and observe the hostname rejection.

**Paperclip version or commit**

`master` when this PR was opened (May 2026); the quickstart file on
current `master` still has no passthrough. The branch is rebased onto
current `master`.

**Deployment mode**

Docker quickstart (`docker-compose.quickstart.yml`), authenticated and
private.

## What Changed

- `docker/docker-compose.quickstart.yml`: forward
`PAPERCLIP_ALLOWED_HOSTNAMES` from the host environment with an empty
default, matching the existing pattern used for `PAPERCLIP_PUBLIC_URL`,
`OPENAI_API_KEY`, etc.

## Verification

```sh
# 1. Set the env var
echo \"PAPERCLIP_ALLOWED_HOSTNAMES=localhost,my-lan-ip\" >> .env

# 2. Bring up the quickstart
docker compose --env-file .env -f docker/docker-compose.quickstart.yml up -d

# 3. Confirm the value reached the container
docker compose -f docker/docker-compose.quickstart.yml exec paperclip \\
  sh -c 'echo \"\$PAPERCLIP_ALLOWED_HOSTNAMES\"'
# → localhost,my-lan-ip

# 4. Confirm boot-time trusted-origins log includes the LAN host
docker compose -f docker/docker-compose.quickstart.yml logs paperclip | grep trustedOrigins

# 5. Confirm a request from the LAN host returns 401 (auth required), not the hostname rejection
curl -i -H \"Host: my-lan-ip:3100\" http://localhost:3100/api/auth/get-session
# → HTTP/1.1 401 Unauthorized
```

Tested locally on Linux with an authenticated/private deployment,
migrated DB from another paperclip instance, and a LAN host reaching the
container. The image was rebuilt with \`--no-cache\` from a clean
checkout of this branch's tip (no other unmerged work in the build
context) to confirm the change is self-contained.

## Risks

Low risk.
- Default value is empty string — behavior identical to before for any
operator who doesn't set the var.
- Env var name and semantics already implemented and documented on the
server side (\`server/src/config.ts\`); this PR only routes the value
through compose.
- One-line yaml change, no code touched, no tests affected.

## Model Used

- Claude (Anthropic) — Opus 4.7 (1M context). Used for the bug
isolation, the env-var-vs-config-file choice, and the PR write-up.
Authored alongside Ross Sclafani who tested end-to-end against a
migrated LAN deployment.

## Checklist

- [x] Thinking path traces from project context to this change
- [x] Model used specified (with version + capability details)
- [x] Checked ROADMAP.md — not a feature, no overlap with planned work
- [x] Ran tests locally (\`pnpm install --frozen-lockfile\`, \`pnpm
build\` clean; container rebuilt \`--no-cache\` from this branch tip and
verified end-to-end)
- Added or updated tests — N/A (compose env passthrough; no executable
code path)
- UI change screenshots — N/A (no UI)
- [x] No documentation updates needed (env var already documented
server-side)
- [x] Considered risks (above)
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] Will address all Greptile/reviewer comments before requesting
merge
2026-09-03 22:22:33 -05:00
Dotta 72fc40a21e fix(runner): preserve macOS verified runtime layout 2026-09-03 22:19:10 -05:00
Dotta b8d84471a3 fix(runner): preserve remote continuation state scope 2026-09-03 22:09:10 -05:00
Magnus b98badb246
fix(recovery): exclude hidden issues from stranded recovery and continuation wakes (#5648)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The recovery subsystem watches assigned issues and re-wakes an agent
whose run ended without finishing the work
> - Intake can hide a duplicate issue by setting `hiddenAt` while
leaving its status and assignee in place
> - The stranded-issue query and the terminal-run cleanup both ignore
`hiddenAt`, so a hidden issue is re-woken on every cycle
> - Nothing on the board shows the hidden issue, so the repeated wakes
have no visible cause
> - This pull request adds a hidden-issue guard to both predicates and a
test for each
> - The benefit is that hiding an issue stops recovery work on it, with
no other change in behavior for visible issues

## Linked Issues or Issue Description

**What happened?**

When intake marks an issue as a duplicate it sets `hiddenAt` but leaves
the status at `todo` or `in_progress` with the agent still assigned. The
stranded-issue recovery timer selects that issue on every tick and
queues an `issue_continuation_needed` wake for it. The agent's run on
the hidden issue fails or is cancelled, the terminal-run cleanup queues
immediate recovery for the same issue, and the cycle repeats
indefinitely. Hidden issues are invisible on the board, so nothing a
person can see explains the wakes.

**Expected behavior**

A hidden issue is never a recovery candidate. Stranded-issue
reconciliation skips it, and a failed, timed-out or cancelled run on it
releases the issue without queuing a continuation.

**Steps to reproduce**

1. Assign an issue to an agent and leave it `in_progress`.
2. Hide the issue (set `hiddenAt`, for example by marking it a duplicate
through intake) without changing its status or assignee.
3. Let a run on that issue fail, or wait for the stranded-issue recovery
timer.
4. Observe a new `issue_continuation_needed` heartbeat run queued for
the hidden issue on every cycle.

**Paperclip version or commit**

Reproduced on `master` when this PR was opened (May 2026). The two
predicates are unchanged on current `master`; this branch is rebased
onto it.

**Deployment mode**

Not deployment-specific: both guards are in the server's recovery and
heartbeat services and apply in every mode.

## What Changed

- `server/src/services/recovery/service.ts`: `isNull(issues.hiddenAt)`
added to the `reconcileStrandedAssignedIssues` candidate query, so
hidden issues never enter the stranded set.
- `server/src/services/heartbeat.ts`: `!issue.hiddenAt` added to
`issueNeedsImmediateRecovery`, so terminal-run cleanup releases a hidden
issue instead of queuing a continuation.
- `server/src/__tests__/heartbeat-process-recovery.test.ts`: one test
per guard. A failed run on a hidden issue queues no recovery run, and a
hidden stranded issue is left out of reconciliation.

## Verification

- `heartbeat-process-recovery.test.ts` covers both guards; CI runs it
against embedded Postgres.

## Risks

Low. Both changes narrow an existing predicate to exclude rows that
already carry `hiddenAt`; visible issues take exactly the path they take
today. A hidden issue that genuinely needs recovery would have to be
unhidden first, which matches how hidden issues behave everywhere else
in the board.

## Model Used

The original two-line fix was authored by @im0xMagnus. The rebase onto
current `master`, the two regression tests, and this description were
produced with Claude (claude-fable-5-1, extended thinking, tool use)
driven by a Paperclip maintainer through Prospector's triage flow.

## 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
- [ ] 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: Andrew Aymeloglu <aaymeloglu@gmail.com>
2026-09-03 22:05:20 -05:00
Dotta 49910c1c24 Merge PR fast-path activation from master
* commit '89bf6a33c23d12c592c2c45b07ac36a362d418e6':
  ci: activate Node-first pnpm setup for PRs (#12810)
  feat(apps): unify permissions and action testing (#12802)
2026-09-03 21:29:36 -05:00
Dotta 89bf6a33c2
ci: activate Node-first pnpm setup for PRs (#12810)
## Thinking Path

> - Paperclip validates every change through an immutable reusable PR
workflow.
> - That caller still pinned a revision that ran pnpm setup before Node
setup.
> - The implementation fix in #12808 is therefore present on master but
inactive for ordinary PR CI.
> - Advancing the immutable caller pin activates the already tested
Node-first workflow.
> - A focused contract prevents the caller from silently returning to
the old revision.
> - The benefit is a faster PR feedback loop without changing product
code or secret boundaries.

## Linked Issues or Issue Description

Refs #12808

## What Changed

- Pin ordinary PR CI to trusted workflow revision
`a0a78ee60946a5f79f85b2bd0584fc766fae43bb`.
- Assert that the reusable workflow call is canonical, unique, and
SHA-pinned to that audited revision.

## Verification

- Focused workflow security test: 8/8.
- Prettier passed.
- Actionlint passed.
- `git diff --check` passed.

## Risks

Low risk. The change only advances an immutable reusable-workflow pin to
a revision whose full ordinary CI and security checks passed. Product
code and credentials are unchanged.

## Model Used

OpenAI Codex GPT-5 with agentic reasoning and repository tool use.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used
- [x] I have linked the related public PR
- [x] I have not referenced internal issue links
- [x] My branch name describes the change
- [x] I have run focused tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have considered and documented risks
2026-09-03 21:28:49 -05:00
Dotta f449b05bc5
feat(apps): unify permissions and action testing (#12802)
## Thinking Path

> - Paperclip is the control plane for companies that use AI agents.
> - Apps give humans and agents controlled access to external services.
> - The existing app detail flow split permissions, tests, setup, and
activity across separate pages.
> - The split made access rules harder to understand and made reconnect
work hard to find.
> - New write actions also defaulted to Ask first, which did not match
the intended connection policy.
> - This pull request combines permission control and action testing,
removes the setup page, and moves connection activity into Audit.
> - The benefit is one clear place to configure, test, reconnect, and
review each app.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The installed app Permissions, Test, Setup, and Activity views.

**Subsystem affected**

Cross-cutting. This change updates the React UI, shared app defaults,
server permission behavior, tests, smoke scripts, and connection
documentation.

**Current behavior**

App access and action testing use separate pages. The app detail view
also links to a setup page after installation. Connection activity uses
a separate tab. New write actions default to Ask first.

**Proposed behavior**

Permissions uses the connection access language from the initial flow.
It includes searchable Read and Write sections, a three-state permission
control, and a Test dialog for each action. Reconnect appears below a
Needs attention header on Permissions and Review. Old Setup and Test
links redirect to Permissions. Old Activity links redirect to the
filtered company Audit feed. New write actions default to Allowed.

**Reason and benefit**

A person can understand and test app access without moving between
several pages. Reconnect work stays visible where the person reviews the
connection. Audit events use one consistent feed and filter model. New
connections have the intended default policy.

**Breaking changes**

The Setup, Test, and app Activity tabs are removed. Existing deep links
redirect to their replacement pages. Existing saved action permissions
do not change. Only defaults for new write actions change.

**Additional context**

This builds on the managed app connection work in #12728. A search found
no duplicate open pull request or issue.

## What Changed

- Combined action testing with Permissions.
- Added searchable Read and Write action groups.
- Added Off, Ask first, and Allowed controls with tooltips.
- Added an action Test dialog with agent selection, arguments, and
formatted results.
- Removed the installed-app Setup and Activity tabs.
- Added reconnect guidance to Permissions and Review when a connection
needs attention.
- Routed connection activity into the company Audit feed and preserved
the Apps & tools filter in streamlined Audit.
- Moved connection removal to the Connectors-page management menu.
- Made new write actions default to Allowed across connection creation
paths.
- Updated regression tests, browser suites, smoke scripts, and
connection documentation.

## Verification

- `pnpm check:token-gates`
- `pnpm exec vitest run packages/shared/src/app-definitions.test.ts
server/src/__tests__/generic-mcp-connection.test.ts
server/src/__tests__/tool-access-service.test.ts
ui/src/components/AppConnectionSidebar.test.tsx
ui/src/pages/apps/AppDetail.test.tsx
ui/src/pages/apps/AppNotConnected.test.tsx
ui/src/pages/apps/AppsConnect.test.tsx ui/src/pages/apps/Browse.test.tsx
ui/src/pages/apps/Connections.test.tsx
ui/src/pages/apps/composio-services.test.ts
ui/src/pages/audit/AuditFeed.test.tsx
ui/src/pages/tools/PasteConfigTab.test.tsx` (517 tests passed)
- `pnpm exec vitest run ui/src/pages/apps/app-detail/TestPanel.test.tsx
ui/src/pages/audit/AuditHub.test.tsx
ui/src/pages/audit/AuditFeed.test.tsx
ui/src/pages/apps/AppDetail.test.tsx ui/src/pages/apps/Browse.test.tsx`
(96 tests passed)
- Targeted Playwright verification for connection removal, rename on
Permissions, inline action testing, and Smoke Lab Audit evidence (5
flows passed)
- `pnpm -r typecheck`
- `pnpm build`
- `pnpm test:run` completed with 5,755 passing tests and 20 unrelated
macOS harness failures. The failures use `/tmp` versus `/private/tmp`,
invalid ports above 65535, and workspace fixtures outside this change.

## Risks

- Low migration risk. This change has no database migration.
- Old app-detail URLs depend on redirect compatibility.
- New connections grant write actions by default. Finalization remains
configure-authorized and audited, Ask first and Off remain available per
action, and existing connections keep their saved policy.

> 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`. The client does not expose the
context-window size. The model used reasoning, repository tools, code
execution, and browser 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-03 21:23:26 -05:00
Dotta 95aa8c514e Merge master into runner paid matrix integrity
* commit 'a0a78ee60946a5f79f85b2bd0584fc766fae43bb':
  ci: bootstrap Node before pnpm setup (#12808)
  ci(runner): stamp paid target provenance (#12805)
  fix: guard listComments against non-UUID afterCommentId to prevent 500 errors (#8695)
  test(plugin-worker): remove the wall-clock race from the duplex buffered-replay tests (#12799)
  ci(runner): skip bootstrap registry telemetry (#12797)
  fix(ui): honor PAPERCLIP_HIDDEN_SETTINGS in the production switcher menu (#12788)
  chore(deps): bump motion from 12.43.0 to 13.1.1 (#12255)
  chore(deps): bump dompurify from 3.4.13 to 3.4.14 (#12266)
  chore(deps-dev): bump @types/react-dom from 19.2.4 to 19.2.5 (#12253)
  ci(runner): inspect Daytona image metadata remotely (#12795)
  fix(ui): polish core navigation and task layout (#12793)
  chore(deps): bump yjs from 13.6.29 to 13.6.32 (#12256)
  chore(deps): bump @aws-sdk/client-s3 from 3.1120.0 to 3.1122.0 (#12261)
  chore(deps-dev): bump vitest from 4.1.10 to 4.1.11 (#12262)
  chore(deps): bump react-i18next from 17.0.11 to 17.0.12 (#12263)
  fix(ui): drop the "Open invite" action from the invites section (#12787)

# Conflicts:
#	tests/runner-e2e/workflow-security.test.ts
2026-09-03 21:19:07 -05:00
Dotta a0a78ee609
ci: bootstrap Node before pnpm setup (#12808)
## Thinking Path
The trusted workflows currently invoke `pnpm/action-setup@v6` before
installing the repository Node version. On hosts whose ambient Node is
older than 22.13, the action downloads standalone `@pnpm/exe`, which has
repeatedly taken several minutes. Supplying Node 24 first lets the same
pinned pnpm action use its normal Node-backed path.

## What Changed
- install Node 24 before every trusted `pnpm/action-setup` invocation
- preserve the existing pnpm-store cache setup, pinned actions,
telemetry suppression, conditions, and secret boundaries
- enforce ordering, modern Node, condition parity, and cache counts in
the workflow security contract

## Verification
- workflow security: 7/7
- Prettier
- actionlint (excluding one pre-existing SC2129 in an untouched Daytona
shell block)
- `git diff --check`

## Risks
Low. Product code, providers, paid-runner selection, credentials, and
pnpm version are unchanged. Jobs that restore pnpm cache run
`setup-node` a second time after pnpm becomes available; the first setup
is deliberately cache-free.

## Model Used
Codex (GPT-5)
2026-09-03 21:18:08 -05:00
Dotta 18ea965442
ci(runner): stamp paid target provenance (#12805)
## Thinking Path
Trusted workflow-dispatch runs execute an authorized target SHA, but
GitHub context still describes the default-branch workflow revision.
Retained paid results and artifact names were therefore labeling
target-branch executions as master. The workflow must explicitly pass
its authorized target coordinates to target code and trusted reporting.

## What Changed
- emit the canonical authorized target ref alongside the immutable
target SHA
- pass those coordinates to paid cells and the trusted report
- name shared build/provider artifacts with the target SHA rather than
workflow SHA
- add workflow-security coverage for all trusted provenance wiring

## Verification
- focused workflow-security tests: 6/6 passed
- Prettier and git diff checks passed
- run 33823252706 independently proved the pre-fix defect: functionally
green target cells were retained as master SHA 0ad180b85 instead of
feature SHA 33c7646d3

## Risks
The execution checkout and secret boundary were already pinned
correctly; this changes retained attribution and artifact labels only.
Target-side report code on PR #12769 consumes these trusted environment
values and overwrites untrusted cell metadata.

## Model Used
Codex (GPT-5)
2026-09-03 21:15:47 -05:00
Maxxsong7 505e7b40fc
fix: guard listComments against non-UUID afterCommentId to prevent 500 errors (#8695)
## Thinking Path

> - Paperclip is an open-source app for managing AI agents
> - The issue history subsystem stores comments per issue, with
cursor-based pagination via the `after` query parameter
> - `GET /issues/:id/comments?after=<commentId>` looks up the anchor
comment by UUID to get its created_at timestamp
> - When agents store an incorrect or truncated comment ID (e.g.
`670427ab` instead of `670427ab-e0ae-4a54-959e-2b13a2e33d14`), Postgres
throws `invalid input syntax for type uuid` before the anchor-not-found
guard can execute
> - This surfaces as an unhandled 500 and causes agents to fail when
doing incremental comment reads on any issue
> - This pull request adds a UUID validation guard in `listComments`
using the already-imported `isUuidLike` helper
> - The benefit is that invalid cursors get a clean empty-array response
instead of a 500, matching what already happens when a valid UUID simply
isn't found

## Linked Issues or Issue Description

Refs #2612 (a different 500 on the same `after=` cursor path, fixed
earlier; this PR covers the malformed-cursor case that remains).

**What happened?**

`GET /issues/:id/comments?after=<value>` returns a 500 when `after` is
not a UUID. The route trims the query value and passes it straight to
the anchor lookup, so Postgres raises `invalid input syntax for type
uuid: "670427ab"` before the anchor-not-found guard can run. Any agent
that stored a truncated or malformed comment ID as its pagination cursor
gets stuck in a 500 loop on that issue.

**Expected behavior**

A cursor that cannot name a comment behaves like a cursor that names a
missing comment: the endpoint returns `[]`.

**Steps to reproduce**

1. Pick any issue id on a running instance.
2. Call `GET /api/issues/<issue-id>/comments?after=670427ab` (8 hex
characters instead of a full UUID).
3. Observe a 500 with `PostgresError: invalid input syntax for type
uuid: "670427ab"`, where a full-but-unknown UUID such as
`00000000-0000-0000-0000-000000000000` returns `[]`.

**Paperclip version or commit**

`master` at the time this PR was opened (June 2026). The `listComments`
anchor lookup in `server/src/services/issues.ts` is unchanged on current
`master`, so the failure still reproduces there.

**Deployment mode**

Local dev (`pnpm dev`). Not deployment-specific: the failure is in the
server's comment-listing service, so it reproduces in every mode.

## What Changed

- `server/src/services/issues.ts` — added `if
(!isUuidLike(afterCommentId)) return [];` guard in `listComments` before
the DB anchor lookup, using the already-imported `isUuidLike` helper

## Verification

```bash
# Start the dev server
pnpm dev

# Pass a truncated UUID — should return [] instead of 500
curl -s "http://localhost:3100/api/issues/<any-valid-issue-id>/comments?after=670427ab"
# Expected: []

# Pass a valid full UUID that doesn't exist — should also return []
curl -s "http://localhost:3100/api/issues/<any-valid-issue-id>/comments?after=00000000-0000-0000-0000-000000000000"
# Expected: []

# Pass a valid full UUID that exists — should return comments after that cursor
curl -s "http://localhost:3100/api/issues/<any-valid-issue-id>/comments?after=<real-comment-uuid>"
# Expected: array of comments
```

## Risks

Low risk. The change only adds an early-return guard for values that are
provably invalid UUIDs. The code path for valid UUIDs is unchanged. The
existing behavior for anchor-not-found (returning `[]`) is preserved for
invalid UUIDs, which is the correct semantic (cursor not found → no
comments after it).

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`) via Paperclip CTO agent, tool
use + code execution mode, 200K context window.

## 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
- [ ] I have run tests locally and they pass
- [ ] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip CTO <cto@paperclip.ai>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Andrew Aymeloglu <aaymeloglu@gmail.com>
2026-09-03 20:47:19 -05:00
Nicky Leach 333abdd2c2
test(plugin-worker): remove the wall-clock race from the duplex buffered-replay tests (#12799)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The plugin worker manager runs agent plugin workers through duplex
channels.
> - The duplex buffered-replay tests check data that arrives before a
listener attaches.
> - The tests used a fixed 60 ms sleep as the barrier for worker output.
> - Worker startup and output latency can exceed that delay under load.
> - This pull request uses a worker exit frame as a deterministic
barrier.
> - The benefit is stable test results without a product code change.

## Linked Issues or Issue Description

**What happened?**

The duplex buffered-replay tests used a fixed 60 ms sleep before they
attached a data listener. Under load, worker output could arrive after
the sleep. The tests then saw a partial buffer and failed.

**Expected behavior**

The tests must wait until the worker sends all three data frames before
they inspect the pre-bind buffer.

**Steps to reproduce**

1. Run npx vitest run src/__tests__/plugin-worker-manager-duplex.test.ts
in the server package.
2. Add a 200 ms or 800 ms delay to the worker fixture emit path.
3. Repeat the test run and observe the old fixed-sleep barrier fail
intermittently.

**Paperclip version or commit**

b773f0f2e2

**Deployment mode**

Built from source. This change affects tests only.

## What Changed

- Replace the fixed sleep in both buffered-replay tests with an
exit-frame barrier.
- Write the three data frames and the exit frame in one worker output
write.
- Wait for the session to settle before the tests attach listeners.
- Keep the non-batch buffer-then-drain path and the throwing-listener
behavior.
- Remove the retry wrapper from the first test because the drain runs
synchronously.

## Verification

- Run npx vitest run src/__tests__/plugin-worker-manager-duplex.test.ts
in the server package.
- The full file passes 35 of 35 tests.
- Run the full file 15 times. All 15 runs pass.
- Test the new barrier with 200 ms and 800 ms worker-output delays. Both
tests pass.
- The server type check still reports 71 pre-existing errors in
native-runtime and paperclip-runner. No new error appears in the changed
test file.
- Search GitHub for duplicate or related public issues and pull
requests. No duplicate open item exists.
- Check ROADMAP.md. This test-only fix does not duplicate planned core
work.

## Risks

- This change affects test synchronization only.
- The test could become invalid if the worker stops sending the exit
frame. The session wait then fails instead of hiding the problem behind
a clock delay.
- No product code, database schema, or runtime behavior changes.

## Model Used

OpenAI GPT-5, exact model ID gpt-5, API model with code execution and
tool use. The model used a 1M-token context window. No extended
reasoning mode was specified.

## 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 described the issue in-PR following the bug report template
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [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 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-09-03 17:55:12 -07:00
Dotta 0ad180b85f
ci(runner): skip bootstrap registry telemetry (#12797)
## Thinking Path
Every trusted PR and paid-workflow job invokes the pinned pnpm setup
action. Its internal npm install is currently waiting four to seven
minutes on npm audit telemetry before any Paperclip or provider code
runs. Audit, funding, and update notifications are not integrity
controls for this action; its committed lockfile still verifies
installed package bytes.

## What Changed
- disable npm audit, funding, and update-notifier telemetry narrowly on
all seven pinned setup steps in each of the trusted PR and full-stack
workflows
- add a workflow security contract proving every setup invocation
remains covered and the overrides do not leak elsewhere

## Verification
- focused workflow security tests: 6/6 passed
- Prettier and git diff checks passed
- observed unhealthy setup: 4-7+ minutes; historical healthy setup:
about four seconds

## Risks
This skips npm vulnerability-report telemetry for the setup action
bootstrap only. Repository dependency checks, lockfile integrity,
provider-secret authorization, and target-lock verification remain
unchanged.

## Model Used
Codex (GPT-5)
2026-09-03 19:47:46 -05:00
Devin Foley 446577d174
fix(ui): honor PAPERCLIP_HIDDEN_SETTINGS in the production switcher menu (#12788)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators control which settings surfaces appear via the
`PAPERCLIP_HIDDEN_SETTINGS` env var (keys like `company.invites`,
`company.members`)
> - The sidebar organization switcher has an "Invite people" shortcut
that points at the company Invites surface
> - The streamlined switcher menu already hides that shortcut when the
Invites/Members surface is hidden, but the production-shell menu
(rendered when the streamlined UI is disabled) renders the invite row
unconditionally
> - So an operator that hides the Invites surface still sees the
shortcut in the production shell — the hide is not fully honored
> - This pull request gates the production menu's invite shortcut on the
same hide keys, so `PAPERCLIP_HIDDEN_SETTINGS` controls it in both
shells
> - The benefit is one consistent, per-deployment knob: a hoster that
wants the shortcut gone (e.g. Paperclip Cloud, whose managed stacks set
`company.invites`) drops it by setting the env var, and every other
hoster keeps it by leaving the key unset

## Linked Issues or Issue Description

No existing issue. Description follows the enhancement template:

**What existing behavior does this improve?**
`PAPERCLIP_HIDDEN_SETTINGS` coverage for the organization switcher's
"Invite people" shortcut in the production shell.

**Subsystem affected**
UI — `ui/src/components/SidebarCompanyMenu.production.tsx`.

**Current behavior**
The streamlined switcher menu hides the "Invite people" shortcut when
`company.invites` or `company.members` is hidden. The production-shell
menu renders the invite row unconditionally, so the hide keys have no
effect there.

**Proposed behavior**
The production menu computes `showInvitePeople` from the same hide keys
and gates the invite row on it. With no hidden settings (the default)
the shortcut still shows; hiding either surface removes it in both
shells.

**Reason and benefit**
This is the per-deployment knob operators already use for the Invites
surface. Making the production shell honor it gives one consistent
mechanism: Paperclip Cloud drops the shortcut on its managed stacks
(which set `company.invites`, because the managed invite accept flow is
being overhauled), while other hosters keep it by leaving the key unset
— no cloud-specific branching in the app.

**Breaking changes**
None. Default behavior (no hidden settings) is unchanged; this only
makes an existing env var take effect where it previously did not.

## What Changed

- `SidebarCompanyMenu.production.tsx` imports `useHiddenSettings` +
`hidesCompanyPage`, computes `showInvitePeople` exactly as the
streamlined menu does, and renders the invite row only when it is true.
- Tests: the production shell shows the shortcut by default and hides it
when `company.invites` is hidden.
- The streamlined menu is unchanged (it already honored the keys).

## Verification

- `cd ui && npx vitest run src/components/SidebarCompanyMenu.test.tsx` —
20 tests pass.
- `cd ui && npx tsc -p tsconfig.json --noEmit` — clean.
- Manual: with `PAPERCLIP_HIDDEN_SETTINGS=company.invites`, the
switcher's "Invite people" row is absent in both the streamlined and
production shells; with the key unset it is present in both.

## Risks

Low risk. UI-only visibility change; default (no hidden settings) is
unchanged, and it only extends an existing, documented env var to a
shell that was missing it.

## Model Used

Claude Fable 5 (`claude-fable-5`, Anthropic), extended thinking, agentic
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
2026-09-03 17:39:56 -07:00
Dotta 33c7646d3f fix(runner-e2e): record trusted target provenance 2026-09-03 19:22:00 -05:00
Dotta 97f771e2ec ci(runner): align Daytona cache exclusions 2026-09-03 19:11:39 -05:00
Dotta d8637d467c fix(runner): preserve authenticated ingress span 2026-09-03 19:11:35 -05:00
dependabot[bot] a661caf74e
chore(deps): bump motion from 12.43.0 to 13.1.1 (#12255)
Bumps [motion](https://github.com/motiondivision/motion) from 12.43.0 to
13.1.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/motiondivision/motion/blob/main/CHANGELOG.md">motion's
changelog</a>.</em></p>
<blockquote>
<h2>[13.1.1] 2026-08-18</h2>
<h3>Fixed</h3>
<ul>
<li>Guard animation <code>window</code> access in non-browser
runtimes.</li>
<li><code>AnimatePresence</code>: Improved compat with React 19 strict
mode.</li>
</ul>
<h2>[13.1.0] 2026-08-10</h2>
<h3>Added</h3>
<ul>
<li><code>Reorder</code>: Multidimensional reorder.</li>
<li><code>Reorder</code>: Automatic axis detection.</li>
<li><code>Reorder</code>: RTL support.</li>
</ul>
<h2>[13.0.0] 2026-08-05</h2>
<h3>Changed</h3>
<ul>
<li>Removed optional <code>@emotion/is-prop-valid</code> dependency in
favour of explicit <code>&lt;MotionConfig
isValidProp={isPropValid}&gt;</code>.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Hardware-accelerated SVG elements correctly apply final style on
animation complete.</li>
<li><code>AnimatePresence</code>: Ensure nodes are marked as safe to
remove when rendering <code>propagate</code> with no <code>motion</code>
children.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1b037b0032"><code>1b037b0</code></a>
v13.1.1</li>
<li><a
href="d734481aca"><code>d734481</code></a>
Updating changelog</li>
<li><a
href="9b9190da21"><code>9b9190d</code></a>
Latest</li>
<li><a
href="c07d12e2bf"><code>c07d12e</code></a>
Merge pull request <a
href="https://redirect.github.com/motiondivision/motion/issues/3752">#3752</a>
from motiondivision/fix-3746-animatepresence-strictm...</li>
<li><a
href="b497f1d2ac"><code>b497f1d</code></a>
Merge branch 'main' into
fix-3746-animatepresence-strictmode-remount</li>
<li><a
href="bbabb00664"><code>bbabb00</code></a>
Merge pull request <a
href="https://redirect.github.com/motiondivision/motion/issues/3751">#3751</a>
from motiondivision/worktree-fix-issue-3735</li>
<li><a
href="06540faa2c"><code>06540fa</code></a>
Merge branch 'main' into worktree-fix-issue-3735</li>
<li><a
href="adaf7a4e53"><code>adaf7a4</code></a>
v13.1.0</li>
<li><a
href="e713759e50"><code>e713759</code></a>
Updating changelog</li>
<li><a
href="bc81c03121"><code>bc81c03</code></a>
Updating publish</li>
<li>Additional commits viewable in <a
href="https://github.com/motiondivision/motion/compare/v12.43.0...v13.1.1">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-09-03 16:50:57 -07:00
dependabot[bot] 1f92011f99
chore(deps): bump dompurify from 3.4.13 to 3.4.14 (#12266)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.13 to
3.4.14.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cure53/DOMPurify/releases">dompurify's
releases</a>.</em></p>
<blockquote>
<h2>DOMPurify 3.4.14</h2>
<ul>
<li>Fixed an issue with possible bypasses when risky tags are
allow-listed, thanks <a
href="https://github.com/AlirezaRouhbakhsh"><code>@​AlirezaRouhbakhsh</code></a></li>
<li>Fixed a couple of edge cases with mixed document contexts, thanks <a
href="https://github.com/fishjojo1"><code>@​fishjojo1</code></a></li>
<li>Added the SVG <code>pointer-events</code> and
<code>vector-effect</code> presentation attributes to the allow-list,
thanks <a
href="https://github.com/Jaybhade"><code>@​Jaybhade</code></a></li>
<li>Conducted another refactoring run, removed dead branches and
duplicated logic, flattened attribute validation</li>
<li>Updated the documentation in several spots, README, wiki, etc.,
thanks <a
href="https://github.com/Akokonunes"><code>@​Akokonunes</code></a></li>
<li>Updated several development dependencies and CI workflow
actions</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4e6fe24173"><code>4e6fe24</code></a>
release: 3.4.14 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1587">#1587</a>)</li>
<li>See full diff in <a
href="https://github.com/cure53/DOMPurify/compare/3.4.13...3.4.14">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-09-03 16:43:44 -07:00
dependabot[bot] d95c71027d
chore(deps-dev): bump @types/react-dom from 19.2.4 to 19.2.5 (#12253)
Bumps
[@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom)
from 19.2.4 to 19.2.5.
<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-09-03 16:17:02 -07:00
Dotta 03faa644fb
ci(runner): inspect Daytona image metadata remotely (#12795)
## Thinking Path
The reused Daytona image path already verifies the signed immutable
digest. It then downloads every filesystem layer only to read OCI config
fields. Buildx can retrieve the same config from that immutable digest
without pulling the layers. The assertions can therefore stay intact
while removing the expensive transfer.

## What Changed
- inspect the signed immutable Daytona image config through Buildx after
GHCR logout
- preserve digest, source revision, content ID, platform, user, and
provider-pack assertions
- extend the workflow contract test for the metadata-only path

## Verification
- Daytona image and workflow security tests: 10 passed
- Prettier and git diff checks passed
- observed full pull/prune cost: about 4m55s; metadata inspection: about
one second

## Risks
The current image has one runnable linux/amd64 platform plus its
attestation. A future genuinely multi-platform image would need explicit
linux/amd64 selection.

## Model Used
Codex (GPT-5)
2026-09-03 18:10:38 -05:00
Dotta 24e0b9776b fix(runner): isolate local smoke credentials per profile 2026-09-03 17:57:56 -05:00
Dotta 7fe94196ba test(runner): stage the build-once binary remotely 2026-09-03 17:45:10 -05:00
Dotta 73a146e076 fix(runner): separate remote artifact identity from launch path 2026-09-03 17:40:21 -05:00
scotttong 871f7d1124
fix(ui): polish core navigation and task layout (#12793)
<!-- Write all pull request text in Simplified Technical English
(ASD-STE100): short sentences, one instruction per sentence, simple
approved vocabulary, and the active voice. -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators use the main navigation, contextual navigation, and task
chat throughout the product.
> - The recent core UI refactor left uneven spacing and inconsistent
navigation styles.
> - The Apps label also did not match the Connectors product language.
> - The account area did not provide a clear direct path for feedback.
> - This pull request aligns these related core UI surfaces and
preserves their existing behavior.
> - The benefit is a more consistent interface with clearer navigation
and balanced task-chat layout.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

This improves the core sidebar, Settings navigation, Connectors catalog,
task-chat layout, and account controls.

**Subsystem affected**

`ui/` — React and Vite board UI.

**Current behavior**

The task chat had uneven edge treatment. Settings used a separate
contextual-navigation style. Apps used inconsistent product labels. The
account footer did not expose a direct feedback control.

**Proposed behavior**

The task chat keeps balanced content padding while its scrollbar sits at
the properties boundary. Settings replaces the primary sidebar with a
matching navigation surface and a Back to app link. Apps uses Connectors
and Browse labels. The account footer provides a dedicated feedback icon
with a tooltip.

**Reason and benefit**

These changes make related navigation and layout patterns predictable.
They reduce duplicate labels and improve access to feedback.

**Breaking changes**

None. Routes, APIs, and stored data do not change.

## What Changed

- Balanced the task-chat content gutter and moved its scrollbar to the
properties-panel boundary.
- Reworked Settings navigation to replace the main sidebar and use the
shared primary-sidebar style.
- Added a Back to app navigation item to Settings.
- Renamed Apps to Connectors in the main navigation and added the
`Unplug` icon.
- Renamed the Connectors contextual item to Browse.
- Added the Connectors top-level header and aligned the search field
with the connector cards.
- Added account-footer hover states and a direct feedback flag with a
Share feedback tooltip.
- Removed the duplicate Feedback item from the account popover.
- Added regression coverage for each changed UI surface.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/AppsSidebar.test.tsx
src/components/CompanySettingsSidebar.test.tsx
src/components/Layout.test.tsx src/components/Sidebar.test.tsx
src/components/SidebarAccountMenu.test.tsx
src/components/task-chat/TaskMessageScroller.test.tsx
src/pages/apps/Browse.test.tsx` — 90 tests passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm --filter @paperclipai/ui build` — passed.
- `pnpm check:token-gates` — passed.
- `git diff --check origin/master...HEAD` — passed.
- `env PAPERCLIP_PLAYWRIGHT_CHANNEL=chrome PAPERCLIP_E2E_PORT=3201 pnpm
exec playwright test --config tests/e2e/playwright.config.ts
tests/e2e/apps-dark-mode-shots.spec.ts
tests/e2e/sidebar-takeover.spec.ts` — 10 tests passed.
- The full workspace typecheck and build reached the Rust runner and
stopped because `cargo` is not installed on this machine.
- The full test suite exposed unrelated server and workspace-runtime
failures and was stopped after the affected suites completed. No changed
UI test failed.
- Manually verified the changed Settings, Connectors, task-chat, and
account-menu surfaces in the running app.

## Risks

- Low risk. The change affects layout and navigation presentation only.
- The Settings sidebar now replaces the main sidebar by design. Users
must use Back to app to return to the application navigation.
- The task scrollbar offset depends on the existing responsive page
gutters. Regression tests cover both narrow and desktop spacing.

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

## Model Used

- OpenAI Codex, `gpt-5.6-sol`, extended reasoning with tool use and code
execution. The host does not expose the 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
- [ ] 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: Scott Tong <scott@scottsmbpm5max.lan>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-03 15:35:39 -07:00
dependabot[bot] fa86407ad8
chore(deps): bump yjs from 13.6.29 to 13.6.32 (#12256)
Bumps [yjs](https://github.com/yjs/yjs) from 13.6.29 to 13.6.32.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/yjs/yjs/releases">yjs's
releases</a>.</em></p>
<blockquote>
<h2>v13.6.32</h2>
<ul>
<li>fix <a
href="https://redirect.github.com/yjs/yjs/issues/797">#797</a> -
undomanager clears destroy handler 95e890d9</li>
</ul>
<hr />
<p><a
href="https://github.com/yjs/yjs/compare/v13.6.31...v13.6.32">https://github.com/yjs/yjs/compare/v13.6.31...v13.6.32</a></p>
<h2>v13.6.31</h2>
<ul>
<li>Merge branch &amp;<a
href="https://redirect.github.com/yjs/yjs/issues/39">#39</a>;ppiotrowicz-fix/757-undo-attr-redo&amp;<a
href="https://redirect.github.com/yjs/yjs/issues/39">#39</a>; into v13
1ddba7e4</li>
<li>fix <a
href="https://redirect.github.com/yjs/yjs/issues/757">#757</a> in v13
d9aaff72</li>
<li>fix undoing setAttribute combined with delete corrupts remote state
- closes <a
href="https://redirect.github.com/yjs/yjs/issues/757">#757</a>
67c809ee</li>
</ul>
<hr />
<p><a
href="https://github.com/yjs/yjs/compare/v13.6.30...v13.6.31">https://github.com/yjs/yjs/compare/v13.6.30...v13.6.31</a></p>
<h2>v13.6.30</h2>
<ul>
<li>lint  0504939a</li>
<li>fix mutation of DeleteItem in sortAndMergeDeleteSet - closes <a
href="https://redirect.github.com/yjs/yjs/issues/767">#767</a>
5d5f1ad6</li>
</ul>
<hr />
<p><a
href="https://github.com/yjs/yjs/compare/v13.6.29...v13.6.30">https://github.com/yjs/yjs/compare/v13.6.29...v13.6.30</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1ce38f75f7"><code>1ce38f7</code></a>
13.6.32</li>
<li><a
href="95e890d99a"><code>95e890d</code></a>
fix <a href="https://redirect.github.com/yjs/yjs/issues/797">#797</a> -
undomanager clears destroy handler</li>
<li><a
href="271330889b"><code>2713308</code></a>
13.6.31</li>
<li><a
href="1ddba7e48c"><code>1ddba7e</code></a>
Merge branch 'ppiotrowicz-fix/757-undo-attr-redo' into v13</li>
<li><a
href="d9aaff72b2"><code>d9aaff7</code></a>
fix <a href="https://redirect.github.com/yjs/yjs/issues/757">#757</a> in
v13</li>
<li><a
href="67c809ee6b"><code>67c809e</code></a>
fix undoing setAttribute combined with delete corrupts remote state -
closes ...</li>
<li><a
href="676cc334ed"><code>676cc33</code></a>
13.6.30</li>
<li><a
href="0504939a75"><code>0504939</code></a>
lint</li>
<li><a
href="5d5f1ad6fa"><code>5d5f1ad</code></a>
fix mutation of DeleteItem in sortAndMergeDeleteSet - closes <a
href="https://redirect.github.com/yjs/yjs/issues/767">#767</a></li>
<li>See full diff in <a
href="https://github.com/yjs/yjs/compare/v13.6.29...v13.6.32">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-09-03 15:16:56 -07:00
dependabot[bot] daa2391021
chore(deps): bump @aws-sdk/client-s3 from 3.1120.0 to 3.1122.0 (#12261)
Bumps
[@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)
from 3.1120.0 to 3.1122.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.1122.0</h2>
<h4>3.1122.0(2026-08-31)</h4>
<h5>Documentation Changes</h5>
<ul>
<li><strong>client-controltower:</strong> Updated the descriptions for
the AWS Control Tower ListEnabledControls API parameters to make them
more accurate and intuitive. (<a
href="c54ac4e601">c54ac4e6</a>)</li>
</ul>
<h5>New Features</h5>
<ul>
<li><strong>client-pinpoint-sms-voice-v2:</strong> AWS End User
Messaging SMS now returns ConditionalBehavior on
DescribeRegistrationFieldDefinitions, allowing you to programmatically
discover which registration fields are required, optional, or disallowed
based on the values of other fields in the same form. (<a
href="9cbace1398">9cbace13</a>)</li>
<li><strong>client-customer-profiles:</strong> This release introduces
new APIs for segment membership events allowing segment definition
membership events to be exported to a kinesis stream for downstream
processing. Additionally, includes new calculated attribute statistic
and 2 new segment dimension types. (<a
href="be1a9dab42">be1a9dab</a>)</li>
<li><strong>client-sagemaker:</strong> Amazon SageMaker Batch Transform
now supports G6e instances, powered by NVIDIA L40S Tensor Core GPUs. G6e
instances are the most cost-efficient GPU instances for deploying
generative AI models and the highest-performance GPU instances for
spatial computing workloads. (<a
href="b063cf77a9">b063cf77</a>)</li>
<li><strong>client-quicksight:</strong> This release adds support for
managing apps in Amazon QuickSight with ListApps, SearchApps,
DescribeApp, DescribeAppPermissions, UpdateAppPermissions, and DeleteApp
(<a
href="98a49570d5">98a49570</a>)</li>
<li><strong>client-connect:</strong> Added support for global routing on
Amazon Connect Global Resiliency instances. New APIs
GetCrossRegionRouting and UpdateCrossRegionRouting allow you to view and
control cross-region contact routing between linked instances, so both
Regions are active at all times. (<a
href="ce41026342">ce410263</a>)</li>
<li><strong>client-agent-registry-control:</strong> AWS Agent Registry
becomes Generally Available (<a
href="e41244e930">e41244e9</a>)</li>
<li><strong>client-kinesis:</strong> Adds support for data delivery to
Amazon S3 Tables (Apache Iceberg) and general purpose Amazon S3 buckets
with new CreateChannel, UpdateChannel, DeleteChannel, DescribeChannel,
and ListChannels APIs for Amazon Kinesis Data Streams. (<a
href="64ebb058e0">64ebb058</a>)</li>
<li><strong>client-agent-registry:</strong> AWS Agent Registry becomes
Generally Available (<a
href="e60306f198">e60306f1</a>)</li>
<li><strong>client-devops-agent:</strong> Adds support for Slack
bidirectional communication configuration in AWS DevOps Agent agent
spaces. (<a
href="75bc6d6da3">75bc6d6d</a>)</li>
<li><strong>client-kafkaconnect:</strong> Amazon MSK Connect now
supports restarting newly created connectors via the asynchronous
RestartConnector API. Restart all tasks or only failed tasks, while
preserving configuration and committed offsets. This returns a connector
operation ARN that you can track with DescribeConnectorOperation. (<a
href="8771afafd4">8771afaf</a>)</li>
<li><strong>client-support:</strong> AWS Support now allows up to 10
attachments (150 MB each) per case correspondence, up from 3 at 5 MB.
Customers can share large diagnostic logs, heap dumps, and packet
captures directly in cases to reduce back-and-forth and speed up
resolution. Available in US East, US West, and Europe (Ireland). (<a
href="4ddd79c106">4ddd79c1</a>)</li>
<li><strong>client-workspaces-instances:</strong> Amazon WorkSpaces Core
managed instances now support nested virtualization. Customers can
enable nested virtualization with supported instance types at launch via
CpuOptions.NestedVirtualization in CreateWorkspaceInstance to run
hypervisors and virtual machines inside their WorkSpaces Instance. (<a
href="29587d1236">29587d12</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1122.0.zip</strong></p>
<h2>v3.1121.0</h2>
<h4>3.1121.0(2026-08-28)</h4>
<h5>New Features</h5>
<ul>
<li><strong>client-ecs:</strong> Amazon Elastic Container Service - This
release adds support for early success criteria on ECS rolling
deployments, letting deployment complete once a configurable percentage
of tasks are healthy, with configurable BLOCKING (required) or DEFERRED
(asynchronous) cleanup of previous service revisions. (<a
href="ef22d750f2">ef22d750</a>)</li>
<li><strong>client-healthlake:</strong> New HealthLake API,
RestoreFHIRDatastore, providing the capability to restore active
datastores to a point in time within the last 30 days or recover a
deleted datastore from the delete snapshot. (<a
href="6249174262">62491742</a>)</li>
<li><strong>client-bedrock-agentcore:</strong> AgentCore Memory now
supports direct ingestion into long-term memory via IngestData API (<a
href="20d652de56">20d652de</a>)</li>
<li><strong>client-partnercentral-selling:</strong> Releasing PARC, new
APN Program that lets sellers add solftware revenue details to aws
opportunity summary (<a
href="2b6350f012">2b6350f0</a>)</li>
<li><strong>client-cognito-identity-provider:</strong> Adds two new
operations - GetClientToken which allows M2M auth through the SDK, and
DescribeTermsByClient to find which Terms are associated with a
user-pool client without knowing the Terms resource id. (<a
href="86dffd282f">86dffd28</a>)</li>
<li><strong>client-bedrock-agent:</strong> Adds an optional syncSchedule
field to CreateDataSource and UpdateDataSource for Managed Knowledge
Bases data source connectors, so a data source can sync automatically on
a daily, weekly, or monthly schedule. (<a
href="a8d3714a75">a8d3714a</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1121.0.zip</strong></p>
</blockquote>
</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.1121.0...v3.1122.0">3.1122.0</a>
(2026-08-31)</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.1120.0...v3.1121.0">3.1121.0</a>
(2026-08-28)</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="e1cf460a1e"><code>e1cf460</code></a>
Publish v3.1122.0</li>
<li><a
href="e53a25aafb"><code>e53a25a</code></a>
Publish v3.1121.0</li>
<li>See full diff in <a
href="https://github.com/aws/aws-sdk-js-v3/commits/v3.1122.0/clients/client-s3">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-09-03 15:16:31 -07:00
dependabot[bot] a0028d7e1b
chore(deps-dev): bump vitest from 4.1.10 to 4.1.11 (#12262)
Bumps
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
from 4.1.10 to 4.1.11.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.11</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li>Revive global concurrency limit for test lifecycle [backport to v4]
 -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> and
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10992">vitest-dev/vitest#10992</a>
<a href="https://github.com/vitest-dev/vitest/commit/5146df80b"><!-- raw
HTML omitted -->(5146d)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>:
<ul>
<li>Encode iframeId in tester iframe URL [backport to v4]  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a>,
<strong>Pduhard</strong> and <strong>Claude Opus 4.8</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10955">vitest-dev/vitest#10955</a>
<a href="https://github.com/vitest-dev/vitest/commit/10b2cd201"><!-- raw
HTML omitted -->(10b2c)<!-- raw HTML omitted --></a></li>
<li>Trigger playwright/chromium gc on lower disk availability [backport
to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Hiroshi Ogawa</strong> and <strong>OpenCode</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10951">vitest-dev/vitest#10951</a>
<a href="https://github.com/vitest-dev/vitest/commit/9851dbc41"><!-- raw
HTML omitted -->(9851d)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>mocker</strong>:
<ul>
<li>Restrict redirect mocks to the fs allowlist [backport to v4]  -  by
<a href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a>
in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10974">vitest-dev/vitest#10974</a>
<a href="https://github.com/vitest-dev/vitest/commit/fe5a11d3c"><!-- raw
HTML omitted -->(fe5a1)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.10...v4.1.11">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9bd8d464e6"><code>9bd8d46</code></a>
chore: release v4.1.11 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10995">#10995</a>)</li>
<li><a
href="9851dbc41c"><code>9851dbc</code></a>
fix(browser): trigger playwright/chromium gc on lower disk availability
[back...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.11/packages/vitest">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-09-03 15:16:02 -07:00
dependabot[bot] 3e28ec5f4c
chore(deps): bump react-i18next from 17.0.11 to 17.0.12 (#12263)
Bumps [react-i18next](https://github.com/i18next/react-i18next) from
17.0.11 to 17.0.12.
<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.12</h2>
<ul>
<li>fix(IcuTrans): key-less <code>icu.macro</code> nodes
(<code>&lt;Trans&gt;Welcome, {name}!&lt;/Trans&gt;</code>,
<code>&lt;Select&gt;</code>, <code>&lt;Plural&gt;</code> without
<code>i18nKey</code>) rendered an empty string since 17.0.0. The macro
now emits <code>&lt;IcuTrans defaultTranslation=&quot;…&quot;&gt;</code>
without a key and <code>IcuTrans</code> passed <code>undefined</code> to
<code>t()</code>, which returns <code>''</code>. Like
<code>Trans</code>, <code>IcuTrans</code> now uses
<code>defaultTranslation</code> as the key when <code>i18nKey</code> is
not provided.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ea721fb58d"><code>ea721fb</code></a>
17.0.12</li>
<li><a
href="6c2a71e1c0"><code>6c2a71e</code></a>
fix(IcuTrans): use defaultTranslation as key when no i18nKey is
given</li>
<li><a
href="258c96daab"><code>258c96d</code></a>
chore(examples): upgrade all example apps off unmaintained
toolchains</li>
<li><a
href="b8677c805c"><code>b8677c8</code></a>
chore: update dependencies to close dependabot alerts</li>
<li><a
href="aa9c92bd7f"><code>aa9c92b</code></a>
docs: point Trans component links at the current docs (<a
href="https://redirect.github.com/i18next/react-i18next/issues/1929">#1929</a>)</li>
<li>See full diff in <a
href="https://github.com/i18next/react-i18next/compare/v17.0.11...v17.0.12">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-09-03 15:04:36 -07:00
Devin Foley 2392a9895e
fix(ui): drop the "Open invite" action from the invites section (#12787)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Members page has an Invites tab where an admin mints single-use
invite links for people
> - After a link is created, the section offers two actions: "Copy link"
and "Open invite"
> - "Open invite" opens the inviter's own single-use link in a new tab,
which is never what the inviter means — the link is for the invitee
> - This pull request removes the "Open invite" button and keeps "Copy
link" as the only action
> - The benefit is that the section no longer invites a mistake, and the
one remaining action matches the section's purpose

## Linked Issues or Issue Description

No existing issue. Description follows the enhancement template:

**What existing behavior does this improve?**
The latest-invite panel on the Members page Invites tab.

**Subsystem affected**
UI — `ui/src/components/access/InvitesSection.tsx`.

**Current behavior**
After an invite is created, the panel shows a "Copy link" button and an
"Open invite" button. "Open invite" opens the invite URL in a new tab as
the inviter.

**Proposed behavior**
The panel shows only "Copy link". The invite URL field itself stays
visible and selectable.

**Reason and benefit**
Invite links are single-use and addressed to the invitee. The inviter
opening their own link at best shows them their own landing page and at
worst walks the link toward consumption. Removing the button removes the
trap.

**Breaking changes**
None. No API or data change.

## What Changed

- Removed the "Open invite" anchor button from `InvitesSection`.
- Removed the now-unused `ExternalLink` icon import.
- The component test now asserts the action is absent.

## Verification

- `cd ui && npx vitest run
src/components/access/InvitesSection.test.tsx` — 3 tests pass.
- `cd ui && npx tsc -p tsconfig.json --noEmit` — clean.
- Manual: create an invite on the Members page Invites tab; the
latest-invite panel shows the URL field and "Copy link" only.

## Risks

Low risk. UI-only removal of one button; the invite URL remains fully
visible and copyable.

## Model Used

Claude Fable 5 (`claude-fable-5`, Anthropic), extended thinking, agentic
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
2026-09-03 15:02:27 -07:00
Dotta 46eed91836 Merge remote-tracking branch 'origin/master' into fix/runner-paid-matrix-integrity
* origin/master:
  chore(deps): bump i18next from 26.3.6 to 26.4.0 (#12267)
  Make managed Cloud OAuth handoffs invisible (#12790)
2026-09-03 16:41:59 -05:00
dependabot[bot] 112ef5beec
chore(deps): bump i18next from 26.3.6 to 26.4.0 (#12267)
Bumps [i18next](https://github.com/i18next/i18next) from 26.3.6 to
26.4.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/i18next/i18next/releases">i18next's
releases</a>.</em></p>
<blockquote>
<h2>v26.4.0</h2>
<ul>
<li>perf: cache <code>toResolveHierarchy</code> results per <code>(code,
fallbackCode)</code> pair. The hierarchy resolver runs on every
<code>t()</code> call and calls <code>Intl.getCanonicalLocales</code>
multiple times, which showed up prominently when profiling render-heavy
UIs (e.g. virtualized data grids); with the cache the per-call cost
drops from ~886 ns to ~41 ns. The cache is invalidated automatically
when <code>options.fallbackLng</code> changes (reassignment or in-place
array mutation); if you mutate other resolution-relevant options at
runtime (<code>load</code>, <code>lowerCaseLng</code>,
<code>cleanCode</code>, <code>nonExplicitSupportedLngs</code>), call
<code>i18next.services.languageUtils.clearCache()</code> afterwards.
Function-valued <code>fallbackLng</code> and per-call array/object
<code>fallbackLng</code> options are never cached, so dynamic fallbacks
keep working as before. Thanks <a
href="https://github.com/equaterina"><code>@​equaterina</code></a> (<a
href="https://redirect.github.com/i18next/i18next/pull/2444">#2444</a>).</li>
<li>chore: update all devDependencies (Babel stays on 7.x until
<code>@rollup/plugin-babel</code> supports 8, eslint on 9.x for
neostandard). Removed the unused <code>coveralls</code> package (CI uses
the Coveralls GitHub Action) and replaced <code>sinon</code> with
<code>nise</code> + <code>vitest.spyOn</code> in the v1 compatibility
tests, which resolves all open <code>npm audit</code> findings (0
vulnerabilities) and should close the dependabot alerts on the
lockfile.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/i18next/i18next/blob/master/CHANGELOG.md">i18next's
changelog</a>.</em></p>
<blockquote>
<h2>26.4.0</h2>
<ul>
<li>perf: cache <code>toResolveHierarchy</code> results per <code>(code,
fallbackCode)</code> pair. The hierarchy resolver runs on every
<code>t()</code> call and calls <code>Intl.getCanonicalLocales</code>
multiple times, which showed up prominently when profiling render-heavy
UIs (e.g. virtualized data grids); with the cache the per-call cost
drops from ~886 ns to ~41 ns. The cache is invalidated automatically
when <code>options.fallbackLng</code> changes (reassignment or in-place
array mutation); if you mutate other resolution-relevant options at
runtime (<code>load</code>, <code>lowerCaseLng</code>,
<code>cleanCode</code>, <code>nonExplicitSupportedLngs</code>), call
<code>i18next.services.languageUtils.clearCache()</code> afterwards.
Function-valued <code>fallbackLng</code> and per-call array/object
<code>fallbackLng</code> options are never cached, so dynamic fallbacks
keep working as before. Thanks <a
href="https://github.com/equaterina"><code>@​equaterina</code></a> (<a
href="https://redirect.github.com/i18next/i18next/pull/2444">#2444</a>).</li>
<li>chore: update all devDependencies (Babel stays on 7.x until
<code>@rollup/plugin-babel</code> supports 8, eslint on 9.x for
neostandard). Removed the unused <code>coveralls</code> package (CI uses
the Coveralls GitHub Action) and replaced <code>sinon</code> with
<code>nise</code> + <code>vitest.spyOn</code> in the v1 compatibility
tests, which resolves all open <code>npm audit</code> findings (0
vulnerabilities) and should close the dependabot alerts on the
lockfile.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="652847e70f"><code>652847e</code></a>
26.4.0</li>
<li><a
href="6c6025f87e"><code>6c6025f</code></a>
prettier fix</li>
<li><a
href="742b9a95dd"><code>742b9a9</code></a>
chore: update dependencies and clean up dev tooling</li>
<li><a
href="06924d961c"><code>06924d9</code></a>
fix: invalidate toResolveHierarchy cache on in-place fallbackLng
mutation</li>
<li><a
href="bb80369e14"><code>bb80369</code></a>
perf: cache toResolveHierarchy (<a
href="https://redirect.github.com/i18next/i18next/issues/2444">#2444</a>)</li>
<li>See full diff in <a
href="https://github.com/i18next/i18next/compare/v26.3.6...v26.4.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-09-03 14:39:00 -07:00
Dotta 5f87090894
Make managed Cloud OAuth handoffs invisible (#12790)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Apps let people give agents governed access to external providers
> - Paperclip Cloud brokers shared provider authorization for managed
stacks
> - The managed flow sent the browser through a confirmation page after
the tenant had already prepared sign-in
> - A lost confirmation response could also show an expired-session
error before the provider page opened
> - This pull request adds an opaque handoff contract and one shared
tenant coordinator
> - The benefit is a direct and recoverable transition from Paperclip to
every Cloud-brokered provider

## Linked Issues or Issue Description

**What happened?**

A managed Paperclip Cloud connection opened the Cloud confirmation
route. A response-loss race could show an expired-session error while
the authorization still continued.

**Expected behavior**

The current Paperclip loading state must stay visible while the tenant
exchanges an opaque session. The browser must then open the provider
directly. Self-hosted and direct OAuth must keep their existing
behavior.

**Steps to reproduce**

1. Open Apps on a Paperclip Cloud stack.
2. Start a managed provider connection.
3. Select Continue to sign in.
4. Observe that the browser visits the Cloud confirmation route before
it reaches the provider.

**Paperclip version or commit**

`b872cd3d1b404bdaff70af493a2973ceb7e5d6ec`

**Deployment mode**

Paperclip Cloud hosted stack.

No related open issue or pull request was found in the repository
search.

## What Changed

- Add a backward-compatible opaque Cloud handoff to the shared OAuth
start contract.
- Validate the Cloud descriptor on the server and expose no
browser-selected endpoint.
- Exchange managed handoffs through one fixed same-origin route in every
Apps OAuth launcher.
- Keep dialog popups reserved before asynchronous work and retain the
tenant loading state.
- Add recent-login resume storage, bounded retry behavior, terminal
tenant errors, tests, and Storybook states.

## Verification

- `pnpm check:token-gates`
- `pnpm -r typecheck`
- Focused connector and UI suites: 184 passed and 202 skipped.
- `pnpm build`
- `pnpm build-storybook`
- The full local suite reached one unrelated macOS path-alias failure.
The untouched test expected `/var/...` and received the equivalent
`/private/var/...`. The same test reproduces in isolation.

## Risks

- A malformed managed descriptor now fails closed in Paperclip instead
of opening a URL.
- A legacy Cloud deployment can omit the descriptor. Paperclip then uses
the existing validated confirmation URL.
- Direct provider OAuth and self-hosted flows do not receive a handoff
and remain unchanged.
- Rollback is a normal revert of this commit because the contract is
optional and backward compatible.

> 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 GPT-5.6, reasoning mode, tool use, code execution,
and browser 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
- [ ] 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-09-03 16:33:13 -05:00
Dotta de38ef52ff Merge remote-tracking branch 'origin/master' into fix/runner-paid-matrix-integrity
* origin/master:
  chore(deps): bump @radix-ui/react-slot from 1.3.0 to 1.3.3 (#12268)
2026-09-03 16:32:27 -05:00
dependabot[bot] a36020da6a
chore(deps): bump @radix-ui/react-slot from 1.3.0 to 1.3.3 (#12268)
Bumps
[@radix-ui/react-slot](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slot)
from 1.3.0 to 1.3.3.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/radix-ui/primitives/blob/main/packages/react/slot/CHANGELOG.md">@​radix-ui/react-slot's
changelog</a>.</em></p>
<blockquote>
<h2>1.3.2, 1.3.3</h2>
<ul>
<li>Reverted breaking changes that caused compatibility issues with
React Server Components.</li>
</ul>
<h2>1.3.1</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>
<li>Updated dependencies: <code>@radix-ui/primitive@1.1.7</code>,
<code>@radix-ui/react-compose-refs@1.1.4</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slot">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-09-03 14:31:56 -07:00
Dotta 77c464dc7a Merge remote-tracking branch 'origin/master' into fix/runner-paid-matrix-integrity
* origin/master:
  fix(runner-e2e): prepare frozen Daytona plugin dependencies (#12791)
  chore(deps): bump @pierre/diffs from 1.3.5 to 1.3.6 (#12311)
  test(server): make the instance settings route suite deterministic under CPU contention (#12789)
2026-09-03 16:31:35 -05:00
Dotta d3c04d8932
fix(runner-e2e): prepare frozen Daytona plugin dependencies (#12791)
## Thinking Path

> - Paperclip manages AI agents and their provider runtimes.
> - The paid runner workflow installs target dependencies with lifecycle
scripts disabled.
> - The bundled Daytona plugin depends on an audited repo-local plugin
SDK link.
> - The lifecycle-safe install path did not create that link.
> - This pull request restores only the trusted Daytona preparation step
before provider secrets are exposed.
> - The benefit is a working Daytona canary without enabling dependency
lifecycle scripts.

## Linked Issues or Issue Description

**What happened?**

The Daytona paid canary stopped before lease or provider startup. The
trusted paid job disabled root lifecycle scripts, so the repo-local
plugin SDK link was absent. The plugin install returned a missing
runtime dependency error for @paperclipai/plugin-sdk.

**Expected behavior**

The trusted workflow must prepare the bundled Daytona plugin without
running untrusted dependency lifecycle scripts. The paid cell must start
only after its runtime dependencies and entrypoints pass validation.

**Steps to reproduce**

1. Dispatch the runner full-stack paid workflow for
core-compatibility.runner-acpx-claude.daytona.message-marker.
2. Let the trusted job install root dependencies with lifecycle scripts
disabled.
3. Observe the Daytona plugin installation fail before a lease or
provider process starts.

**Paperclip version or commit**

Feature head 781ac7e08c. The failed canary
is Actions run 33803959325.

**Deployment mode**

GitHub Actions paid runner validation.

**Agent adapter(s) involved**

ACPX Claude through the bundled Daytona plugin.

**Additional context**

This is a small trusted-workflow prerequisite for public PR #12769. Old
green run 33118525827 created the SDK link through root postinstall.
This change keeps lifecycle scripts disabled and restores only the
audited prerequisite.

## What Changed

- Install standalone Daytona dependencies with lifecycle scripts
disabled.
- Run the audited repo-local plugin SDK linker before provider secrets
are exposed.
- Build the bundled Daytona plugin and verify its runtime dependency
plus both entrypoints.
- Add a security regression for ordering, scope, and secret isolation.

## Verification

- Five focused workflow-security tests passed.
- Seven focused linker tests passed.
- The exact Daytona preparation command completed locally in nine
seconds.
- Prettier and diff whitespace checks passed.

## Risks

Risk is low and limited to Daytona paid cells. The setup still disables
dependency lifecycle scripts. The trusted step runs before provider
credentials enter the job. Any missing or mismatched path fails closed
before provider startup.

## Model Used

OpenAI GPT-5 Codex with repository tools 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 described the issue in this PR with the bug template labels
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change
- [x] Focused local tests pass
- [x] I added tests for the change
- [x] I updated the relevant trusted-workflow security regression
- [x] I documented the risks above
2026-09-03 16:31:22 -05:00
dependabot[bot] e0d5f02b8e
chore(deps): bump @pierre/diffs from 1.3.5 to 1.3.6 (#12311)
Bumps @pierre/diffs from 1.3.5 to 1.3.6.
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~ije">ije</a>, a new releaser for
<code>@​pierre/diffs</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>
2026-09-03 14:31:13 -07:00
Nicky Leach 66ea41812d
test(server): make the instance settings route suite deterministic under CPU contention (#12789)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip tests its server routes with mocked services and database
calls
> - The instance settings route suite reset and reloaded its module
graph before each test
> - Two concurrent module imports could bind a route to the real service
module under CPU contention
> - The task-drain overlap test also relied on a fixed delay and
operating system request order
> - This pull request loads the mocked graph once and waits for real
events that prove request order
> - The benefit is a deterministic 48-test suite with no production code
change

## Linked Issues or Issue Description

**What happened?**

The instance settings route suite failed intermittently under CPU
contention. A request that expected a 200 or 403 response sometimes
received 500. The failing test changed between runs.

**Expected behavior**

The suite must use the configured service mocks for every test and must
produce the expected response on every run.

**Steps to reproduce**

1. Run `npx vitest run
server/src/__tests__/instance-settings-routes.test.ts` many times in
parallel on a busy host.
2. Compare the result with the same command on the base branch.
3. Observe intermittent 500 responses on the base branch and stable
results on this branch.

**Paperclip version or commit**

Commit `02ae87010e621cf46bfbdf0d48b6f73887448a83`.

**Deployment mode**

Local dev (`pnpm dev`). The change affects tests only.

**Installation method**

Built from source.

**Agent adapter(s) involved**

Not adapter-specific (core bug).

**Database mode**

Not database-related. The test uses a mocked database layer.

**Access context**

Not applicable.

**Node.js version**

The CI environment runs the repository-supported Node.js version.

**Operating system**

Linux in continuous integration.

**Relevant logs or output**

The base branch reproduced `expected 500 to be 200` and `expected 500 to
be 403` under parallel contention.

**Relevant config (if applicable)**

Not applicable.

**Additional context**

The branch loads the mocked module graph once per suite, restores mock
behavior before each test, waits for the real transaction events, and
sends the DELETE request after the POST holds the transition queue.

## What Changed

- Load the mocked instance settings module graph once for the suite.
- Restore each mock implementation before every test.
- Wait for two real transaction events instead of a fixed 30 millisecond
delay.
- Send the overlapping DELETE request after the POST proves that it
holds the transition queue.
- Keep the test count at 48 with no skipped tests.

## Verification

- Run `npx vitest run
server/src/__tests__/instance-settings-routes.test.ts`.
- Confirm that all 48 tests pass.
- Run the 20-way parallel contention differential.
- Confirm that the base arm passed 18 of 20 runs and reproduced two
failures.
- Confirm that the branch arm passed 20 of 20 runs, with 48 tests in
each run.
- Confirm that `git status --porcelain` is clean at the submitted
commit.

## Risks

Low risk. The change affects one test file and does not change
production code, route behavior, database schema, or public API
behavior.

## Model Used

OpenAI Codex, GPT-5, current deployment, tool use and code execution
enabled.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-03 14:23:07 -07:00
Dotta 6e7f72a906 fix(runner-e2e): freeze Daytona plugin dependencies 2026-09-03 16:17:21 -05:00
Dotta 5871ebefc6 fix(runner-e2e): prepare Daytona plugin before paid cells 2026-09-03 16:10:39 -05:00
Dotta 781ac7e08c Merge remote-tracking branch 'origin/master' into fix/runner-paid-matrix-integrity
* origin/master:
  test(server): select exposure reservation host ports at run time (#12783)
2026-09-03 15:30:06 -05:00
Nicky Leach b872cd3d1b
test(server): select exposure reservation host ports at run time (#12783)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The server manages runtime exposure and host port leases for
workspace services
> - This test suite used fixed host port pairs inside the Linux
ephemeral port range
> - An unrelated short-lived socket could take one pair and cause a
false test failure
> - This pull request selects free host port pairs at run time and
starts above the low lease lane
> - The benefit is a more stable test suite with the same deterministic
allocator checks

## Linked Issues or Issue Description

**What happened?**

The runtime exposure reservation test suite used two fixed app and HMR
port pairs. These ports sit inside the Linux ephemeral port range. An
unrelated socket could use a pair during the test, and the guest bind
could fail with `EADDRINUSE`.

**Expected behavior**

The suite must select two free app and HMR port pairs before each test.
It must avoid the low lease lane that a live instance can own without a
listener.

**Steps to reproduce**

1. Run `npx vitest run
server/src/__tests__/workspace-runtime-exposure-reservation.test.ts`.
2. Start another process that briefly uses one fixed test port.
3. Observe that the guest bind can fail even when the allocator works
correctly.

**Paperclip version or commit**

`c982003e00f4e8a325bafec3af4ddb113c0c1f8a`

**Deployment mode**

Local dev test run.

**Installation method**

Built from source with pnpm.

**Agent adapter(s) involved**

Not adapter-specific. This change tests the runtime exposure allocator.

**Database mode**

Not database-related.

## What Changed

- Select two free app and HMR port pairs in `beforeEach`.
- Start the scan 500 ports above the runtime exposure range minimum.
- Keep the synthetic host stub limited to the selected pairs.
- Keep all seven test cases and the existing lifecycle coverage.

## Verification

- Run `npx vitest run
server/src/__tests__/workspace-runtime-exposure-reservation.test.ts`.
- Run `npx vitest run
server/src/services/workspace-runtime-exposure.test.ts`.
- Run `pnpm --filter @paperclipai/server exec tsc --noEmit`.
- Confirm the full CI suite reaches a terminal green state.

## Risks

Low risk. This change updates one test file and does not change
production code. A port can still become busy after discovery and before
the guest bind; the test documents this remaining race.

## Model Used

OpenAI GPT-5 (`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-09-03 13:18:37 -07:00
Dotta 19a9d28f87 Merge remote-tracking branch 'origin/master' into fix/runner-paid-matrix-integrity
* origin/master:
  fix(ui): stamp the service worker with a per-build id so deploys reach parked tabs (#12725)
  test(server): make secret write-serialization tests deterministic (#12781)
  test(acpx): bind ACPX credential waits to the real retry envelope (#12780)

# Conflicts:
#	packages/paperclip-runner/src/drivers/acpx/runtime-host.test.ts
2026-09-03 15:11:07 -05:00