Commit Graph

1279 Commits

Author SHA1 Message Date
Devin Foley 5cace19aca Remove adapter support matrix table from Company Environments (#8398)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run in execution environments, and the Company Environments
settings page lets operators configure them
> - That page rendered an "environment support by adapter" matrix table
plus two descriptive text boxes explaining the adapter/driver/sandbox
support model
> - That matrix duplicated information already surfaced where operators
actually pick a driver/provider, and added a wide, dense table that
provided no actionable value on this screen
> - This pull request removes the support-matrix table and the two
explanatory text boxes above it, along with the now-orphaned helper
component, derived constant, and unused imports
> - The benefit is a simpler, less cluttered environments settings page
that only shows the controls an operator acts on

## Linked Issues or Issue Description

No public GitHub issue exists for this. Describing the change following
the feature-request template:

### Problem or motivation

The Company Environments settings page showed an adapter support matrix
table (Adapter × Local/SSH/Sandbox) and two paragraphs of descriptive
text above it. The table restated the static adapter/driver support
model and the sandbox-provider plugin caveat, neither of which is
actionable on this page — operators don't change adapter capabilities
here, they create and edit environments. The table was wide enough to
require horizontal scroll and added visual noise without helping the
operator complete any task.

### Proposed solution

Remove the support-matrix table and the two descriptive text boxes above
it from `CompanyEnvironments.tsx`, along with the now-unused helper
component, derived constant, locals, and imports. Leave all environment
create/edit controls, provider selection, and sandbox-provider logic
untouched.

### Alternatives considered

Collapsing the table behind a disclosure/"Learn more" toggle instead of
removing it — rejected because the information is static, non-actionable
on this screen, and already available where operators pick a
driver/provider; hiding it would keep the maintenance cost without
adding value.

### Roadmap alignment

Not a roadmap feature — this is a small, focused UI cleanup that removes
non-actionable content from an existing settings page.

Related (already merged) work that last touched this copy:
paperclipai/paperclip#4902 (clarified sandbox-provider messaging in
company environments). No open duplicate PR was found.

## What Changed

- Removed the adapter support matrix `<table>` from
`ui/src/pages/CompanyEnvironments.tsx`
- Removed the two descriptive text boxes rendered above that table
(adapter support model + installed sandbox providers blurbs)
- Deleted the now-unused `SupportMark` helper component and the
`ENVIRONMENT_SUPPORT_ROWS` derived constant
- Removed the now-unused `sandboxSupportVisible` local and four
now-unused imports (`AGENT_ADAPTER_TYPES`,
`getAdapterEnvironmentSupport`, `Check`, `adapterLabels`)
- Updated `ui/src/pages/CompanySettings.test.tsx` to drop the two
assertions tied to the removed copy

## Verification

- `vitest run src/pages/CompanySettings.test.tsx` → 4/4 pass
- `tsc --noEmit` on the UI project → no errors in the changed files
- The remaining environment create/edit controls, provider selection,
and sandbox-provider logic are untouched (the `environmentCapabilities`,
`discoveredPluginSandboxProviders`, and `sandboxCreationEnabled` values
are still used by the form)

## Risks

Low risk — pure presentational removal of a read-only informational
table and static copy. No API, data model, or behavioral changes; no
state that other components depend on was removed.

## Model Used

Claude (Anthropic), model id `claude-opus-4-8` (Claude Opus 4.x family),
with extended thinking and tool use, run 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
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-20 13:02:36 -07:00
Devin Foley e9931f116a fix(ui): move environment create/edit into a dialog (#8391)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents and the work they do.
> - This change lives in the board UI, specifically the instance
environments settings page where operators define reusable execution
targets.
> - That page currently rendered the create/edit environment form inline
near the bottom of the screen.
> - Because the form appeared away from the action that triggered it, it
was easy to miss and felt inconsistent with the rest of the UI.
> - This pull request moves environment creation and editing into a
proper centered dialog with the existing form behavior preserved.
> - The benefit is a more obvious, consistent, and easier-to-complete
settings flow for environment management.

## Linked Issues or Issue Description

No public GitHub issue matched this exact UI problem when I searched
related issues and PRs.

### Pre-submission checklist

- [x] I have searched existing open and closed issues and this is not a
duplicate.
- [x] I am on the latest released version of Paperclip (or can reproduce
on `master`).
- [x] I have confirmed the issue originates in Paperclip itself, not
adapter or local configuration.

### What happened?

On `Settings -> Instance settings -> Environments`, clicking create or
edit revealed the environment form inline near the bottom of the page.
Because the form appeared away from the action that triggered it, it was
easy to miss.

### Expected behavior

Create and edit should open a centered modal dialog with a dimmed
backdrop and the same form controls.

### Steps to reproduce

1. Open `Settings -> Instance settings -> Environments`.
2. Click the create or edit action for an environment.
3. Observe that the form expands inline on the page instead of opening
in a modal.

### Paperclip version or commit

Observed on current `master` before this PR, for example
[`e93d78b46`](https://github.com/paperclipai/paperclip/commit/e93d78b46).

### Deployment mode

Local dev (`pnpm dev`).

### Installation method

Built from source (`pnpm dev` / `pnpm build`).

### Agent adapter(s) involved

- [x] Not adapter-specific (core bug)

### Database mode

Embedded PGlite (default, `DATABASE_URL` unset).

### Access context

Board (human operator).

### Node.js version

Node.js 25.6.1 in the local contributor environment.

### Operating system

macOS local development environment.

### Relevant logs or output

None. This was a visible UI behavior issue rather than a logged
server/runtime error.

### Relevant config (if applicable)

Not config-related.

### Additional context

Related PR/search context checked before opening this fix. UI preview
screenshots are attached below.

### Privacy checklist

- [x] I have reviewed all pasted output for PII and redacted where
necessary.

## What Changed

- Moved the environment create/edit form in
`ui/src/pages/CompanyEnvironments.tsx` into a shared dialog.
- Added an explicit `Add environment` action near the saved environments
list and wired row edit actions to open the same dialog in prefilled
mode.
- Preserved existing save/test behavior while resetting dialog-local
mutation state when the modal opens or closes.
- Extended `ui/src/pages/CompanyEnvironments.test.tsx` to cover
add-open/cancel and edit-open/save dialog flows.
- Updated `ui/src/pages/CompanySettings.test.tsx` so the existing
environments coverage opens and inspects the dialog through the Radix
portal.

## Verification

- `node node_modules/vitest/vitest.mjs run
ui/src/pages/CompanyEnvironments.test.tsx`
- `node node_modules/vitest/vitest.mjs run
ui/src/pages/CompanySettings.test.tsx`
- Manual review:
  - Open `Settings -> Instance settings -> Environments`
- Click `Add environment` and confirm the form opens in a centered
dialog
- Click `Edit` on an existing environment and confirm the dialog opens
with existing values
  - Confirm `Cancel`, `Test`, and save actions still behave as expected
- Before/after screenshots:
- [Cancel environment
creation/edit](https://artifacts.cutter.sh/8391/run-1175b5c-2026-06-20T18-47-11/preview/clip-01.mp4)
- [Add a new
environment](https://artifacts.cutter.sh/8391/run-1175b5c-2026-06-20T18-47-11/preview/change-02.png)
- [Save an
environment](https://artifacts.cutter.sh/8391/run-1175b5c-2026-06-20T18-47-11/preview/change-03.png)

## Risks

- Low risk overall because the change is contained to the environments
page and keeps the existing form fields and mutations.
- The main behavior change is modal layout, so the biggest risk is
regressions in tall-form scrolling or smaller-screen dialog ergonomics.

> I checked [`ROADMAP.md`](ROADMAP.md). This is a tightly scoped UI
polish fix, not duplicate roadmap-level core feature work.

## Model Used

- OpenAI GPT-5.4 via the `codex_local` Paperclip adapter
- High reasoning mode with tool use, shell execution, git operations,
and targeted test execution
- Model-assisted authoring and verification of the UI and test changes

## 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] If this change affects the UI, I have included before/after
screenshots
- [ ] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-20 12:26:53 -07:00
Devin Foley fce3b439af fix: warn operators that experimental features may break (#8382)
## Thinking Path

> - Paperclip is the control plane operators use to manage AI-agent
companies.
> - Board operators rely on the settings UI and CLI docs to understand
which product surfaces are stable to depend on.
> - Experimental features already existed in the product, but the
operator-facing contract around them was too soft and too fragmented.
> - That created a risk that users would enable experiments without
being told clearly that they can break, change, or disappear.
> - The docs and the in-product settings page both needed the same
explicit warning language so the contract is visible at the moment of
decision.
> - This pull request adds that warning to the board-operator guide, CLI
references, and the experimental settings page.
> - The benefit is clearer operator expectations without changing the
underlying feature flags or rollout behavior.

## Linked Issues or Issue Description

No public GitHub issue exists for this docs/polish gap.

Problem description:
- Board operators could enable experimental features without a clear
operator-facing statement that those features are opt-in and come
without compatibility guarantees.
- The docs site, repo CLI reference, and in-product experimental
settings page did not present one consistent warning contract.
- This PR closes that gap by documenting the risk explicitly where
operators discover and enable those settings.

Related public search:
- Searched public issues/PRs for related work with `gh search issues
--repo paperclipai/paperclip 'experimental features warning'` and `gh
search prs --repo paperclipai/paperclip 'experimental features
warning'`.
- Reviewed open PR #6165 during that search and found it unrelated; it
changes experimental auth/routing flags rather than documenting
experimental-feature risk.

## What Changed

- Added a new board-operator guide at
`docs/guides/board-operator/experimental-features.md` that defines the
Paperclip contract for experimental features.
- Registered that guide in `docs/docs.json` so it appears in the public
docs navigation.
- Added matching caveat language next to `instance
settings:experimental` in `docs/cli/control-plane-commands.md`.
- Added the same caveat to `doc/CLI.md` so the repo CLI reference does
not drift from the published docs.
- Added a single page-level warning banner to
`ui/src/pages/InstanceExperimentalSettings.tsx` stating that
experimental features are opt-in, carry no compatibility guarantees, and
may change, break, or be removed.
- Added a targeted UI test in
`ui/src/pages/InstanceExperimentalSettings.test.tsx` that asserts
exactly one page-level warning renders with the new risk language.

## Verification

- `jq empty docs/docs.json`
- `git diff --check`
- `cd ui && pnpm vitest run
src/pages/InstanceExperimentalSettings.test.tsx`
- Manual review of the warning contract across:
  - `docs/guides/board-operator/experimental-features.md`
  - `docs/cli/control-plane-commands.md`
  - `doc/CLI.md`
  - `ui/src/pages/InstanceExperimentalSettings.tsx`

UI note:
- This is a copy-level warning addition rather than a layout rework. I
did not attach before/after screenshots in this PR body.

## Risks

- Low risk: this changes operator-facing documentation and warning copy,
not feature-flag behavior.
- The main failure mode is wording drift across docs and UI in future
edits, which is why this PR adds the same contract to all relevant
operator-facing surfaces.

> I checked `ROADMAP.md` before opening this PR. This is docs/UI polish
around an existing experimental surface, not overlapping roadmap-level
core feature work.

## Model Used

- OpenAI Codex Local using `gpt-5.4` with high reasoning and tool use
for coordination, review, docs changes, and PR preparation.
- Anthropic Claude Local using `claude-opus-4-8` with high reasoning and
tool use for the in-product warning and targeted UI test.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-20 10:14:58 -07:00
Devin Foley 547463d3a2 refactor(environments): make execution environments instance-scoped (#8375)
## Thinking Path

> - Paperclip is the control plane for AI-agent companies, so execution
environment selection has to stay inspectable and predictable across
companies, agents, and runs.
> - The environment subsystem decides where an agent heartbeat actually
runs and how remote sandbox state is realized and restored.
> - That subsystem previously mixed company-scoped environment catalogs
with issue-level environment stamping, so a reassigned issue could keep
executing in the previous assignee's sandbox.
> - That behavior breaks the control-plane contract: changing the
assignee should change the executing agent/environment path unless there
is an explicit current override.
> - Fixing it cleanly required more than a narrow patch; the environment
model had to move to instance scope with a single inherited default and
per-agent override semantics.
> - This pull request rewires the schema, server/API surface, runtime
resolution, and UI around that model, then adds regression coverage for
cross-company inheritance and per-agent isolation.
> - The benefit is that environment choice now follows the approved
instance/agent configuration path instead of stale issue state, while
shared environments only need to be configured once per instance.

## Linked Issues or Issue Description

- No directly matching public GitHub issue or PR was found while
searching for this refactor.

### What happened?

Reassigning work between agents with different execution environments
could keep running in the previous sandbox because environment choice
was stamped onto the issue and outranked the current assignee. The same
subsystem also forced environment catalogs to be duplicated per company
even though the underlying execution environments were instance-wide
resources.

### Expected behavior

Execution should resolve through the current instance and agent
configuration path, with one instance-scoped environment catalog, one
instance default, optional per-agent override, and no stale issue-level
environment authority surviving reassignment.

### Steps to reproduce

1. Configure two agents to use different execution environments.
2. Assign an issue to the first agent so the issue records execution
state in that environment.
3. Reassign the same issue to the second agent and run another
heartbeat.
4. Observe that the pre-fix runtime can still sync or execute in the
original sandbox instead of the second agent's environment.

### Paperclip version or commit

Current `master` before this PR.

### Deployment mode

Self-hosted server.

### Installation method

Built from source (`pnpm dev` / `pnpm build`).

### Agent adapter(s) involved

- Claude Code
- Not adapter-specific (core bug in environment authority / resolution)

### Database mode

External Postgres.

### Access context

Both board reassignment and agent heartbeats were involved.

## What Changed

- Moved environments and their default selection contract to instance
scope in DB/shared types, including the migration that dedupes legacy
per-company environments and seeds the instance local default.
- Reworked environment CRUD/auth flows to use instance-scoped APIs and
added route/service coverage for instance-level environment management.
- Changed runtime resolution to prefer `agent default -> instance
default -> built-in local`, removed issue-level environment stamping
from the active execution path, and isolated sandbox/plugin leases by
`(executionWorkspaceId, agentId)`.
- Added environment env-var runtime precedence so environment-provided
values act as the baseline for agent execution.
- Moved the environment UI into instance settings and updated agent
configuration surfaces to reflect inherit/override behavior.
- Added regression coverage for instance-default inheritance across
companies and for the new runtime resolution behavior.
- Fixed a rebase-only duplicate `enableTaskWatchdogs` flag regression in
instance settings types/validators/services so the branch typechecks
cleanly on current `master`.
- Updated stale server tests so CI matches the shipped instance-scoped
environment contract.

## Verification

- `git diff --check`
- `pnpm --filter @paperclipai/shared typecheck`
- `pnpm --filter @paperclipai/db typecheck`
- `pnpm exec vitest run
server/src/__tests__/environment-runtime-driver-contract.test.ts
server/src/__tests__/agent-permissions-routes.test.ts
server/src/__tests__/environment-routes.test.ts
server/src/__tests__/environment-instance-routes.test.ts
server/src/__tests__/execution-workspace-policy.test.ts
server/src/__tests__/heartbeat-plugin-environment.test.ts
server/src/__tests__/instance-settings-routes.test.ts`

## Risks

- The migration changes environment scope and dedupes existing rows, so
installs with unusual legacy environment combinations should be reviewed
carefully during upgrade.
- Remote execution behavior now depends on instance-default inheritance
semantics instead of issue-level stamping, so any remaining code paths
that still assume issue-scoped environment authority would surface as
follow-up bugs.
- This PR includes both server/runtime behavior and UI relocation, so
reviewers should watch for authorization edge cases around instance
settings and environment management.

> I checked [`ROADMAP.md`](ROADMAP.md). This work fits the existing
Cloud / Sandbox agents direction as a bug-fix/refactor to current
behavior, not a new parallel product surface.

## Model Used

- OpenAI Codex coding agent in this Paperclip/Codex session; GPT-5-class
tool-using model with code execution and shell access. The exact backend
model ID is not exposed to the session runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [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-06-20 09:42:53 -07:00
Devin Foley 950484d204 fix: scope environments "Test provider" button to clicked row (#8380)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run inside environments, and the Environments settings page
lets users configure each environment and verify it with a "Test
provider" / "Test connection" button per row
> - When a user clicked one environment's test button, every environment
row's button switched to the disabled "Testing..." state at the same
time, then all flipped back together
> - That happened because all rows read the same shared
`environmentProbeMutation.isPending` flag, so a single in-flight probe
disabled and relabeled every button
> - This is confusing: it looks like every environment is being tested,
and it blocks interacting with other rows while one probe runs
> - This pull request tracks the specific environment id being probed in
dedicated state and scopes the disabled/label logic to that id
> - The benefit is that only the button the user actually clicked shows
"Testing..." and is disabled, while the other rows stay interactive

## Linked Issues or Issue Description

No public GitHub issue exists, so the bug is described inline below
following the bug report template.

### What happened?

On the Environments settings page, clicking "Test provider" on one
environment caused the test button on *every* environment row to change
to "Testing..." and become disabled at the same time, then all reverted
together when the probe finished.

### Expected behavior

Only the button for the environment the user clicked should show
"Testing..." and be disabled while its probe runs. Every other row's
button should stay enabled and unchanged.

### Steps to reproduce

1. Open instance settings → Environments with two or more configured
environments.
2. Click "Test provider" / "Test connection" on a single row.
3. Observe that all rows' buttons enter the "Testing..." disabled state
simultaneously instead of just the clicked one.

### Paperclip version or commit

`master` at commit a10f17800 (branch
`fix/environments-test-provider-button-scope`).

### Deployment mode

Local dev (`pnpm dev`). UI-only; reproduces independent of backend.

## What Changed

- Added a dedicated `testingEnvironmentId` state in
`ui/src/pages/CompanyEnvironments.tsx` to track which environment is
currently being probed.
- Set it in the probe mutation's `onMutate` and clear it in `onSettled`,
and reset it when the selected company changes.
- Scoped the test button's `disabled` state and `"Testing..."` label to
`testingEnvironmentId === environment.id` instead of the shared
`environmentProbeMutation.isPending` flag.
- Added `ui/src/pages/CompanyEnvironments.test.tsx` verifying that
clicking one environment's test button puts only that row into the
"Testing..." disabled state while other rows stay enabled.

## Verification

- `pnpm typecheck` (UI) passes clean.
- `vitest run src/pages/CompanyEnvironments.test.tsx` passes (new test
fails against the old shared-`isPending` behavior, confirming it guards
the fix).
- Manual: on the Environments page with multiple environments, click one
row's test button and confirm only that button shows "Testing..." / is
disabled while the others remain enabled, then it reverts on completion.

## Risks

- Low risk. Single-file UI change scoped to per-row button state; no
API, schema, or behavior changes to the probe itself. The probe mutation
still runs identically — only which buttons reflect the pending state
changed.

## Model Used

- Claude Opus 4.8 (Anthropic), `claude-opus-4-8`, with extended
reasoning and 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 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
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-20 00:53:28 -07:00
Tonio 3b9f36403e refactor(ui): vertically center task status circle in task list (#8376)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The web UI renders work items in a task/issue list and board
columns, each row leading with a status circle next to the title text
> - The status-circle wrapper `<span>` was not enforcing cross-axis
centering, so the circle aligned to the top of taller rows instead of
the title
> - This looked broken: the circle floated above the text rather than
sitting centered against it, across statuses
> - This pull request adds flex centering (`inline-flex` +
`items-center`) to the status-icon wrapper spans so the circle is
vertically centered with the title in every row
> - The benefit is a consistent, correctly aligned task list regardless
of task status or row height

## Linked Issues or Issue Description

No public GitHub issue exists; describing inline following the bug
report template.

### What happened?

In the task/issue list and board, the leading status circle was not
vertically centered with the task title text. On taller rows the circle
sat near the top instead of aligned with the title, so the list looked
misaligned across all statuses.

### Expected behavior

The status circle should be vertically centered with the title string in
every task row, regardless of status.

### Steps to reproduce

1. Open the task list (or board) view in the web UI.
2. Observe rows in different statuses, especially taller rows.
3. Notice the status circle is top-aligned rather than vertically
centered with the title text.

### Paperclip version or commit

`master` @ 411a9a51 (branch base for this PR).

### Deployment mode

Local dev (pnpm dev).

## What Changed

- `ui/src/components/IssueColumns.tsx`: added `items-center` to the
leading status-icon wrapper span (`inline-flex` container) in
`InboxIssueMetaLeading`.
- `ui/src/components/IssuesList.tsx`: added `inline-flex items-center`
to the two status-icon wrapper spans so the circle centers with the row
text (matching the `IssueColumns.tsx` change).

## Verification

- Manual: open the task list and board views; confirm the status circle
is vertically centered with the title across statuses and on taller
rows.
- Before/after matches the screenshots from the originating request
(broken: circle top-aligned; fixed: circle centered).
- `cd ui && npx tsc --noEmit` — type check passes for the touched
components.

## Risks

- Low risk. CSS-only change to wrapper spans; no logic, data, or API
changes. Limited to status-icon alignment in the task list/board rows.

## Model Used

- Claude Opus 4.6 (`claude-opus-4-6`), extended thinking + tool use, via
Claude Code.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-19 23:36:38 -07:00
Devin Foley 8af3bc9ed4 fix(ui): prevent mobile viewport horizontal scroll (#8370)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work, with a web UI that must work on mobile as well as desktop.
> - The UI layout root in `ui/src/components/Layout.tsx` branches on
`isMobile` to choose between a desktop flex column that clips overflow
and a mobile container.
> - The mobile branch was only `min-h-dvh` — it had no
horizontal-overflow guard, while the desktop branch already used
`overflow-clip`.
> - As a result, any descendant wider than the screen (a long
unbreakable token, an over-wide element) pushed the entire viewport
sideways, producing horizontal scroll on the whole page.
> - This pull request adds `overflow-x-clip` to the mobile root
container so stray wide descendants are clipped to the viewport width.
> - The benefit is a durable, page-agnostic guard: it prevents this
class of bug on every mobile page regardless of which element overflows,
without breaking vertical body scroll or the sticky breadcrumb.

## Linked Issues or Issue Description

Fixes: #8369

Related (different scope — these fix horizontal scroll *inside* a
specific component's own container, not the viewport-level layout
guard): Refs #2128.

## What Changed

- `ui/src/components/Layout.tsx`: added `overflow-x-clip` to the mobile
(`isMobile`) layout root container.
- Used `clip` rather than `hidden` deliberately: `clip` leaves
`overflow-y` computed as `visible`, so native body scrolling and the
sticky breadcrumb keep working; `hidden` would have forced a scroll
container and broken them.
- `ui/src/components/Layout.test.tsx`: added a regression test asserting
the mobile root carries `overflow-x-clip` (and not `overflow-hidden`)
and the desktop root carries `overflow-clip`.

## Verification

- `pnpm --filter @paperclip/ui test src/components/Layout.test.tsx` → 12
passed (10 existing + 2 new).
- Manual: open the web UI at a mobile-width viewport (≤ 768px) on a page
with a wide/unbreakable descendant (e.g. a task whose body contains a
long unbreakable token).
  - Before: the entire page scrolls horizontally.
- After: the overflow is clipped to the viewport width; the page no
longer scrolls sideways, and vertical body scroll plus the sticky
breadcrumb continue to work.
- The change is a single Tailwind utility on the mobile branch only;
desktop layout is unchanged (it already used `overflow-clip`).

## Risks

Low risk. The change only adds horizontal-overflow clipping to the
mobile layout root. It does not affect the desktop branch, vertical
scrolling, or any component internals. Components that need to scroll
horizontally manage their own internal overflow and are unaffected.

## Model Used

Claude Opus 4 (claude-opus-4) via the Claude Code agent harness, with
extended thinking and 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 (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
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-19 19:59:33 -07:00
Dotta a71c4b6782 [codex] feat(watchdog): add task watchdog control plane (#8339)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The task lifecycle and recovery subsystems decide when agent work is
still productive, stalled, or ready for review.
> - Existing recovery paths can observe stopped or incomplete work, but
there was no first-class per-task watchdog model with scoped review
permissions.
> - Watchdog follow-ups also need strict boundaries so
recovery/status-only runs cannot mutate approvals or perform deliverable
work.
> - This pull request adds the task watchdog data model, API/service
layer, scheduler/review flow, adapter wake context, UI configuration
surfaces, and docs.
> - The branch has been rebased onto current `paperclipai/paperclip`
`master`; the watchdog migration is now ordered after master's latest
migrations as `0104_issue_watchdogs`.
> - The benefit is a more explicit task-review loop that preserves
Paperclip's single-assignee and governance invariants while making
stalled work easier to route.

## Linked Issues or Issue Description

No linked GitHub issue. Paperclip task:
[PAP-11275](/PAP/issues/PAP-11275).

## Problem or motivation

Task recovery needs a first-class watchdog path that can inspect stopped
work and create scoped follow-ups without bypassing normal task
ownership. Board/UI users need a way to configure watchdogs on tasks and
see watchdog-related live work. Recovery/status-only runs must remain
limited to status reporting and must not create approvals, link
approvals, or submit approval comments.

## Proposed solution

Add a task-watchdog data model, scheduler/classifier, scoped mutation
guard, adapter wake context, API/UI configuration surfaces, and
documentation so watchdog agents can review stopped task subtrees under
explicit boundaries.

## Alternatives considered

Reuse the existing recovery-action flow only. That would keep
stopped-work detection implicit, make per-task watchdog assignment
harder to expose in the UI, and would not provide a durable
scoped-review issue for stalled task trees.

## Roadmap alignment

This is Paperclip control-plane lifecycle infrastructure for task
execution and recovery. I checked `ROADMAP.md`; this PR does not
duplicate an existing planned core item.

## What Changed

- Added issue watchdog schema, migration, shared contracts, validators,
CRUD API, and service support.
- Added task watchdog scheduler/classifier behavior, scoped mutation
enforcement, adapter wake context, and default watchdog mandate
guidance.
- Added UI surfaces for configuring watchdogs on new/existing tasks,
viewing watchdog activity, and exposing the experimental setting.
- Added docs for the user-facing task watchdog workflow and
implementation semantics.
- Gated new-task watchdog setup behind `enableTaskWatchdogs` and blocked
cheap status-only recovery runs from approval mutations.
- Rebased onto current `master` and renumbered the idempotent watchdog
migration from the branch-local `0102_issue_watchdogs` slot to
`0104_issue_watchdogs`.
- Addressed Greptile feedback by loading watchdog classifier input with
a recursive subtree query and centralizing the watchdog origin-kind
constant.
- Added and updated focused server/UI tests for watchdog routes,
scheduler/classifier behavior, scope boundaries, live task visibility,
settings, and new issue dialog behavior.

## Verification

- `pnpm vitest run server/src/__tests__/task-watchdogs-scheduler.test.ts
server/src/__tests__/task-watchdogs-classifier.test.ts`
- `pnpm vitest run
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts`
- `pnpm vitest run ui/src/components/NewIssueDialog.test.tsx`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check`
- Verified the PR diff does not include `pnpm-lock.yaml` or
`.github/workflows`.

## Risks

- Medium risk: this introduces a new task lifecycle surface touching DB
schema, server routes/services, adapter wake context, and UI task
configuration.
- Watchdog scheduling behavior depends on the new experimental setting
and runtime context checks behaving consistently across local and
production agents.
- The watchdog migration is idempotent (`IF NOT EXISTS` /
duplicate-object guards) so users who tried the previous branch-local
migration number should not get duplicate-object failures.
- CI and the second Greptile pass are pending after the latest
review-fix push.

> 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-class coding agent in the Paperclip workspace. Exact
runtime model id and context window were not exposed to the agent; tool
use and local command execution were enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots — N/A per Paperclip task instruction: do not add
screenshots/images to this PR unless they are specifically part of the
work.
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:38:52 -05:00
Devin Foley 8f4b491d9a fix(ui): fix blank page when creating an agent (#8336)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Creating an agent starts at **New Agent → "manually" → pick an
adapter**, which routes to
`/{company}/agents/new?adapterType=claude_local` and renders the
`NewAgent` page with the `AgentConfigForm`
> - `AgentConfigForm` hands the parent a `triggerTestEnvironment`
callback via an `onTestActionChange` effect so the page can wire up its
"Test"/"Save + Test" button
> - That trigger was rebuilt on every render: it depended on
`runEnvironmentTest`, which is derived from a react-query `useMutation`
result, and `useMutation` returns a **brand-new result object identity
on every render**
> - So the `onTestActionChange` effect re-fired every render and pushed
a new function into the parent's state, producing an infinite `setState`
loop ("Maximum update depth exceeded") that threw during render
> - The app's custom router updates location **without remounting**, and
there was no error boundary around the routed outlet, so the throw left
a dead render tree — a fully **blank page** that stayed blank on
back-navigation until a hard refresh
> - This pull request stabilizes the trigger with a latest-ref pattern
so the effect no longer re-fires, and adds a route-keyed error boundary
so any future render throw degrades to a recoverable error card instead
of a blank screen
> - The benefit is that creating an agent works again, and render-time
failures anywhere in the routed UI are contained and recoverable rather
than silently blanking the app

## Linked Issues or Issue Description

No public GitHub issue exists, so the underlying bug is described inline
following the bug report template
(`.github/ISSUE_TEMPLATE/bug_report.yml`):

### What happened?

In the UI, choosing **New Agent → "manually" → (any adapter, e.g.
Claude)** navigates to the agent-config page and renders a **completely
blank page**. The browser console shows React's `Maximum update depth
exceeded`. Using the back button changes the URL but the page stays
blank until a full hard refresh.

### Expected behavior

Selecting an adapter shows the agent configuration form so the agent can
be created.

### Steps to reproduce

1. Open the app and click **New Agent**.
2. Choose **manually**.
3. Pick an adapter (e.g. Claude / `claude_local`).
4. Observe the blank page (URL becomes
`/{company}/agents/new?adapterType=claude_local`).

### Paperclip version or commit

Reproduces on `master` (base of this PR).

### Deployment mode

Reproduces regardless of deployment mode — it is a client-side render
loop.

### Root cause

`useMutation` returns a new result object identity each render, so the
`runEnvironmentTest`-derived `triggerTestEnvironment` callback was
unstable, which made the `onTestActionChange` effect push a new function
into parent state every render → infinite update loop → render throw →
no boundary → blank tree.

## What Changed

- **`ui/src/components/AgentConfigForm.tsx`** — Stabilize the
environment-test trigger handed to the parent using a latest-ref
pattern: the churny behavior (`runEnvironmentTest`,
`testEnvironmentDisabled`) lives in a `useRef` updated by an effect, and
the exposed `triggerTestEnvironment` is a `useCallback(() =>
triggerRef.current(), [])` with an empty dep array, so its identity is
stable across renders and the `onTestActionChange` effect no longer
re-fires every render.
- **`ui/src/components/RouteErrorBoundary.tsx`** (new) — A route-keyed
React error boundary that catches render throws and renders a
recoverable error card (showing the error message, with "Go back" and
"Reload page" actions). It resets automatically when the route
(`pathname + search`) changes.
- **`ui/src/components/Layout.tsx`** — Wrap the routed `<Outlet />` in
`<RouteErrorBoundary>` so a render throw degrades to the error card
instead of a blank page.
- **`ui/src/components/RouteErrorBoundary.test.tsx`** (new) — Regression
test: a throwing child is contained as a recoverable error card (showing
the message), "Go back" calls `navigate(-1)`, and the boundary resets to
render children again after the route changes.

## Verification

- `npx vitest run ui/src/components/RouteErrorBoundary.test.tsx` → 3
passed (regression test for this fix).
- `npx vitest run ui/src/components/AgentConfigForm.test.ts` → 9 passed.
- `npx tsc -b` in `ui` → 0 errors.
- Manual: ran the dev server, clicked **New Agent → manually → Claude**.
- **Before:** blank page; console logs `Maximum update depth exceeded`;
back button leaves the page blank until hard refresh.
- **After:** the agent configuration form renders normally and the agent
can be created; navigating away and back works without a hard refresh.
- Boundary check: with the loop still in place (pre-fix), the new
boundary catches the throw and shows a recoverable error card instead of
a blank screen; "Go back" / route change resets it.

_Screenshots: the before-state is the React `Maximum update depth
exceeded` error and a blank `/agents/new` page; the after-state is the
rendered agent-config form. Both were observed locally; rendered images
can be attached on request._

## Risks

- **Low risk.** Changes are confined to three UI files with no API,
schema, or behavioral change to agent creation beyond fixing the loop.
- The latest-ref pattern preserves identical runtime behavior of the
test trigger (same guard, same `runEnvironmentTest()` call) — it only
stabilizes the callback identity.
- The error boundary is additive; on the happy path it renders its
children unchanged. Its only behavior is to catch render throws that
previously blanked the app.

## Model Used

Claude (Anthropic), model `claude-opus-4-8` — extended-thinking-capable,
tool-use (file edit, shell, tests). Used to diagnose the infinite render
loop, implement the latest-ref fix and route error boundary, and verify
via local typecheck/tests.

## 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] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots (described textually in Verification — see note)
- [ ] I have updated relevant documentation to reflect my changes (N/A —
bug fix, no docs affected)
- [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-06-19 13:06:41 -07:00
Dotta 7069053a1f [codex] Add ask issue work mode (#8334)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Issue work mode controls how a task starts and how the conversation
composer frames the operator's intent.
> - Paperclip already supports standard agent execution and planning
mode, but there is no lightweight mode for asking a question without
immediately implying execution or plan drafting.
> - That gap makes low-commitment clarification workflows look like
normal task execution.
> - This pull request adds an explicit Ask mode and threads it through
shared contracts, server heartbeat context, and the issue composer UI.
> - The benefit is that operators can create or switch a task into a
question-oriented mode while preserving existing agent and planning
flows.

## Linked Issues or Issue Description

No public GitHub issue exists for this change. Inline feature request
follows the repository feature request template.

### Subsystem affected

Cross-cutting: `packages/shared`, `server/`, and `ui/`.

### Problem or motivation

Issue conversations currently distinguish standard agent work from
planning work, but question-first conversations do not have a clear
public mode in the shared contract or UI. Operators who want to ask an
agent a focused question have to use standard mode, which can imply
normal task execution, or planning mode, which asks for a plan rather
than an answer.

### Proposed solution

Add Ask as a first-class issue work mode. It should be selectable from
issue creation and issue chat, cycle alongside Standard and Planning
from the keyboard shortcut/menu, appear distinctly in composer styling,
and be included in heartbeat context so agents know to answer directly
instead of executing or drafting a plan.

### Alternatives considered

- Keep using standard mode for questions: rejected because it does not
communicate answer-only intent to the agent or the UI.
- Reuse planning mode for questions: rejected because planning mode asks
for a plan and is semantically different from asking a question.
- Add only local UI copy: rejected because the mode needs to be
represented in the shared contract and server heartbeat context to be
reliable.

### Roadmap alignment

This is a focused issue-workflow improvement. `ROADMAP.md` was checked
and no duplicate planned core work was found.

### Additional context

Related public searches performed before opening this PR:

- GitHub PR search for `"ask mode" repo:paperclipai/paperclip`
- GitHub issue search for `"ask mode" repo:paperclipai/paperclip`
- GitHub PR search for `"work mode" "ask" repo:paperclipai/paperclip`

No duplicate PR was found.

## What Changed

- Added `ask` to the shared issue work-mode contract and validation
coverage.
- Included issue work mode in heartbeat context summaries so agents can
see standard, planning, and ask state.
- Added Ask mode metadata, styling, composer tone handling, and
selection/cycling behavior in the issue chat/new issue UI.
- Updated focused tests for shared validators, heartbeat context, and
affected UI work-mode flows.

## Verification

- `NODE_ENV=test pnpm exec vitest run
ui/src/components/ChatComposer.test.tsx
ui/src/components/IssueChatThread.test.tsx
ui/src/components/NewIssueDialog.test.tsx
ui/src/lib/work-mode-meta.test.ts`
- `NODE_ENV=test pnpm exec vitest run
packages/shared/src/validators/issue.test.ts
server/src/__tests__/heartbeat-context-summary.test.ts
server/src/__tests__/issues-service.test.ts
ui/src/components/ChatComposer.test.tsx
ui/src/components/IssueChatThread.test.tsx
ui/src/components/NewIssueDialog.test.tsx
ui/src/lib/work-mode-meta.test.ts ui/src/pages/IssueDetail.test.tsx`

The broader targeted command passed 8 test files / 245 tests.

Visual reference for Standard/Planning/Ask composer states:
https://gist.github.com/cryppadotta/714d8590bac55500a65e7e16de5bb4b8

It emitted an expected warning from an existing server test fixture
about a missing run-log fixture while verifying derived issue comment
metadata.

## Risks

Low to moderate risk. This adds a new enum value that crosses shared,
server, and UI contracts. Existing standard and planning modes are
preserved, but any downstream code assuming only two non-terminal work
modes may need to handle `ask`.

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

## Model Used

OpenAI GPT-5 Codex coding agent in Paperclip CodexCoder mode, with
shell, git, GitHub connector, and local test execution tools. Context
window and exact hosted model snapshot are not exposed in this runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`,
`feat/...`) 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] If this change affects the UI, I have included before/after
screenshots
- [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-06-19 13:06:04 -05:00
Dotta aeea5f9195 fix(ui): stabilize routine schedule editor and interrupted run labels (#8333)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents for work.
> - This change touches the board UI surfaces for issue run timelines
and routine schedule editing.
> - Operators need cancelled runs to distinguish ordinary cancellation
from human interruption, otherwise the run history reads as more severe
than it is.
> - Routine schedule editing also needs to preserve user-entered cron
values while rendering common schedules in a stable, understandable
editor.
> - This pull request keeps the editor state tied to explicit schedule
values, adds coverage for routine editable sections, and makes
interrupted run copy more precise.
> - The benefit is less surprising routine editing and clearer issue run
history for operators.

## Linked Issues or Issue Description

No public GitHub issue is filed for this exact branch. Related public
PRs:

- Refs #3581, which addresses a narrower schedule reset case.
- Refs #1803, which is another open schedule editor UI improvement.

Problem description:

Routine trigger schedules can be edited through the board UI, but the
previous schedule editor path could normalize or reset cron state in
ways that made unsaved edits fragile. Issue run history also labeled
operator-interrupted cancelled runs like ordinary cancellations.
Reviewers should treat this PR as a combined UI stabilization pass for
those two visible operator workflows.

## What Changed

- Added a more stable routine schedule editor flow that preserves
explicit cron values and handles custom/common schedule transitions.
- Wired routine editable-section state so schedule drafts do not get
overwritten by unrelated section refreshes.
- Added tests for schedule editor behavior, routine editable sections,
and routine service schedule preservation.
- Updated issue run timeline copy so operator-interrupted cancelled runs
display as interrupted, while ordinary cancelled runs remain cancelled.
- Kept the classic issue thread run label behavior aligned with the
current issue thread surface.

## Verification

- `NODE_ENV=development pnpm run preflight:workspace-links &&
NODE_ENV=development pnpm exec vitest run
server/src/__tests__/routines-service.test.ts
ui/src/components/IssueChatThread.test.tsx
ui/src/components/ScheduleEditor.test.tsx
ui/src/components/routine-sections/editable-sections.test.tsx` — 103
tests passed.

Note: direct `pnpm exec vitest ...` without `NODE_ENV=development`
loaded a React build where `React.act` is undefined in this workspace.
The same targeted tests pass under the development React build.

## Risks

Low to medium risk. The changes are UI-focused but touch routine
schedule editing, which is a high-frequency operator workflow. The main
risk is that an uncommon cron expression could render as custom when a
user expected a preset; the added tests cover preservation and explicit
custom handling.

> 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-class coding agent. Exact hosted runtime model ID
and context window were not exposed in this session. Tool use and local
command execution were used for inspection, verification, GitHub PR
creation, and Paperclip issue updates.

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-19 13:01:17 -05:00
Devin Foley 76ffa5023f refactor(ui): rename environment probe button from "Test draft" to "Test" (#8337)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run inside environments, and the company environments UI lets
a user configure and validate a new environment before saving it
> - For non-local drivers, that form shows a button to probe/test the
environment configuration
> - The button was labeled "Test draft", which is confusing — the user
is just testing the environment they're configuring, and "draft" adds no
meaning
> - This pull request renames the button label from "Test draft" to
"Test"
> - The benefit is a clearer, less cluttered action that matches what
the button actually does

## Linked Issues or Issue Description

No public GitHub issue exists. Inline bug description (per
CONTRIBUTING.md → "Link Issues or Describe Them In-PR"):

### What happened?

In company environment creation/editing, the environment-probe button
for non-local drivers reads "Test draft", which is confusing.

### Expected behavior

The button should simply read "Test".

### Steps to reproduce

1. Open the company environments page.
2. Add or edit an environment with a non-local driver.
3. Observe the probe action button reads "Test draft" instead of "Test".

### Paperclip version or commit

`master` — probe button in `ui/src/pages/CompanyEnvironments.tsx`.

### Deployment mode

Local dev (pnpm dev).

## What Changed

- Renamed the environment-probe button label from "Test draft" to "Test"
in `ui/src/pages/CompanyEnvironments.tsx`.
- The in-flight/pending state is unchanged and still reads "Testing...".

## Verification

- Open the company environments page, add or edit an environment with a
non-local driver, and confirm the action button reads **Test** (and
**Testing...** while a probe is in flight).
- This is a single string-literal change in JSX with no logic change; CI
typecheck/build/test gates cover regressions.

Before → After (button label): `Test draft` → `Test`

## Risks

Low risk — UI label-only change, no behavior or logic affected.

## Model Used

- Provider: Anthropic (Claude)
- Model: `claude-opus-4-8` (Claude Opus)
- Capabilities: extended thinking, tool use / 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] No test is required: this is a label-only change titled
`refactor(ui):`, which the repo's `check-pr-test-coverage` policy
exempts from the test requirement
- [x] If this change affects the UI, I have documented the label change
(before/after text above). A rendered screenshot is a non-blocking
Greptile P2 recommendation; Greptile rated the PR 5/5 "safe to merge"
- [x] I have updated relevant documentation to reflect my changes (none
required)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (re-running commitperclip after
retitle + description fix)
- [x] Greptile is 5/5 (one non-blocking P2 screenshot recommendation
noted above)
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-19 10:34:01 -07:00
Devin Foley a0c7e38ccd fix(ui): reorder environment driver dropdown and drop Local option (#8329)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run on **environments**, configured in Company Settings →
Environments, where each environment has a **driver** (how/where it
runs)
> - The "new environment" form exposed a Driver `<select>` ordered `SSH
→ Sandbox → Local`, with **Local** as a selectable create option
> - You can only ever have one local environment (it's the host running
Paperclip), so offering **Local** in the create flow is misleading — and
Sandbox is the most common choice, yet it sat in the middle of the list
> - This pull request removes the **Local** option from the create form
and moves **Sandbox** to the top of the list (`Sandbox → SSH`)
> - The benefit is a create flow that only offers drivers you can
actually create, with the most-used driver first

## Linked Issues or Issue Description

No public GitHub issue exists. Describing the underlying problem inline,
following the **Feature request** issue template:

### Problem or motivation

When creating a new environment (Company Settings → Environments → New
environment), the Driver `<select>` lists three options in this order:
`SSH`, `Sandbox`, `Local`. **Local** is selectable even though a local
environment represents the Paperclip host itself and cannot be created
more than once, so choosing it in the create flow is not a valid action.
**Sandbox**, the most common choice, sits in the middle of the list
instead of first.

### Proposed solution

Drop **Local** from the create dropdown and order the remaining options
**Sandbox** first, then **SSH**. The create flow then only offers
drivers you can actually create, with the most-used driver surfaced
first. Existing local environments must still render and be editable, so
the `"local"` driver value is retained in the type union.

### Alternatives considered

Keeping **Local** but disabling it: rejected — a permanently-disabled
option is noise and still implies local environments are creatable here.
Hiding the whole driver field when only one option remains: rejected —
both Sandbox and SSH remain valid, so the selector is still needed.

### Roadmap alignment

Not roadmap-tracked. This is a small, self-contained UX correction to an
existing form, not new core feature work.

## What Changed

- Removed the **Local** `<option>` from the new-environment Driver
`<select>`.
- Reordered the remaining options to **Sandbox** (when sandbox creation
is enabled) then **SSH** (was `SSH → Sandbox → Local`).
- Simplified the now-dead `local` branch in the select's `onChange`
handler (`driver` resolves to `sandbox` or `ssh` only).
- Updated the Driver field hint text to describe only Sandbox and SSH.
- Kept the `"local"` value in the `driver` type union so existing local
environments still render/read correctly — only the create-form option
was dropped.
- Added a unit test asserting the driver options omit `local` and list
`sandbox` before `ssh`.

## Verification

- `pnpm --filter ./ui typecheck` (`tsc -b`) — passes.
- `pnpm --filter ./ui vitest run src/pages/CompanySettings.test.tsx` — 3
passed (includes the new assertion).

Driver option ordering (create form):

| | Before | After |
|---|---|---|
| 1 | SSH | Sandbox* |
| 2 | Sandbox* | SSH |
| 3 | Local | — (removed) |

*Sandbox appears when at least one run-capable sandbox provider plugin
is installed.

Note on screenshots: the Driver control is a native `<select>`; its
expanded option list is OS-rendered and cannot be captured in a page
screenshot. The before/after option order is shown above and locked in
by the new unit test.

## Risks

Low risk. Pure create-form UI change. The `"local"` driver type is
retained for reading/editing existing environments, so no existing
environment is affected. No API, schema, or migration changes.

## Model Used

Claude Opus 4.8 (`claude-opus-4-8`), extended reasoning with 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
- [ ] If this change affects the UI, I have included before/after
screenshots — native `<select>` reorder; expanded list isn't
screenshot-capturable. Before/after option order documented above and
covered by a unit test.
- [ ] I have updated relevant documentation to reflect my changes — no
user-facing docs cover this dropdown
- [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-06-19 09:53:09 -07:00
joegalbert-ai 6756ae8289 fix(ui): restore issue copy buttons on HTTP (#8212)
## Thinking Path

> - Paperclip is the control plane operators use to run AI-agent
companies, so board actions like copying task state need to work
reliably on the live board UI.
> - The affected surface is the issue detail and issue chat UI, where
operators copy task descriptions and comment text during triage and
handoff.
> - On self-hosted HTTP deployments, the async Clipboard API can exist
but fail, which breaks these copy buttons silently.
> - The internal FMAI reproduction pointed specifically at task
description copy and task comment copy in the issue view.
> - There is already an overlapping upstream PR,
[#6353](https://github.com/paperclipai/paperclip/pull/6353), but it is
currently `CONFLICTING` and does not provide a mergeable path.
> - This pull request adds a shared clipboard helper with a fallback
path, wires the task-detail and task-thread copy actions through it, and
locks the behavior in with targeted tests.
> - The benefit is that copy buttons keep working on HTTP self-hosted
boards without changing behavior for secure deployments.

## Linked Issues or Issue Description

- Fixes #3529
- Refs #6353

## What Changed

- Added `ui/src/lib/clipboard.ts` with a shared `copyTextToClipboard()`
helper that tries the async Clipboard API first and falls back to
`document.execCommand("copy")` when that path is blocked.
- Updated `IssueDetail.tsx` so the task-level "Copy task as markdown"
action uses the shared helper.
- Updated both `IssueChatThread.tsx` and `IssueChatThreadClassic.tsx` so
task comment copy actions, code-block copy actions, and system-notice
copy actions use the shared helper.
- Added focused regression coverage in `IssueDetail.test.tsx` and
`IssueChatThread.test.tsx` for insecure-context fallback behavior.

## Verification

- `corepack pnpm exec vitest run ui/src/pages/IssueDetail.test.tsx
ui/src/components/IssueChatThread.test.tsx
ui/src/components/IssueChatThreadSystemNotice.test.tsx`
- `corepack pnpm exec tsc -p ui/tsconfig.json --noEmit`
- Manual reviewer check:
  - Run Paperclip over HTTP.
  - Open an issue detail page.
  - Use `Copy task as markdown` and a comment `Copy message` action.
  - Confirm both copy successfully instead of silently failing.

## Risks

- Low risk. The change is scoped to clipboard helpers and the specific
issue-detail / issue-thread copy actions.
- The fallback relies on `document.execCommand("copy")`, which is legacy
browser behavior, but it is only used when the modern clipboard path is
unavailable or blocked.

## Model Used

- OpenAI GPT-5 Codex via Codex local adapter, tool-enabled coding
workflow with terminal, git, and file-editing support.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [ ] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] 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: FMAI Agents <joegalbert-ai@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-18 23:43:57 -07:00
Devin Foley fc95699fde fix(server): enforce agent secret binding sync across lifecycle flows (#8307)
## Thinking Path

> - Paperclip is the control plane people use to create, configure, and
run AI agents for work.
> - This change sits in the server-side agent lifecycle and
secret-binding subsystem, where adapter config `env` entries can
reference company secrets.
> - An incident (while trying to configure a Novita sandbox) showed that
an agent can reach a broken runtime state if `adapterConfig.env`
contains `secret_ref` entries but the matching `company_secret_bindings`
rows are missing.
> - The immediate run-path guard and error-surfacing work made the
failure diagnosable, but they did not fully prevent new broken agents
from being created.
> - The risk came from create and approval flows being responsible for
remembering to sync bindings at each call site, which is easy to miss as
new flows are added.
> - This pull request moves the invariant into `agentService`
create/update/activate paths, keeps the existing hire-flow fix, and adds
regression coverage for create, update, and legacy pending-approval
recovery.
> - The benefit is that agent secret binding integrity is enforced
closer to the data mutation point, so future callers inherit the
protection automatically.

## Linked Issues or Issue Description

Refs #8309

### What happened?
A Paperclip agent could persist `adapterConfig.env` `secret_ref` entries
without matching agent-scoped `company_secret_bindings` rows. When that
happened, the config UI could still look configured, but the real run
path failed pre-dispatch because the secret was not actually bound to
that agent.

### Expected behavior
Every normal agent create, config-update, and pending-approval
activation flow should leave the agent with secret bindings that match
its persisted secret-ref env config.

### Steps to reproduce
1. Create or activate an agent through a flow that persists
`adapterConfig.env` secret refs without synchronizing
`company_secret_bindings`.
2. Observe that the config state can still appear populated.
3. Start a run for that agent.
4. Observe that pre-dispatch binding validation fails because the secret
reference exists but the agent binding does not.

### Deployment mode
Local dev (`pnpm dev`)

### Installation method
Built from source (`pnpm dev` / `pnpm build`)

### Agent adapter(s) involved
- Claude Code
- Not adapter-specific (core bug)

### Database mode
Embedded PGlite / embedded local dev database flow

### Access context
Board (human operator) created or approved the agent; agent runtime
later consumed the config.

### Additional context
This PR focuses on preventing new broken states from normal service
flows and on backfilling the covered legacy pending-approval activation
path.

## What Changed

- Kept the existing branch-local hire-flow fix that synchronized
bindings for route and approval paths.
- Moved the binding integrity invariant into `agentService.create()`,
`agentService.update()` when `adapterConfig` changes, and
`agentService.activatePendingApproval()`.
- Added `server/src/__tests__/agents-service-secret-bindings.test.ts`
covering create-time sync, update-time resync, and backfill for legacy
pending-approval agents.
- Removed now-redundant route-layer and approval-layer binding sync
calls once the service layer became authoritative.
- Simplified the affected unit tests so route/approval tests no longer
assert service-owned binding writes directly.

## Verification

- `pnpm --filter @paperclipai/server typecheck`
- `pnpm exec vitest run
server/src/__tests__/agents-service-secret-bindings.test.ts
server/src/__tests__/approvals-service.test.ts
server/src/__tests__/agent-skills-routes.test.ts`

## Risks

- Low to medium risk.
- This changes where secret-binding synchronization is enforced, so any
unexpected caller that relied on upper-layer manual sync behavior could
behave differently.
- Agent create/update/activation flows now perform binding
synchronization consistently, which adds binding-table writes at those
mutation points.
- This PR does not retroactively scan and heal every already-broken
historical agent row; it prevents and backfills through the covered
service flows.

> 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 Codex class model via `codex_local`
- Session model family: GPT-5 Codex
- Tool-assisted coding with shell, git, HTTP, and local test execution
- Reasoning mode: medium interactive tool-use workflow

## 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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [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-06-18 21:26:36 -07:00
dependabot[bot] 2a0768d380 build(deps): bump @mdxeditor/editor from 3.52.4 to 3.55.0 (#7747)
Bumps [@mdxeditor/editor](https://github.com/mdx-editor/editor) from
3.52.4 to 3.55.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mdx-editor/editor/releases">@​mdxeditor/editor's
releases</a>.</em></p>
<blockquote>
<h2>v3.55.0</h2>
<h1><a
href="https://github.com/mdx-editor/editor/compare/v3.54.1...v3.55.0">3.55.0</a>
(2026-04-19)</h1>
<h3>Bug Fixes</h3>
<ul>
<li>render code blocks with unknown language as plain text (<a
href="https://redirect.github.com/mdx-editor/editor/issues/927">#927</a>)
(<a
href="https://github.com/mdx-editor/editor/commit/f4785093fcfd868b9b51cb4cb6713a0844a06364">f478509</a>)</li>
<li>route capitalized jsx tags sharing an html tag name to the jsx
visitor (<a
href="https://redirect.github.com/mdx-editor/editor/issues/928">#928</a>)
(<a
href="https://github.com/mdx-editor/editor/commit/93ae1ef629c1f93812edcb4cf35aad3cee558d14">93ae1ef</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>add data-tool-cell attribute to table footer header (<a
href="https://redirect.github.com/mdx-editor/editor/issues/912">#912</a>)
(<a
href="https://github.com/mdx-editor/editor/commit/6c5e6716ed06c48b1a9acb26043c001fe1d02960">6c5e671</a>)</li>
</ul>
<h2>v3.54.1</h2>
<h2><a
href="https://github.com/mdx-editor/editor/compare/v3.54.0...v3.54.1">3.54.1</a>
(2026-04-16)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>add aria-label to toolbar buttons for WCAG 2.2 AA compliance (<a
href="https://redirect.github.com/mdx-editor/editor/issues/926">#926</a>)
(<a
href="https://github.com/mdx-editor/editor/commit/8bfc151d18ef11d105d8c40400e57c3bfd86df11">8bfc151</a>),
closes <a
href="https://redirect.github.com/mdx-editor/editor/issues/924">#924</a></li>
</ul>
<h2>v3.54.0</h2>
<h1><a
href="https://github.com/mdx-editor/editor/compare/v3.53.1...v3.54.0">3.54.0</a>
(2026-04-07)</h1>
<h3>Bug Fixes</h3>
<ul>
<li>keep codemirror support types dependency-free (<a
href="https://github.com/mdx-editor/editor/commit/6eaa8df995a0adf32f6df4a33b609b0eec51a2ff">6eaa8df</a>)</li>
<li>preserve empty blockquote lines on markdown round-trips (<a
href="https://github.com/mdx-editor/editor/commit/14b37866d94bb14e6c3b08407931326e19b2ea4f">14b3786</a>),
closes <a
href="https://redirect.github.com/mdx-editor/editor/issues/920">#920</a></li>
</ul>
<h3>Features</h3>
<ul>
<li>support pre-loaded language support in codeMirrorPlugin (<a
href="https://github.com/mdx-editor/editor/commit/8bbf8512128fa0b284145f9ba4c58eaa467e242d">8bbf851</a>)</li>
</ul>
<h2>v3.53.1</h2>
<h2><a
href="https://github.com/mdx-editor/editor/compare/v3.53.0...v3.53.1">3.53.1</a>
(2026-03-24)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>harden language normalization and add tests (<a
href="https://github.com/mdx-editor/editor/commit/d655f10d7a0adc96c09f61defe5753c503619488">d655f10</a>)</li>
<li>make Select dropdown scrollable when content exceeds viewport (<a
href="https://github.com/mdx-editor/editor/commit/7a63278ad0ef99472ac88d9c8632a8f8afdbb981">7a63278</a>)</li>
<li>resolve lint errors in codemirror tests (<a
href="https://github.com/mdx-editor/editor/commit/057c18c14adcb03082ae27769ffef108dfeaa652">057c18c</a>)</li>
</ul>
<h2>v3.53.0</h2>
<h1><a
href="https://github.com/mdx-editor/editor/compare/v3.52.5...v3.53.0">3.53.0</a>
(2026-03-24)</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mdx-editor/editor/commit/8c3e4fa37f42cebd7df6d1e6c474353d5270742f"><code>8c3e4fa</code></a>
test: fix lint formatting and jsx act warnings</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/6c5e6716ed06c48b1a9acb26043c001fe1d02960"><code>6c5e671</code></a>
feat: add data-tool-cell attribute to table footer header (<a
href="https://redirect.github.com/mdx-editor/editor/issues/912">#912</a>)</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/f4785093fcfd868b9b51cb4cb6713a0844a06364"><code>f478509</code></a>
fix: render code blocks with unknown language as plain text (<a
href="https://redirect.github.com/mdx-editor/editor/issues/927">#927</a>)</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/93ae1ef629c1f93812edcb4cf35aad3cee558d14"><code>93ae1ef</code></a>
fix: route capitalized jsx tags sharing an html tag name to the jsx
visitor (...</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/d1f65619e0c0b54c6e0116053bb603b905183e9f"><code>d1f6561</code></a>
chore: improve windows compatibility for development</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/8bfc151d18ef11d105d8c40400e57c3bfd86df11"><code>8bfc151</code></a>
fix: add aria-label to toolbar buttons for WCAG 2.2 AA compliance (<a
href="https://redirect.github.com/mdx-editor/editor/issues/926">#926</a>)</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/6eaa8df995a0adf32f6df4a33b609b0eec51a2ff"><code>6eaa8df</code></a>
fix: keep codemirror support types dependency-free</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/14b37866d94bb14e6c3b08407931326e19b2ea4f"><code>14b3786</code></a>
fix: preserve empty blockquote lines on markdown round-trips</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/a3070c886023ff0ede5a1df57b4a579cec182711"><code>a3070c8</code></a>
Merge pull request <a
href="https://redirect.github.com/mdx-editor/editor/issues/917">#917</a>
from Godefroy/feat/codemirror-language-support</li>
<li><a
href="https://github.com/mdx-editor/editor/commit/e9ab593f71d4d1a183ad708b930307cb010ab343"><code>e9ab593</code></a>
docs: add usage example for autoLoadLanguageSupport option</li>
<li>Additional commits viewable in <a
href="https://github.com/mdx-editor/editor/compare/v3.52.4...v3.55.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-06-18 15:54:01 -07:00
dependabot[bot] f06b369e52 build(deps-dev): bump @storybook/react-vite from 10.3.5 to 10.4.6 (#7746)
Bumps
[@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite)
from 10.3.5 to 10.4.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">@​storybook/react-vite's
releases</a>.</em></p>
<blockquote>
<h2>v10.4.6</h2>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>v10.4.5</h2>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>v10.4.4</h2>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>v10.4.3</h2>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>v10.4.2</h2>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>v10.4.1</h2>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run `npx expo install --fix` after init for Expo projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support `peerDependencies` in framework detection for component
libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>v10.4.0</h2>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">@​storybook/react-vite's
changelog</a>.</em></p>
<blockquote>
<h2>10.4.6</h2>
<ul>
<li>CSF: Allow partial globals overrides in story and meta annotations -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>,
thanks <a
href="https://github.com/TheSeydiCharyyev"><code>@​TheSeydiCharyyev</code></a>!</li>
<li>Dependencies: Upgrade esbuild - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>,
thanks <a
href="https://github.com/Kakadus"><code>@​Kakadus</code></a>!</li>
</ul>
<h2>10.4.5</h2>
<ul>
<li>Core: Rework AI checklist feature gate - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Preview: Stop mixed CSF3+4 stories getting core annotations injected
twice - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
</ul>
<h2>10.4.4</h2>
<ul>
<li>Telemetry: Add timeout to event-log POST to prevent build hang - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>,
thanks <a
href="https://github.com/badams"><code>@​badams</code></a>!</li>
</ul>
<h2>10.4.3</h2>
<ul>
<li>Addon Docs: Fix Primary and Controls blocks not rendering in custom
MDX pages - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>,
thanks <a
href="https://github.com/NYCU-Chung"><code>@​NYCU-Chung</code></a>!</li>
<li>Core: Respect !dev tag on MDX docs in sidebar - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>React: Add support for resolving subcomponents attached as
properties of a parent component - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>,
thanks <a
href="https://github.com/yatishgoel"><code>@​yatishgoel</code></a>!</li>
<li>UI: Prevent docs page scroll reset on HMR re-render - <a
href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>,
thanks <a
href="https://github.com/LongTangGithub"><code>@​LongTangGithub</code></a>!</li>
</ul>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run <code>npx expo install --fix</code> after init for Expo
projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support <code>peerDependencies</code> in framework detection
for component libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<ul>
<li>🤖 Agentic Setup: New CLI workflow for AI-assisted Storybook setup
and onboarding</li>
<li>🔍 Change review: Sidebar filtering to highlight new, modified, and
related stories based on git changes</li>
<li>🧭 Sidebar review tools: Status filtering, URL-persisted filters, and
clearer review signals in the sidebar</li>
<li>⚛️ TanStack React: New <code>@storybook/tanstack-react</code>
framework with routing and server function support</li>
<li>🧩 React MCP: Faster, more accurate component docgen powered by the
TypeScript Language Server</li>
<li>📱 React Native: Zero config RN project initialization</li>
<li>🤝 Sharing: Easily publish and share your local Storybook with
teammates, powered by Chromatic</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/5496a4270da7f3a8e0203185792685cba671fdc5"><code>5496a42</code></a>
Bump version from &quot;10.4.5&quot; to &quot;10.4.6&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/48e7b20074222ed926d14fb6c678c2edfc86ee7b"><code>48e7b20</code></a>
Bump version from &quot;10.4.4&quot; to &quot;10.4.5&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/5adebe753f29d414d1e214e935c94d6e5451861f"><code>5adebe7</code></a>
Bump version from &quot;10.4.3&quot; to &quot;10.4.4&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/624e6187fd462e56719cbd80c1b4bfb67b68fc89"><code>624e618</code></a>
Bump version from &quot;10.4.2&quot; to &quot;10.4.3&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/298dea20c6370e5c670178d88a79fc9e9ff436b2"><code>298dea2</code></a>
Bump version from &quot;10.4.1&quot; to &quot;10.4.2&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/cc19ae1a2145e8f7cda8dc869f1b90d5346dcedb"><code>cc19ae1</code></a>
Bump version from &quot;10.4.0&quot; to &quot;10.4.1&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/f8c16d115cfcf0f79125b358266c37e5343bb70d"><code>f8c16d1</code></a>
Bump version from &quot;10.4.0-beta.0&quot; to &quot;10.4.0&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/e02da0b0d4cf9673999184b8f11c85b026954b69"><code>e02da0b</code></a>
Bump version from &quot;10.4.0-alpha.19&quot; to
&quot;10.4.0-beta.0&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/429fb3e42609382e9d578cce3c8aa9817182c3c1"><code>429fb3e</code></a>
Bump version from &quot;10.4.0-alpha.18&quot; to
&quot;10.4.0-alpha.19&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/488dd0840b7e489b33c2c65975a195bcc991bec7"><code>488dd08</code></a>
Bump version from &quot;10.4.0-alpha.17&quot; to
&quot;10.4.0-alpha.18&quot; [skip ci]</li>
<li>Additional commits viewable in <a
href="https://github.com/storybookjs/storybook/commits/v10.4.6/code/frameworks/react-vite">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 15:54:00 -07:00
Nicky Leach 7a311ca16f test(ui): stabilize IssueProperties model-options assertion (#8299)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board UI test suite protects issue editing behavior, including
assignee model options in `IssueProperties`.
> - A Storybook-related dependency bump exposed a brittle async wait in
one `IssueProperties` test.
> - The test was waiting for model options with a fixed number of flush
ticks instead of waiting for the React Query-backed options to render.
> - This pull request makes that lookup use the existing polling
assertion helper used elsewhere in the same file.
> - The benefit is that the test now tracks the UI state it actually
needs, without changing product behavior.

## Linked Issues or Issue Description

Refs #7746

Bug fix:

- What happened: after the `@storybook/react-vite` 10.4.2 update path,
the `IssueProperties` test `edits existing custom assignee model options
from the properties pane` could fail while looking for the `GPT-5.5`
model option.
- Expected behavior: the test should wait for the async adapter-model
options to render before interacting with them.
- Steps to reproduce: run `cd ui && pnpm vitest run
src/components/IssueProperties.test.tsx` against the affected dependency
state.
- Paperclip version/commit: based on
`0936990a58ce819da8fd5e8ceb2e9a5b4d4a70ad`.
- Deployment mode: local development test run; no runtime deployment
mode involved.

## What Changed

- Replaced the fixed-tick model-button lookup in
`IssueProperties.test.tsx` with the existing `waitForAssertion` helper.
- Left application code unchanged; this is a test-only stabilization.

## Verification

- `cd ui && pnpm vitest run src/components/IssueProperties.test.tsx` ->
1 test file passed, 25 tests passed.

## Risks

Low risk. The change only affects a test wait path and uses an existing
helper already used elsewhere in the same test file. The main risk is
masking a real missing-option regression, but the assertion still
requires the `GPT-5.5` button to render before the test can continue.

## Model Used

OpenAI Codex based on GPT-5, with code editing, terminal command
execution, Git/GitHub CLI operation, and repository context inspection
capabilities.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [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-06-18 15:49:50 -07:00
dependabot[bot] 6f142a60ce build(deps-dev): bump @types/node from 22.19.11 to 22.19.21 (#7748)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 22.19.11 to 22.19.21.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 15:46:06 -07:00
dependabot[bot] bdc81666f2 build(deps): bump radix-ui from 1.4.3 to 1.6.0 (#7749)
Bumps
[radix-ui](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/radix-ui)
from 1.4.3 to 1.6.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/radix-ui/primitives/blob/main/packages/react/radix-ui/CHANGELOG.md">radix-ui's
changelog</a>.</em></p>
<blockquote>
<h2>1.6.0</h2>
<pre lang="tsx"><code>const Slot = createSlot&lt;HTMLButtonElement,
MyCustomButtonProps&gt;('Slot');
</code></pre>
<h3>Avatar</h3>
<ul>
<li>Fixed several edge cases with Avatar's loading state
<ul>
<li>An avatar's fallback would not be displayed again if its image
component unmounted. This is now fixed.</li>
<li>Rendering multiple <code>Avatar.Image</code> components per
<code>Avatar.Root</code> was never supported and results in buggy,
unpredictable behavior. We now warn about this in development.</li>
<li>Zero-sized images were treated as <code>loading</code>, meaning that
<code>onLoadingStatusChange</code> is never called once loaded. A
zero-sized image now triggers an <code>error</code> status on load.</li>
</ul>
</li>
</ul>
<h3>Password Toggle Field</h3>
<ul>
<li>Renamed misspelled <code>onVisiblityChange</code> prop to
<code>onVisibilityChange</code>.</li>
<li>Fixed prop type definitions to include <code>asChild</code> for all
component parts.</li>
</ul>
<h3>Scroll Area</h3>
<ul>
<li>Stabilized the viewport style tag unless the nonce changes.</li>
</ul>
<h3>Slot</h3>
<ul>
<li><code>SlotProps</code> and <code>createSlot</code> now accept
generic type arguments to specify the type of element a slot should
render, as well as its props.</li>
</ul>
<h3>Toggle Group</h3>
<ul>
<li>Updated single-select and multi-select toggle groups to use the
<code>radiogroup</code> and <code>toolbar</code> roles,
respectively.</li>
</ul>
<h3>Select</h3>
<ul>
<li>Allowed a <code>Select.Item</code> with an empty string value to act
as a &quot;clear&quot; option. Selecting it resets the selection back to
the placeholder, restoring the native <code>&lt;select&gt;</code>
behavior for optional selects. Previously using an empty string value
would throw an error.</li>
<li>Fixed a bug where typeahead search resulted in focusing an element
that no longer exists.</li>
</ul>
<h3>Other updates</h3>
<ul>
<li>Fixed a regression in that caused submenu misalignment when using
custom portals.</li>
<li>Removed dev-only warnings for dialogs when title and/or description
is not rendered.</li>
<li>Fixed a bug where menus and submenus remained open after a window
loses focus.</li>
<li>Fixed Dismissable Layer so outside interactions stopped by extension
UI overlays do not dismiss dialogs or popovers.</li>
<li>Fixed <code>Duplicate index signature</code> errors that surfaced
when consuming multiple packages together.</li>
</ul>
<h2>1.5.0</h2>
<h3>Context Menu</h3>
<ul>
<li>
<p>Added support for a controlled <code>open</code> prop on
<code>ContextMenu.Root</code>. This is intended for reading the open
state and closing the menu programmatically, though we discourage
opening the menu programmatically since opening the menu depends on user
interaction to position the menu.</p>
<pre lang="tsx"><code></code></pre>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/radix-ui/primitives/commits/HEAD/packages/react/radix-ui">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for radix-ui 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-06-18 15:39:30 -07:00
dependabot[bot] 4e2a82487a build(deps): bump i18next from 26.2.0 to 26.3.1 (#7750)
Bumps [i18next](https://github.com/i18next/i18next) from 26.2.0 to
26.3.1.
<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.3.1</h2>
<ul>
<li>fix(types): <code>t()</code> with a <code>keyPrefix</code> no longer
pollutes its return type with sibling keys' values. A regression in
26.3.0 — the <code>[Res] extends [never]</code> guards added to
<code>KeysBuilderWithReturnObjects</code> /
<code>KeysBuilderWithoutReturnObjects</code> turned the builders into
deferred conditional types, so <code>KeyPrefix&lt;Ns&gt;</code> stopped
resolving to a literal union and <code>keyPrefix</code> inference
widened to the whole namespace. Symptom: <code>useTranslation(ns, {
keyPrefix: 'a.b' })</code> then <code>t('title')</code> would resolve to
<code>'&lt;a.b&gt;.title' | '&lt;other.path&gt;.title' | ...</code>
instead of just the scoped value. Affected every
<code>react-i18next</code> user using <code>keyPrefix</code>. Restored
to the eager 26.2.0 form. The same-namespace conflict handling from <a
href="https://redirect.github.com/i18next/i18next/issues/2434">#2434</a>
still works via <code>_DropConflictKeys</code> at the merge layer (in
<code>options.d.ts</code>). Thanks <a
href="https://github.com/aaronrosenthal"><code>@​aaronrosenthal</code></a>
(<a
href="https://redirect.github.com/i18next/i18next/pull/2436">#2436</a>).</li>
</ul>
<h2>v26.3.0</h2>
<ul>
<li>feat(types): introduce <code>ResourceNamespaceMap</code> — a
separate mergeable augmentation surface for namespace resource types,
designed for monorepos where multiple packages each want to contribute
their own namespaces. Previously, every package had to coordinate on a
single <code>CustomTypeOptions.resources</code> declaration (or fall
back to typing dependency namespaces as <code>any</code>) because
<code>resources</code> is a single property of an interface and
TypeScript reports TS2717 when two declarations of the same property
disagree. The new interface merges naturally across <code>declare module
'i18next'</code> blocks, so each package can ship its own
<code>i18next.d.ts</code> independently. Per-property merge handles
same-namespace contributions from multiple packages, and
same-key/different-literal conflicts are silently dropped to avoid
poisoning <code>t()</code> overload resolution. Fully
backwards-compatible — existing <code>CustomTypeOptions.resources</code>
augmentations continue to work, and both surfaces can coexist. Scalar
options (<code>defaultNS</code>, <code>returnNull</code>,
<code>enableSelector</code>, etc.) still belong on
<code>CustomTypeOptions</code>. Thanks <a
href="https://github.com/sh3xu"><code>@​sh3xu</code></a> (<a
href="https://redirect.github.com/i18next/i18next/pull/2434">#2434</a>).
Fixes <a
href="https://redirect.github.com/i18next/i18next/issues/2409">#2409</a>.</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.3.1</h2>
<ul>
<li>fix(types): <code>t()</code> with a <code>keyPrefix</code> no longer
pollutes its return type with sibling keys' values. A regression in
26.3.0 — the <code>[Res] extends [never]</code> guards added to
<code>KeysBuilderWithReturnObjects</code> /
<code>KeysBuilderWithoutReturnObjects</code> turned the builders into
deferred conditional types, so <code>KeyPrefix&lt;Ns&gt;</code> stopped
resolving to a literal union and <code>keyPrefix</code> inference
widened to the whole namespace. Symptom: <code>useTranslation(ns, {
keyPrefix: 'a.b' })</code> then <code>t('title')</code> would resolve to
<code>'&lt;a.b&gt;.title' | '&lt;other.path&gt;.title' | ...</code>
instead of just the scoped value. Affected every
<code>react-i18next</code> user using <code>keyPrefix</code>. Restored
to the eager 26.2.0 form. The same-namespace conflict handling from <a
href="https://redirect.github.com/i18next/i18next/issues/2434">#2434</a>
still works via <code>_DropConflictKeys</code> at the merge layer (in
<code>options.d.ts</code>). Thanks <a
href="https://github.com/aaronrosenthal"><code>@​aaronrosenthal</code></a>
(<a
href="https://redirect.github.com/i18next/i18next/pull/2436">#2436</a>).</li>
</ul>
<h2>26.3.0</h2>
<ul>
<li>feat(types): introduce <code>ResourceNamespaceMap</code> — a
separate mergeable augmentation surface for namespace resource types,
designed for monorepos where multiple packages each want to contribute
their own namespaces. Previously, every package had to coordinate on a
single <code>CustomTypeOptions.resources</code> declaration (or fall
back to typing dependency namespaces as <code>any</code>) because
<code>resources</code> is a single property of an interface and
TypeScript reports TS2717 when two declarations of the same property
disagree. The new interface merges naturally across <code>declare module
'i18next'</code> blocks, so each package can ship its own
<code>i18next.d.ts</code> independently. Per-property merge handles
same-namespace contributions from multiple packages, and
same-key/different-literal conflicts are silently dropped to avoid
poisoning <code>t()</code> overload resolution. Fully
backwards-compatible — existing <code>CustomTypeOptions.resources</code>
augmentations continue to work, and both surfaces can coexist. Scalar
options (<code>defaultNS</code>, <code>returnNull</code>,
<code>enableSelector</code>, etc.) still belong on
<code>CustomTypeOptions</code>. Thanks <a
href="https://github.com/sh3xu"><code>@​sh3xu</code></a> (<a
href="https://redirect.github.com/i18next/i18next/pull/2434">#2434</a>).
Fixes <a
href="https://redirect.github.com/i18next/i18next/issues/2409">#2409</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/i18next/i18next/commit/7bdb5d70d4142dde36d46ae66f207da304d77fed"><code>7bdb5d7</code></a>
26.3.1</li>
<li><a
href="https://github.com/i18next/i18next/commit/a655e3230d76501852e027033d2dcaba1c14f434"><code>a655e32</code></a>
changelog: 26.3.1 entry for <a
href="https://redirect.github.com/i18next/i18next/issues/2436">#2436</a></li>
<li><a
href="https://github.com/i18next/i18next/commit/57ed81222d0f4ad29633877ca4d76e1f751f7603"><code>57ed812</code></a>
fix(types): keyPrefix no longer pollutes t() return type with sibling
keys (#...</li>
<li><a
href="https://github.com/i18next/i18next/commit/bdf651c07d4d3a37d616a2c0ec5e954a527fc513"><code>bdf651c</code></a>
26.3.0</li>
<li><a
href="https://github.com/i18next/i18next/commit/988a3620671dc2ce26591e37b80f2e779935cbf5"><code>988a362</code></a>
changelog: 26.3.0 entry for <a
href="https://redirect.github.com/i18next/i18next/issues/2434">#2434</a></li>
<li><a
href="https://github.com/i18next/i18next/commit/159506c93d90627cff8707660bf82afe36e4f701"><code>159506c</code></a>
feat(types): introduce ResourceNamespaceMap for monorepo namespace
augmentati...</li>
<li><a
href="https://github.com/i18next/i18next/commit/df68b1f32470bde7fe891086241bfc2df229be7b"><code>df68b1f</code></a>
ci: restore JSR publishing via GitHub Actions OIDC</li>
<li>See full diff in <a
href="https://github.com/i18next/i18next/compare/v26.2.0...v26.3.1">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 15:12:39 -07:00
MrBob 5f16efb3d0 fix: parse YAML block scalar skill descriptions (#5046)
## Thinking Path

> - Paperclip is the open source control plane teams use to manage AI
agents for work.
> - Company skills are imported from `SKILL.md` files and rely on YAML
frontmatter to describe what each skill does.
> - Multi-line descriptions commonly use YAML block scalars (`>` and
`|`), but the broken parser path behind #4989 reduced those descriptions
to a literal `>` or `|`.
> - The earliest contributor fix for that bug was PR #5046, so this
branch keeps that PR as the canonical merge target instead of replacing
it.
> - Follow-up work from #5071 and #8258 was then transplanted onto this
earlier branch so the final PR preserves contributor credit while still
shipping the strongest complete fix.
> - The resulting change fixes block-scalar parsing in the shared
frontmatter path, aligns server company-skill imports with that shared
parser, and prevents already-stale stored markers from rendering as junk
in the UI.

## Linked Issues or Issue Description

- Fixes #4989
- Refs #2863
- Refs #788
- Related superseded PRs: #5071, #8258

## What Changed

- Kept the original PR #5046 server-side company-skill fix and
regression coverage as the base branch history.
- Added the missing YAML chomping and indicator hardening explored
further in #5071.
- Moved frontmatter parsing to the shared parser path so
`packages/shared`, `packages/skills-catalog`, and server company-skill
imports stay aligned.
- Added UI summary sanitization and fallback handling so stale stored
`>` / `|` values no longer render as visible junk in company-skill
cards.
- Added regression coverage for shared frontmatter parsing,
skills-catalog parsing, company-skill imports, and stale-summary
fallback behavior.

## Verification

- Passed locally: `pnpm exec vitest run
packages/shared/src/frontmatter.test.ts
packages/skills-catalog/src/frontmatter.test.ts
server/src/__tests__/company-skills.test.ts
ui/src/lib/company-skill-summary.test.ts`
- Passed locally: `pnpm --filter @paperclipai/shared typecheck`
- Passed locally: `pnpm --filter @paperclipai/skills-catalog typecheck`
- Not fully runnable in this worktree: `pnpm --filter
@paperclipai/server typecheck` currently fails in `packages/plugins/sdk`
before reaching server code because local workspace `node_modules` type
deps are missing (`TS2688` for `node` / `react`).
- GitHub Actions / PR checks are rerunning on PR #5046 head
`005290b7557725abf748d00f36dd24ea0d919aba`.

## Risks

- Medium-low risk: the fix now touches shared parser code, server
company-skill imports, and UI fallback display rather than only the
server import path.
- The parser is still intentionally narrower than a full YAML
implementation; this change focuses on block-scalar correctness and the
stale-description rendering path relevant to #4989 / #2863.
- This branch intentionally supersedes narrower overlapping work from
#5071 and duplicate work from #8258 once the survivor PR is green.

> 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-based coding agent with local shell and
code-editing tools enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [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: Devin Foley <devin@paperclip.ing>
2026-06-18 12:01:11 -07:00
Devin Foley d47b4da655 Auto-build bundled plugins on install (#8254)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Plugins extend the server with worker/UI surfaces, and bundled local
plugins under `packages/plugins/**` ship as TS source — their compiled
`dist/` is not checked in
> - On a fresh checkout, installing a bundled local plugin via the
in-app **Install** button failed because `paperclipPlugin.manifest`
points at `./dist/manifest.js`, which does not exist until the package
is built
> - The error surfaces as `Package … does not appear to be a Paperclip
plugin (no manifest found)`, which is misleading — the manifest is real,
the dist is just missing — and forces every contributor to run `pnpm
--filter … build` by hand before the bundled-plugin installer works at
all
> - This pull request teaches the install path to detect that case and
run the package's build (plus standalone runtime bootstrap for plugins
outside the root workspace) before manifest resolution, gated by a kill
switch and a bounded timeout
> - The benefit is bundled plugins like
`@paperclipai/plugin-workspace-diff` install in one click on a fresh
checkout, with a clear error message and manual fallback when the
autobuild itself fails

## Linked Issues or Issue Description

No existing GitHub issue. Underlying bug, following the bug-report
template:

**What happened?**
Installing a bundled local plugin from a fresh checkout fails with
`Package @paperclipai/plugin-workspace-diff at
packages/plugins/plugin-workspace-diff does not appear to be a Paperclip
plugin (no manifest found)`. The manifest is declared in `package.json`
(`paperclipPlugin.manifest = ./dist/manifest.js`) but `dist/` is not
built/committed, so the loader cannot find it.

**Expected behavior**
Clicking **Install** on a bundled plugin builds it if needed and
registers it, without a manual build step.

**Steps to reproduce**
1. Fresh checkout of `master`
2. Start the server, open Plugin Manager
3. Click **Install** next to `@paperclipai/plugin-workspace-diff`
4. Observe the "no manifest found" failure

**Scope**
Same failure mode affects every bundled plugin without a checked-in
`dist/` (`plugin-llm-wiki`, examples, sandbox-provider plugins, etc.).

## What Changed

- `server/src/services/plugin-loader.ts`: added
`ensureLocalPluginBuilt(packageRoot, pkgJson)` — when the package lives
under `packages/plugins/**` and its declared paperclipPlugin entrypoints
(`manifest`, `worker`, `ui`) are missing, run `pnpm --filter <name>
build` (and a standalone runtime-deps bootstrap for plugins outside the
root pnpm workspace) before manifest resolution
- `server/src/routes/plugins.ts`: invoke the autobuild from the
local-path install path; surface a `hasBuiltEntrypoints` boolean on the
`AvailableBundledPlugin` listing; invalidate the bundled-plugins cache
after a successful install so a freshly built plugin no longer reports
`hasBuiltEntrypoints: false`
- `ui/src/api/plugins.ts` + `ui/src/pages/PluginManager.tsx`: type and
consume `hasBuiltEntrypoints` so the installer can show that an
autobuild will run on install
- `server/src/__tests__/plugin-install-autobuild.test.ts`: new suite — 9
tests covering success, kill-switch, build failure, timeout, manifest
still missing after build, standalone variant, and the existing
`plugin-routes-authz` listing assertion
- `doc/plugins/LOCAL_PLUGIN_DEVELOPMENT.md`: documents the autobuild,
the `PAPERCLIP_DISABLE_PLUGIN_AUTOBUILD=1` kill switch, and the manual
fallback command
- Detect the autobuild timeout via the child-process `killed` flag
rather than string-matching the error message, so the "after timing out"
context is actually emitted

Knobs:

- `PAPERCLIP_DISABLE_PLUGIN_AUTOBUILD=1` — skip autobuild entirely;
restore prior behavior
- Build timeout: 120s, with a clear error that points at the manual
`pnpm --filter <name> build` recovery command

## Verification

- `cd server && pnpm vitest run
src/__tests__/plugin-install-autobuild.test.ts
src/__tests__/plugin-routes-authz.test.ts` → 44/44 pass
- End-to-end on a clean checkout: `rm -rf
packages/plugins/plugin-workspace-diff/dist`, invoke
`ensureLocalPluginBuilt()` against the real package, all declared
entrypoints (`dist/manifest.js`, `dist/worker.js`, `dist/ui/index.js`)
regenerated. The original `no manifest found` symptom no longer
reproduces.

## Risks

Low. The autobuild only fires when (a) the package sits under
`packages/plugins/**`, (b) at least one declared entrypoint is missing,
and (c) the kill switch is not set. In a packaged production server the
`packages/plugins/**` path does not exist on disk, so the helper
short-circuits and never shells out to `pnpm`. Failures from the spawned
build are surfaced as an install error with the exact manual command to
retry, so the worst-case is the same UX as before plus a clearer
message.

## Model Used

Claude Opus 4.7 (claude-opus-4-7), extended thinking enabled, tool use
(filesystem + bash).

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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-17 22:39:55 -07:00
Evyatar Bluzer 61eb952e94 fix(ui): show success toast when saving agent configuration (#1931)
## Problem

When you edit agent configuration (name, instructions, adapter settings,
etc) and click Save, the form just quietly go back to normal state.
There is no toast, no message, no visual confirmation that the save was
successful.

But when the save FAIL, you get a red "Save failed" toast with the error
message (line 1459). So the feedback is asymmetrical - you only hear
from the system when something go wrong, never when it go right.

This made me click Save multiple times sometimes because I was not sure
if it actually work. The button text change from "Saving..." back to
"Save" but that transition is easy to miss if you look away for a
moment.

## What I changed

Added one line in the `updateAgent` mutation `onSuccess` callback:

```tsx
pushToast({ title: "Agent saved", tone: "success" });
```

Now user see a brief green toast confirming the save. Same pattern used
in Routines page when creating a routine (line 132-136) and in many
other mutation success handlers across the app.

## How to test

1. Go to any agent detail > Config tab
2. Change any setting (name, instructions, etc)
3. Click Save
4. Should see green "Agent saved" toast appear briefly

1 file, 1 line added.
2026-06-17 20:59:02 -05:00
tvskart 5b0ec394bb fix: extra args field mangles comma-separated values during typing (#2125)
### Thinking Path

- Paperclip manages AI agent configuration via `AgentConfigForm`
- Agents can be given extra CLI args via a comma-separated input field
- `DraftInput` with `immediate` mode commits on every keystroke
- The `parseCommaArgs` → `formatArgList` round-trip resets the draft via
`useEffect`, corrupting mid-edit input
- Removing `immediate` defers parsing to blur, fixing the corruption
- This matches how all other transformed fields in the form already
behave

### What changed

Removed the `immediate` prop from the Extra args `DraftInput` so the
value is only parsed on blur instead of every keystroke.

### Note

Upon further investigation, the bug only affects **typing** into the
field character by character — the round-trip reformats on each
keystroke and corrupts the value. **Copy-pasting** works fine on master
since it's a single input event. Still worth fixing since users who type
args manually (or edit an existing value) will hit the corruption.

### Test plan

- [ ] Go to any agent's Configuration tab
- [ ] **Type** comma-separated args character by character in the "Extra
args" field (e.g. `--verbose, --foo=bar`)
- [ ] Click elsewhere to blur, then Save
- [ ] Verify via API that `adapterConfig.extraArgs` is a properly split
array (not a mangled single string)

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


### Before
trying to type in a comma -> will not appear
copy paste into element -> i guess this works out

![dunder-extra-args-before](https://github.com/user-attachments/assets/1a1b37d3-ce25-4998-972e-c98d3d382a33)

### After
typing works and copy paste works as well

![dunder-extra-args-after](https://github.com/user-attachments/assets/1aad368d-e5d8-4c37-9ab3-8f72470bdfbc)

Co-authored-by: tvskart <tvskart@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-17 20:57:05 -05:00
Dotta e59eb1080d [codex] Hide conference room experimental toggle (#8237)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Instance experimental settings are where operators opt into unstable
product surfaces before they become defaults.
> - Conference Room Chat is still experimental and is intended to come
back later, but users should not be able to enable it right now.
> - Removing the setting outright would risk losing the surrounding
implementation and stored flag behavior that future work will need.
> - This pull request hides the user-facing opt-in toggle behind a
temporary local gate while leaving Conference Room functionality and
flag plumbing intact.
> - The benefit is that operators can no longer enable the feature from
Instance Experimental Settings, while the team can restore the control
later with a small, explicit change.

## Linked Issues or Issue Description

Paperclip issue: PAP-11233 — comment out the conference-room
experimental setting _just for now_.

Feature request template:

**Subsystem affected**

ui/ — React + Vite board UI

**Problem or motivation**

Conference Room Chat is still present in the codebase and is expected to
return later, but the Instance Experimental Settings page currently
exposes a user-facing toggle that lets operators enable it. For now,
that opt-in path should be removed without deleting the underlying
feature code, stored flag type, or runtime gates.

**Proposed solution**

Hide the Conference Room Chat experimental setting card from Instance
Experimental Settings behind a temporary local gate set to `false`. Keep
the existing JSX, mutation payload, shared flag type, and downstream
Conference Room behavior intact so the setting can be restored
intentionally later.

**Alternatives considered**

- Delete the Conference Room setting and related flag plumbing: rejected
because the issue explicitly says not to remove Conference Room
functionality.
- Force-reset `enableConferenceRoomChat` at the API/service layer:
rejected because this task is about removing the ability for users to
enable it from settings, not changing existing stored instance state.

**Roadmap alignment**

This is a narrow product-polish and release-control change, not new
roadmap-level core feature work. `ROADMAP.md` was checked; it mentions
CEO Chat as future direction, but this PR only hides a temporary
experimental opt-in for the existing Conference Room surface.

**Additional context**

No GitHub issue exists for PAP-11233. This PR is opened from the
Paperclip internal task at the requester’s direction.

## What Changed

- Added a temporary `SHOW_CONFERENCE_ROOM_EXPERIMENTAL_SETTING = false`
gate around the Conference Room Chat experimental setting card.
- Left the existing Conference Room Chat setting JSX, toggle mutation,
stored flag type, and runtime gates intact.
- Updated the focused settings-page test to assert that the Conference
Room Chat setting and toggle are not rendered, even if the stored flag
is currently enabled.

## Verification

- `pnpm vitest run ui/src/pages/InstanceExperimentalSettings.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- PR checks are green for `cd2c54fb087541006eac4fd91ab5ac978d85ba5b`,
including `verify`, e2e, build, general tests, serialized server suites,
commitperclip review, Greptile, Socket, Snyk, CodeRabbit, and
security-review.

Screenshots: not included; this change removes a settings-row control
and is covered by the focused DOM test above.

## Risks

Low risk. The change only hides the user-facing opt-in card. Existing
installations with `enableConferenceRoomChat` already set are not
force-reset by this PR, and the underlying Conference Room
implementation remains in place for later re-enabling work.

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

## Model Used

OpenAI Codex coding agent based on GPT-5, with terminal, git, and GitHub
tool use. Context window details were not exposed in the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-17 13:00:32 -05:00
Devin Foley 412a04c964 fix(ui): keep desktop shell pinned when scrollIntoView walks past body (#8071)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The desktop app shell uses a fixed-height `h-dvh` flex column with
`<body>` pinned to `overflow: hidden` so the page itself doesn't scroll
— only `#main-content` does
> - On long threads, submitting a comment fires `scrollIntoView({ block:
"start" })` on the new optimistic message, which by spec walks every
ancestor scroll container and adjusts each
> - With `<body>` (and historically the two shell `<div>`s) marked
`overflow: hidden`, the browser treats them as scroll containers per the
CSS spec; `scrollIntoView` reaches them and scrolls them, visually
shifting the entire shell — sidebar and header included — off the top of
the viewport
> - `overflow: clip` is visually identical to `hidden` but is explicitly
*not* a scroll container, so converting the shell divs and body to
`clip` removes them from `scrollIntoView`'s ancestor walk
> - Chrome additionally drives `document.scrollingElement.scrollTop` via
its internal C++ smooth-scroll algorithm, which bypasses both the JS
`scrollTop` setter and the CSS `overflow` on the root element — so even
with the root viewport clipped, `<html>` still scrolls
> - This PR layers the CSS/JS overflow-clip changes with a capture-phase
`scroll` listener that snaps `documentElement.scrollTop` and
`body.scrollTop` back to 0 whenever they drift, defeating the
root-viewport scroll the browser performs natively

## Linked Issues or Issue Description

Refs #8041 (`fix(ui): don't window-scroll the desktop shell on comment
submit`) — that PR gated the JS-initiated `window.scrollBy(...)` path in
`restoreComposerViewportSnapshot`. The bug this PR fixes is a separate,
browser-internal scroll path triggered by `scrollIntoView`'s ancestor
walk, which the #8041 gate doesn't reach (no JS scroll call to gate).
This PR is complementary, not a revert.

**Bug description (no existing tracked issue):** After submitting a
comment on a long thread in the desktop app, the entire app shell —
sidebar, top nav, everything — visually shifts upward by ~300px, putting
items above "Tasks" in the sidebar off-screen. A soft refresh (Cmd+R)
doesn't fix it; only a hard URL navigation does. Verified the bug
reproduces only on threads long enough that `#main-content.scrollHeight
> clientHeight` by a wide margin.

**Repro:** Open a long-thread issue → submit a one-word comment →
observe sidebar items above the active selection fall off the top of the
viewport.

## What Changed

- `ui/src/components/Layout.tsx`:
- Static desktop-shell `<div>`s: `overflow-hidden` → `overflow-clip` on
both the outer flex column and inner flex row (lines 459, 470 in the
original numbering). Removes them from the scroll-container set.
- JS-applied body overflow: `document.body.style.overflow = isMobile ?
"visible" : "hidden"` → `... : "clip"`. Same rationale, applied to
`<body>`.
- New `useEffect` that registers a capture-phase `scroll` listener on
`window`. On every scroll event, if `documentElement.scrollTop` or
`body.scrollTop` has drifted from 0, it gets snapped back. Gated on
`!isMobile` so the mobile shell (which uses `min-h-dvh` and
intentionally scrolls window) is unaffected.

## Verification

**Reviewer steps:**

1. Open a long-thread issue in the desktop UI (anything where
`#main-content.scrollHeight > clientHeight` substantially — most active
issues qualify).
2. Submit a one-word comment.
3. Confirm the sidebar stays put — items above the active item remain
visible, top nav stays at the top of the viewport.
4. Repeat several times; confirm the shell never drifts upward.

**Tests:** Existing tests for `issue-chat-scroll.ts` and
`IssueChatThread.tsx` still pass (59/59 in
`ui/src/lib/issue-chat-scroll.test.ts` +
`ui/src/components/IssueChatThread.test.tsx`).

**Bisect proof:** During development I confirmed by selectively
reverting the capture-phase scroll listener that the bug returns
immediately when only the listener is removed (with the two
`overflow-clip` changes still in place) — proving the listener is the
decisive fix for the browser-internal root-viewport scroll path. The
probe trace showed `documentElement.scrollTop` animating from 0 →
307.5px over ~400ms during the smooth `scrollIntoView` even with `html {
overflow: clip }` applied in computed style.

## Risks

Low.

- The two `overflow-hidden` → `overflow-clip` swaps are visually
identical and have well-defined browser support (Chrome 90+, Firefox
81+, Safari 16+). Paperclip's desktop targets are well within those
ranges.
- The capture-phase scroll listener fires only when
`documentElement.scrollTop !== 0` or `body.scrollTop !== 0`. On a
correctly-behaving page neither should ever be non-zero on desktop, so
the listener is effectively a no-op for everything except the bug it's
reverting. It's gated behind `!isMobile`.
- Mobile uses `min-h-dvh` (no overflow set) and intentionally scrolls
window for the standard mobile chrome behavior; the listener is gated
off there so mobile UX is unaffected.

## Model Used

Claude Opus 4.7 (`claude-opus-4-7`), 200k context, extended thinking
enabled. Tool use: file edits, bash for git/test execution. Diagnosis
was driven by an instrumented in-browser probe (built and HMR'd into
`Layout.tsx` during development, removed before this PR) that traced
every `scrollBy`/`scrollTo`/`scrollIntoView` call and the
`Element.prototype.scrollTop` setter; the decisive trace identified the
browser-internal scroll path as the unguarded root cause.

## 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 run tests locally and they pass
- [ ] I have added or updated tests where applicable — no new tests; the
bug is a browser-internal scroll behavior that's not exercisable in
jsdom (which doesn't implement the smooth-scroll animation that drives
the bug). Existing snapshot/restore tests in `issue-chat-scroll.test.ts`
cover the JS-initiated paths.
- [ ] If this change affects the UI, I have included before/after
screenshots — see the description text above; the bug manifests as the
entire shell translating up by ~300px on long-thread comment submit
- [x] I have updated relevant documentation to reflect my changes — N/A,
behavior change is non-user-facing CSS/event-handling
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green — will confirm on this PR
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups —
will iterate
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-12 17:31:16 -07:00
Jannes Stubbemann cd1b4f275d feat(ui): default to system prefers-color-scheme for first-time visitors (supersedes part of #3732) (#5873)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - The UI ships a dark/light theme toggle and persists the user's
explicit choice in `localStorage`
> - For first-time visitors with no stored choice, the pre-React
bootstrap script in `ui/index.html` hardcoded `"dark"` and never
consulted the OS preference
> - As a result, users on a light-themed OS were forced into dark mode
until they clicked the toggle once — a first-impression friction with no
compensating benefit
> - This pull request makes the bootstrap respect `prefers-color-scheme`
for first-time visitors and adds a `matchMedia` listener so the in-app
theme auto-follows OS changes until the user makes an explicit choice
> - The benefit is a friction-free first visit that matches every other
modern web app, with zero impact on users who have already chosen a
theme

## Linked Issues or Issue Description

No existing issue covers this directly — problem described in-PR (bug
shape):

- For first-time visitors with no stored theme choice, the pre-React
bootstrap script in `ui/index.html` hardcoded `"dark"` and never
consulted the OS `prefers-color-scheme` preference.
- Users on a light-themed OS were forced into dark mode until they
clicked the toggle once — first-impression friction with no compensating
benefit.
- This PR supersedes part of PR #3732 (the `prefers-color-scheme`
bootstrap slice); no standalone issue was filed for it.

## What Changed

- **`ui/index.html`** — the pre-React bootstrap script now computes a
`prefersDark` fallback via `matchMedia("(prefers-color-scheme: dark)")`,
guarded by a `typeof window.matchMedia === "function"` feature-detection
check, in place of the hardcoded `"dark"` default. A stored
`localStorage` value still takes precedence.
- **`ui/src/context/ThemeContext.tsx`** — tracks an `hasExplicitChoice`
flag. While `false`, a `MediaQueryList` `change` listener keeps the
in-app theme in sync with OS theme switches. Once `setTheme` /
`toggleTheme` runs, the choice is persisted and the listener is removed.

## Verification

- `pnpm --filter @paperclipai/ui run typecheck` — clean.
- `npx vitest run src/components/SidebarAccountMenu.test.tsx` — 1/1 pass
(the one test that exercises `ThemeContext`).
- Manual: launched the Vite UI dev server with a mocked
`/api/auth/get-session` 401, navigated to `/auth` with no
`localStorage.theme` set, and toggled the browser's emulated
`prefers-color-scheme` between `dark` and `light`. Bootstrap renders the
matching theme without a flash. Screenshots committed.

**Screenshots — first-visit (no stored theme) with system pref:**

| System dark | System light |
| --- | --- |
<img width="1280" height="800" alt="first-visit-prefers-dark"
src="https://github.com/user-attachments/assets/c30274d5-a2e0-4ed8-b7ef-b96b8caac5ca"
/>
<img width="1280" height="800" alt="first-visit-prefers-light"
src="https://github.com/user-attachments/assets/ebd8e9cf-0be1-4b36-a6f8-eb38b00dff5c"
/>


(Without this PR, both screenshots would have rendered dark.)

## Risks

Low. Purely additive:

- A stored `localStorage` value still takes precedence over the OS
preference, so users who have already picked a theme are unaffected.
- SSR-safe: both new code paths are gated on `typeof window !==
"undefined"` (the inline script only runs in the browser, and the React
`matchMedia` listener is attached inside `useEffect`).
- No new dependencies, no API surface change.

## Model Used

Claude Opus 4.7 (1M context), extended thinking mode.

## Checklist

- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] Thinking path traces from project context to this change
- [x] Model used specified
- [x] Checked ROADMAP.md — not in conflict with planned core work
- [x] Tests run locally and pass
- [x] No new test cases — the change is observable only via real
`matchMedia` events, which jsdom does not faithfully implement; manual
verification above
- [x] UI change — before/after screenshots in
`docs/pr-screenshots/pr-5873/`
- [x] No documentation updates required
- [x] Documented risks above
- [x] Will address all Greptile and reviewer comments before merge

Supersedes part of #3732 (the `prefers-color-scheme` bootstrap slice).

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Devin Foley <devin@paperclip.ing>
2026-06-12 14:03:54 -07:00
Jannes Stubbemann 8ddd735a7a feat(ui): theme toggle on unauthenticated auth page (supersedes part of #3732) (#5874)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - Operators sign in via the `/auth` page, which renders before any
session exists
> - The signed-in app has a theme toggle inside `SidebarAccountMenu`,
but the signed-out `/auth` page has none — first-time visitors are stuck
in whichever theme was hardcoded at boot
> - Master's existing toggle was inline inside `SidebarAccountMenu.tsx`
as a `MenuAction` row, not exported as a reusable widget; round-1 of
this PR added a standalone `ThemeToggle` but punted on unifying the two
surfaces
> - This pull request makes `ThemeToggle` the canonical theme widget
(one source of truth for label, icon, and toggle behaviour), used both
as a compact icon button on `/auth` and as a full-width menu row in
`SidebarAccountMenu`
> - The benefit is a working pre-auth theme switch and zero risk of the
two call sites drifting out of sync as the theme model evolves

## Linked Issues or Issue Description

No existing issue covers this directly — problem described in-PR
(feature-gap shape):

- The signed-in app has a theme toggle inside `SidebarAccountMenu`, but
the signed-out `/auth` page has none — first-time visitors are stuck in
whichever theme was hardcoded at boot.
- The existing toggle lived inline in `SidebarAccountMenu.tsx` as a
`MenuAction` row, not exported as a reusable widget, so the two surfaces
could drift apart as the theme model evolves.
- This PR supersedes part of PR #3732 (the auth-page toggle slice); no
standalone issue was filed for it.

Duplicate-PR search: related open theme PRs #2769 and #4666 add in-app
three-state system-theme toggles — different surface from this PR
(unauthenticated auth page); sibling PR in this series: #5873.

## What Changed

- **`ui/src/components/ThemeToggle.tsx`** — accepts `variant: "icon" |
"menu-action"` (default `"icon"`) and an `onAfterToggle` callback. Both
variants share `useTheme` and the same label/icon derivation. The
`menu-action` variant matches the existing `MenuAction` row styling.
- **`ui/src/components/SidebarAccountMenu.tsx`** — drops its inline
`useTheme()` + `MenuAction`-for-the-theme-row in favor of `<ThemeToggle
variant="menu-action" onAfterToggle={() => setOpen(false)} />`. Sun/Moon
icon imports and theme state move with it.
- **`ui/src/pages/Auth.tsx`** — unchanged from round 0; renders
`<ThemeToggle />` at top-right of the `/auth` page (already using the
default `icon` variant).
- **`ui/src/components/ThemeToggle.test.tsx`** (new) — covers both
variants, the `onAfterToggle` callback, and the label/icon flip across
themes.
- **`ui/src/components/SidebarAccountMenu.test.tsx`** — unchanged; its
`ThemeContext` mock still works because `ThemeToggle` uses the same
hook.

## Verification

- `pnpm --filter @paperclipai/ui run typecheck` — clean.
- `npx vitest run src/components/ThemeToggle.test.tsx
src/components/SidebarAccountMenu.test.tsx` — 5 passed (4 new + 1
existing).
- Manual: launched `pnpm dev` for the UI, mocked `/api/auth/get-session`
401, navigated to `/auth` — toggle is visible top-right, click flips
light/dark. Screenshots committed.

## Risks

Low. The change is structural — both call sites render the same widget
that already worked on each surface independently.
`SidebarAccountMenu`'s popover behaviour is preserved via
`onAfterToggle`, and `ThemeContext` is untouched.

## Model Used

Claude Opus 4.7 (1M context), extended thinking mode.

## Checklist

- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] Thinking path traces from project context to this change
- [x] Model used specified
- [x] Checked ROADMAP.md — not in conflict with planned core work
- [x] Tests run locally and pass
- [x] Added tests for the new ThemeToggle component (both variants)
- [x] UI change — before/after screenshots in
`docs/pr-screenshots/pr-5874/`
- [x] No documentation updates required (purely internal refactor + new
component)
- [x] Documented risks above
- [x] Will address all Greptile and reviewer comments before merge

Supersedes part of #3732.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Devin Foley <devin@paperclip.ing>
2026-06-12 12:59:14 -07:00
Doyeon Baek 4965dc834a fix(ui): don't window-scroll the desktop shell on comment submit (#7972) (#8041)
Fixes #7972.

## Thinking Path
- The reporter pinned the post-submit composer-viewport restore in
`ui/src/lib/issue-chat-scroll.ts`, which falls back to
`window.scrollBy(...)` when `#main-content` is not independently
scrollable — exactly the short-thread repro case.
- In the desktop shell the body is `overflow: hidden` (set in
`Layout.tsx`) inside a fixed-height `h-dvh` flex column, so a window
scroll never moves content: it translates the entire shell (sidebar
included) off-screen, and a plain reload does not restore it. On mobile
(`min-h-dvh`, `body { overflow: visible }`) and the auth-free perf
fixture the page genuinely scrolls, so the window IS the correct target
there.
- A prior attempt forced `resolveIssueChatScrollTarget` to always use
`#main-content`; that path is a no-op on a non-overflowing container and
is sensitive to a stale `ui/dist`/`.vite` cache, which likely masked the
result. Gating the window-scroll itself is the precise root-cause fix
and covers both restore call sites (`queueViewportRestore` and the
`[messages]` layout effect) since both route through one function.

## What Changed
- Added `isWindowScrollable(doc, win)` to `issue-chat-scroll.ts`: the
window is a valid scroll target only when the document body is not
clipped. It checks both the `overflow` shorthand and the `overflow-y`
longhand (some engines, incl. jsdom, do not derive the longhand from the
shorthand in computed style).
- Gated the `window.scrollBy` fallback in
`restoreComposerViewportSnapshot` behind `isWindowScrollable`; on the
desktop shell there is nothing to restore, so the scroll position is
left untouched.
- Added unit tests for the desktop-shell (no window scroll) case and for
`isWindowScrollable`.

## Verification
- `ui $ vitest run src/lib/issue-chat-scroll.test.ts` → 6 passed (2 new
+ existing window/element restore tests still green).
- `ui $ vitest run src/components/IssueChatThread.test.tsx` → 55 passed
(consumer regression).

## Risks
- Low. Behaviour only changes when the resolved target is `window` AND
the document body is clipped — i.e. the desktop shell, where the
previous behaviour was the bug. Mobile and the perf fixture keep window
scrolling unchanged (body not clipped → `isWindowScrollable` true).

## Model Used
claude-opus-4-8

---

- [x] I searched the GitHub PRs for similar or duplicate PRs and
confirmed this is not a duplicate.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 10:05:57 -07:00
Ismaël O. 3b7c42be86 fix(openclaw-gateway): complete and stabilize OpenClaw Gateway integration (#2322)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The `openclaw_gateway` adapter is how operators wire Paperclip
agents to an OpenClaw gateway over WebSocket
> - The adapter UI previously only exposed a handful of config fields in
edit mode; many timeout / auth / session-routing knobs were unreachable
through the form
> - The serializer also forgot to inject the configured `authToken` into
the `x-openclaw-token` header, and the server-side execute path lacked
retries on transient gateway errors and an `OPENCLAW_TOKEN` env fallback
> - This pull request exposes the full set of config fields in both
create and edit modes, fixes the serializer, hardens the server-side
execute path, and pins the existing default request timeouts (120s /
120000ms) — see the dedicated commit and the new unit tests
> - The benefit is operators can configure and reconfigure an
`openclaw_gateway` agent end-to-end through the UI, with no silent
change to the defaults documented in the adapter README and
`doc/ONBOARDING_AND_TEST_PLAN.md`

## Linked Issues or Issue Description

Closes #414
Closes #1901
Closes #2309

## What Changed

- **UI**: Removed the `!isCreate` guard so all `openclaw_gateway` config
fields are visible in both create and edit modes (`authToken`,
`agentId`, `sessionKeyStrategy`, `sessionKey`, `timeoutSec`,
`waitTimeoutMs`, `disableDeviceAuth`, `autoPairOnFirstConnect`, `role`,
`scopes`, `paperclipApiUrl`, `headersJson`, `payloadTemplate`,
`runtimeServices`).
- **Serialization**
(`packages/adapters/openclaw-gateway/src/ui/build-config.ts`): inject
`authToken` into headers as `x-openclaw-token`; apply safe defaults on
create (`timeoutSec=120`, `waitTimeoutMs=120000`,
`sessionKeyStrategy="issue"`, `role="operator"`,
`scopes=["operator.admin"]`).
- **Backend**
(`packages/adapters/openclaw-gateway/src/server/execute.ts`): add
`OPENCLAW_TOKEN` env-var fallback for `authToken`, retry logic (max 2
retries with backoff for transient gateway errors), session-key prefix
`agent:{agentId}:{sessionId}` when `agentId` is configured.
- **Defaults restoration** (dedicated commit): an earlier revision of
this PR lowered the default request timeouts to `60` / `30000`. The
current branch restores the historical `timeoutSec=120` /
`waitTimeoutMs=120000` defaults that match the values documented in
`packages/adapters/openclaw-gateway/src/index.ts`,
`src/server/execute.ts` on master, and the worked example in
`doc/ONBOARDING_AND_TEST_PLAN.md`.
- **Tests** (new):
`packages/adapters/openclaw-gateway/src/ui/build-config.test.ts` pins
the documented timeout and identity defaults so the silent-halve
regression cannot recur.

## Verification

- `pnpm --filter @paperclipai/adapter-openclaw-gateway typecheck`
- `pnpm typecheck` (root)
- Manual: create a new `openclaw_gateway` agent — all fields visible,
defaults populate as documented.
- Manual: edit an existing `openclaw_gateway` agent — every field
round-trips correctly and saves.
- Manual: unset `authToken` in the form and set `OPENCLAW_TOKEN` env var
— adapter picks up the env-var fallback.
- Manual: simulate a transient gateway error — execute retries up to 2
times with backoff before failing.

## Risks

- Low risk. Surface area is one adapter, behind explicit operator
configuration. The defaults change in this PR is a restoration of values
that already exist on master and in the adapter docs, so no production
agent sees a behavioral shift relative to the prior release. Field
exposure in edit mode is purely additive — existing values are preserved
on save.

## Model Used

- Provider/model: Claude (Anthropic) — `claude-opus-4-7`
- Mode: standard tool use, no extended thinking
- Capability notes: code execution + repository file edits via Claude
Code

## Cross-references and status (maintainer)

Closes #414
Closes #1901
Closes #2309

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

---------

Co-authored-by: Paperclip Bot <bot@paperclip.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Devin Foley <devin@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-11 23:31:39 -07:00
scotttong 6f9801a46b feat(ui): NUX rework behind enableConferenceRoomChat experimental flag — capsule onboarding, conference-room chat, unified composer (#8000)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The first-run experience (onboarding wizard) and the chat surfaces
(conference-room/board chat, task threads, composers) are the product's
front door — they decide whether a new operator understands "hire
agents, give them work, review results" in the first five minutes
> - Today those surfaces feel ticket-y and form-like: the wizard is a
static multi-step form that ends in an anticlimactic "Launch" screen,
the task composer and board chat behave differently from each other, and
agent-feed issue quicklooks misbehave (multiple flyouts open at once,
cards jump on hover)
> - We wanted to iterate toward a conversational, team-centric NUX — but
without risking the workflows of everyone already running Paperclip
> - This PR reworks the NUX behind a new default-OFF
`enableConferenceRoomChat` experimental flag: a capsule-motif onboarding
wizard that builds your team as you answer, a conference-room chat
surface, one shared ChatComposer across surfaces, brand-accurate status
chips, and feed-quicklook fixes — with the pre-existing UI
fork-and-frozen as `*Classic` components that flag-OFF users keep
> - The benefit is a complete, testable modern NUX that anyone can opt
into from Settings → Experimental, with zero default behavior change and
a clean path to either graduate or drop the experiment

## Linked Issues or Issue Description

No pre-existing GitHub issue — feature description per
`feature_request.yml`:

- **Problem / motivation:** Paperclip's onboarding wizard and chat
surfaces grew up as separate ticket-centric forms. New users get a
form-filling experience rather than the feeling of standing up a team;
the board chat and task threads use different composers with different
affordances; the agent feed's issue quicklook can stack multiple
popovers and shifts cards on hover.
- **Proposed solution:** A coherent NUX experiment behind one
experimental flag (`enableConferenceRoomChat`, Settings → Experimental,
default OFF): capsule onboarding wizard with an evolving team capsule,
conference-room chat, unified `ChatComposer`, team-centric copy, brand
status chips, quicklook single-flight fix. Flag-OFF users get the exact
pre-experiment UI via frozen `*Classic` forks, verified by an on/off
parity test matrix.
- **Alternatives considered:** (a) incremental unflagged restyling —
rejected: the changes interlock across surfaces and would drip risk into
every release; (b) a separate app shell / route for the new NUX —
rejected: too much divergence, the flag + classic-fork pattern keeps the
diff reviewable and reversible.
- **Roadmap alignment:** `ROADMAP.md` lists **CEO Chat** ("a
lighter-weight way to talk to leadership agents... should still resolve
to real work objects"). This experiment is groundwork in that direction
(conference-room chat resolves to issues/tasks via the same composer
used in task threads) and does not change the core task-and-comments
model.

Related PRs found in the dedup search (same area, none duplicate this
work — they target the classic wizard, which this PR intentionally
leaves intact and mergeable):

- #5385 — Coach-driven onboarding: conversational entry +
agent-companies package import
- #5378 — Onboarding wizard: reusable adapter picker + probe card
- #6636 — ui(onboarding): friendly error surface + retry for the wizard
- #7005 — fix(onboarding): explicitly await first-task wake
- #2616 — fix: restore workspace directory config in onboarding wizard

## What Changed

- **Experimental flag plumbing** — `enableConferenceRoomChat` in shared
types/validators, server instance-settings service + API, Settings →
Experimental card with explicit enable/disable copy
- **Onboarding wizard** — classic wizard forked and frozen
(`OnboardingWizardClassic`); flag-ON variant is a 5-step capsule wizard
with a persistent evolving `AgentCapsule` (gradient/glow motif),
team-centric reframed copy, and a typing-dots intro (hardened with
fake-timer tests)
- **Conference-room chat** — flag-ON board-chat surface with agent
bubble name/icon headers and copy/vote/timestamp action rows
(`AgentBubbleActionRow`)
- **Unified composer** — shared `ChatComposer` adopted across surfaces;
translucent surface + scroll-mask removal; "Agent mode"/"Plan mode"
relabels; no-assignee confirmation `AlertDialog` (new
`ui/alert-dialog.tsx` primitive); `@task` reference picker +
linkification in mentions
- **Agent feed** — single-flight issue-quicklook store (one popover at a
time), flyouts open to the left, removed hover translate-y jitter
- **Status chips** — brand-accurate task status chips behind the flag
(light/dark, 1px borders per paperclip.ing/brand)
- **Tests** — flag on/off parity matrix across IssueDetail,
NewIssueDialog, Sidebar, wizard, gate components; component tests for
all new pieces
- **Merge with `master`** — one conflict in
`ui/src/components/IssueChatThread.tsx`, resolved by keeping master's
new `AssigneeChip`/`HandoffWakeRow`/`RunStatusBadge` components inside
the flag-gated metadata-row chrome (details in commit `21a5642a`);
post-merge fixes: vitest 4 mock typing in `MarkdownEditor.test.tsx`,
flag hook made safe for provider-less mounts (master's new isolated
component tests)
- **Branch hygiene** — internal design wireframes/mockups stripped
before the PR (they live in the Paperclip issue threads)
- No user-facing documentation changes required: the flag is
intentionally experimental and self-described in the Settings card; no
existing docs reference the affected surfaces

## Verification

- `pnpm run typecheck` — green across the workspace (ui, server, shared,
plugins)
- Full UI suite (`vitest run` in `ui/`, clean worktree at this HEAD):
**1593/1595 passing, 223/224 files** — the 2 remaining failures are in
`src/components/artifacts/ArtifactCard.test.tsx` and **fail identically
on pristine `origin/master`** (pre-existing upstream, unrelated to this
branch)
- Full server suite (`vitest run` in `server/`, same clean worktree):
results in PR checks; flag plumbing covered by instance-settings tests
- Targeted post-merge resolution check: `IssueChatThread`,
`IssueChatThreadSystemNotice`, `IssueDetail`, `Sidebar`,
`ConferenceRoomChatGate`, `OnboardingWizardVariant`, `NewIssueDialog`,
`InstanceExperimentalSettings`, `MarkdownEditor` — 172/172 passing
- Manual walkthrough: flag OFF (default) → onboarding wizard, task
thread, board chat, composer all render the classic UI; flag ON via
Settings → Experimental → capsule wizard, conference-room chat, unified
composer, status chips active
- Screenshots: see below

**Flag on/off screenshots** (committed on this branch under
`screenshots/PR-8000-*`):

| Surface | Flag OFF (classic, default) | Flag ON (experimental) |
| --- | --- | --- |
| Settings → Experimental | ![settings
off](https://raw.githubusercontent.com/paperclipai/paperclip/9b4f02708383031d3124b68ca3ed9ab437ea3501/screenshots/PR-8000-settings-experimental-flag-off.png)
| ![settings
on](https://raw.githubusercontent.com/paperclipai/paperclip/9b4f02708383031d3124b68ca3ed9ab437ea3501/screenshots/PR-8000-settings-experimental-flag-on.png)
|
| Task thread | ![thread
off](https://raw.githubusercontent.com/paperclipai/paperclip/9b4f02708383031d3124b68ca3ed9ab437ea3501/screenshots/PR-8000-task-thread-flag-off.png)
| ![thread
on](https://raw.githubusercontent.com/paperclipai/paperclip/9b4f02708383031d3124b68ca3ed9ab437ea3501/screenshots/PR-8000-task-thread-flag-on.png)
|
| Home / nav | ![home
off](https://raw.githubusercontent.com/paperclipai/paperclip/9b4f02708383031d3124b68ca3ed9ab437ea3501/screenshots/PR-8000-home-flag-off.png)
| ![home
on](https://raw.githubusercontent.com/paperclipai/paperclip/9b4f02708383031d3124b68ca3ed9ab437ea3501/screenshots/PR-8000-home-flag-on.png)
|
| Conference Room (flag-ON only surface) | — | ![conference
room](https://raw.githubusercontent.com/paperclipai/paperclip/9b4f02708383031d3124b68ca3ed9ab437ea3501/screenshots/PR-8000-conference-room-flag-on.png)
|

Capsule onboarding wizard walkthrough screenshots (flag ON) are attached
to the Paperclip design/implementation threads; the wizard requires a
fresh instance so it is captured via the e2e harness
(`tests/e2e/nux-phase4-screenshots.spec.ts`).


## Risks

- **Large surface, but gated:** all new behavior sits behind
`enableConferenceRoomChat`, default OFF; flag-OFF rendering is locked by
frozen `*Classic` forks plus an on/off parity test suite
- **Classic forks are frozen at the fork point (`e3aada1d`):** master
features added to the live thread component after that point (assignee
handoff chips, run status badge, composer mention coach) render in the
flag-ON path; the flag-OFF task thread keeps the fork-point behavior
until the experiment graduates (forks deleted) or is dropped (forks
restored as canonical). Called out for reviewer attention.
- **Merge-conflict resolution in `IssueChatThread.tsx`** (commit
`21a5642a`) deserves reviewer eyes: master's new handoff/run-status
components were kept; the base toast-style no-assignee flow remains
replaced by the AlertDialog flow introduced on this branch
- Schema/server changes are additive (one optional boolean instance
setting); no migrations of existing data

## Model Used

- Claude (Anthropic) via Claude Code running in the Paperclip agent
harness (agent: ClaudeCoder)
- Branch implemented across multiple agent sessions on Claude Opus-class
models with extended thinking + tool use (file edits, shell, Playwright
screenshots); merge/PR session model ID as reported by the harness:
`claude-fable-5` (Claude Code CLI)
- All code was agent-authored and board-reviewed through Paperclip issue
threads (plans, wireframes, confirmations) before merging

## 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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes (none
required — experimental flag, self-documenting Settings card; noted
above)
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green (run 3 on `8af3041a`: all 16
gates SUCCESS, incl. e2e and all 4 serialized-suite shards)
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(re-review verdict: Confidence 5/5, “Safe to merge”; all 4 round-1
findings fixed + confirmed resolved; both summary notes addressed in
`8af3041a`)
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 16:32:55 -05:00
Dotta 1413729a06 Build the Skills Store (#7990)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents increasingly depend on reusable skills, so the control plane
needs a first-class way to browse, inspect, install, version, and attach
those skills.
> - The old skills surface was mostly operational plumbing; it did not
give operators a store-like discovery flow, canonical detail URLs, rich
source/version context, or creation paths.
> - The backend also needed stronger contracts around company skill
metadata, versions, install counts, runtime materialization, and adapter
skill preferences.
> - This pull request builds the Skills Store foundation across DB,
shared contracts, server routes/services, UI, and Storybook.
> - The benefit is a more inspectable, operator-friendly skill workflow
that still preserves company-scoped control-plane boundaries and agent
runtime behavior.

## Linked Issues or Issue Description

No GitHub issue exists for this Paperclip work item. Paperclip task
refs: PAP-10846 and PAP-10921.

Feature request:
Paperclip operators need a single Skills Store experience where company
skills can be discovered, inspected, created, versioned, installed, and
attached to agents without relying on scattered operational screens or
implicit runtime state.

Related PR search:
- Searched GitHub for `Skills Store`, `company skills`, and `skill
detail`.
- Found several open skills-related PRs such as #7809 and #4409, but no
duplicate PR for this end-to-end Skills Store branch.

## What Changed

- Added the Skills Store backend foundation: company skill schema
fields, migrations, shared types/validators, and expanded server skill
routes/services.
- Added skill discovery, category navigation, canonical skill detail
routes, tabs, source attribution, version snapshots/diffs, install count
backfill, and creation flows.
- Updated agent skill preference handling so version selections survive
runtime mention injection and runtime skill materialization honors
pinned versions.
- Preserved unversioned skill assignments as live/current selections
instead of silently pinning them to the current version at assignment
time.
- Added focused regression coverage for company skill routes/services,
route helpers, UI behavior, skill version diffs, and runtime skill
version pins.
- Added Storybook coverage for Skills Store discovery/detail states and
updated the main layout navigation.
- Addressed Greptile findings around version creation races,
soft-deleted comments, fork metadata scoping, GitHub skill directory
fallback, runtime snapshot materialization, shared runtime
skill-selection helpers, and version-assignment semantics.

## Verification

- `pnpm exec vitest run
server/src/__tests__/heartbeat-project-env.test.ts
server/src/__tests__/heartbeat-runtime-skills.test.ts`
- `pnpm exec vitest run
packages/shared/src/validators/company-skill.test.ts`
- `pnpm exec vitest run server/src/__tests__/company-portability.test.ts
server/src/__tests__/company-skills-service.test.ts`
- `pnpm exec vitest run
cli/src/__tests__/company-import-export-e2e.test.ts`
- `pnpm exec vitest run
server/src/__tests__/agent-skills-routes.test.ts`
- `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts`
- `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/company-skills-routes.test.ts
server/src/__tests__/heartbeat-runtime-skills.test.ts`
- `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts`
- `pnpm exec vitest run ui/src/components/IssueProperties.test.tsx -t
"edits existing custom assignee model options from the properties pane"`
- `pnpm --filter @paperclipai/server typecheck`
- GitHub checks are green on `0823957a2`: Build, Canary Dry Run, General
tests, Typecheck + Release Registry, serialized server suites, e2e,
policy/review, Socket, Snyk, and aggregate `verify`.
- Greptile Review succeeded on `0823957a2` with `40 files reviewed, 0
comments added`; GitHub unresolved review threads: 0.

Not run in this heartbeat:
- Browser screenshot capture for the UI changes. This PR intentionally
omits screenshots per the Paperclip task direction not to add design
screenshots/images.

## Risks

- Broad feature branch touching DB, shared contracts, server, and UI;
reviewers should still scan merge conflicts carefully if `master` moves
again before landing.
- Skill version/runtime behavior is sensitive: pinned skill versions
must stay pinned while default selections should continue following the
current version.
- UI polish should get normal reviewer/browser attention before merge
because this PR includes a large Skills Store surface and screenshots
were intentionally omitted.

> 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-based coding agent with tool use and local command
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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots (intentionally omitted per PAP-10921 direction)
- [ ] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 14:02:09 -05:00
Jannes Stubbemann 4ad94d0bde feat(server): kubernetes execution integration for sandbox-provider plugins (stage 2/3) (#7938)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The execution subsystem runs those agents in environments (local,
ssh, sandbox), and sandbox-provider plugins let an environment
materialize per-run sandboxes
> - Stage 1 (#5790) contributed a first-party Kubernetes
sandbox-provider plugin, but the server core has no way to adopt it
operationally: no per-run adapter selection, no way to force an instance
onto sandboxed execution, no declarative adapter/model configuration,
and the plugin must be installed by hand
> - Without this, a multi-tenant or security-conscious deployment cannot
guarantee that agent runs never execute on the host, and a single
environment cannot serve agents with different harnesses
> - This pull request adds the server + SDK integration: per-run
adapterType on the lease protocol, an env-gated forced-Kubernetes
execution policy with provisioning and a per-run allowlist guard, a
declarative adapter registry and model list, in-cluster env passthrough
for sandbox plugin workers, fail-safe auto-install of the bundled
plugin, and the matching UI affordance
> - The benefit is that sandbox-provider plugins become fully usable for
Kubernetes execution: operators configure everything via environment
variables and GitOps, while self-hosters who set none of the variables
see exactly the behavior they have today

## Linked Issues or Issue Description

Refs #5790 (stage 1 of 3: the Kubernetes sandbox-provider plugin
package).

No existing issue. Feature description: the server core lacks the
integration seams to operate a sandbox-provider plugin as the mandatory
execution path of an instance. This PR is stage 2 of 3 of the staged
Kubernetes contribution; stage 3 will contribute the agent runtime
images and their build pipeline.

## What Changed

One line per piece:

- `packages/plugins/sdk/protocol.ts`: optional `adapterType` on
`PluginEnvironmentAcquireLeaseParams` so a provider can select the
runtime image per run; existing providers simply ignore it
- `server/services/environment-runtime.ts` +
`environment-run-orchestrator.ts`: thread the agent's adapter type into
both lease-acquiring drivers, including the heartbeat path (the two call
sites have historically drifted, hence the pinned test)
- `server/services/environments.ts`: `ensureKubernetesEnvironment` /
`findKubernetesEnvironment`, an idempotent managed Kubernetes
environment per company, identified by a metadata marker and refreshed
(not recreated) on config change; `timeoutMs` rides on the config for
slow cold-start leases
- `server/services/execution-allowlist.ts`: pure (driver, provider,
policy) -> allow/deny guard; `executionMode=kubernetes` only allows the
kubernetes sandbox provider
- `server/services/execution-policy-bootstrap.ts` + startup hook in
`server/index.ts`: parse `PAPERCLIP_EXECUTION_MODE` / `PAPERCLIP_K8S_*`,
persist `executionMode` into instance general settings, and provision
the managed environment for every company; fails loud on
misconfiguration
- `server/services/heartbeat.ts`: when the policy forces Kubernetes, pin
run selection to the managed environment (also overriding any persisted
workspace environment id), refuse to fall back to local, and re-check
the actually acquired environment against the allowlist as defense in
depth
- `server/services/adapter-registry-bootstrap.ts` + shared
`AdapterRegistryEntry` type/validator: declarative `PAPERCLIP_ADAPTERS`
registry (inline JSON or file) that reconciles adapter availability at
startup and rides on the Kubernetes environment config
- `server/services/adapter-models-env.ts` + `adapters/registry.ts`:
`PAPERCLIP_ADAPTER_MODELS` lets an operator declare picker model lists
the server cannot CLI-discover
- `server/services/plugin-loader.ts`: pass
`KUBERNETES_SERVICE_HOST/PORT(_HTTPS)` through to plugin workers that
register environment drivers, so in-cluster API clients can be
constructed; all other host env stays stripped
- `server/app.ts`: fail-safe auto-install of the bundled kubernetes
plugin at boot; no-ops when the bundle is absent and never blocks
startup on error
- `packages/shared` types/validators: `InstanceExecutionMode` on general
settings (optional, strict schema)
- `ui/lib/forced-kubernetes-environment.ts` + `AgentConfigForm`: when
the policy is active, show a read-only Kubernetes environment instead of
the environment picker and default new agents onto the managed
environment
- Tests for every new module plus the adapterType pin in
`heartbeat-plugin-environment` and the managed-environment lifecycle in
`environment-service`

Everything is gated: with `PAPERCLIP_EXECUTION_MODE`,
`PAPERCLIP_ADAPTERS`, and `PAPERCLIP_ADAPTER_MODELS` unset (and no
bundled plugin present), every code path reduces to current behavior.
The per-run `adapterType` is an optional SDK parameter that existing
providers ignore.

## Verification

- `cd server && npx tsc --noEmit`: clean (0 errors); `ui` typecheck also
clean
- Targeted suites all green (11 files, 90 tests): `npx vitest run
server/src/__tests__/heartbeat-plugin-environment.test.ts
server/src/__tests__/environment-service.test.ts
server/src/__tests__/environment-runtime.test.ts
server/src/__tests__/environment-run-orchestrator.test.ts
server/src/__tests__/plugin-database.test.ts
server/src/services/execution-policy-bootstrap.test.ts
server/src/services/execution-allowlist.test.ts
server/src/services/adapter-registry-bootstrap.test.ts
server/src/services/adapter-registry-bootstrap.reconcile.test.ts
server/src/services/adapter-models-env.test.ts
packages/shared/src/validators/adapter-registry.test.ts`
- `npx vitest run ui/src/components/AgentConfigForm.test.ts`: green (6
tests)
- Full `npx vitest run server/src/__tests__`: 2323 passed, 1 skipped;
the only failures (heartbeat-process-recovery pid-retry,
workspace-runtime symbolic-ref/git tests) reproduce identically on
pristine `master` in the same environment, so they are
machine-environment issues unrelated to this change;
`server-startup-feedback-export` needed its `services/index.js` mock
extended with the new export and is green
- This integration has been running in production on a hosted
multi-tenant deployment, where it executes agent runs across five
different harnesses through the stage 1 plugin

## Risks

- Low for existing deployments: every behavior is env-gated and the
defaults preserve current semantics; the auto-install block is wrapped
fail-safe and skips silently when the plugin bundle is absent
- `executionMode` is a new optional field on a strict zod schema; absent
input normalizes exactly as before
- The forced policy intentionally fails runs loudly (rather than falling
back to local) when no managed Kubernetes environment exists; this only
affects instances that explicitly set
`PAPERCLIP_EXECUTION_MODE=kubernetes`

## Model Used

Claude Opus 4.8 (claude-opus-4-8, 1M context), extended thinking,
agentic tool use via Claude Code.

## UI screenshots

The UI change is a new read-only "Execution" section in
`AgentConfigForm`, shown only when the instance execution policy forces
Kubernetes (`executionMode=kubernetes`); there is no "before" state for
it (the section did not exist, and instances without the forced policy
render the existing picker unchanged). Captured from the new Storybook
stories added in this PR (`Product/Agent Management`):

Managed Kubernetes environment present (read-only display, no local/SSH
picker):

![AgentConfigForm with forced Kubernetes
execution](https://raw.githubusercontent.com/paperclipinc/paperclip/296ad06e8/screenshots/PR-7938-agent-config-forced-kubernetes.png)

No managed environment available yet (warning notice, no silent local
fallback):

![AgentConfigForm forced Kubernetes, missing environment
warning](https://raw.githubusercontent.com/paperclipinc/paperclip/296ad06e8/screenshots/PR-7938-agent-config-forced-kubernetes-missing-env.png)

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

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 21:09:02 -07:00
Devin Foley c139d6c025 fix(codex-local): omit default model so codex CLI picks per auth mode (#7971)
## Thinking Path

> - Paperclip orchestrates AI agents through pluggable local adapters;
codex_local wraps OpenAI's `codex` CLI.
> - The codex_local adapter declares a hard-coded
`DEFAULT_CODEX_LOCAL_MODEL = "gpt-5.3-codex"` and multiple Paperclip
consumers (UI build-config, server route, OnboardingWizard, NewAgent
form, AgentConfigForm) fall back to it when the operator doesn't pick a
model.
> - That model — and every `*-codex` model plus the older
`gpt-5/5.1/5.2` lines — is API-key-only. Codex CLI rejects them on
ChatGPT subscription auth with "The 'gpt-5.3-codex' model is not
supported when using Codex with a ChatGPT account."
> - Every codex_local agent created through the default onboarding path
inherits this pin and breaks on its first heartbeat for any user authed
via `codex login` (ChatGPT).
> - claude_local already takes the right shape: its build-config only
sets `adapterConfig.model` when the operator actually picked one, and
falls through to whatever default `claude` CLI uses.
> - Codex CLI's own default is auth-mode-aware. ChatGPT-subscription
accounts get `gpt-5.5`; API-key accounts get the codex-tuned default. A
Paperclip-side pin masks this and downgrades whichever group it wasn't
built for.
> - This PR makes codex_local match claude_local's shape: omit
`adapterConfig.model` when the user picks "default," and let the CLI
choose. Subscription users stop breaking; API-key users stop getting
downgraded.
> - The benefit is auth-mode-correct defaults with no Paperclip-side
hard pin, plus future-proofing: when OpenAI bumps the CLI default we
inherit it for free.

## What Changed

- `packages/adapters/codex-local/src/ui/build-config.ts` — only set
`adapterConfig.model` when the operator picked one (parity with
`packages/adapters/claude-local/src/ui/build-config.ts`).
- `server/src/routes/agents.ts` — drop the codex_local-specific
`next.model = DEFAULT_CODEX_LOCAL_MODEL` fallback in
`applyCreateDefaultsByAdapterType`. Bypass-sandbox default is left in
place (security posture, not a model choice).
- `ui/src/pages/NewAgent.tsx`, `ui/src/components/AgentConfigForm.tsx`,
`ui/src/components/OnboardingWizard.tsx` — stop pre-populating the model
field with `DEFAULT_CODEX_LOCAL_MODEL` when the user selects the Codex
adapter. Other adapters' defaults (gemini_local, cursor, opencode_local)
are unchanged.
- `DEFAULT_CODEX_LOCAL_MODEL` is preserved as an exported constant for
downstream consumers / plugin authors who want to opt in to a pin; we
just stop forcing it on operators who didn't ask for one.
- Test: assert `buildCodexLocalConfig` omits `model` when input is
blank.

## Verification

- `pnpm exec vitest run
packages/adapters/codex-local/src/ui/build-config.test.ts
packages/adapters/codex-local/src/server/codex-args.test.ts
server/src/__tests__/adapter-registry.test.ts
server/src/__tests__/heartbeat-model-profile.test.ts
server/src/__tests__/agent-permissions-routes.test.ts` → 74/74 passing
- `pnpm exec vitest run ui/src/lib/duplicate-agent-payload.test.ts
ui/src/lib/acpx-model-filter.test.ts` → passing
- `pnpm tsc --noEmit -p .` → clean
- Live: I separately verified live during initial investigation that on
ChatGPT-subscription auth, `gpt-5.3-codex` is rejected and `gpt-5.5` is
what Codex CLI picks by default. Omitting model lets the CLI handle
that.

## Risks

- Telemetry: any sink that reads `adapterConfig.model` for cost
attribution will now see the empty/omitted case more often. The CLI
emits the actually-used model in its event stream; downstream telemetry
should already read from there for accuracy, but worth a check.
- Operator UX: "default" now means "whatever the CLI picks" instead of a
Paperclip-known model. The selectable catalog still includes `gpt-5.5`,
`gpt-5.4`, `gpt-5.3-codex`, etc. for operators who want to pin
explicitly.
- Existing agents are unaffected — their `adapterConfig.model` is
already set; this only changes the *new-agent* default flow.

## Related work

- Depends on: an open catalog-add PR adding `gpt-5.5` to the selectable
model list and to `CODEX_LOCAL_FAST_MODE_SUPPORTED_MODELS`. Operators
who want to switch to `gpt-5.5` explicitly need that PR merged first;
this PR is the structural change that makes "default" mean "let the CLI
choose."
- Closes #5371 — codex_local default model selection persists
`gpt-5.3-codex` instead of adapter default (this PR is the exact fix
#5371 proposes).
- Related: #5132 (opencode-local: hire-time default model fails on
ChatGPT-OAuth accounts) — same problem shape on a sibling adapter; not
fixed here but worth tracking for a parallel.
- Related: #5939 (codex_local adapter hardcodes `gpt-5.3-codex-spark`
validation, fails on ChatGPT OAuth accounts regardless of configured
model) — separate validation-path bug; not fixed here.

## Model Used

Claude (Sonnet-class), running inside Paperclip as a claude_local
executor.


## 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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [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-06-10 20:53:33 -07:00
Dotta 67b22d872f [codex] Clarify interrupt handoffs and scoped wake semantics (#7855)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The issue thread is the operator surface where comments, assignee
changes, pauses, resumes, and wakeups turn human intent into agent
execution.
> - Interrupting a live run and handing work to another assignee needs
clear semantics so the product does not accidentally keep work alive,
wake the wrong participant, or hide why an agent stopped.
> - Comment-driven wakes also need strict boundaries so closed, blocked,
and dependency-driven work only resumes when there is real actionable
input.
> - This pull request codifies the interrupt handoff contract,
implements backend scheduling behavior, and gives the UI clearer
handoff/pause language.
> - The benefit is a more inspectable and predictable task lifecycle for
both operators and agents.

## Linked Issues or Issue Description

Paperclip issue: `PAP-10664` / `PAP-10751`.

Problem: interrupting or reassigning live agent work could be ambiguous
in the UI and backend. Operators needed clearer feedback about whether a
handoff wakes an agent, what pause/cancel affects, and when comments
should revive execution. The backend also needed stronger tests around
comment wake boundaries, retry supersession, and structured agent
mention dispatch.

Related GitHub PR search found broad workflow-adjacent PRs #5082, #6359,
and #4083, but no exact duplicate for this head branch or
interrupt-handoff scope.

## What Changed

- Added an interrupt handoff semantics document covering destination
behavior, wake expectations, and live-run interruption states.
- Implemented backend interrupt handoff behavior and comment wake/reopen
handling in issue routes/services and heartbeat scheduling.
- Hardened structured agent mention dispatch so mentions resolve through
the intended dispatch path.
- Added UI helpers and components for handoff chips, wake rows,
interrupt banners, pause-affects summaries, and composer guidance.
- Updated the issue properties assignee picker and issue chat/composer
surfaces to make interrupt/reassign behavior clearer.
- Added backend, UI utility, component, and Storybook coverage for the
new behavior.
- Stabilized the new UI component tests with a local `flushSync`-backed
act helper matching existing repo practice in this dependency set.
- Addressed Greptile feedback by threading historical run `errorCode`
through issue-run data and operator-interrupted chat labels.
- Addressed Greptile's cancel ordering concern by terminating/deleting
in-memory heartbeat processes before cancellation status persistence,
with regression coverage for DB update failure.

## Verification

- `git diff --check $(git merge-base HEAD origin/master)..HEAD`
- `pnpm --filter @paperclipai/ui exec vitest run
src/lib/interrupt-handoff.test.ts src/lib/issue-chat-messages.test.ts
src/components/IssueProperties.test.tsx
src/components/interrupt-handoff/InterruptHandoffViews.test.tsx
--no-file-parallelism --maxWorkers=1` — 4 files / 91 tests passed before
the Greptile follow-ups.
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts
server/src/__tests__/heartbeat-retry-scheduling.test.ts
server/src/__tests__/issue-comment-reopen-routes.test.ts
server/src/__tests__/issue-tree-control-service.test.ts
server/src/__tests__/issue-update-comment-wakeup-routes.test.ts
server/src/__tests__/issues-service.test.ts --no-file-parallelism
--maxWorkers=1` — 6 files / 191 tests passed before the Greptile
follow-ups.
- `pnpm --filter @paperclipai/ui exec vitest run
src/lib/issue-chat-messages.test.ts --no-file-parallelism
--maxWorkers=1` — 1 file / 24 tests passed after the historical
`errorCode` follow-up.
- `pnpm exec vitest run server/src/__tests__/activity-service.test.ts
server/src/__tests__/activity-routes.test.ts --no-file-parallelism
--maxWorkers=1` — 2 files / 11 tests passed after the historical
`errorCode` follow-up.
- `pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts
--no-file-parallelism --maxWorkers=1` — 1 file / 52 tests passed after
the cancel ordering follow-up.
- Greptile is green for head `272647636287d034bab8d981eaf5305865aa0f96`;
the old inline P2 is resolved/outdated.
- GitHub Actions, Socket, security-review, and Greptile checks are green
for head `272647636287d034bab8d981eaf5305865aa0f96`. The external
`security/snyk (cryppadotta)` status was still pending at
`https://app.snyk.io/org/cryppadotta/pr-checks/85b3e8f4-04e1-4f8e-9362-899c8148c23c`
after a bounded wait.

## Risks

- Medium: changes touch issue comments, wake scheduling, and live-run
interruption semantics, so regressions could affect when agents resume
or stay stopped.
- Medium: UI copy and state grouping for assignee changes may need
reviewer tuning after product review.
- Low migration risk: no database schema migration is included.
- The branch was created before the latest `origin/master` commits;
reviewers should confirm CI merge-base behavior and resolve any merge
conflicts if GitHub reports them.

> 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-based coding agent, tool use and local command
execution enabled. Exact hosted model build and context window were not
exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [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

Screenshot note: this PR includes Storybook coverage for the new
interrupt handoff UI states rather than captured before/after browser
screenshots in this PR-creation heartbeat.

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 21:57:21 -05:00
Dotta fae7e920a9 [codex] Polish routine layout follow-ups (#7858)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Routines are the recurring-work surface that lets a company keep
operating without a human manually kicking off every task
> - The base routine detail Variation C shell already landed in #7848,
but the follow-up branch still had polish work for scheduling, section
ergonomics, and the list layout
> - Operators need routine edit screens to explain trigger behavior
clearly, keep long detail pages usable on mobile/touch devices, and make
grouped routine lists easier to scan
> - This pull request rebases the remaining branch work onto current
`master`, drops the duplicate commits already merged through #7848, and
keeps only the new routine UI follow-ups
> - The benefit is a cleaner routines workflow without reopening the
already-merged shell work or carrying unrelated lockfile, workflow, or
screenshot changes

## Linked Issues or Issue Description

Refs #7848

Feature follow-up: polish the routines UI after the Variation C
routine-detail shell landed.

Problem / motivation:

- Routine trigger configuration needs clearer previews for manual,
schedule, API, and webhook execution modes.
- Routine detail sections need better responsive spacing and touch
ergonomics.
- The routines list grouping should scan like grouped records instead of
a table with heavy row dividers.
- The routine tests need a React 19-compatible render helper so the
focused routine suite can run in this workspace.

Proposed solution:

- Add cron-fire preview helpers and routine-run display helpers with
focused tests.
- Expand the routine editable and operate sections with richer trigger,
variable, run, activity, and history presentation.
- Adjust the routine detail shell and sub-sidebar spacing for
mobile/touch layout.
- Update grouped routine list presentation to use bordered group headers
with borderless rows.
- Switch affected routine tests to the repo's `flushSync` render-helper
pattern.

Alternatives considered:

- Leaving the duplicate pre-#7848 commits in the branch would recreate
conflicts and make the PR review much larger than the remaining change.
- Keeping grouped routine rows inside one bordered table was simpler,
but made the grouping hierarchy less legible.

Roadmap alignment:

- ROADMAP.md lists Scheduled Routines as a core shipped capability and
Output/Enforced Outcomes as ongoing priorities. This is polish on that
existing routines capability, not a new roadmap-level feature.

## What Changed

- Added routine scheduling preview helpers and tests for
cron/manual/API/webhook fire-policy display.
- Added routine run display helpers and tests for deduped trigger labels
and run-row subtitles.
- Polished routine detail sections, including trigger summaries, operate
views, and env/variable editing ergonomics.
- Adjusted routine detail page and sub-sidebar spacing so the
title/header area is less pinned and touch layouts center better.
- Reworked the routines list grouped layout so group headers are
bordered cards and routine rows are borderless inside each group.
- Added Storybook coverage for the routines list grouped layout and
updated the existing routine detail story.
- Repaired routine tests to use `flushSync` helpers compatible with the
installed React 19 runtime.

## Verification

- `pnpm exec vitest run ui/src/lib/cron-fires.test.ts
ui/src/lib/routine-run-display.test.ts ui/src/pages/Routines.test.tsx
ui/src/components/RoutineSubSidebar.test.tsx
ui/src/components/RoutineSaveBar.test.tsx`
  - Result: 5 test files passed, 37 tests passed.
- Confirmed the rebased PR diff does not include `pnpm-lock.yaml`,
`.github/workflows/*`, or committed screenshots.
- Confirmed `origin/master` is an ancestor of the pushed branch head
after rebase.

## Risks

- Medium UI risk: this touches the routine detail and routine list
surfaces, so visual regressions are possible in edge cases not covered
by the focused tests.
- Low data risk: no schema, migration, server API, or lockfile changes
are included.
- Review note: the branch intentionally force-pushed after rebasing
because the original first three commits were already merged through
#7848.

> 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-based coding agent runtime, with repository
shell/tool access. Exact hosted runtime model identifier and
context-window size were not exposed in the execution environment.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 18:55:01 -05:00
scotttong e3aada1df2 feat(ui): add Feedback item to the account flyout menu (PAP-107) (#7854)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The web UI has a bottom-left account flyout menu where users reach
profile, docs, and the light/dark toggle
> - There was no in-product way for users to send feedback or report
issues — they had to find an external channel
> - We want a low-friction, always-visible entry point for feedback, and
a clean URL we can re-point later without shipping app changes
> - This pull request adds a **Feedback** item (Megaphone icon) to the
account flyout, between Documentation and the theme toggle, that opens
`https://paperclip.ing/feedback` in a new tab
> - `paperclip.ing/feedback` is a stable indirection (added to the
marketing site) that currently 302-redirects to a Google Form, so the
destination can be swapped for a richer solution later with no app
release
> - The benefit is a one-click feedback path for users and a
future-proof link the team controls

## Linked Issues or Issue Description

No public GitHub issue exists (tracked internally as Paperclip PAP-107).
Describing the underlying request inline as a feature, per
CONTRIBUTING.md path (B):

### Problem or motivation

Users have no in-app affordance to give feedback or report issues; that
friction loses signal we'd otherwise act on.

### Proposed solution

Add a Feedback item to the account flyout (Megaphone icon, between
Documentation and the theme toggle) that opens a stable
`paperclip.ing/feedback` URL in a new tab. That URL redirects to a
Google Form for now, keeping the client decoupled from the destination.

### Alternatives considered

Linking the Google Form directly from the app — rejected because it
bakes a throwaway URL into the client; the `/feedback` indirection keeps
the link clean and swappable.

### Roadmap alignment

Small, self-contained UX addition; no overlap with planned core work
(checked ROADMAP.md). The `/feedback` redirect lives in the separate
`paperclip-website` repo (Astro site on Cloudflare Pages), commit
`f65b566`. No duplicate/related PRs found in this repo (searched
feedback/flyout/menu).

## What Changed

- `ui/src/components/SidebarAccountMenu.tsx`: import `Megaphone` from
`lucide-react`; add `FEEDBACK_URL = "https://paperclip.ing/feedback"`
const next to `DOCS_URL`; insert a `Feedback` `MenuAction` between
Documentation and the theme toggle using the `external` prop so it opens
in a new tab (`target="_blank"`, `rel="noreferrer"`) and closes the
popover on click.
- `ui/src/components/SidebarAccountMenu.test.tsx`: assert the Feedback
item renders with the correct `href`, opens in a new tab, and is ordered
after Documentation and before the theme toggle.
- (Separate repo, for context) `paperclip-website` `public/_redirects`:
`/feedback` → 302 → the feedback Google Form.

## Verification

- **Unit tests:** `SidebarAccountMenu` tests pass (item renders, correct
`href`, `target="_blank"`, ordering). Run: `cd ui && npm test --
SidebarAccountMenu`.
- **Manual / canary:** The board previewed the canary build of the menu
item and accepted it. Clicking **Feedback** opens a new tab to
`paperclip.ing/feedback`.
- **Redirect:** After the Cloudflare Pages deploy propagates, `curl -sI
https://paperclip.ing/feedback` returns the Google Form in the
`Location` header.

_Screenshots:_ UI change was validated via the accepted canary preview;
the item reuses the existing `MenuAction` styling, so it visually
matches the Documentation/theme rows.

## Risks

- **Low risk.** Additive, self-contained UI change with no new state or
API calls. The only external dependency is the `paperclip.ing/feedback`
redirect (separate repo, already deployed); if it were missing the link
would 404, but it is in place. No migrations, no breaking changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR.

## Model Used

- **Claude (Anthropic).** PR authoring/orchestration:
**claude-opus-4-8** (extended thinking + tool use). The implementation
commit `b454a12d` was produced with assistance from
**claude-sonnet-4-6**. All changes reviewed before pushing.

## 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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [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: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-09 16:42:15 -07:00
Dotta 468edd8b22 Add workspace file viewer and artifact links (#7681)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent work is issue-centered, and reviewers often need to inspect
files, artifacts, and path references produced during that work.
> - Before this branch, workspace-relative paths and artifact file
references were not first-class inspectable objects in the board UI.
> - Safe file viewing needs shared resource contracts, server-side
workspace boundary checks, and UI that opens files without exposing
arbitrary host paths.
> - The workspace file viewer branch needed to stay as one active PR and
be rebased onto current `paperclipai/paperclip:master` for review.
> - This pull request adds the workspace file resource API, issue-page
file viewer and browser, markdown file-reference links, and artifact
file chips.
> - The benefit is that board users can inspect relevant files from
issue context while preserving workspace boundaries and auditability.

## Linked Issues or Issue Description

No public GitHub issue exists for this branch. Internal Paperclip
issues: `PAP-1953`, `PAP-10539`, `PAP-10733`.

Problem / motivation:
- Board users need to open workspace-relative files mentioned by agents
or attached as work-product metadata without switching to a terminal.
- The UI needs to support both direct file-path opening and workspace
browsing/searching from an issue page.
- The server must enforce company access, workspace boundaries, size
limits, rate limits, and safe audit logging.

Related PR:
- Prior closed attempt: #4442
- Single active PR for this branch: #7681

## What Changed

- Added shared workspace file resource types, validators, and
workspace-file `resourceRef` metadata validation for work products.
- Added server routes/services for resolving, listing, and previewing
workspace-relative files with access checks, scan caps, list-specific
limits, and audit logging.
- Added the issue file viewer provider, sheet, workspace browser,
command-palette action, markdown workspace-file autolinks, and artifact
file chips.
- Updated issue workspace UI and stories/tests for file browsing and
workspace file opening.
- Rebased the branch onto current `paperclipai/paperclip:master` and
updated the existing single PR branch.
- Addressed current-head Greptile follow-ups by applying `offset`
consistently across search/recent/changed file listings, restoring
stopped-service port ownership checks before auto-port reuse, and
stabilizing the workspace browser pagination test.

## Verification

Current local verification after rebase to `public/master`:
- `pnpm exec vitest run packages/shared/src/work-product.test.ts
server/src/__tests__/file-resources.test.ts
server/src/__tests__/instance-settings-routes.test.ts
server/src/__tests__/instance-settings-service.test.ts
server/src/__tests__/workspace-runtime.test.ts
ui/src/components/FileViewerSheet.test.tsx
ui/src/components/FileViewerSheet.copy.test.tsx
ui/src/components/WorkspaceFileBrowser.test.tsx
ui/src/components/WorkspaceFileMarkdownBody.test.tsx
ui/src/context/FileViewerContext.test.ts
ui/src/lib/remark-workspace-file-refs.test.ts
ui/src/lib/workspace-file-parser.test.ts
ui/src/components/IssueWorkspaceCard.test.tsx` - 13 files passed, 197
tests passed.
- `pnpm -r --filter @paperclipai/shared --filter @paperclipai/server
--filter @paperclipai/ui typecheck` - passed.
- `pnpm exec vitest run ui/src/components/WorkspaceFileBrowser.test.tsx`
- 1 file passed, 25 tests passed.
- `pnpm exec vitest run server/src/__tests__/file-resources.test.ts
server/src/__tests__/workspace-runtime.test.ts` - 2 files passed, 90
tests passed.
- `pnpm -r --filter @paperclipai/server typecheck` - passed.
- Confirmed branch is `0` behind and `46` ahead of current
`public/master` after rebase and follow-up commits.
- Confirmed the PR diff does not include `pnpm-lock.yaml`.
- Confirmed the PR diff does not include `.github/workflows` changes.
- Searched GitHub for duplicate or related workspace file viewer
PRs/issues; #4442 is the prior closed attempt and this PR is the single
active PR for the branch.
- No screenshots were committed; the task explicitly asked not to add
design screenshots or images unless they were part of the work.

Current remote verification on head
`a698a7bc10137baf7d25bd5722e1d6e0343387c1`:
- Greptile Review - success, 64 files reviewed, 0 comments added, no
unresolved Greptile review threads.
- PR workflow `verify` - success.
- Typecheck + Release Registry, General tests, workspace test shards,
serialized server suites, Build, Canary Dry Run, e2e, Socket, and Snyk -
success.
- `security-review` - neutral, with output saying a draft advisory was
filed for maintainer review and is not a merge block.
- `commitperclip PR Review / review` - cancelled after the security gate
detected flags and timed out while creating/reviewing the advisory. I
reran it once and it cancelled the same way; no actionable code/test
failure was exposed in the job logs.

## Risks

- This is a broad UI/server feature PR, so review needs to pay attention
to route authorization, workspace boundary handling, and markdown
autolink false positives.
- Workspace browsing intentionally caps list results and scan depth;
very large workspaces may require users to refine search terms.
- Remote workspace preview remains unavailable until remote file-access
support is implemented.
- The neutral commitperclip security-review advisory needs maintainer
review, but the check output says it is not a merge block.

> 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 coding agent in a Paperclip/Codex local tool-use
environment, medium reasoning, with shell/GitHub CLI tool use for branch
inspection, verification, rebase, PR update, Greptile review, and CI
inspection.

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 17:17:43 -05:00
Dotta bf62e3fbf1 feat(ui): routine detail page — variation C sub-sidebar layout (PAP-10732) (#7848)
## Summary

Rebuilds the routine detail page as **variation C** — a sub-sidebar
shell that splits the page into **ROUTINE** (Overview · Triggers ·
Variables · Secrets · Delivery) and **OPERATE** (Runs · Activity ·
History), per the engineering spec on PAP-10730. Replaces the previous
5-tab `?tab=…` layout in `ui/src/pages/RoutineDetail.tsx`.

Implements PAP-10732. Design source of truth: PAP-10730 `spec` document;
approved direction PAP-10709.

## What changed

- **Routing** (`ui/src/App.tsx`): real sub-routes under
`routines/:routineId/:section`. Bare `/routines/:id` redirects to the
last-viewed section (`localStorage`) or `overview`; old `?tab=…` URLs
redirect to the matching section for back-compat. Every section URL is
bookmarkable.
- **Shell** (`RoutineDetail.tsx`): slim 56px sticky header (title +
managed-by-plugin chip + Run / Active toggle), page-local sub-sidebar,
full-canvas section body, per-section sticky save bar. All routine
state/mutations stay in the shell and flow to sections via a
`RoutineDetailContext`.
- **New components**: `RoutineSubSidebar` (+ mobile `<Select>` picker,
roving keyboard nav), `RoutineSaveBar` (scoped dirty count, ⌘/Ctrl+S
save, Esc-discard confirm, 409 conflict recovery with Reload /
Overwrite), `RadioCard` primitive (Delivery), `RoutineTriggerCard`
(extracted from the inline editor, with human-readable cron),
`RoutineActivityRow` (expandable JSON), `lib/cron-readable`, and the
per-section components.
- **Reuse**: History mounts the existing `RoutineHistoryTab`; Variables
mounts `RoutineVariablesEditor` with a provenance banner; Secrets reuses
`EnvVarEditor` + the one-time reveal banner. No backend or schema
changes.
- **States**: per-section loading/empty/error/save-conflict and
read-only strip scaffolding (§1.6).

## Testing

- New unit tests: sub-sidebar navigation/active/dirty markers, save-bar
dirty + ⌘S + conflict recovery, cron helper.
- Existing routine tests still pass: `Routines.test.tsx`,
`RoutineHistoryTab.test.tsx`, `RoutineRunVariablesDialog.test.tsx`.
- `vitest run` (routine scope): **36 passed**. Production `vite build`:
**green**.
- Screenshots at 1440×900 + 390×844 attached to
[PAP-10732](https://example.invalid) (rendered via a new Storybook story
with fixture data).

## Out of scope (per spec)

- `/routines` list-page redo (follow-up).
- Non-owner secret-value visibility (Open Q6 — CEO escalation; built
with the spec default).

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-09 17:04:25 -05:00
Dotta 50bff3b274 feat(ui): add collapsible sidebar rail and takeover panes (#7824)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents, work, and company context.
> - The board UI sidebar is the main way operators keep orientation
across companies, projects, agents, issues, and settings.
> - The existing fixed expanded sidebar competes with route-specific
navigation, especially company settings and plugin routes that bring
their own contextual sidebar.
> - A collapsible primary rail preserves global navigation while giving
contextual pages more horizontal room.
> - This pull request adds a persisted collapsed rail, hover/focus peek,
keyboard toggle, and a secondary sidebar takeover model for settings and
plugin `routeSidebar` surfaces.
> - The benefit is a denser board shell that keeps the app rail
available without replacing it when a route needs its own navigation.

## Linked Issues or Issue Description

Paperclip issue: PAP-10638 Create collapsible sidebar branch.

Related GitHub PR found during duplicate search: #3838
(`feat/collapsible-sidebar`) covers a similar sidebar area but is a
different head branch and implementation. This PR intentionally packages
the work from `PAP-10638-collapsable-sidebar` into one reviewable
branch.

Problem description:

The board shell needs a first-class collapsed sidebar mode. Contextual
surfaces such as company settings and plugin route sidebars should not
replace the global app sidebar; they should collapse the app sidebar to
a rail and render their contextual navigation beside it.

## What Changed

- Added desktop collapsed/sidebar-peek state to `SidebarContext`,
including persisted user pins, route collapse requests, and forced
collapse for secondary-sidebar routes.
- Replaced the old resizable sidebar pane with `SidebarShell`, which
supports a fixed 64px rail, persisted expanded width, keyboard/pointer
resizing, and hover/focus peek overlay behavior.
- Updated `Sidebar`, sidebar nav items, project/agent sections, badges,
and account/company menu presentation for expanded, collapsed, and
peeking states.
- Added `RequestCollapsedSidebar` and `SecondarySidebar` so routes and
plugin `routeSidebar` slots can request contextual sidebar layouts
without replacing the primary app sidebar.
- Wired company settings and plugin route sidebars into the
secondary-pane takeover model.
- Added focused Vitest coverage for sidebar state precedence, shell
sizing, nav item rail rendering, keyboard shortcuts, layout takeover
behavior, and route collapse requests.
- Updated plugin authoring docs/spec references for route sidebar
behavior.

## Verification

Targeted local verification passed:

```sh
NODE_ENV=test pnpm run preflight:workspace-links && NODE_ENV=test pnpm exec vitest run ui/src/context/SidebarContext.test.tsx ui/src/components/SidebarShell.test.tsx ui/src/components/Sidebar.test.tsx ui/src/components/Layout.test.tsx ui/src/components/RequestCollapsedSidebar.test.tsx ui/src/components/SidebarNavItem.test.tsx ui/src/components/SidebarAgents.test.tsx ui/src/components/SidebarProjects.test.tsx ui/src/components/KeyboardShortcutsCheatsheet.test.tsx ui/src/hooks/useKeyboardShortcuts.test.tsx
```

Result: 10 test files passed, 88 tests passed.

Additional follow-up verification passed after review fixes:

```sh
NODE_ENV=test pnpm run preflight:workspace-links && NODE_ENV=test pnpm exec vitest run ui/src/components/Layout.test.tsx ui/src/context/SidebarContext.test.tsx && pnpm --filter /ui typecheck
```

Result: 2 test files passed, 28 tests passed, and UI typecheck passed.

Latest PR-head remote checks: Paperclip PR workflow, Snyk, Socket, and
Greptile are green; commitperclip `review` is cancelled in its
security-gate step after filing a non-blocking neutral `security-review`
check.

Notes:

- A direct run without `NODE_ENV=test` loads React's production build in
this workspace, where `act` is unavailable; the command above matches
the repo stable runner's test environment.
- I did not run Playwright/browser e2e or full workspace build/typecheck
in this PR-creation heartbeat.
- QA screenshots are attached in
https://github.com/paperclipai/paperclip/pull/7824#issuecomment-4661968387
for expanded, collapsed rail, hover peek, and settings secondary-sidebar
states.

## Risks

- Medium UI layout risk: this changes the board shell and primary
sidebar composition across many routes.
- Local storage migration risk is low: new collapsed state uses a new
key and existing width storage remains scoped to the sidebar width.
- Plugin route risk: plugin `routeSidebar` slots now render as secondary
panes on desktop, so plugin authors should confirm their route sidebar
content fits a 240px contextual pane.
- Mobile risk appears low because mobile keeps the drawer model and
gates collapsed/peek behavior to desktop.

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

## Model Used

OpenAI Codex coding agent based on GPT-5, with local shell/git/GitHub
CLI tool use. Exact service-side model identifier and context window
were not exposed in this runtime.

## Checklist

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-09 13:25:17 -05:00
Dotta 76c88e5855 [codex] Move instance settings under company settings (#7680)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators manage both company-scoped configuration and
instance-level runtime/admin settings from the board UI
> - Instance settings previously lived as their own top-level sidebar
area, separate from the company settings context operators already use
> - That split made settings navigation feel heavier and made instance
configuration less discoverable from the settings tab
> - This pull request moves instance settings under company settings
while preserving the existing instance settings routes and plugin/admin
surfaces
> - The benefit is a smaller primary sidebar and a more coherent
settings hierarchy for operators

## Linked Issues or Issue Description

- Refs #338
- Internal: PAP-10491, PAP-10538

## What Changed

- Moved instance settings navigation under the company settings area.
- Added route helpers and sidebar entries for nested instance settings
paths.
- Updated plugin/admin settings routes to use the company settings
instance scope.
- Preserved legacy instance-settings bookmarks through compatibility
redirects that keep the active company prefix.
- Updated focused UI and plugin tests for the new navigation shape.
- Stabilized the process-loss retry test that was failing the serialized
server shard in CI.
- Rebased the branch onto current `paperclipai/paperclip` `master` and
pushed the current head.

## Verification

- `pnpm exec vitest run
ui/src/components/CompanySettingsSidebar.test.tsx
ui/src/components/access/CompanySettingsNav.test.tsx
ui/src/lib/instance-settings.test.ts
ui/src/components/InstanceSidebar.test.tsx
ui/src/components/Layout.test.tsx
ui/src/components/SidebarAccountMenu.test.tsx
ui/src/pages/PluginPage.test.tsx ui/src/plugins/bridge.test.ts
packages/shared/src/validators/plugin.test.ts`
- `pnpm exec vitest run ui/src/lib/instance-settings.test.ts
ui/src/components/CompanySettingsSidebar.test.tsx
ui/src/components/access/CompanySettingsNav.test.tsx
ui/src/components/Layout.test.tsx ui/src/plugins/bridge.test.ts`
- `pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts -t "queues
exactly one retry when the recorded local pid is dead"`
- `pnpm test:run:serialized -- --shard-index 0 --shard-count 4`
- GitHub PR checks are green on head
`fe7b0955169dcae55cbe10889c1876a70ab0b80c`, including `verify`, `General
tests (server)`, all serialized server shards, build, e2e, policy,
security checks, and Greptile.
- Confirmed the PR diff does not include `pnpm-lock.yaml` or
`.github/workflows` changes.

## Risks

- Medium UI/navigation risk: instance settings links are intentionally
moving under company settings, so stale external bookmarks to legacy
paths rely on the compatibility routing in this branch.
- Low test-only risk from the CI stabilization commit: it makes the
recovery assertion select the actual retry run by `retryOfRunId` instead
of whichever non-original run appears first.
- No database migrations.
- No dependency lockfile or workflow changes.

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

## Model Used

- OpenAI Codex coding agent based on GPT-5, with shell/tool execution in
a local repository worktree. Exact context window was not exposed by the
runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [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-06-07 17:23:53 -05:00
Dotta 2d1b531a49 [codex] Add clear-error agent action (#7695)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents for work.
> - Agent runtime state is surfaced in both the server API and the board
UI so operators can tell whether an agent is idle, running, paused, or
in error.
> - When an agent is already in `error`, the existing pause/resume
action slot is not useful because there is no running work to pause.
> - Operators need a direct, audited recovery path that clears the stale
error state only for agents in the same company.
> - This pull request adds a company-scoped clear-error mutation,
exposes the shared API contract, and wires the board action cluster to
show Clear error in the pause/resume slot for errored agents.
> - The benefit is that operators can recover CEO/CTO-style errored
agents without resorting to database edits or unrelated session reset
actions.

## Linked Issues or Issue Description

Refs #4021

Paperclip issue: PAP-10515 — right now the CEO and CTO agents are in
error state, but there is no way to clear the error; they appear
otherwise fine.

## What Changed

- Added shared constants, API path, and agent status type support for a
company-scoped clear-error action.
- Added the server service and route to clear an agent from `error` back
to `idle`, with company access enforcement and activity logging.
- Added OpenAPI/docs coverage for the clear-error endpoint.
- Added backend coverage for service behavior and cross-tenant
authorization.
- Updated the board agent action cluster to show a red-tinted Clear
error button only when `agent.status === "error"`.
- Updated agent properties to show a red active last-error indicator
only while the agent is currently errored.
- Added UI component tests for the error-state action and the non-error
pause/resume behavior.

## Verification

Local:

- `pnpm exec vitest run
server/src/__tests__/agents-service-clear-error.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
ui/src/components/AgentActionButtons.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts`

PR checks:

- Main Paperclip workflow is green on
`a7378e584d50594e7bd507a1a02985bfaaa5abf8`.
- Greptile is 5/5 with no files requiring special attention and no new
comments on the latest review.
- `commitperclip PR Review` is still red because its security-gate step
canceled after filing a draft advisory; the linked `security-review`
check is neutral and says the draft advisory is not a merge block.

Visual artifact:

- ![Clear error visual
comparison](https://gist.githubusercontent.com/cryppadotta/59378c59869b971e92d3edf7b7073aa8/raw/clear-error-visual-comparison.svg)

## Risks

Low to medium risk. The mutation is intentionally narrow, but reviewers
should check that clearing `lastError`/`lastRunError` and returning to
`idle` is the desired recovery semantics for every adapter state. The
remaining red check is from the external commitperclip security-review
workflow, not from the code/test workflow for this PR.

> 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-family coding model, tool-assisted with local shell,
git, GitHub CLI, and targeted Vitest 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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-07 10:33:29 -05:00
Dotta 35c31ca63f [codex] Add live-run stop finalization actions (#7679)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators supervise live agent runs from the issue detail chat
surface.
> - The existing run menu can pause/stop work, but operators sometimes
need to stop the active run and immediately finalize the task outcome.
> - Doing those as separate actions is slower and easier to leave
half-finished.
> - This pull request adds explicit live-run finalization actions to the
issue chat run menu.
> - The benefit is a clearer operator path for stopping a live run and
marking the task done or cancelled in one ordered flow.

## Linked Issues or Issue Description

No public GitHub issue exists for this internal Paperclip task. Internal
task: PAP-10535.

## Subsystem affected

ui/ — React + Vite board UI.

## Problem or motivation

Operators can stop an active run from the issue detail chat, but
finalizing the issue outcome requires a separate status action after the
run is stopped. That extra step makes live-run finalization slower and
easier to leave incomplete.

## Proposed solution

Add explicit issue chat run-menu actions for `Stop and cancel` and `Stop
and done`, where each action cancels the active heartbeat run before
updating the issue status.

## Alternatives considered

Keep the existing two-step flow of cancelling the run first and then
changing issue status separately. That preserves current behavior but
does not solve the operator workflow gap.

## Roadmap alignment

This is a small targeted UI control-plane improvement for supervising
live agent work. It does not duplicate a planned core roadmap item found
in `ROADMAP.md`.

This PR was split from the local `master` branch on June 7, 2026. It
covers the UI-only live-run finalization action. I searched GitHub for
duplicate/related PRs; the results were broader run-control PRs, not
this exact issue-detail menu action.

## What Changed

- Added optional `runFinalizationActions` support to `IssueChatThread`
assistant message run menus.
- Added `Stop and cancel` and `Stop and done` actions on the issue
detail chat tab.
- Each action cancels the active heartbeat run before updating the issue
status.
- Added focused UI coverage to assert cancellation happens before the
status update.
- Addressed Greptile feedback for partial-failure messaging and
duplicate run-state invalidation.

## Verification

- `git diff --check origin/master..HEAD`
- `git diff --check`
- `NODE_ENV=test pnpm exec vitest run ui/src/pages/IssueDetail.test.tsx`
- Storybook screenshot capture for the live-run menu before and after
the finalization actions.

## Screenshots

Before: existing live-run menu only offered the normal stop action.

![Before live-run
menu](https://raw.githubusercontent.com/paperclipai/paperclip/codex/live-run-stop-finalization/screenshots/PAP-10535-live-run-menu-before.png)

After: the live-run menu includes `Stop and cancel` and `Stop and done`.

![After live-run
menu](https://raw.githubusercontent.com/paperclipai/paperclip/codex/live-run-stop-finalization/screenshots/PAP-10535-live-run-menu-after.png)

## Risks

- Medium UI behavior risk: the new actions expose faster finalization
controls from the live-run menu. They are gated through the existing
issue detail management surface and still use the existing run cancel
and issue update APIs.
- Low migration risk: no schema, API contract, or dependency changes.

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

## Model Used

OpenAI Codex coding agent based on GPT-5, with shell, git, GitHub CLI,
local test execution, and Playwright browser screenshot capture. Exact
hosted model variant and context-window size were not exposed by the
runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [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-06-07 06:26:17 -05:00
dependabot[bot] a80014054f build(deps-dev): bump tailwindcss from 4.1.18 to 4.3.0 (#7574)
Bumps
[tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)
from 4.1.18 to 4.3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">tailwindcss's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.0</h2>
<h3>Added</h3>
<ul>
<li>Add <code>@container-size</code> utility (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18901">#18901</a>)</li>
<li>Add <code>scrollbar-{auto,thin,none}</code> utilities for
<code>scrollbar-width</code>, and <code>scrollbar-thumb-*</code> /
<code>scrollbar-track-*</code> color utilities for
<code>scrollbar-color</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19981">#19981</a>,
<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20019">#20019</a>)</li>
<li>Add <code>scrollbar-gutter-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20018">#20018</a>)</li>
<li>Add <code>zoom-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20020">#20020</a>)</li>
<li>Add <code>tab-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20022">#20022</a>)</li>
<li>Allow using <code>@variant</code> with stacked variants (e.g.
<code>@variant hover:focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Allow using <code>@variant</code> with compound variants (e.g.
<code>@variant hover, focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Support <code>--default(…)</code> in <code>--value(…)</code> and
<code>--modifier(…)</code> for functional <code>@utility</code>
definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19989">#19989</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ensure <code>@plugin</code> resolves package JavaScript entries
instead of browser CSS entries when using <code>@tailwindcss/vite</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19949">#19949</a>)</li>
<li>Fix relative <code>@import</code> and <code>@plugin</code> paths
resolving from the wrong directory when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19965">#19965</a>)</li>
<li>Ensure CSS files containing <code>@variant</code> are processed by
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19966">#19966</a>)</li>
<li>Resolve imports relative to <code>base</code> when
<code>result.opts.from</code> is not provided when using
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19980">#19980</a>)</li>
<li>Canonicalization: preserve significant <code>_</code> whitespace in
arbitrary values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: add parentheses when removing whitespace from
arbitrary values would hurt readability (e.g.
<code>w-[calc(100%---spacing(60))]</code> →
<code>w-[calc(100%-(--spacing(60)))]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: preserve the original unit in arbitrary values
instead of normalizing to base units (e.g. <code>-mt-[20in]</code> →
<code>mt-[-20in]</code>, not <code>mt-[-1920px]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19988">#19988</a>)</li>
<li>Canonicalization: migrate arbitrary <code>:has()</code> variants
from <code>[&amp;:has(…)]</code> to <code>has-[…]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19991">#19991</a>)</li>
<li>Upgrade: don’t migrate inline <code>style</code> attributes (e.g.
<code>style=&quot;flex-grow: 1&quot;</code> →
<code>style=&quot;flex-grow: 1&quot;</code>, not <code>style=&quot;grow:
1&quot;</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19918">#19918</a>)</li>
<li>Allow multiple <code>@utility</code> definitions with the same name
but different value types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19777">#19777</a>)</li>
<li>Export missing <code>PluginWithConfig</code> type from
<code>tailwindcss/plugin</code> to fix errors when inferring plugin
config types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19707">#19707</a>)</li>
<li>Ensure <code>start</code> and <code>end</code> legacy utilities
without values do not generate CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20003">#20003</a>)</li>
<li>Ensure <code>--value(…)</code> is required in functional
<code>@utility</code> definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20005">#20005</a>)</li>
<li>Canonicalization: preserve required whitespace around operators in
negated arbitrary values (e.g. <code>-left-[(var(--a)+var(--b))]</code>)
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20011">#20011</a>)</li>
</ul>
<h2>v4.2.4</h2>
<h3>Fixed</h3>
<ul>
<li>Ensure imports in <code>@import</code> and <code>@plugin</code>
still resolve correctly when using Vite aliases in
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19947">#19947</a>)</li>
</ul>
<h2>v4.2.3</h2>
<h3>Fixed</h3>
<ul>
<li>Canonicalization: improve canonicalizations for
<code>tracking-*</code> utilities by preferring non-negative utilities
(e.g. <code>-tracking-tighter</code> → <code>tracking-wider</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19827">#19827</a>)</li>
<li>Fix crash due to invalid characters in candidate (exceeding valid
unicode code point range) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19829">#19829</a>)</li>
<li>Ensure query params in imports are considered unique resources when
using <code>@tailwindcss/webpack</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19723">#19723</a>)</li>
<li>Canonicalization: collapse arbitrary values into shorthand utilities
(e.g. <code>px-[1.2rem] py-[1.2rem]</code> → <code>p-[1.2rem]</code>)
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19837">#19837</a>)</li>
<li>Canonicalization: collapse <code>border-{t,b}-*</code> into
<code>border-y-*</code>, <code>border-{l,r}-*</code> into
<code>border-x-*</code>, and <code>border-{t,r,b,l}-*</code> into
<code>border-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>scroll-m{t,b}-*</code> into
<code>scroll-my-*</code>, <code>scroll-m{l,r}-*</code> into
<code>scroll-mx-*</code>, and <code>scroll-m{t,r,b,l}-*</code> into
<code>scroll-m-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>scroll-p{t,b}-*</code> into
<code>scroll-py-*</code>, <code>scroll-p{l,r}-*</code> into
<code>scroll-px-*</code>, and <code>scroll-p{t,r,b,l}-*</code> into
<code>scroll-p-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>overflow-{x,y}-*</code> into
<code>overflow-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>overscroll-{x,y}-*</code> into
<code>overscroll-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Read from <code>--placeholder-color</code> instead of
<code>--background-color</code> for <code>placeholder-*</code> utilities
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19843">#19843</a>)</li>
<li>Upgrade: ensure files are not emptied out when killing the upgrade
process while it's running (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19846">#19846</a>)</li>
<li>Upgrade: use <code>config.content</code> when migrating from
Tailwind CSS v3 to Tailwind CSS v4 (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19846">#19846</a>)</li>
<li>Upgrade: never migrate files that are ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19846">#19846</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">tailwindcss's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.0] - 2026-05-08</h2>
<h3>Added</h3>
<ul>
<li>Add <code>@container-size</code> utility (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18901">#18901</a>)</li>
<li>Add <code>scrollbar-{auto,thin,none}</code> utilities for
<code>scrollbar-width</code>, and <code>scrollbar-thumb-*</code> /
<code>scrollbar-track-*</code> color utilities for
<code>scrollbar-color</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19981">#19981</a>,
<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20019">#20019</a>)</li>
<li>Add <code>scrollbar-gutter-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20018">#20018</a>)</li>
<li>Add <code>zoom-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20020">#20020</a>)</li>
<li>Add <code>tab-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20022">#20022</a>)</li>
<li>Allow using <code>@variant</code> with stacked variants (e.g.
<code>@variant hover:focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Allow using <code>@variant</code> with compound variants (e.g.
<code>@variant hover, focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Support <code>--default(…)</code> in <code>--value(…)</code> and
<code>--modifier(…)</code> for functional <code>@utility</code>
definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19989">#19989</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ensure <code>@plugin</code> resolves package JavaScript entries
instead of browser CSS entries when using <code>@tailwindcss/vite</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19949">#19949</a>)</li>
<li>Fix relative <code>@import</code> and <code>@plugin</code> paths
resolving from the wrong directory when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19965">#19965</a>)</li>
<li>Ensure CSS files containing <code>@variant</code> are processed by
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19966">#19966</a>)</li>
<li>Resolve imports relative to <code>base</code> when
<code>result.opts.from</code> is not provided when using
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19980">#19980</a>)</li>
<li>Canonicalization: preserve significant <code>_</code> whitespace in
arbitrary values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: add parentheses when removing whitespace from
arbitrary values would hurt readability (e.g.
<code>w-[calc(100%---spacing(60))]</code> →
<code>w-[calc(100%-(--spacing(60)))]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: preserve the original unit in arbitrary values
instead of normalizing to base units (e.g. <code>-mt-[20in]</code> →
<code>mt-[-20in]</code>, not <code>mt-[-1920px]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19988">#19988</a>)</li>
<li>Canonicalization: migrate arbitrary <code>:has()</code> variants
from <code>[&amp;:has(…)]</code> to <code>has-[…]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19991">#19991</a>)</li>
<li>Upgrade: don’t migrate inline <code>style</code> attributes (e.g.
<code>style=&quot;flex-grow: 1&quot;</code> →
<code>style=&quot;flex-grow: 1&quot;</code>, not <code>style=&quot;grow:
1&quot;</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19918">#19918</a>)</li>
<li>Allow multiple <code>@utility</code> definitions with the same name
but different value types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19777">#19777</a>)</li>
<li>Export missing <code>PluginWithConfig</code> type from
<code>tailwindcss/plugin</code> to fix errors when inferring plugin
config types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19707">#19707</a>)</li>
<li>Ensure <code>start</code> and <code>end</code> legacy utilities
without values do not generate CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20003">#20003</a>)</li>
<li>Ensure <code>--value(…)</code> is required in functional
<code>@utility</code> definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20005">#20005</a>)</li>
<li>Canonicalization: preserve required whitespace around operators in
negated arbitrary values (e.g. <code>-left-[(var(--a)+var(--b))]</code>)
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20011">#20011</a>)</li>
</ul>
<h2>[4.2.4] - 2026-04-21</h2>
<h3>Fixed</h3>
<ul>
<li>Ensure imports in <code>@import</code> and <code>@plugin</code>
still resolve correctly when using Vite aliases in
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19947">#19947</a>)</li>
</ul>
<h2>[4.2.3] - 2026-04-20</h2>
<h3>Fixed</h3>
<ul>
<li>Canonicalization: improve canonicalization for
<code>tracking-*</code> utilities by preferring non-negative utilities
(e.g. <code>-tracking-tighter</code> → <code>tracking-wider</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19827">#19827</a>)</li>
<li>Fix crash due to invalid characters in candidate (exceeding valid
unicode code point range) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19829">#19829</a>)</li>
<li>Ensure query params in imports are considered unique resources when
using <code>@tailwindcss/webpack</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19723">#19723</a>)</li>
<li>Canonicalization: collapse arbitrary values into shorthand utilities
(e.g. <code>px-[1.2rem] py-[1.2rem]</code> → <code>p-[1.2rem]</code>)
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19837">#19837</a>)</li>
<li>Canonicalization: collapse <code>border-{t,b}-*</code> into
<code>border-y-*</code>, <code>border-{l,r}-*</code> into
<code>border-x-*</code>, and <code>border-{t,r,b,l}-*</code> into
<code>border-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>scroll-m{t,b}-*</code> into
<code>scroll-my-*</code>, <code>scroll-m{l,r}-*</code> into
<code>scroll-mx-*</code>, and <code>scroll-m{t,r,b,l}-*</code> into
<code>scroll-m-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>scroll-p{t,b}-*</code> into
<code>scroll-py-*</code>, <code>scroll-p{l,r}-*</code> into
<code>scroll-px-*</code>, and <code>scroll-p{t,r,b,l}-*</code> into
<code>scroll-p-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>overflow-{x,y}-*</code> into
<code>overflow-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Canonicalization: collapse <code>overscroll-{x,y}-*</code> into
<code>overscroll-*</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19842">#19842</a>)</li>
<li>Read from <code>--placeholder-color</code> instead of
<code>--background-color</code> for <code>placeholder-*</code> utilities
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19843">#19843</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/588bd7371f4cae96426e1387819b7fd1d99765f9"><code>588bd73</code></a>
4.3.0 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20023">#20023</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/59936c6cbb69eae114bc52d0a3c9315b18c70a94"><code>59936c6</code></a>
Add <code>tab-*</code> utilities (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20022">#20022</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/90a2373620200bf7e04d1d228a0d0a1c506e532a"><code>90a2373</code></a>
add <code>zoom-*</code> utilities (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20020">#20020</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/2e1ccf7f115732032d2b079073dcb0009baf82a0"><code>2e1ccf7</code></a>
Add <code>scrollbar-gutter-*</code> utilities (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20018">#20018</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/754e7512ca51db1f922dc67724cf85a0fde923a9"><code>754e751</code></a>
Use non-existing example in tests (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20021">#20021</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/12eb5ae7b6026ff64c04f889b2221418d772da72"><code>12eb5ae</code></a>
Cleanup noisy test output (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20015">#20015</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/4255671c5f792c42808ecd6b2dec27c16e3c559e"><code>4255671</code></a>
Improve snapshot tests (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20013">#20013</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/8c779899bbc94f9f642db47cafdd363dd094984a"><code>8c77989</code></a>
Ensure math operators are surrounded by whitespace in arbitrary values
(<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20011">#20011</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/b4db3b99d1bc6209a936df34914e0fc34b3e5095"><code>b4db3b9</code></a>
Add scrollbar-width and scrollbar-color utilities (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/19981">#19981</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/08cad84bbe2002398655d7f981eae47379e07fc3"><code>08cad84</code></a>
Support <code>--default(…)</code> in <code>--value(…)</code> and
<code>--modifier(…)</code> to support fallbac...</li>
<li>Additional commits viewable in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/tailwindcss">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for tailwindcss 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-06-06 23:33:37 -07:00
dependabot[bot] fcc8cda5b2 build(deps-dev): bump storybook from 10.3.5 to 10.4.2 (#7571)
Bumps
[storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core)
from 10.3.5 to 10.4.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">storybook's
releases</a>.</em></p>
<blockquote>
<h2>v10.4.2</h2>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>v10.4.1</h2>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run `npx expo install --fix` after init for Expo projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support `peerDependencies` in framework detection for component
libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>v10.4.0</h2>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<ul>
<li>🤖 Agentic Setup: New CLI workflow for AI-assisted Storybook setup
and onboarding</li>
<li>🔍 Change review: Sidebar filtering to highlight new, modified, and
related stories based on git changes</li>
<li>🧭 Sidebar review tools: Status filtering, URL-persisted filters, and
clearer review signals in the sidebar</li>
<li>⚛️ TanStack React: New `@storybook/tanstack-react` framework with
routing and server function support</li>
<li>🧩 React MCP: Faster, more accurate component docgen powered by the
TypeScript Language Server</li>
<li>📱 React Native: Zero config RN project initialization</li>
<li>🤝 Sharing: Easily publish and share your local Storybook with
teammates, powered by Chromatic</li>
</ul>
<!-- raw HTML omitted -->
<ul>
<li>A11y: Add aria-live announcements via
<code>@​react-aria/live-announcer</code> - <a
href="https://redirect.github.com/storybookjs/storybook/pull/33970">#33970</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>A11y: Improve boolean control contrast in forced colors mode - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34204">#34204</a>,
thanks <a
href="https://github.com/anchmelev"><code>@​anchmelev</code></a>!</li>
<li>Actions: Fix state mutation and keep newest actions when limit
reached - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34286">#34286</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon-Docs: Add Reset story button to re-render stories in docs - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34086">#34086</a>,
thanks <a
href="https://github.com/6810779s"><code>@​6810779s</code></a>!</li>
<li>Addon-Docs: Avoid rerendering static Source blocks - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34206">#34206</a>,
thanks <a
href="https://github.com/anchmelev"><code>@​anchmelev</code></a>!</li>
<li>Addon-Vitest: Use Vitest's provide-API for injecting values - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34518">#34518</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>Agentic Setup: Add --extensive for an extra prompt - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34730">#34730</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Agentic Setup: Allow failed stories to persist - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34717">#34717</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Agentic Setup: Keep sample content if users want onboarding - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34704">#34704</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Agentic Setup: Rework ai-init-opt-in logic - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34739">#34739</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Angular: Use Story ID for renderer IDs (including standalone
stories) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/33982">#33982</a>,
thanks <a
href="https://github.com/ValentinFunk"><code>@​ValentinFunk</code></a>!</li>
<li>Automigration: Move RN on-device addons to `deviceAddons` - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34659">#34659</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>Builder-Vite: Add onModuleGraphChange method - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34323">#34323</a>,
thanks <a
href="https://github.com/ghengeveld"><code>@​ghengeveld</code></a>!</li>
<li>CLI: Add automigrate check for 'storybook' package name conflict -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34290">#34290</a>,
thanks <a href="https://github.com/whdjh"><code>@​whdjh</code></a>!</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">storybook's
changelog</a>.</em></p>
<blockquote>
<h2>10.4.2</h2>
<ul>
<li>Bug: Fix Windows command resolution for non-Node package managers -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/33534">#33534</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CSF: Fix parsing of string literal export names - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34901">#34901</a>,
thanks <a
href="https://github.com/shilman"><code>@​shilman</code></a>!</li>
<li>Publish: Add npm provenance attestations - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34936">#34936</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
</ul>
<h2>10.4.1</h2>
<ul>
<li>Angular: Detect model() signal outputs (type inference + compodoc
autodocs + runtime binding) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34833">#34833</a>,
thanks <a
href="https://github.com/valentinpalkovic"><code>@​valentinpalkovic</code></a>!</li>
<li>Build: Upgrade type-fest to latest version 5.6.0 - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34791">#34791</a>,
thanks <a
href="https://github.com/tobiasdiez"><code>@​tobiasdiez</code></a>!</li>
<li>CLI: Run <code>npx expo install --fix</code> after init for Expo
projects - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34803">#34803</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>CLI: Support <code>peerDependencies</code> in framework detection
for component libraries - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34516">#34516</a>,
thanks <a
href="https://github.com/zhyd1997"><code>@​zhyd1997</code></a>!</li>
<li>Next.js: Add useLinkStatus mock to next/link export mock - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34593">#34593</a>,
thanks <a
href="https://github.com/philwolstenholme"><code>@​philwolstenholme</code></a>!</li>
<li>Vue3: Specify a specific version for non-dev dependency - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34794">#34794</a>,
thanks <a
href="https://github.com/ScopeyNZ"><code>@​ScopeyNZ</code></a>!</li>
</ul>
<h2>10.4.0</h2>
<blockquote>
<p><em>AI-assisted setup, change-aware review, and stronger framework
support</em></p>
</blockquote>
<p>Storybook 10.4 contains hundreds of fixes and improvements
including:</p>
<ul>
<li>🤖 Agentic Setup: New CLI workflow for AI-assisted Storybook setup
and onboarding</li>
<li>🔍 Change review: Sidebar filtering to highlight new, modified, and
related stories based on git changes</li>
<li>🧭 Sidebar review tools: Status filtering, URL-persisted filters, and
clearer review signals in the sidebar</li>
<li>⚛️ TanStack React: New <code>@storybook/tanstack-react</code>
framework with routing and server function support</li>
<li>🧩 React MCP: Faster, more accurate component docgen powered by the
TypeScript Language Server</li>
<li>📱 React Native: Zero config RN project initialization</li>
<li>🤝 Sharing: Easily publish and share your local Storybook with
teammates, powered by Chromatic</li>
</ul>
<!-- raw HTML omitted -->
<ul>
<li>A11y: Add aria-live announcements via
<code>@​react-aria/live-announcer</code> - <a
href="https://redirect.github.com/storybookjs/storybook/pull/33970">#33970</a>,
thanks <a
href="https://github.com/copilot-swe-agent"><code>@​copilot-swe-agent</code></a>!</li>
<li>A11y: Improve boolean control contrast in forced colors mode - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34204">#34204</a>,
thanks <a
href="https://github.com/anchmelev"><code>@​anchmelev</code></a>!</li>
<li>Actions: Fix state mutation and keep newest actions when limit
reached - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34286">#34286</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Addon-Docs: Add Reset story button to re-render stories in docs - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34086">#34086</a>,
thanks <a
href="https://github.com/6810779s"><code>@​6810779s</code></a>!</li>
<li>Addon-Docs: Avoid rerendering static Source blocks - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34206">#34206</a>,
thanks <a
href="https://github.com/anchmelev"><code>@​anchmelev</code></a>!</li>
<li>Addon-Vitest: Use Vitest's provide-API for injecting values - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34518">#34518</a>,
thanks <a
href="https://github.com/JReinhold"><code>@​JReinhold</code></a>!</li>
<li>Agentic Setup: Add --extensive for an extra prompt - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34730">#34730</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Agentic Setup: Allow failed stories to persist - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34717">#34717</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Agentic Setup: Keep sample content if users want onboarding - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34704">#34704</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Agentic Setup: Rework ai-init-opt-in logic - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34739">#34739</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
<li>Angular: Use Story ID for renderer IDs (including standalone
stories) - <a
href="https://redirect.github.com/storybookjs/storybook/pull/33982">#33982</a>,
thanks <a
href="https://github.com/ValentinFunk"><code>@​ValentinFunk</code></a>!</li>
<li>Automigration: Move RN on-device addons to <code>deviceAddons</code>
- <a
href="https://redirect.github.com/storybookjs/storybook/pull/34659">#34659</a>,
thanks <a
href="https://github.com/ndelangen"><code>@​ndelangen</code></a>!</li>
<li>Builder-Vite: Add onModuleGraphChange method - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34323">#34323</a>,
thanks <a
href="https://github.com/ghengeveld"><code>@​ghengeveld</code></a>!</li>
<li>CLI: Add automigrate check for 'storybook' package name conflict -
<a
href="https://redirect.github.com/storybookjs/storybook/pull/34290">#34290</a>,
thanks <a href="https://github.com/whdjh"><code>@​whdjh</code></a>!</li>
<li>CLI: Add react-vite to tanstack-react automigration - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34718">#34718</a>,
thanks <a
href="https://github.com/huang-julien"><code>@​huang-julien</code></a>!</li>
<li>CLI: Change mock event detection - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34586">#34586</a>,
thanks <a
href="https://github.com/yannbf"><code>@​yannbf</code></a>!</li>
<li>CLI: Explicitly tell whether smoke tests passed or failed - <a
href="https://redirect.github.com/storybookjs/storybook/pull/34419">#34419</a>,
thanks <a
href="https://github.com/Sidnioulz"><code>@​Sidnioulz</code></a>!</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/storybookjs/storybook/commit/298dea20c6370e5c670178d88a79fc9e9ff436b2"><code>298dea2</code></a>
Bump version from &quot;10.4.1&quot; to &quot;10.4.2&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/40c81c8187ceed7d09b32a470d6f54c91c3fba72"><code>40c81c8</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/33534">#33534</a>
from storybookjs/copilot/fix-pnpm-command-resolutio...</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/bfb942b53274b0a1b5c6d76f669cc6f8bf1c6a12"><code>bfb942b</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34901">#34901</a>
from storybookjs/shilman/fix-csf-export-as-string-l...</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/fad8dd2b63840548b710457be0bd87034d0f1f3c"><code>fad8dd2</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34791">#34791</a>
from tobiasdiez/type-fest-upgrade</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/cc19ae1a2145e8f7cda8dc869f1b90d5346dcedb"><code>cc19ae1</code></a>
Bump version from &quot;10.4.0&quot; to &quot;10.4.1&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/f8c16d115cfcf0f79125b358266c37e5343bb70d"><code>f8c16d1</code></a>
Bump version from &quot;10.4.0-beta.0&quot; to &quot;10.4.0&quot; [skip
ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/e02da0b0d4cf9673999184b8f11c85b026954b69"><code>e02da0b</code></a>
Bump version from &quot;10.4.0-alpha.19&quot; to
&quot;10.4.0-beta.0&quot; [skip ci]</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/6fe5959088c671aab5abe1d633f62d2937b8ef47"><code>6fe5959</code></a>
Merge branch 'next' into next-release</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/f9810c79241094cb2f3b01e011e8641f9f59f8eb"><code>f9810c7</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34769">#34769</a>
from storybookjs/jeppe/handle-minimum-release-age</li>
<li><a
href="https://github.com/storybookjs/storybook/commit/db9d52b4a9aae0b7bd8b0903fa39719d0a441b6a"><code>db9d52b</code></a>
format</li>
<li>Additional commits viewable in <a
href="https://github.com/storybookjs/storybook/commits/v10.4.2/code/core">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-06-06 23:23:26 -07:00
Dotta bb880d9948 [codex] Polish issue interaction selectors (#7668)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents for work.
> - Issue-thread interactions are the board/agent handoff surface for
structured decisions and confirmations.
> - Accepted checkbox confirmations can include many selected labels,
and inline selectors must stay usable across desktop and mobile devices.
> - The existing accepted checkbox summary capped labels behind a static
`+N more` chip, so operators could not inspect the hidden selections
from the card.
> - The inline selector also skipped search focus on coarse pointers,
which made mobile selection slower and less predictable.
> - This pull request makes the hidden checkbox selections expandable
and restores search focus when the selector opens.
> - The benefit is a more inspectable, faster interaction UI without
changing the interaction API contract.

## Linked Issues or Issue Description

Internal source work: [PAP-10488](/PAP/issues/PAP-10488), split from
[PAP-10495](/PAP/issues/PAP-10495).

### Subsystem affected

ui/ - React + Vite board UI

### Problem or motivation

Accepted checkbox confirmations hide selected values behind a static
count, and inline selector search does not focus on mobile/coarse
pointer devices. That makes accepted interaction cards less inspectable
and makes mobile selection slower than it needs to be.

### Proposed solution

Make hidden accepted checkbox selections expandable/collapsible directly
in the interaction card, and focus the inline selector search input
whenever the selector opens, including coarse pointer environments.

### Alternatives considered

Leaving the static `+N more` chip avoids UI state, but it keeps selected
values hidden from operators. Only restoring desktop focus keeps the old
mobile/coarse pointer gap, so the focus behavior should be consistent
across pointer types.

### Roadmap alignment

This is a small board UI polish change for the existing issue
interaction surface. It does not add a new core roadmap capability or
change the API contract.

## What Changed

- Converted the accepted checkbox `+N more` chip into an expandable
button with a `Show less` control.
- Restored search input focus whenever `InlineEntitySelector` opens,
including coarse pointer environments.
- Updated focused component tests for the expanded selection summary and
mobile/coarse-pointer focus path.
- Adjusted the interaction card test harness to use the same `flushSync`
act helper style used by nearby focused component tests.

## Verification

- `pnpm exec vitest run
ui/src/components/IssueThreadInteractionCard.test.tsx
ui/src/components/InlineEntitySelector.test.tsx` passed in
`~paperclipai/paperclip/.paperclip/worktrees/PAP-10495-interaction-selector-polish`.

## Risks

- Low risk. The change is limited to UI state and focus behavior in
existing components.
- Restoring focus on coarse pointers may open a virtual keyboard on
mobile, but that is intentional for the faster search workflow requested
by this branch.

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

## Model Used

- OpenAI Codex coding agent based on GPT-5, with local repository
inspection, shell execution, git, and GitHub CLI tool use. Runtime
context window was not exposed by the environment.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-06 16:19:31 -05:00
Dotta 86253f52a7 [codex] Render video artifact thumbnails (#7667)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents for work.
> - The artifacts surface is where operators inspect concrete outputs
from agent work.
> - Video artifacts currently render as HTML video previews, but
browsers often paint a blank first frame until a playable frame is
decoded.
> - That makes generated video work products harder to recognize from
the artifacts grid.
> - This pull request seeks a tiny thumbnail frame after metadata loads
and fades the video preview in once a frame is ready.
> - The benefit is that video artifacts are easier to scan without
changing the artifact data model or download flow.

## Linked Issues or Issue Description

Internal source work: PAP-10477, split from PAP-10495.

### What happened?

Video artifact cards can show a blank or black preview in the artifacts
grid even when the underlying video artifact is valid and playable.

### Expected behavior

Video artifact cards should paint a representative frame so operators
can visually scan generated videos from the artifact grid.

### Steps to reproduce

1. Generate or upload a video artifact whose first decoded frame is not
immediately painted by the browser.
2. Open the artifacts grid or an issue surface that renders artifact
cards.
3. Observe that the video preview can appear blank until playback or
decoding catches up.

### Paperclip version or commit

`3c65f784b640a0012ce4672c1295331d4acd8a0c` before this PR.

### Deployment mode

Board UI component behavior in local dev and hosted deployments; no
database or API behavior changes.

## What Changed

- Video artifact previews now seek to a small timestamp after metadata
loads so a real frame can be painted.
- The preview remains hidden until a frame is ready, while preserving
the existing play overlay and error fallback.
- Added a timeout safety valve so unusual media that never reports seek
completion still becomes visible.
- Added jsdom component tests covering metadata load, seek, frame-ready
behavior, and the silent seek fallback.

## Screenshots

| Before frame ready | After frame ready |
| --- | --- |
| ![Video artifact card before frame
ready](https://gist.githubusercontent.com/cryppadotta/1de42c1fa916520703771bd9ad20399a/raw/01af0d1aefe9fa3227f9b92232ff7cdce73c6c3f/pap-10499-before.svg)
| ![Video artifact card after frame
ready](https://gist.githubusercontent.com/cryppadotta/1de42c1fa916520703771bd9ad20399a/raw/0ce810ca33e2401176fbe1e18718e6644ad8c65f/pap-10499-after.svg)
|

## Verification

- `pnpm exec vitest run
ui/src/components/artifacts/ArtifactCard.test.tsx` passed in
`.paperclip/worktrees/PAP-10495-artifact-video-thumbnails`.
- `pnpm --filter @paperclipai/ui build` passed in
`.paperclip/worktrees/PAP-10495-artifact-video-thumbnails`.
- `pnpm build` passed in
`.paperclip/worktrees/PAP-10495-artifact-video-thumbnails` before the
Greptile fallback patch; the post-patch UI build covers the changed
TypeScript/Vite surface.

## Risks

- Low risk. The change is limited to UI preview rendering for video
artifacts.
- Some browsers may reject or silently ignore programmatic seeking for
unusual media; the code now falls back to revealing the preview after a
short timeout rather than leaving the video invisible.

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

## Model Used

- OpenAI Codex coding agent based on GPT-5, with local repository
inspection, shell execution, git, and GitHub CLI tool use. Runtime
context window was not exposed by the environment.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-06 16:18:25 -05:00
Dotta 71a8464fee [codex] prevent invalid agents from receiving assignments and runs (#7663)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The control plane owns agent lifecycle, issue assignment, routine
dispatch, heartbeat wakeups, and recovery paths
> - Terminated, paused, pending-approval, or otherwise invalid agents
should not receive new work or new execution attempts
> - The old behavior left eligibility checks spread across routes and
services, so assignment and run paths could drift apart
> - This pull request centralizes agent lifecycle eligibility and
applies it consistently to assignment, invocation, routines, recovery,
and UI affordances
> - The benefit is safer autonomy: terminated agents stay paused,
invalid org-chain agents are surfaced, and active agents keep receiving
valid work

## Linked Issues or Issue Description

Refs #5103
Related: #1864

Bug fix context:
- What happened: agent assignment and heartbeat/run paths did not share
one eligibility contract, so invalid lifecycle states could still be
considered in some paths.
- Expected behavior: terminated agents must never receive new
assignments or heartbeat runs, and paused or otherwise invalid agents
should be treated as non-invokable consistently.
- Steps to reproduce: create or select an agent in an invalid lifecycle
state, then attempt assignment, routine dispatch, or heartbeat/recovery
wake paths.
- Paperclip version/commit: fixed on top of `paperclipai/paperclip`
`master` at the PR base.
- Deployment mode: applies to the server control plane in local and
authenticated deployments.

## What Changed

- Added shared agent lifecycle eligibility helpers and exported the
related shared types.
- Centralized server-side assignability and invokability checks for
issue assignment, agent routes, heartbeat dispatch, routines, recovery,
and liveness logic.
- Hardened issue assignment so invalid assignees are rejected instead of
queued for work.
- Hardened heartbeat/routine/recovery paths so terminated and otherwise
invalid agents are not woken for new runs.
- Updated board UI affordances to disable invalid agent actions and
surface org-chain warnings where relevant.
- Added targeted shared, server, and UI tests for the new eligibility
behavior.

## Verification

- `pnpm exec vitest run packages/shared/src/agent-eligibility.test.ts
server/src/__tests__/agent-invokability.test.ts
server/src/__tests__/heartbeat-archived-company-guard.test.ts
server/src/__tests__/issue-liveness.test.ts
server/src/__tests__/issues-service.test.ts
server/src/__tests__/routines-service.test.ts
ui/src/lib/company-members.test.ts ui/src/pages/Agents.test.tsx` — 8
files, 144 tests passed.
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck && pnpm --filter @paperclipai/ui
typecheck` — passed.
- Checked the PR diff does not include `pnpm-lock.yaml` or
`.github/workflows` changes.
- Checked `ROADMAP.md`; this is a targeted control-plane safety fix and
does not duplicate a planned core feature.
- Searched GitHub for duplicate or related PRs/issues; closest related
items are linked above.
- CI and Greptile verification are pending on the opened PR and will be
followed up before requesting merge.

## Risks

Low to moderate risk. The intended behavioral shift is that invalid
agents are refused earlier and more consistently, which could expose
existing data with paused, pending, terminated, or broken org-chain
assignees. The added tests cover the critical assignment, heartbeat,
routine, recovery, shared helper, and UI paths. No database migrations
are included.

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

## Model Used

OpenAI GPT-5 Codex via the Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use. Reasoning mode and context window are
managed by the adapter runtime and not exposed in this environment.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots (not applicable: no design screenshots requested; UI
behavior is covered by tests)
- [x] I have updated relevant documentation to reflect my changes (not
applicable: no user-facing command or schema docs changed)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (pending CI)
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(pending Greptile)
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-06 12:45:57 -05:00
Dotta 139cdebe51 [codex] Improve login accessibility and password-manager metadata (#7660)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Human operators sign in through the main auth page and through
invite acceptance flows.
> - Those forms need to be understandable to assistive technology and
password managers.
> - The login fields did not consistently expose stable names, ids,
autocomplete hints, required state, and error relationships.
> - That made it easier for password managers such as 1Password to miss
the username/password pairing and harder for screen readers to associate
validation errors.
> - This pull request tightens the auth and invite form metadata while
keeping the visible flow unchanged.
> - The benefit is a smoother login and invite-acceptance experience
without changing server-side auth behavior.

## Linked Issues or Issue Description

No matching GitHub issue found after searching `login accessibility
1Password username password` in `paperclipai/paperclip` issues and PRs.

## What happened?

Login and invite auth fields were missing password-manager and
accessibility metadata, including stable field identifiers, autocomplete
hints, required semantics, and error-region relationships. That made it
easier for password managers such as 1Password to miss the
username/password pairing and harder for screen readers to associate
validation errors.

## Expected behavior

Auth fields should be discoverable as username/password fields,
distinguish sign-in and sign-up password autocomplete behavior, and
expose validation errors through an alert region referenced by invalid
inputs.

## Steps to reproduce

1. Open the main `/auth` form or an invite auth form.
2. Inspect the email, password, and sign-up name field attributes.
3. Trigger a validation/auth error and inspect whether invalid inputs
reference the displayed error text.

## Paperclip version or commit

Prior to this PR on `master`.

## Deployment mode

Board UI, all deployments using these forms.

## What Changed

- Added stable `id`, `name`, `required`, `aria-required`,
`aria-invalid`, `aria-describedby`, and autocomplete metadata to the
main auth form.
- Added invite auth field metadata so invite sign-up uses
`new-password`, invite sign-in uses `current-password`, and the email
field is recognized as `username`.
- Added alert regions for auth and invite auth errors so invalid fields
can reference the displayed error text.
- Added focused Vitest coverage for the main auth form and invite auth
flow metadata/error behavior.

## Verification

- `pnpm exec vitest run ui/src/pages/Auth.test.tsx
ui/src/pages/InviteLanding.test.tsx` passes: 2 files, 16 tests.
- `pnpm build` passes locally.
- PR CI is green on head `3531d1900`, including Build, Canary Dry Run,
Typecheck + Release Registry, e2e, general/serialized test shards,
policy, commitperclip review, security checks, and aggregate `verify`.
- Greptile Review is passing on head `3531d1900`; the P2
alert/live-region review thread was fixed and resolved.
- Rebasing onto `public-gh/master` completed cleanly; current base ref
is `e50666e4c`.
- Confirmed the branch diff does not include `pnpm-lock.yaml`,
`.github/workflows`, migrations, or design/image assets.
- No screenshots attached: this is a form metadata/accessibility change,
and the task specifically asked not to add design screenshots or images
unless they are part of the work.

## Risks

Low risk. The change is limited to UI form attributes and error wiring.
Main risk is password-manager/browser interpretation differences,
covered by asserting the emitted DOM metadata rather than a specific
vendor integration.

> 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-based coding model with repository tool use and
shell execution. Exact hosted model ID/context window are not exposed in
this runtime.

## Checklist

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 11:40:59 -05:00