Commit Graph

2783 Commits

Author SHA1 Message Date
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
uky333 eb68198c42 feat(adapter-claude-local): emit errorCode claude_refusal on stop_reason refusal (#8314)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run through adapters; `@paperclipai/adapter-claude-local`
shells out to the Claude CLI and maps its result JSON into Paperclip's
run outcome (`errorCode` / `errorFamily`)
> - A Fable 5 policy refusal exits the CLI cleanly (`exitCode=0`,
`is_error=false`) with `stop_reason: "refusal"`, which the adapter
mapped to `errorCode: null`
> - Paperclip therefore recorded the run as a silent success, so the
agent's heartbeat stalled with no signal for operators and no hook to
retry or alert
> - This pull request adds a refusal detector to the adapter so a
refusal resolves to a distinct `errorCode: "claude_refusal"`
(`errorFamily: "model_refusal"`)
> - The benefit is that policy refusals become observable: the server
persists the code, operators can see it on the run, and downstream
retry/alert policy can key off it

## Linked Issues or Issue Description

No public GitHub issue exists. Describing the underlying bug in-PR,
following `.github/ISSUE_TEMPLATE/bug_report.yml`:

**What happened?**
When the Claude CLI returns `stop_reason: "refusal"` (a model policy
refusal), it still exits cleanly (`exitCode=0`, `is_error=false`).
`@paperclipai/adapter-claude-local` keyed refusal detection off the
failure flag during error-code resolution, so it returned `errorCode:
null` — a refused run was indistinguishable from a successful one,
recorded by Paperclip as a silent success with no signal to retry or
alert.

**Expected behavior**
A refusal should resolve to a distinct, non-null error code (`errorCode:
"claude_refusal"`, `errorFamily: "model_refusal"`) so the server can
surface it to operators and downstream policy can react.

**Steps to reproduce**
1. Run any agent on the `claude-local` adapter with a prompt the model
refuses on policy grounds.
2. The Claude CLI exits `0` with `is_error=false` and `stop_reason:
"refusal"`.
3. Observe the run resolves `errorCode: null` (pre-fix) instead of a
refusal-specific code.

**Paperclip version or commit**
`adapter-claude-local` v2026.609.0 (`dist/server/execute.js` error-code
resolution block); reproduced on `master`.

**Deployment mode**
Local / self-hosted.

**Agent adapter(s) involved**
`@paperclipai/adapter-claude-local` (Claude Code, local).

## What Changed

- **`packages/adapters/claude-local/src/server/parse.ts`** — new
`isClaudeRefusalResult()` helper, parallel to
`isClaudeMaxTurnsResult()`. Detects `stop_reason` / `stopReason` /
`error_code` / `errorCode` == `refusal` and `subtype` ==
`model_refusal`, case/whitespace tolerant.
- **`packages/adapters/claude-local/src/server/execute.ts`** — compute
the refusal flag independent of the `failed` flag (a refusal exits
cleanly, so keying off `failed` would miss it); resolve `errorCode:
"claude_refusal"` and `errorFamily: "model_refusal"`; surface
`stopReason: "refusal"` in `resultJson`.
- **`packages/adapter-utils/src/types.ts`** — widen
`AdapterExecutionErrorFamily` with `"model_refusal"`.
- **`packages/adapters/claude-local/src/server/index.ts`** — export the
new helper.
- **`packages/adapters/claude-local/src/server/parse.test.ts`** — 7 new
unit tests.

## Verification

```
npx vitest run packages/adapters/claude-local           # 35 passed (7 new)
npx tsc --noEmit -p packages/adapter-utils              # clean
npx tsc --noEmit -p packages/adapters/claude-local      # clean
```

Manual: a result JSON with `stop_reason: "refusal"` on a clean exit now
resolves `errorCode: "claude_refusal"` and `errorFamily:
"model_refusal"`; non-refusal results are unaffected.

## Risks

Low risk. Additive only — it introduces a new error code on a path that
previously returned `null`; no existing error code or success path
changes. `claude_refusal` is deliberately **not** added to the
transient-upstream retry set: a refusal is deterministic, so retrying
the same prompt yields the same refusal. It surfaces as a distinct
non-transient code for operators; downstream retry/alert policy can key
off `claude_refusal` / `errorFamily: model_refusal` later.

## Model Used

Claude Opus 4.8 (`claude-opus-4-8`), extended-thinking mode, run via
Claude Code with 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 (no related PRs found)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] 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 — no UI changes)
- [x] I have updated relevant documentation to reflect my changes (N/A —
internal adapter error-code addition; no user-facing docs)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (this push re-runs the gates;
will confirm once green)
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(prior run was 4/5 on a PR-description note now addressed; will confirm
on re-run)
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Full-Stack Engineer <noreply@paperclip.ing>
2026-06-19 23:24:06 -07:00
levineam 631b7806ed Add heartbeat preflight budget caps (#8347)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Heartbeats are the control-plane path that turns scheduled,
comment-driven, or on-demand wakeups into adapter executions.
> - Budgeting and recurring work need enforcement before an adapter
starts, not only after model usage is recorded.
> - Empty timer wakes also need an opt-in fast-exit path so operators
can keep routine schedules without paying for no-op model turns.
> - This pull request adds heartbeat preflight gates for daily run and
daily cost caps, plus an explicit timer no-work skip policy.
> - The benefit is safer autonomous operation: capped agents stop before
new execution, queued work is cancelled cleanly at claim time, and
proactive agents still run by default unless the operator opts into
no-work skipping.

## Linked Issues or Issue Description

No public issue exists for this change. Inline bug report:

### What happened?

Heartbeat execution can start without enforcing per-agent daily
invocation and spend limits at the heartbeat boundary. A run that was
queued before a cap was reached can also be claimed later and invoke the
adapter unless the cap is checked again immediately before execution.
Operators also do not have an explicit opt-in fast-exit policy for
generic timer wakes with no actionable assigned work.

### Expected behavior

Configured daily run and daily cost caps should stop new heartbeat runs
before adapter execution. Already queued runs should be rechecked at
claim time and cancelled cleanly when a cap is now reached. Queued issue
runs cancelled by daily caps should release their issue execution locks
and promote deferred wakeups without entering immediate recovery loops.
Generic timer no-work skipping should be opt-in so proactive agents
continue to run by default.

### Steps to reproduce

1. Configure an agent heartbeat policy with a one-run daily cap or a
daily cost cap.
2. Create or queue heartbeat wakeups for that agent after the cap has
already been consumed.
3. Observe that without preflight and claim-time checks, the heartbeat
path can still enqueue or claim work that should be blocked before
adapter execution.

### Paperclip version or commit

Reproduced against `master` before this branch.

### Deployment mode

Local dev (`pnpm dev`) / built from source.

### Installation method

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

### Agent adapter(s) involved

Not adapter-specific (core heartbeat scheduling and claim logic).

### Database mode

External Postgres in tests via embedded test harness.

### Access context

Not applicable.

### Node.js version

Node 20 in CI-compatible local development.

### Operating system

macOS local development, Linux CI-compatible tests.

### Relevant logs or output

The regression suite added in this PR covers the failing paths:

```shell
pnpm exec vitest run server/src/__tests__/heartbeat-stale-queue-invalidation.test.ts
```

### Relevant config (if applicable)

```json
{
  "heartbeat": {
    "maxDailyRuns": 1,
    "maxDailyCostCents": 1,
    "skipTimerWhenNoActionableWork": true
  }
}
```

### Additional context

This affects recurring/autonomous operation because the safest place to
stop excess work is before adapter execution starts.

### Privacy checklist

Reviewed for sensitive data; no private logs, credentials, or local
instance URLs are included.

## What Changed

- Added heartbeat policy parsing for per-agent daily run caps, daily
cost caps, and opt-in no-actionable-work timer skipping.
- Added pre-queue daily cap checks while preserving same-issue wake
coalescing.
- Added claim-time cap checks so already queued runs are cancelled
before adapter execution when a cap is reached.
- Added skipped wakeup metadata for cap and timer fast-exit decisions.
- Released issue execution locks for queued issue runs cancelled by
daily caps, with deferred wake promotion and without immediate recovery
loops while caps are active.
- Added regression coverage for timer skipping, proactive default
behavior, run caps, cost caps, queued-run cancellation, started
cancelled runs, and deferred issue wake promotion.

## Verification

- `git diff --check`
- `node -c server/src/services/heartbeat.ts`
- `pnpm exec vitest run
server/src/__tests__/heartbeat-stale-queue-invalidation.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- Local autoreview: `skills/autoreview/scripts/autoreview --mode branch
--base origin/master --engine codex --model gpt-5.5 --thinking high`
  - Result: clean, no accepted/actionable findings

## Risks

- Medium operational risk because this changes heartbeat scheduling and
claim-time behavior.
- The no-actionable-work timer fast-exit is explicitly opt-in to avoid
suppressing proactive agents unexpectedly.
- Daily run caps count runs by `startedAt` so old queued rows do not
consume today’s cap, while started runs still count even if they later
end as cancelled.
- Queued issue-run cap cancellation uses the existing release/promotion
path with immediate recovery suppressed to avoid retry loops while caps
are active.

## Model Used

Codex with GPT-5.5 high reasoning assisted with implementation, local
testing, and autoreview. The final review gate used local autoreview
with `gpt-5.5` high reasoning.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [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
2026-06-19 21:39:50 -07:00
Sergio Sánchez Zavala 323b6220cc Fix Gemini headless invocation stalls (#8368)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Local adapters turn Paperclip runs into unattended CLI invocations.
> - The `gemini_local` adapter depends on Gemini CLI behaving
non-interactively in headless worker sessions.
> - When Gemini CLI falls back to browser-based auth, the process can
stall at startup instead of producing stream-json output.
> - The adapter should make headless intent explicit and turn missing
auth into a classified, fast failure.
> - This pull request hardens the Gemini child-process environment and
parser classification around that failure mode.
> - The benefit is that operators get actionable `gemini_auth_required`
failures instead of silent hung runs.

## Linked Issues or Issue Description

No exact public issue exists for this runtime stall.

Related: #2344 covers a Gemini CLI adapter environment/auth probe
failure. This PR addresses a different runtime path: unattended
`gemini_local` executions that can stall when Gemini CLI attempts
interactive browser auth in a headless session.

Bug summary:
- Adapter: `gemini_local`
- Symptom: child Gemini CLI process starts but produces no stream-json
output when auth requires interactive browser flow
- Expected: unattended runs either produce stream-json output or fail
quickly with a classified auth error
- Actual: the run can hang at invocation until an external watchdog
kills it
- Scope: Gemini adapter process env, auth-required parsing, and adapter
docs/tests

Duplicate search performed:
- `gh pr list --state all --search "gemini headless invocation stall"`
found only this PR.
- `gh pr list --state all --search "gemini NO_BROWSER NO_COLOR"` found
only this PR.
- `gh issue list --state all --search "gemini headless authentication"`
found related issue #2344 but no exact duplicate.

## What Changed

- Set a headless-safe Gemini invocation env at the final child-process
boundary: `TERM=xterm-256color`, `COLORTERM=truecolor`, and
`NO_BROWSER=1`.
- Delete inherited `NO_COLOR` from the child env so Gemini CLI keeps
color-capable terminal behavior when deciding whether it can run
non-interactively.
- Classify Gemini `FatalAuthenticationError: Manual authorization is
required...` failures as `gemini_auth_required`.
- Update Gemini adapter docs to describe the non-interactive `--prompt`
path and headless env behavior.
- Add/extend focused parser and remote execution tests for the
auth-required and env invariants.

## Verification

- `pnpm exec vitest run
packages/adapters/gemini-local/src/server/parse.test.ts
packages/adapters/gemini-local/src/server/execute.remote.test.ts` — 23
tests passed.
- `pnpm --filter @paperclipai/adapter-gemini-local typecheck` — passed.
- Local Gemini CLI probe confirmed `NO_BROWSER=1` turns the browser-auth
stall into a fast auth error instead of an interactive wait.

## Risks

Low risk. The change is limited to `gemini_local` invocation env,
parsing, docs, and tests. It does not touch schemas, API routes,
persisted data, or other adapters.

Operational risk: environments that intentionally rely on `NO_COLOR`
being inherited by Gemini child processes will no longer pass that
variable through. That is intentional here because Gemini CLI
auth/headless behavior should not depend on inherited color suppression.

> 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 Codex CLI, with shell/file-editing tool use for
repository inspection, code edits, tests, and GitHub PR maintenance.

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

/cc @codex — please review.
2026-06-19 21:31:36 -07:00
Devin Foley 277a9a43d6 fix(recovery): convert review-parked continuations into dependency waits (#8371)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The productivity-recovery subsystem watches for "stranded" assigned
issues — claims whose live run disappeared — and repairs, resumes, or
visibly blocks them
> - When an executor decomposes an umbrella issue into sub-tasks, it
parks its own continuation as "waiting on review/approval" (error code
`issue_continuation_waiting_on_review`) — a deliberate pause, not a lost
run
> - Recovery's staleness gate mistook that deliberate park for a
disappeared run: it retried once, then escalated the issue to `blocked`
with a recovery action and an operator-facing failure notice — even
though nothing had failed and there was nothing for a human to do
> - The user is left staring at an inscrutable, over-technical
"stranded" error on a task they did nothing wrong with, with no idea
what action to take
> - This pull request teaches recovery to recognize a review-parked
continuation and, when the issue has a real waiting target (open
sub-tasks or unresolved blockers), convert it into a first-class
dependency wait: `blocked`-by-children, original assignee kept, plus a
plain-language comment saying it will resume automatically
> - The benefit is that post-decomposition umbrellas sit on a real
waiting path and self-resume through the normal blockers-resolved flow,
while genuine strands (no waiting target) still escalate exactly as
before

## Linked Issues or Issue Description

Refs #6503

## What Changed

- `server/src/services/recovery/service.ts`: add
`resolveContinuationWaitingOnReview`. When a continuation was cancelled
with `issue_continuation_waiting_on_review` and the issue has a real
waiting target — open (non-terminal) sub-tasks or existing unresolved
blockers — recovery sets the issue `blocked` by those issues, keeps the
original assignee, posts a plain-language `system` comment, and logs the
activity. Wired into `reconcileStrandedAssignedIssues` ahead of the
escalation path, with a new `waitingOnReviewResolved` counter on the
result.
- With no waiting target, the code falls through to the existing
escalation, preserving genuine stranded-run detection.
- `server/src/__tests__/heartbeat-process-recovery.test.ts`: two new
tests — (1) a review-parked continuation converts into a dependency wait
on its open sub-tasks (done children excluded, no recovery issue opened,
plain-language comment, raw error code never leaks), and (2) it still
escalates when no open dependency remains.
- `doc/execution-semantics.md`: document the "Deliberate wait is not a
lost run" recovery rule and the requirement that a post-decomposition
umbrella hold a first-class waiting path rather than relying on
`parentId` rollup.

## Verification

- `cd server && npx tsc --noEmit` — passes against current `master`.
- New tests in `server/src/__tests__/heartbeat-process-recovery.test.ts`
(describe: "heartbeat orphaned process recovery"):
- "converts a continuation parked for review into a dependency wait on
its open sub-tasks"
- "still escalates a continuation parked for review when no open
dependency remains"
- Run with the repo's vitest setup, e.g. `pnpm vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts` (requires the
embedded-postgres test harness).

## Risks

Low. The change adds a single guarded pre-check ahead of the existing
escalation path; behavior is unchanged when the cancellation error code
is not `issue_continuation_waiting_on_review` or when the issue has no
open sub-task / unresolved blocker to wait on. No schema or migration
changes.

## Model Used

Claude (Anthropic), Opus-class model, via the Claude Code agent harness
— extended thinking and tool use enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
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 (N/A — server-only)
- [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 (pending CI)
- [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-19 20:52:18 -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
Devin Foley 2853a9ae69 perf(ci): shard the general-server test lane across 3 runners (#8360)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Every PR runs the `PR` GitHub Actions workflow, whose `verify` gate
fans out into parallel test lanes (general tests, serialized server
route suites, build, typecheck)
> - The `General tests (server)` lane had grown into the run's critical
path: it executed all ~213 non-route server suites serially in a single
job (~7.2m of test time), more than 2x any other job
> - It runs serially because `server/vitest.config.ts` pins `maxWorkers:
1`, so server suites cannot parallelize within a single runner — the
only lever is spreading them across runners
> - This pull request shards that lane into 3 even partitions that run
on separate runners, mirroring the 4-way sharding already used for the
serialized route suites
> - The benefit is the lane drops from ~7.7m to ~2.4m/shard, cutting
overall PR wall time roughly in half (~8.5m → ~4.2m)

## Linked Issues or Issue Description

No public GitHub issue exists for this work, so the underlying issue is
described inline following the feature-request template.

### Problem or motivation

PR CI wall time had crept back up to ~8.5m. On a recent fully-green run,
the `General tests (server)` job took 7.72m — more than double any other
job and the clear critical path. Of that, 7.23m was pure test execution
(dependency install was a cached 0.27m). The job ran all server suites
that are not route/authz tests (213 files) one after another, because
the server vitest project pins `maxWorkers: 1`, making these suites
inherently serial within a single runner.

### Proposed solution

Shard the general-server lane across 3 parallel runners — the same
technique the route/authz suites already use — so the suite set is split
into even, deterministic partitions that run concurrently. Add a
regression test that proves the shards always cover the full suite set
with no gaps or overlap.

### Alternatives considered

- **Raise `maxWorkers` for the server project** to parallelize within
one runner — rejected: the server suites share process-level state
(DB/port), which is exactly why `maxWorkers: 1` is pinned.
- **Two shards instead of three** — would leave the lane at ~3.6m, still
above the next bottleneck (Canary Dry Run, ~4.1m wouldn't be the gate).
Three lands the lane comfortably below it.
- **Do nothing / accept the slow lane** — rejected: it gates every PR.

### Roadmap alignment

Developer-experience / CI tooling. Not core product roadmap work; does
not overlap with planned features in `ROADMAP.md`.

## What Changed

- `scripts/run-vitest-stable.mjs`: the `general-server` general-test
group now accepts `--shard-index` / `--shard-count`. It enumerates the
full server test set (the whole `server/src` tree, minus the route/authz
suites that already run in their own serialized shards) and splits it
deterministically by modulo. The non-sharded local invocation (`pnpm
test:run:general --group general-server`) is unchanged.
- `.github/workflows/pr.yml`: the `general_tests` matrix runs
`general-server` as 3 parallel shards (1/3, 2/3, 3/3). Workspace groups
are unchanged. The `verify` gate already aggregates the whole matrix
result, so the required check name is unaffected.
- `scripts/__tests__/run-vitest-stable-shard.test.mjs`: a `node:test`
suite asserting the 3 shards form a complete, non-overlapping partition
of the general-server set, that no route/authz suite leaks into it, and
that shard flags are rejected for the parallel workspace groups. Wired
into the `policy` job.

## Verification

- New partition test passes locally: `node --test
./scripts/__tests__/run-vitest-stable-shard.test.mjs` (3/3).
- Confirmed the 3 shards form a complete, non-overlapping partition of
all 213 files (71/71/71).
- Ran a live thin shard (3 real server suites, including one outside
`__tests__`) — 23 tests passed, confirming positional-include execution
works end to end.
- This PR's own CI is the authoritative check: all three `General tests
(server (n/3))` jobs went green on the prior run, collectively covering
every suite the old single job ran.

## Risks

- Low risk. No product code changes — only test orchestration and CI
matrix. Shard partitioning is deterministic and is now covered by an
automated test that fails if the partition ever develops a gap or
overlap. Modulo-on-sorted-filenames balances duration reasonably,
matching the approach already proven by the serialized route shards.

## Model Used

- Claude (Anthropic), `claude-opus-4-8`, extended thinking + tool use
(agentic coding via Paperclip).

## 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 (N/A — no UI change)
- [x] I have updated relevant documentation to reflect my changes
(inline comments explain the sharding rationale)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (pending this PR's run)
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(pending review)
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-19 19:22:17 -07:00
Devin Foley 4518f272b2 fix(release): publish all remaining @paperclipai workspace packages from CI + guard unpublishable edges (#8365)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work, distributed primarily via the `paperclipai` npm package and its
`@paperclipai/*` workspace packages.
> - The release subsystem (`scripts/release-package-*`) decides which
workspace packages CI republishes at the unified calver version each
release, and `replaceWorkspaceDeps()` rewrites every internal
`workspace:` dependency to that calver version at publish time.
> - The gap: a package that publishes from CI can declare a `workspace:`
dependency on a package that is NOT enrolled for CI publish. The
dependency spec gets rewritten to a calver version that is never
actually published, so the dependent becomes uninstallable.
> - This shipped for real: a recent change made `@paperclipai/server`
depend on `@paperclipai/skills-catalog`, but skills-catalog was not on
the calver release train — so canary builds after that merge failed to
resolve `@paperclipai/skills-catalog@<calver>` and `npx
paperclipai@canary run` broke.
> - This PR addresses it durably by (a) putting every remaining internal
package on the CI release train so no internal dependency can dangle,
and (b) adding a fail-fast guard so this class of break can never ship
again.
> - The benefit is that canary and stable installs resolve all internal
dependencies, and any future unpublishable workspace edge fails the
release build with a clear, named error instead of producing a broken
package.

## Linked Issues or Issue Description

Refs #8327 (introduced the `server -> skills-catalog` runtime dependency
that surfaced the gap).

No public issue tracks this; describing it in-PR:

- **Problem:** After #8327, `npx paperclipai@canary run` failed for
builds past the merge because `@paperclipai/skills-catalog` was
rewritten to a calver version that was never published (the package was
not enrolled for CI publish). Versions before the merge still ran.
- **Root cause:** A `publishFromCi:true` package can declare a
`workspace:` dependency on a package that is not `publishFromCi:true`;
the release-time version rewrite then points at a non-existent published
version.

## What Changed

- Enrolled every remaining internal package on the calver release train
by setting `publishFromCi: true` in
`scripts/release-package-manifest.json`: `skills-catalog`,
`teams-catalog`, `plugin-workspace-diff`, `plugin-kubernetes`,
`plugin-novita-sandbox`. There are now zero `publishFromCi:false`
entries.
- `skills-catalog`, `teams-catalog`, `plugin-workspace-diff` already
existed on npm — CI simply republishes them at calver.
- `plugin-kubernetes` and `plugin-novita-sandbox` were not on npm; their
one-time first publish was bootstrapped so the
`check-release-package-bootstrap` gate passes.
- Added `findUnpublishableWorkspaceEdges()` to
`scripts/release-package-map.mjs`, wired into
`buildReleasePackagePlan()`. The release map build now fails fast
(surfaced by the `check` CI already runs) whenever a
`publishFromCi:true` package declares a runtime `workspace:` dependency
(`dependencies`/`optionalDependencies`/`peerDependencies`) on a
non-`publishFromCi:true` `@paperclipai/*` package, naming the offending
edge.
- Added tests covering positive/negative detection, all three dependency
sections, unknown-package edges, off-train edges, and the live manifest.

## Verification

- `node --test scripts/release-package-map.test.mjs` → 9/9 pass
(includes a test asserting the live manifest has no unpublishable
edges).
- `node scripts/check-release-package-bootstrap.mjs
scripts/release-package-manifest.json` → passes, naming all five
newly-enabled packages (all confirmed present on npm).
- Confirmed via `npm view` that all five packages resolve on the public
registry.

## Risks

- Low risk. The change only enrolls already-existing (or
freshly-bootstrapped) packages onto the existing release train and adds
a build-time validation. No runtime code paths change. The new guard can
only *fail* a release that was already going to ship a broken package.

## Model Used

Claude Opus 4.7 (claude-opus-4-7), extended thinking, with 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] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots (N/A — no UI changes)
- [x] I have updated relevant documentation to reflect my changes (N/A —
no doc-facing behavior change)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge
2026-06-19 19:11:20 -07:00
Nicky Leach 6b45b1559d refactor: revert headless Chromium provisioning script (#8362)
Deletes scripts/qa/provision-headless-chromium.sh, reverting PR #8349's host-specific Chromium provisioning helper.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-19 18:39:29 -07:00
Nicky Leach 713b3b08f0 chore(qa): add no-sudo headless Chromium provisioning script (#8349)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Visual QA and screenshot-based review depend on a working headless
browser in agent sandboxes.
> - Playwright can provide the Chromium binary, but some sandboxes lack
the host shared libraries that Chromium needs to launch.
> - Those sandboxes often do not have sudo, so `playwright install-deps`
cannot install system packages.
> - This pull request adds a user-space provisioning script for the
Chromium runtime dependency closure.
> - The benefit is that QA can bootstrap a render-capable Chromium
environment without requiring root access or changing app runtime code.

## Linked Issues or Issue Description

No public issue exists for this exact QA provisioning gap.

Problem: in no-sudo Linux sandboxes, Playwright's bundled Chromium may
fail to launch because the host is missing required shared libraries
such as libatk, libcups, libgbm, libpango, and libasound.

Expected behavior: QA agents should be able to provision a local prefix
that lets Playwright launch bundled Chromium headlessly and render text
without root access.

Related public PR: #7301 covers broader runtime tooling/dependency
setup, but this PR is a focused userspace script for the no-sudo
Chromium dependency case.

## What Changed

- Added `scripts/qa/provision-headless-chromium.sh`.
- The script downloads the dependency closure for Playwright's Ubuntu
24.04 Chromium runtime packages with `apt-get download`, extracts the
`.deb` files into a user-space prefix, and emits an env file that sets
`LD_LIBRARY_PATH` and `FONTCONFIG_FILE`.
- The script also configures extracted fonts and an isolated font cache
so headless rendering paints text.

## Verification

- Ran `bash -n scripts/qa/provision-headless-chromium.sh`.
- The handoff verification states the script was run from a clean prefix
on Ubuntu 24.04 arm64 as a non-root user, then Chromium 145 launched
headless and rendered text at 1440x900 and 390x844 in light and dark
mode.

## Risks

Low risk. This adds a standalone QA utility script and does not modify
application runtime, package manifests, CI configuration, migrations, or
production code.

## Model Used

OpenAI GPT-5 Codex, tool-enabled coding agent with shell and GitHub CLI
access. The original script was prepared by an agent workflow; Git
Expert amended public-facing references and prepared the PR.

## 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
- [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 16:55:23 -07:00
Nicky Leach fb0e3fb02a Fix mention-granted closed issue comments with resume intent (#8350)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Issue comments are part of the control plane boundary between agent
collaboration and task mutation.
> - Mention grants intentionally let a mentioned peer agent answer on an
issue thread without taking ownership of the task.
> - Closed issue comments have a second mutation guard because comments
can also request resume or reopen behavior.
> - A mention-granted comment should stay append-only unless the actor
also has mutation authority.
> - This pull request preserves the narrow comment path while keeping
explicit `resume` and `reopen` intent behind mutation authorization.
> - The benefit is a smaller authorization exception with regression
coverage for both allowed and denied paths.

## Linked Issues or Issue Description

Refs #2884
Related prior authorization work: #8024, #7863, #6113, #7998.

Bug fix description:
- What happened: a mention-granted non-assignee agent could be treated
as authorized for the closed issue comment route without preserving a
clean distinction between append-only comments and explicit
reopen/resume mutation intent.
- Expected behavior: a mention grant allows a plain comment on a closed
issue, but `resume: true` or `reopen: true` still requires mutation
authorization.
- Steps to reproduce: create a closed issue assigned to one agent, give
a different agent a valid mention-scoped comment grant, then POST a
comment as that agent with and without `resume`/`reopen` intent.
- Deployment mode: server route behavior; covered by focused Vitest
regression tests.

## What Changed

- Preserve the `issue:comment` authorization decision in `POST
/api/issues/:id/comments` so the route can identify legitimate
mention-grant decisions.
- Skip the closed-issue non-assignee mutation fallback only for inert
mention-granted comments.
- Continue requiring mutation authorization when a mention-granted
closed issue comment includes explicit `resume` or `reopen` intent.
- Add regression coverage for the allowed inert comment and denied
resume/reopen cases.

## Verification

- `pnpm vitest run
server/src/__tests__/issue-comment-reopen-routes.test.ts` passed
locally: 72 tests.

## Risks

- Low risk: scoped to the issue comment route and tests for a specific
authorization decision reason.
- Residual risk: CI should run the full PR suite.

## Model Used

OpenAI GPT-5 Codex via Paperclip Git Expert agent, with tool use for
code inspection, test execution, Git, and GitHub operations.

## 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
- [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 16:47:06 -07:00
Nicky Leach 67f97e8fb0 fix(server): enforce read auth for single issue comments (#8346)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Issue comments are part of the control-plane audit trail and must
respect the same company and issue authorization boundaries as issue
reads.
> - Mention-scoped commenting gives low-trust agents a narrow way to
reply when an authorized assignee mentions them.
> - The comment list route already enforces issue-read authorization,
but the single-comment read route only checked same-company access
before returning a known comment id.
> - That created a broken object-level authorization gap for
same-company low-trust agents outside the issue boundary.
> - This pull request applies the existing issue-read guard to the
single-comment route before loading the comment.
> - The benefit is consistent comment-read authorization across list and
single-comment endpoints, with regression coverage for the low-trust
boundary.

## Linked Issues or Issue Description

Refs #7389

Bug fix context:
- What happened: `GET /api/issues/:id/comments/:commentId` checked
company access but did not enforce the issue-read authorization boundary
before returning a single comment by known id.
- Expected behavior: single-comment reads should use the same issue-read
boundary as issue thread list reads.
- Steps to reproduce: authenticate as a same-company low-trust agent
outside an issue's readable boundary, then request a known comment id
via the single-comment endpoint.
- Deployment mode: applies to server authorization behavior in
authenticated agent API usage.

## What Changed

- Added `assertIssueReadAllowed` to the single issue-comment read route
before `getComment` is called.
- Added mocked route coverage proving peer agents outside the issue-read
boundary get `403` and the comment is not loaded.
- Added authorization and embedded route coverage for mention-scoped
low-trust comment grants so the intended narrow reply path remains
allowed.

## Verification

- `NODE_ENV=test pnpm exec vitest run
server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts` —
passed, 60 tests.
- `NODE_ENV=test pnpm exec vitest run
server/src/__tests__/authorization-service.test.ts` — passed, 26 tests.
- `NODE_ENV=test pnpm exec vitest run
server/src/__tests__/low-trust-red-team-routes.test.ts` — passed, 8
tests.
- `git diff --check` — passed.

## Risks

Low risk. This reuses the existing issue-read guard for a read endpoint.
The main behavioral shift is that same-company actors who cannot read an
issue can no longer fetch a known comment id from that issue, which is
the intended authorization boundary.

> 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 via Codex, with repository tool use and command execution.
Runtime context-window details were 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 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
- [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 15:57:36 -07:00
Nicky Leach 364f0f5a8d fix(server): enforce issue read for issue thread lists (#8331)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents coordinate through issue threads, so issue comments and
interactions are part of the task authorization surface.
> - Low-trust and boundary-limited agents can receive narrow
mention-scoped access, but that must not turn into broad same-company
issue-thread reads.
> - The comment creation path was narrowed to allow explicit mention
replies without granting mutation access.
> - The surrounding list/read routes still needed to enforce the same
`issue:read` boundary before returning thread data.
> - This pull request applies the issue read check to issue comment and
interaction listing routes, and locks that behavior with server
regressions.
> - The benefit is that narrow cross-agent collaboration remains
possible without exposing unrelated issue-thread history.

## Linked Issues or Issue Description

Bug fix:
- What happened: same-company agents outside an issue read boundary
could still hit issue-thread listing routes and receive thread data.
- Expected behavior: issue comments and issue-thread interactions should
only be listed after the actor is allowed to read the issue.
- Steps to reproduce: configure a peer agent denied by the issue read
boundary, then request `GET /api/issues/:id/comments` or the issue
interaction listing route.
- Paperclip version/commit: current `master` before this branch.
- Deployment mode: applies to server authorization in all modes.

Related public context: #7389, #7863, #8024.

## What Changed

- Added issue read enforcement before listing issue comments.
- Added issue read enforcement before listing issue-thread interactions.
- Added server regressions for denied peer-agent issue-thread access
while preserving mention-scoped collaboration behavior.
- Removed an avoidable per-mentioned-comment issue reload in
mention-grant authorization by passing the already-loaded issue assignee
through the helper.
- Documented cross-agent issue read/comment authorization behavior in
the Paperclip API reference.
- Added a resilient fallback for pinned external skills when GitHub tree
fetches are temporarily unavailable during catalog builds.

## Verification

- `pnpm vitest run
server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts
server/src/__tests__/authorization-service.test.ts`
  - 2 test files passed
  - 84 tests passed
- Existing mocked recovery revalidation warnings were emitted by the
route suite and the command exited 0
- Greptile: 5/5 on commit `b73fc323f192dc44f88374c16865008d4348923b`; no
unresolved review threads.
- `pnpm vitest run packages/skills-catalog/src/catalog-builder.test.ts`
  - 1 test file passed
  - 6 tests passed
- CI: all visible PR checks are terminal green on commit
`b73fc323f192dc44f88374c16865008d4348923b`.

## Risks

Low risk. This tightens read authorization on issue-thread listing
routes; any caller that depended on same-company access without
`issue:read` will now receive 403 and must use an explicit grant or
valid issue read path.

## Model Used

OpenAI GPT-5 Codex, Codex coding agent environment, tool use and local
command execution enabled, reasoning mode active. Context window not
exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] 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 15:16:17 -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
Devin Foley 6a3f5b685d fix(agents): clear inbox hire approval when approving/terminating from detail page (#8340)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Hiring a new agent creates a `hire_agent` approval record; until it
is resolved, the agent sits in `pending_approval` and the open approval
surfaces an "Approve/Reject" card in the inbox
> - There are two places to act on that hire: the inbox approval card
and the agent detail page's Approve/Terminate buttons
> - The agent detail page only flipped the agent to `idle` via
`activatePendingApproval`, never resolving the linked approval record
> - So after approving (or terminating) from the detail page, the
approval stayed `pending` and the inbox kept showing a stale
"Approve/Reject" card for an agent that was already decided
> - This pull request routes the detail-page approve through the shared
`approvalsSvc.approve()` (which resolves the approval and runs
activation, budget policy, and the hire-approved notification), and
rejects the linked approval when a still-pending agent is terminated
> - The benefit is a single source of truth: deciding a hire in one
place clears it everywhere, so the inbox no longer asks you to approve
an agent you already approved

## Linked Issues or Issue Description

No public GitHub issue exists for this; describing in-PR (bug report).

**What happened:** Create a new agent, then approve it from the agent
detail page. The agent activates, but the inbox still shows a "Hire
Agent" item with Approve/Reject buttons for it.

**Expected:** Once a hire is approved or rejected anywhere in the UI, it
should be resolved everywhere — the inbox should not re-ask you to
approve an agent that is already decided.

**Root cause:** `POST /agents/:id/approve` called
`activatePendingApproval`, which only changes the agent's status. The
linked `hire_agent` approval row stayed `pending`. The inbox lists
approvals filtered to unresolved statuses, so the card persisted.
Terminating a pending agent from the detail page had the mirror problem
for the "reject" half.

Related (not duplicates): #215 (join-request inbox badge), #1815
(approval detail button loading text).

## What Changed

- Added `approvalService.findOpenHireApprovalForAgent(companyId,
agentId)` to locate the open `hire_agent` approval for an agent. The
company/type/open-status **and** `payload->>'agentId'` predicates all
run in SQL (jsonb operator), so the DB returns only the relevant row
instead of filtering in JS (`server/src/services/approvals.ts`).
- `POST /agents/:id/approve` resolves the linked approval through the
shared `approvalsSvc.approve()` — running activation, budget-policy
upsert, and the hire-approved notification as one path — and falls back
to direct `activatePendingApproval` only when no open approval exists
(legacy agents created before approvals were tracked)
(`server/src/routes/agents.ts`).
- `POST /agents/:id/terminate` now branches the same way: when a
still-`pending_approval` agent has an open hire approval, it delegates
to `approvalsSvc.reject()` (which resolves the approval **and**
terminates the agent internally) and re-reads the agent, otherwise it
terminates directly. This avoids terminating the agent twice (`reject()`
already calls `agentsSvc.terminate()`) (`server/src/routes/agents.ts`).
- The `agent.approved` activity log records the resolved `approvalId`
(or `null` on the fallback path) for traceability.

## Verification

- `pnpm --filter @paperclipai/server typecheck` — clean.
- Targeted server tests pass (57 tests):
`npx vitest run src/__tests__/approvals-service.test.ts
src/__tests__/agent-permissions-routes.test.ts`
- `findOpenHireApprovalForAgent` returns the row the SQL filter yields /
returns null when none matches.
- Approving from the detail page resolves the linked approval via
`approvalsSvc.approve()` and does not double-activate; legacy fallback
still calls `activatePendingApproval`.
- Terminating a still-pending agent with an open approval calls
`approvalsSvc.reject()` and does **not** call `agentsSvc.terminate()` a
second time; terminating with no open approval terminates directly.
- Manual: create an agent → inbox shows the hire card → approve from the
agent detail page → inbox card is gone and the agent is active. Same for
terminate-while-pending clearing the card.

## Risks

Low risk, server-only, no schema or migration changes. The fallback to
`activatePendingApproval` preserves existing behavior for agents with no
tracked approval record, so legacy agents still activate. The shared
approval path is the same one the inbox card already uses, so
approve/terminate-from-detail-page now match approve/reject-from-inbox
exactly.

## Model Used

Claude Opus 4.8 (claude-opus-4-8), extended thinking 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] 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 (server-only change, no UI diff)
- [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
(in progress)
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-19 12:15:57 -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 a2abebee07 docs: require descriptive, instance-free PR branch names (#8312)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Contributions flow through GitHub PRs against
`paperclipai/paperclip`, but most contributors author their work inside
their own private Paperclip instance
> - That tooling names a working branch after the internal issue/task —
e.g. `PAPA-42-why-did-this-break`
> - When that branch is pushed for a PR, the public PR's head branch
carries instance-local context: it's not meaningful to reviewers and
leaks instance-derived identifiers
> - We just documented the issue-reference side of this (#8292), but
said nothing about branch names
> - This pull request adds a **Branch Naming** section to
`CONTRIBUTING.md` and a matching PR-template checklist item, telling
contributors to rename branches to descriptive, change-scoped names
before pushing
> - The benefit is public PRs whose branch names describe the change and
contain no instance-local details

## Linked Issues or Issue Description

Fixes: #8311
Refs: #8292

## What Changed

- `CONTRIBUTING.md`: new **Branch Naming** subsection — rename
instance-named branches (e.g. `PAPA-42-...`) to descriptive,
change-scoped, kebab-case names before pushing, with examples and the
rename commands.
- `.github/PULL_REQUEST_TEMPLATE.md`: new checklist item asserting the
branch name describes the change and contains no internal ticket id or
instance-derived details.

## Verification

Docs-only change. Rendered Markdown locally and confirmed the new
**Branch Naming** section and the new checklist item appear as intended.
This PR's own branch (`docs/contributor-branch-naming`) follows the new
guidance. No code paths affected.

## Risks

Low risk — documentation and PR-template text only; no runtime, build,
or schema impact. Automatically renaming branches at push time in the
tooling is intentionally out of scope and tracked as separate follow-up
work.

## Model Used

Claude Opus 4.7 (claude-opus-4-7), extended thinking, agentic tool use
via Claude Code.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change 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
- [ ] 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 10:14:24 -07:00
Zen Process f13fd1157b feat(adapters): stamp agent id via X-Anthropic-Agent-Id for claude_local (#8322)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Local agents run through the `claude_local` adapter, which spawns
Claude Code and routes its Anthropic API traffic through a shared proxy
(e.g. better-ccflare).
> - That proxy's request log feeds observability dashboards that break
down cost and token usage.
> - But requests from local agents arrive without an agent identifier,
so all traffic collapses into a single unattributed bucket and per-agent
telemetry is impossible.
> - Anthropic's CLI forwards `ANTHROPIC_CUSTOM_HEADERS` onto each API
request, and better-ccflare now reads an `X-Anthropic-Agent-Id` header
to attribute requests per agent.
> - This pull request stamps the agent's id into
`ANTHROPIC_CUSTOM_HEADERS` as `X-Anthropic-Agent-Id`, injected into the
env the adapter actually forwards to the spawned process.
> - The benefit is per-agent cost/token attribution in proxy-backed
dashboards, with zero impact on agents that don't run behind such a
proxy.

## Linked Issues or Issue Description

No public GitHub issue exists; describing inline per CONTRIBUTING.md
(feature template).

**Problem or motivation**

When several `claude_local` agents share a proxy (better-ccflare) in
front of the Anthropic API, the proxy cannot tell which agent issued a
given request. Per-agent cost and token dashboards therefore can't be
built — every request is attributed to one undifferentiated bucket.

**Proposed solution**

Have the `claude_local` adapter stamp each spawned Claude Code process
with `ANTHROPIC_CUSTOM_HEADERS: X-Anthropic-Agent-Id: <agentId>`. The
Anthropic CLI forwards that header on every API call, so the proxy can
attribute requests to the specific agent.

**Alternatives considered**

Parsing per-agent identity from workspace paths or session ids in the
proxy — brittle and proxy-specific. A first-class request header is the
stable contract; it pairs with better-ccflare's `X-Anthropic-Agent-Id`
support
([tombii/better-ccflare#260](https://github.com/tombii/better-ccflare/pull/260))
and dashboards like
[danieltamas/axon](https://github.com/danieltamas/axon).

**Roadmap alignment**

Additive observability glue for an existing adapter; no overlap with
planned core work.

## What Changed

- Added `server/src/adapters/claude-agent-id-header.ts` exporting
`stampClaudeAgentIdHeader`, which wraps the `claude_local` execute and
merges `X-Anthropic-Agent-Id: <agentId>` into the run's
`config.env.ANTHROPIC_CUSTOM_HEADERS`.
- `server/src/adapters/registry.ts`: the `claude_local` adapter now uses
the wrapped execute (`stampClaudeAgentIdHeader(claudeExecute)`).
- The header is merged into **`config.env`** — the env the Claude
adapter actually forwards into the spawned process — rather than
`agent.adapterConfig.env`, which is resolved upstream before `execute`
runs and is never read by the Claude adapter.
- `agentId` is sanitized (CR/LF stripped, capped at 256 chars) before
interpolation to prevent HTTP header injection.
- Passthrough when no agent id is available; a pre-existing
`X-Anthropic-Agent-Id` (manual override) is respected and not
duplicated.
- Added `server/src/adapters/claude-agent-id-header.test.ts` covering
injection into `config.env`, append-to-existing
`ANTHROPIC_CUSTOM_HEADERS`, CR/LF sanitization, length bounding,
no-agent-id passthrough, and the duplicate-header guard.

## Verification

- Unit tests: `cd server && npx vitest run
src/adapters/claude-agent-id-header.test.ts` → 6 passing.
- CI: typecheck, build, server suites, and Greptile gates run on this
PR.
- Manual: configure a `claude_local` agent behind better-ccflare, run a
heartbeat, and confirm the proxy log shows `X-Anthropic-Agent-Id:
<agentId>` on that agent's requests. An agent that already sets
`X-Anthropic-Agent-Id` in its adapter config keeps its override (no
duplicate line).

## Risks

Low risk. The change is additive and non-breaking:

- When no agent id is present, or when an `X-Anthropic-Agent-Id` is
already configured, execution is byte-for-byte unchanged (the original
`ctx` is passed straight through).
- The header only has an effect for deployments whose proxy reads it;
agents without such a proxy are unaffected.
- The agent id is sanitized (CR/LF removed, length-bounded) before it is
interpolated into a header value, preventing header injection.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. This is additive
observability glue for an existing adapter and does not overlap planned
core work.

## Model Used

Claude (Anthropic) — Claude Opus 4.8 (`claude-opus-4-8`), via the Claude
Code CLI with extended reasoning 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] 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 (N/A — no UI 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: zenprocess <zenprocess@users.noreply.github.com>
Co-authored-by: Devin Foley <devin@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-19 09:56:28 -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
github-actions[bot] af22abc80e chore(lockfile): refresh pnpm-lock.yaml (#8332)
Auto-generated lockfile refresh after dependencies changed on master.
This PR only updates pnpm-lock.yaml.

Co-authored-by: lockfile-bot <lockfile-bot@users.noreply.github.com>
2026-06-19 09:38:44 -07:00
Devin Foley 5e086cb828 fix(server): resolve published skills catalog package root and fallback (#8327)
## Thinking Path

> - Paperclip is the open source control plane people use to run and
supervise AI-agent companies.
> - The skills system is part of that core operator experience because
agents and humans both depend on the catalog-backed Skills Manager
surfaces.
> - In source checkouts, the server can find the catalog manifest and
bundled skill files through monorepo-relative paths, but published
installs do not preserve that layout.
> - That mismatch makes `GET /api/skills/catalog` fail in npm/pnpm
installs even though the catalog package itself is present.
> - The server therefore needs to resolve the catalog from the published
`@paperclipai/skills-catalog` package first, while still keeping a
monorepo fallback for local development.
> - This pull request makes the published package the primary resolution
path, uses the same resolved package root for bundled skill file reads,
and degrades the list route safely when the manifest is unavailable.
> - The benefit is that Skills Manager catalog reads behave correctly in
packaged installs instead of only in repo-local development layouts.

## Linked Issues or Issue Description

Fixes #8316
Refs #7281
Refs #7313
Refs #7350
Refs #7860
Refs #8223
Refs #8227

## What Changed

- Added `@paperclipai/skills-catalog` as a runtime dependency of
`@paperclipai/server`.
- Exported `./package.json` from `@paperclipai/skills-catalog` so the
server can resolve the published package root directly.
- Updated `server/src/services/skills-catalog.ts` to resolve the
manifest and package root from the published package first, with the
monorepo path retained only as a development fallback.
- Applied that resolved package root to bundled catalog file reads so
manifest lookup and skill-file reads use the same published layout.
- Added `listCatalogSkillsOrEmpty()` so `GET /api/skills/catalog`
returns `[]` and logs a warning when the manifest is unavailable instead
of surfacing a 500.
- Added targeted server tests for published-package resolution and
missing-manifest fallback handling.

## Verification

- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/skills-catalog-service.test.ts
src/__tests__/company-skills-routes.test.ts`
- `pnpm --filter @paperclipai/server build`
- Packaging smoke:
- pack `@paperclipai/shared` and `@paperclipai/skills-catalog` from this
checkout
  - mount those packed artifacts under `server/dist/node_modules`
  - import `server/dist/services/skills-catalog.js`
- verify a bundled catalog `SKILL.md` resolves and reads successfully
from the packed package layout

## Risks

- Low risk: the change is narrowly scoped to catalog package resolution
and fallback behavior.
- The new `./package.json` export slightly broadens the catalog
package's public surface, so reviewers should confirm that is an
acceptable runtime contract.
- The empty-array fallback intentionally changes failure mode for a
missing manifest from `500` to a warning + empty payload, which is safer
for packaged installs but could hide packaging regressions if logs are
not monitored.

## Model Used

- OpenAI Codex via Paperclip `codex_local` (GPT-5-based coding agent;
exact backend model ID/context window not exposed in this harness), with
tool use, shell execution, git, and local test/build verification.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] 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
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-19 09:14:41 -07:00
dmndbrp-oss 0186e66c7c test(SAG-4328): de-flake checkout-lock race in orphan-recovery test (#8315)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The server heartbeat subsystem tracks agent runs and recovers
orphaned processes via `reapOrphanedRuns`
> - When a local process dies mid-run, the recovery path queues a retry
run and releases the checkout lock asynchronously
> - The test `queues exactly one retry when the recorded local pid is
dead` verifies both the retry state and that the checkout lock is
released
> - The `checkoutRunId` null-check was a bare synchronous assertion, but
the checkout-lock release is async — so the test could read
`checkoutRunId` before the write committed
> - This PR wraps the predicate already gating on `executionRunId` to
also wait for `checkoutRunId === null`, so both writes are committed
before the assertions fire
> - The benefit is a deterministic test that does not race the async
checkout-lock release

## Linked Issues or Issue Description

-

## What Changed

- `server/src/__tests__/heartbeat-process-recovery.test.ts`: Extended
the `waitForValue` predicate (line ~1024) from `executionRunId ===
retryRun?.id` to also require `checkoutRunId === null` before returning
the row. This eliminates the race between the assertion and the async
terminal-run checkout-lock release.

## Verification

- No production code changed — test file only.
- Ran the test file 10× locally with `pnpm exec vitest run
server/src/__tests__/heartbeat-process-recovery.test.ts
--no-file-parallelism --maxWorkers=1`:

```
Run  1: Test Files 1 passed (1) | Tests 57 passed (57)
Run  2: Test Files 1 passed (1) | Tests 57 passed (57)
Run  3: Test Files 1 passed (1) | Tests 57 passed (57)
Run  4: Test Files 1 passed (1) | Tests 57 passed (57)
Run  5: Test Files 1 passed (1) | Tests 57 passed (57)
Run  6: Test Files 1 passed (1) | Tests 57 passed (57)
Run  7: Test Files 1 passed (1) | Tests 57 passed (57)
Run  8: Test Files 1 passed (1) | Tests 57 passed (57)
Run  9: Test Files 1 passed (1) | Tests 57 passed (57)
Run 10: Test Files 1 passed (1) | Tests 57 passed (57)
```

10/10 green streak — race eliminated.

## Risks

Low risk — test-only change. No production code modified. The predicate
change only narrows the waitForValue poll to require both writes
committed before asserting, matching the intent already documented in
the comment on line 1031.

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

## Model Used

Claude Sonnet 4.6 (claude-sonnet-4-6) — Anthropic, 200K context, tool
use enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] 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
- [ ] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Director of Engineering <cto@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Devin Foley <devin@paperclip.ing>
2026-06-19 08:59:23 -07:00
ashCold 9cd62cf3bb fix(cli): handle headless browser-open failure in board auth (#8328)
## Thinking Path

> - Paperclip is the open-source app for managing AI agents, very
commonly self-hosted as a headless Docker container.
> - Its CLI authorizes board/admin actions through an interactive
browser-approval flow (`auth login`, and the auto-recover path behind
commands like `run list`).
> - That flow calls `openUrl()`, which `spawn`s the OS browser opener
(`xdg-open` on Linux).
> - In a headless container there is no `xdg-open`; `spawn` reports the
missing binary asynchronously via an `'error'` event, which the
surrounding `try/catch` cannot catch, so Node aborts the process before
the approval can be polled.
> - This makes CLI board auth impossible in the most common self-hosted
deployment shape.
> - This PR makes `openUrl` error-handled, async, and truthful, and adds
headless affordances.
> - The benefit is that board-authenticated CLI commands degrade
gracefully and work headless instead of crashing.

## Linked Issues or Issue Description

Closes #7941 

## What Changed

- `openUrl` (`cli/src/client/board-auth.ts`) is now async and attaches
an `'error'` listener to the spawned opener: resolves `false` on async
spawn failure (missing binary) or sync throw, and `true` only on a
successful `'spawn'`. Fixes the unhandled-`'error'` crash and makes the
return value honest.
- `loginBoardCli` prints an accurate "couldn't open a browser" message,
supports `--no-browser` / `PAPERCLIP_NO_BROWSER` to skip the open
attempt, and renders the approval URL from `PAPERCLIP_PUBLIC_URL` (or
`publicBaseUrl`) so it's reachable from a remote operator's browser.
- Updated the three other `openUrl` call sites (`cloud.ts` ×2,
`company.ts`) to `await` it.
- Added the `auth login --no-browser` flag.
- Tests: new `open-url.test.ts` (launch → true, async ENOENT → false,
sync throw → false); extended auth-command-registration test for
`--no-browser`.

## Verification

- `pnpm --filter paperclipai typecheck` — clean.
- `pnpm exec vitest run cli/src/__tests__/open-url.test.ts
cli/src/__tests__/auth-command-registration.test.ts` — pass.
- Manual, in a headless container with no `xdg-open`: `pnpm paperclipai
auth login -C <company-id>` now prints the approval URL and waits
(previously crashed with `spawn xdg-open ENOENT`); `--no-browser` skips
the open attempt; `PAPERCLIP_PUBLIC_URL=...` renders a reachable
approval URL; completing approval in a browser stores the credential and
`run list` works.

## Risks

Low. `openUrl` became async; all four call sites updated to `await`.
Desktop behavior is unchanged (successful spawn still resolves true and
opens the browser). No API, schema, or migration changes.

## Model Used

Claude Opus 4.8 (`claude-opus-4-8`) via Claude Code, with extended
thinking and tool use, used to diagnose the bug and draft the fix and
tests. Human-reviewed and tested on a live headless deployment.

## 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
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [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 (N/A — CLI only)
- [ ] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-19 08:58:17 -07:00
Tattoofamily f672a9e2e5 fix(runtime): keep agent pause durable at execution-start (#8317)
**Issue (described inline; no existing tracking issue):** Pausing an
agent is not durable. Pausing cancels the in-flight run, but a queued or
recovery-dispatched run can clobber the agent back to `running` because
the execution-start status update is unconditional — so a "paused" agent
silently resumes work while `paused_at` is still set.

## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies; agent
work executes as "runs" tracked in `heartbeat_runs`, with a
recovery/automation layer that re-dispatches work when a run disappears.
> - The agent lifecycle has a pause control (status `paused`,
`paused_at` set) meant to stop an agent from taking or continuing work.
> - The problem: pause is not durable. Pausing cancels the in-flight
run, but the execution-start path then sets `agents.status = 'running'`
with an unconditional `UPDATE ... WHERE id = ?`, so any queued or
recovery-dispatched run can clobber the paused agent back to `running`
and execute.
> - Why it matters: a "paused" agent silently resuming undermines the
core operational control operators rely on to halt runaway,
cost-sensitive, or unsafe work.
> - This pull request guards the execution-start status flip with an
atomic conditional UPDATE, and tags pause-cancellations for
observability without changing resume behaviour.
> - The benefit is that a paused agent can no longer transition back to
`running`; queued/recovery-dispatched runs are cancelled cleanly instead
of clobbering status, while un-pausing still resumes in-flight work.

## What Changed

- Execution-start guard: replaced the unconditional `UPDATE agents SET
status='running' WHERE id = ?` with an atomic conditional `UPDATE ...
WHERE id = ? AND status NOT IN
('paused','terminated','pending_approval')`. On a zero-row match the run
is cancelled (`errorCode: "agent_not_invokable"`), the issue execution
lock is released, and the path returns — instead of clobbering status.
- Exported `DIRECT_NON_INVOKABLE_STATUSES` from `agent-invokability.ts`
and reused it in `heartbeat.ts` as the single source of truth for the
guard.
- Pause observability: `cancelActiveForAgentInternal` now accepts an
`errorCode` (default `"cancelled"`); the pause-route wrapper
`cancelActiveForAgent` passes `"agent_paused"`. This is
classification-neutral — `agent_paused` is NOT added to
`NON_RETRYABLE_CONTINUATION_ERROR_CODES`, so on un-pause the issue's
continuation re-enqueues and work resumes.
- Exported `classifyContinuationFailure` from `recovery/service.ts` for
unit testing (no logic change).
- Added `server/src/services/recovery/service.pause-durability.test.ts`
covering continuation classification.

## Verification

- `pnpm --filter @paperclipai/server typecheck` — clean.
- `pnpm exec vitest run
server/src/services/recovery/service.pause-durability.test.ts` — 5
passed.
- `pnpm exec vitest run server` — full server suite passes locally. The
only failures are pre-existing and environment-specific, unrelated to
this change (a git default-branch test fixture, and a known
checkout-lock race) — both reproduce identically on clean `master` with
this change stashed out.
- Behavioural: a paused agent's execution-start now aborts cleanly with
no status clobber; non-pause cancellations keep `errorCode "cancelled"`
and existing behaviour; un-pausing resumes the in-flight issue.

## Risks

- Low risk. No schema change, no migration, no new dependency; four
files. The change narrows a single UPDATE to be conditional and adds a
rarely-taken abort branch on the run-start path; behaviour for invokable
agents is unchanged. The abort's `agent_not_invokable` code is already
in `NON_RETRYABLE_CONTINUATION_ERROR_CODES`. The only caller of
`cancelActiveForAgent` is the pause route.

## Related upstream work — not duplicates

This area has prior and in-flight PRs; #8317 was checked against them
and is intentionally distinct:

- **#4503** (`fix(heartbeat): make agent pause status guard atomic with
status update`) targets a different TOCTOU race on the **post-run /
finalize** path (`finalizeAgentStatus`). #8317 targets the
**execution-start** race, where a recovery-dispatched run flips a paused
agent back to `running` *before the run begins*. #4503 does not cover
the proven failure path here: `pause → active run cancelled → recovery
dispatches a new run → execution-start overwrites the paused state`.
#4503 also does not add the resume semantics below.
- **#4356** (`honor system/manual/auto pause at all heartbeat-run
enqueue sites`) and **#1067** (`pause guard on queue drain`) protect the
**enqueue / queue-drain** layer. They are complementary to — not
substitutes for — the execution-start guard, which is the last gate
before a run actually starts.
- **#6944** (`guard executeRun against paused agent`), **#7140**, and
**#7141** attempted similar execution-start ideas but were closed for
implementation hygiene / build issues, not because the guard concept was
wrong. #8317 implements that concept cleanly: a single atomic
conditional UPDATE, a clean abort with `errorCode:
"agent_not_invokable"`, a shared `DIRECT_NON_INVOKABLE_STATUSES` source
of truth, and passing tests + typecheck.

Intentional, minor difference (not a criticism of #4503): #8317's
execution-start deny-list is `paused`, `terminated`, and
`pending_approval` — the full non-invokable set for run-start
invokability — whereas #4503 appears focused on `paused`/`terminated`.
The broader set is deliberate for the execution-start guard.

Resume semantics: #8317 keeps `agent_paused` as observability-only and
classification-neutral (retryable), so a paused agent's in-flight work
resumes on un-pause rather than escalating to blocked.

## Model Used

- Provider: Anthropic. Model: Claude Opus 4 (`claude-opus-4-8`), via the
Claude desktop "Cowork" agent. Mode: agentic/extended reasoning with
tool use (shell, file editing, running `tsc`/`vitest`, git). Used to
investigate the root cause in source, design the fix, implement it, and
validate locally.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have 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 (N/A — no UI change)
- [ ] I have updated relevant documentation to reflect my changes (N/A —
no doc-facing change)
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
- [x] I have searched the open and closed PR list for similar/duplicate
PRs and found none
2026-06-19 08:35:53 -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
BuyWhere 67c98323b0 fix(recovery): exempt routine-parent issues from missing-disposition handoff (#8157)
Recognize active routine-parent issues as having a valid continuation path during successful-run handoff recovery. This prevents unnecessary missing-disposition corrective wakes when an active routine owns the next scheduled action.

Also keeps the routine-continuation guard before the productivity check so logs surface the decisive skip reason for both productive and non-productive routine-parent runs.

Verification:
- CI status checks passed on PR #8157
- Greptile Review passed at 5/5
- Focused recovery unit test passed locally

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-18 17:59:06 -07:00
dependabot[bot] 5c11725784 build(deps-dev): bump tsx from 4.21.0 to 4.22.4 (#7754)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.21.0 to 4.22.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/privatenumber/tsx/releases">tsx's
releases</a>.</em></p>
<blockquote>
<h2>v4.22.4</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.22.3...v4.22.4">4.22.4</a>
(2026-05-31)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>resolve CommonJS directory requires inside dependencies (<a
href="https://redirect.github.com/privatenumber/tsx/issues/803">#803</a>)
(<a
href="https://github.com/privatenumber/tsx/commit/1ce846335b7c445a3328c7d27f06424949356d97">1ce8463</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.22.4"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.22.3</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.22.2...v4.22.3">4.22.3</a>
(2026-05-19)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>decode typed loader source (<a
href="https://github.com/privatenumber/tsx/commit/dce02fc3b8b64a58d24560714902b16f89332f1f">dce02fc</a>)</li>
<li>preserve entrypoint with TypeScript preload hooks (<a
href="https://github.com/privatenumber/tsx/commit/68f72f3304d8c3ff7048bde8571af9c163fcefa2">68f72f3</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.22.3"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.22.2</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.22.1...v4.22.2">4.22.2</a>
(2026-05-18)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>preserve CJS JSON require in ESM hooks (<a
href="https://github.com/privatenumber/tsx/commit/35b700bd8620696df03827068af29dcd0d091a60">35b700b</a>)</li>
<li>preserve named exports from CommonJS TypeScript (<a
href="https://github.com/privatenumber/tsx/commit/11de737dae1fb9dae28db3716df5b1a7e1a6a089">11de737</a>)</li>
<li>support module.exports require(esm) interop (<a
href="https://github.com/privatenumber/tsx/commit/cf8f19918e4e0a0dc5ee5c52d8cc15e5e22d7c49">cf8f199</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.22.2"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<h2>v4.22.1</h2>
<h2><a
href="https://github.com/privatenumber/tsx/compare/v4.22.0...v4.22.1">4.22.1</a>
(2026-05-17)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>resolve tsconfig path aliases containing a colon (<a
href="https://redirect.github.com/privatenumber/tsx/issues/780">#780</a>)
(<a
href="https://github.com/privatenumber/tsx/commit/6979f28810829dc79ec9baf406e162a18b65ab4b">6979f28</a>)</li>
</ul>
<hr />
<p>This release is also available on:</p>
<ul>
<li><a href="https://www.npmjs.com/package/tsx/v/4.22.1"><code>npm
package (@​latest dist-tag)</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/privatenumber/tsx/commit/1ce846335b7c445a3328c7d27f06424949356d97"><code>1ce8463</code></a>
fix: resolve CommonJS directory requires inside dependencies (<a
href="https://redirect.github.com/privatenumber/tsx/issues/803">#803</a>)</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/dce02fc3b8b64a58d24560714902b16f89332f1f"><code>dce02fc</code></a>
fix: decode typed loader source</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/68f72f3304d8c3ff7048bde8571af9c163fcefa2"><code>68f72f3</code></a>
fix: preserve entrypoint with TypeScript preload hooks</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/69455cfefbfe71100a3c58d3ce7cea42445d9113"><code>69455cf</code></a>
test: cover package exports for ambiguous ESM reexports</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/35b700bd8620696df03827068af29dcd0d091a60"><code>35b700b</code></a>
fix: preserve CJS JSON require in ESM hooks</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/ef807dba6832260fb4cafd78d81f5469a733966b"><code>ef807db</code></a>
chore: update testing dependencies</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/3917090d4f61863ea6ea16e4a9a3722a112cc3f7"><code>3917090</code></a>
test: document compatibility test taxonomy</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/de8113ffa8edbcd4e05fa218324c3e8c2a4afdbe"><code>de8113f</code></a>
refactor: centralize Node capability facts</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/c1f62db45ada60b24ceb3dfdf7f64173d9a15396"><code>c1f62db</code></a>
test: consolidate tsconfig path edge coverage</li>
<li><a
href="https://github.com/privatenumber/tsx/commit/4e08174ec10276ac71c9a69eb28426ad702d0c76"><code>4e08174</code></a>
test: consolidate loader hook coverage</li>
<li>Additional commits viewable in <a
href="https://github.com/privatenumber/tsx/compare/v4.21.0...v4.22.4">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 tsx 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 17:56:49 -05: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] dd92c7d2dd build(deps): bump @agentclientprotocol/claude-agent-acp from 0.31.4 to 0.47.0 (#7744)
Bumps
[@agentclientprotocol/claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp)
from 0.31.4 to 0.47.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/claude-agent-acp/releases">@​agentclientprotocol/claude-agent-acp's
releases</a>.</em></p>
<blockquote>
<h2>v0.47.0</h2>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.46.0...v0.47.0">0.47.0</a>
(2026-06-17)</h2>
<h3>Features</h3>
<ul>
<li>Update to claude-agent-sdk 0.3.179 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/783">#783</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/59a098c2b530bbae034e9a2dfbd31f8b4ef2a4d0">59a098c</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Duplicate assistant messages in feed (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/785">#785</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/12d34e64e53564602ac1c38a30127e234c5c25ff">12d34e6</a>)</li>
</ul>
<h2>v0.46.0</h2>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.45.1...v0.46.0">0.46.0</a>
(2026-06-16)</h2>
<h3>Features</h3>
<ul>
<li>Update to claude-agent-sdk 0.3.178 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/777">#777</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/58549ffe6a8b02ce59894e567407bd4299c11428">58549ff</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Better handle out of turn events (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/780">#780</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/4f273a20d870c9c69f71556b8e0519f1de30f285">4f273a2</a>)</li>
<li>Forward option details in elicitation meta (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/779">#779</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/b3640599ae685beecacd93e012d5bbc9dac716f7">b364059</a>),
closes <a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/764">#764</a></li>
</ul>
<h2>v0.45.1</h2>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.45.0...v0.45.1">0.45.1</a>
(2026-06-16)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fix terminal error printing as text instead of terminal output (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/776">#776</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/db6eaaf71484a321e47093ad65bcf8994943cb31">db6eaaf</a>)</li>
<li>Scope custom answers per question (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/774">#774</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/d58004a34880e0a76833697319eb2a9efa6a43c7">d58004a</a>)</li>
</ul>
<h2>v0.45.0</h2>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.44.0...v0.45.0">0.45.0</a>
(2026-06-15)</h2>
<h3>Features</h3>
<ul>
<li><strong>deps-dev:</strong> bump the minor group with 3 updates (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/763">#763</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/7de5e4bcca9bfea70593092060f82bc8abe33e0e">7de5e4b</a>)</li>
<li><strong>deps:</strong> bump
<code>@​anthropic-ai/claude-agent-sdk</code> to 0.3.177 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/771">#771</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/1be5ca57ee772fe90e41126365dc4186a18ad257">1be5ca5</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>preserve ANTHROPIC_CUSTOM_MODEL_OPTION when availableModels is set
(<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/768">#768</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/cc2885f6a9993cf61e759c3c770015f94c218627">cc2885f</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/agentclientprotocol/claude-agent-acp/blob/main/CHANGELOG.md">@​agentclientprotocol/claude-agent-acp's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.46.0...v0.47.0">0.47.0</a>
(2026-06-17)</h2>
<h3>Features</h3>
<ul>
<li>Update to claude-agent-sdk 0.3.179 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/783">#783</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/59a098c2b530bbae034e9a2dfbd31f8b4ef2a4d0">59a098c</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Duplicate assistant messages in feed (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/785">#785</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/12d34e64e53564602ac1c38a30127e234c5c25ff">12d34e6</a>)</li>
</ul>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.45.1...v0.46.0">0.46.0</a>
(2026-06-16)</h2>
<h3>Features</h3>
<ul>
<li>Update to claude-agent-sdk 0.3.178 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/777">#777</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/58549ffe6a8b02ce59894e567407bd4299c11428">58549ff</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Better handle out of turn events (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/780">#780</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/4f273a20d870c9c69f71556b8e0519f1de30f285">4f273a2</a>)</li>
<li>Forward option details in elicitation meta (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/779">#779</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/b3640599ae685beecacd93e012d5bbc9dac716f7">b364059</a>),
closes <a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/764">#764</a></li>
</ul>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.45.0...v0.45.1">0.45.1</a>
(2026-06-16)</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fix terminal error printing as text instead of terminal output (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/776">#776</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/db6eaaf71484a321e47093ad65bcf8994943cb31">db6eaaf</a>)</li>
<li>Scope custom answers per question (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/774">#774</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/d58004a34880e0a76833697319eb2a9efa6a43c7">d58004a</a>)</li>
</ul>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.44.0...v0.45.0">0.45.0</a>
(2026-06-15)</h2>
<h3>Features</h3>
<ul>
<li><strong>deps-dev:</strong> bump the minor group with 3 updates (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/763">#763</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/7de5e4bcca9bfea70593092060f82bc8abe33e0e">7de5e4b</a>)</li>
<li><strong>deps:</strong> bump
<code>@​anthropic-ai/claude-agent-sdk</code> to 0.3.177 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/771">#771</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/1be5ca57ee772fe90e41126365dc4186a18ad257">1be5ca5</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>preserve ANTHROPIC_CUSTOM_MODEL_OPTION when availableModels is set
(<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/768">#768</a>)
(<a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/cc2885f6a9993cf61e759c3c770015f94c218627">cc2885f</a>)</li>
</ul>
<h2><a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.43.0...v0.44.0">0.44.0</a>
(2026-06-09)</h2>
<h3>Features</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/794aa846844a2fe8a8574c2539e2c4107e9182d1"><code>794aa84</code></a>
chore(main): release 0.47.0 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/784">#784</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/12d34e64e53564602ac1c38a30127e234c5c25ff"><code>12d34e6</code></a>
fix: Duplicate assistant messages in feed (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/785">#785</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/59a098c2b530bbae034e9a2dfbd31f8b4ef2a4d0"><code>59a098c</code></a>
feat: Update to claude-agent-sdk 0.3.179 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/783">#783</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/c27e6aec9059a920f9cd768f492e25934653b3ff"><code>c27e6ae</code></a>
chore(main): release 0.46.0 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/778">#778</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/4f273a20d870c9c69f71556b8e0519f1de30f285"><code>4f273a2</code></a>
fix: Better handle out of turn events (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/780">#780</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/b3640599ae685beecacd93e012d5bbc9dac716f7"><code>b364059</code></a>
fix: Forward option details in elicitation meta (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/779">#779</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/58549ffe6a8b02ce59894e567407bd4299c11428"><code>58549ff</code></a>
feat: Update to claude-agent-sdk 0.3.178 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/777">#777</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/116f06eab178fe50857f7a4150deb7f5c4cfee28"><code>116f06e</code></a>
chore(main): release 0.45.1 (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/775">#775</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/db6eaaf71484a321e47093ad65bcf8994943cb31"><code>db6eaaf</code></a>
fix: Fix terminal error printing as text instead of terminal output (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/776">#776</a>)</li>
<li><a
href="https://github.com/agentclientprotocol/claude-agent-acp/commit/d58004a34880e0a76833697319eb2a9efa6a43c7"><code>d58004a</code></a>
fix: Scope custom answers per question (<a
href="https://redirect.github.com/agentclientprotocol/claude-agent-acp/issues/774">#774</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/agentclientprotocol/claude-agent-acp/compare/v0.31.4...v0.47.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:32:15 -07:00
dependabot[bot] b15fc221ca build(deps): bump @aws-sdk/client-s3 from 3.994.0 to 3.1072.0 (#7752)
Bumps
[@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)
from 3.994.0 to 3.1072.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/releases">@​aws-sdk/client-s3's
releases</a>.</em></p>
<blockquote>
<h2>v3.1072.0</h2>
<h4>3.1072.0(2026-06-18)</h4>
<h5>Documentation Changes</h5>
<ul>
<li><strong>client-ec2:</strong> Documentation updates clarifying
CancelCapacityReservation cancellable states (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/e3723ba73e2f2d307254d49ec73c5b3d91b8d892">e3723ba7</a>)</li>
</ul>
<h5>New Features</h5>
<ul>
<li><strong>client-compute-optimizer:</strong> This release surfaces two
new metrics Volume IOPS Exceeded and Volume Throughput Exceeded into EBS
volume rightsizing recommendations. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/ded6618d5249ab413bd90b26d4cea91d5f4b9b8f">ded6618d</a>)</li>
<li><strong>client-application-auto-scaling:</strong> Adds support for
ECS high-resolution predefined scaling metrics
(ECSServiceAverageCPUUtilizationHighResolution,
ECSServiceAverageMemoryUtilizationHighResolution) enabling 20-second
metric periods for faster scaling (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/95b3513a224a678fb92dc623f149d24adb96ae7b">95b3513a</a>)</li>
<li><strong>client-cognito-identity-provider:</strong> In order to
support the new TLS Self-Service feature, this change adds
SecurityPolicyType to CustomDomainConfigType. During
CreateUserPoolDomain and UpdateUserPoolDomain this is used to select a
custom domain's TLS enforcement, and for DescribeUserPoolDomain it
informs users about the current TLS. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/e89377876aa392ea403636b6821cdb3df253648b">e8937787</a>)</li>
<li><strong>client-sagemaker:</strong> Adds support for automatic AMI
patching on HyperPod clusters. Customers can configure patching
strategies to automatically apply security patch with zero job
termination. Customers can also specify an AMI version at instance group
level and update cluster software to a certain AMI version. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/fd33a5e46ca314f064b9149900abe4e451661b5e">fd33a5e4</a>)</li>
<li><strong>client-ecs:</strong> Amazon ECS services now support high
resolution (20 second) CloudWatch metrics for CPUUtilization and
MemoryUtilization. Use these metrics for faster service auto scaling.
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/93055ac93bffca3e2957b2d67cb24ecdc784457a">93055ac9</a>)</li>
<li><strong>client-healthlake:</strong> Adding New Configurations to the
FHIR Create Datastore. The new configurations include NLP Configuration,
AnalyticsConfiguration, ProfileConfiguration (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/494fa59f48705e23ab79da259046966831183c71">494fa59f</a>)</li>
<li><strong>client-gamelift:</strong> Amazon GameLift Servers has
launched support for customizing Linux capabilities in container fleets.
You can now specify additional Linux capabilities for containers in a
container group definition, giving you finer control over the default
Docker capabilities available to your containers. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/93cefd905d4fc0c649b1d7ed69f4c8f0d79d3371">93cefd90</a>)</li>
<li><strong>client-eks:</strong> Adds support for configurable control
plane egress routing in Amazon EKS, allowing you to route control plane
egress traffic through your VPC and control how the control plane
reaches resources in your network such as webhook servers and OIDC
providers. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/693db62958c6818b4cb847887b8e36a66347c119">693db629</a>)</li>
<li><strong>client-lambda:</strong> Converging and fixing existing
documentation gaps in Lambda SDK (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/6555a565348a308dad7a51c85457c2bcee87feb8">6555a565</a>)</li>
<li><strong>client-synthetics:</strong> CloudWatch Synthetics adds
support for multi-location canaries. Customers can now monitor their
endpoints from multiple locations with centralized management from a
primary location. The SDK includes new parameters for configuring
multiple locations and tracking their state. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/f2c8b480812b5ba2d1e173a8a074df6d72654239">f2c8b480</a>)</li>
<li><strong>client-cloudwatch-logs:</strong> Added optional
startFromHead parameter to FilterLogEvents enabling descending timestamp
order (newest first) when set to false. Default true preserves existing
ascending order. Reverse sorting requires a startTime on or after Jan 1,
2024. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/1be63ed942af46df978e55df4bec6fb6c9d16e60">1be63ed9</a>)</li>
<li><strong>client-batch:</strong> Adds Support for ordered allocation
strategies- BEST-FIT-PROGRESSIVE-ORDERED or
SPOT-CAPACITY-OPTIMIZED-PRIORITIZED (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/0e57e53b1e0914a03b5b7c7d346245a1e6b6da11">0e57e53b</a>)</li>
</ul>
<hr />
<p>For list of updated packages, view
<strong>updated-packages.md</strong> in
<strong>assets-3.1072.0.zip</strong></p>
<h2>v3.1071.0</h2>
<h4>3.1071.0(2026-06-17)</h4>
<h5>New Features</h5>
<ul>
<li><strong>client-partnercentral-selling:</strong> Cosell Resonate AND
Prospecing API Launch with ARN correction (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/7e8c98abe070924fbbd1ea2abc183f0715f80945">7e8c98ab</a>)</li>
<li><strong>client-compute-optimizer-automation:</strong> This launch
adds IfExists comparison operators to Compute Optimizer Automation rule
criteria, so a rule can include recommended actions whose specified
attribute isn't present. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/ab2c616d167a0796fba91e44d1118a6a8baee60d">ab2c616d</a>)</li>
<li><strong>client-bedrock-agent:</strong> Launching Bedrock Managed
Knowledge Bases. Added support for resource-based policies on Knowledge
Base resources, enabling cross-account access for Managed Knowledge
Bases. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/de0affe4ad738b7f07d91574e2b2cfd83a447d44">de0affe4</a>)</li>
<li><strong>client-securityagent:</strong> Updated AWS Security Agent
SDK model with new APIs for threat modeling, code review, security
requirements, and additional integration providers. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/9c3d3351842902b1ea1e8be52c4e7f40b868daae">9c3d3351</a>)</li>
<li><strong>client-opensearch:</strong> Adds support for configuring IAM
Identity Center options on existing OpenSearch applications via the
UpdateApplication API. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/94f06a20a15ab75302088d5f3c31d708a8256e5c">94f06a20</a>)</li>
<li><strong>client-glue:</strong> This release adds support for Search
and Discovery in AWS Glue, letting you and your applications search Data
Catalog assets such as table and enrich them with business context and
glossary terms. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/b394fc0b39c814d5f72593dfc4db5ff5c2cbe643">b394fc0b</a>)</li>
<li><strong>client-bedrock-agentcore-control:</strong> AgentCore Gateway
now supports inference targets to LLM providers (direct config or
built-in connectors), HTTP passthrough targets with session stickiness,
runtime target API schemas, AWS WAF web ACL association with
configurable fail-open or fail-close modes, and interceptor payload
filtering. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/75f1d588d526de04060ebd653ca1a96e7ea75ff6">75f1d588</a>)</li>
<li><strong>client-devops-agent:</strong> Adds support for Remote A2A
(Agent-to-Agent) agent registration and management. Adds new Release
Readiness Review and Release Testing capabilities. Adds support for Git
managed skills in AWS DevOps Agent. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/ebc040e1f3fc292d3eee1a9b146c972338e14807">ebc040e1</a>)</li>
<li><strong>client-bedrock-agentcore:</strong> AgentCore Harness service
will be Generally Available at NYS 2026 with this Treb release. Harness
will support invoking specific endpoints via the qualifier parameter,
AWS Skills for pre-built agent capabilities, and improved validation for
skill git source URLs. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/5bf9fcccc3b4cc204df57caea2adcf254c5d3846">5bf9fccc</a>)</li>
<li><strong>client-ecs:</strong> Releasing the ability to bring-your-own
task-definition for CreateExpressGatewayService and
UpdateGatewayExpressService (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/b7b9cb4f46a34c4ab0fedf2138a9a5ba17bdd731">b7b9cb4f</a>)</li>
<li><strong>client-mq:</strong> This release adds private networking
support for Amazon MQ for RabbitMQ. You can now associate AWS RAM
resource shares with your broker and retrieve shared resource details
using the new DescribeSharedResources API. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/e96af4503bfea9a6f211bc905b8e949af6cc38d7">e96af450</a>)</li>
<li><strong>client-bedrock-agent-runtime:</strong> Adds new
AgenticRetrieveStream API for managed knowledge bases to use
conversation history and autonomously plan for multi-hop multi-KB
reasoning with built-in evaluation and access-control. Updates Retrieve
API for access-control-based filtering for managed knowledge bases. (<a
href="https://github.com/aws/aws-sdk-js-v3/commit/557f7b3246fb6530fb8dcb481f1035d7827d2a1e">557f7b32</a>)</li>
</ul>
<h5>Tests</h5>
<ul>
<li><strong>core:</strong>
<ul>
<li>prebuild before integration and e2e (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8111">#8111</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/363f3fb7165d327e3ca24b3d7beffb19cc528c31">363f3fb7</a>)</li>
<li>prebuild core before unit tests (<a
href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8108">#8108</a>)
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/5f789e7fe2089eacff868a6e1d0b6c2c11313bbc">5f789e7f</a>)</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md">@​aws-sdk/client-s3's
changelog</a>.</em></p>
<blockquote>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1071.0...v3.1072.0">3.1072.0</a>
(2026-06-18)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1070.0...v3.1071.0">3.1071.0</a>
(2026-06-17)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1069.0...v3.1070.0">3.1070.0</a>
(2026-06-16)</h1>
<h3>Features</h3>
<ul>
<li><strong>client-s3:</strong> Added support for annotations. You can
now attach up to 1000 annotations (up to 1 MB each) directly to objects
and create, retrieve, list, and delete them using new annotation APIs.
Also added support for configuring an annotation table in S3 Metadata.
(<a
href="https://github.com/aws/aws-sdk-js-v3/commit/c555874690846b81904a2c0c1e96130bd03bbeaa">c555874</a>)</li>
</ul>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1068.0...v3.1069.0">3.1069.0</a>
(2026-06-15)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1067.0...v3.1068.0">3.1068.0</a>
(2026-06-12)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<h1><a
href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1066.0...v3.1067.0">3.1067.0</a>
(2026-06-11)</h1>
<p><strong>Note:</strong> Version bump only for package
<code>@​aws-sdk/client-s3</code></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/501cd332619533ae96f154d7c226dc2f7bf8d615"><code>501cd33</code></a>
Publish v3.1072.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/3ce820aa54c953459eb58abe4f06e28ba4ceb87d"><code>3ce820a</code></a>
Publish v3.1071.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/4f2cfe1cfc420d0b5bfa226ae6619dd67de73ccc"><code>4f2cfe1</code></a>
Publish v3.1070.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/c555874690846b81904a2c0c1e96130bd03bbeaa"><code>c555874</code></a>
feat(client-s3): Added support for annotations. You can now attach up to
1000...</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/7058d13814795c6ff06a960077269458520bf161"><code>7058d13</code></a>
Publish v3.1069.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/67981c5a65d6dd797a065df034a8d0fcdaa9b7bd"><code>67981c5</code></a>
chore(scripts): tuning the build graph (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8095">#8095</a>)</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/0632f6dc8842caaa916c5f43a5043342ff9ba6bb"><code>0632f6d</code></a>
Publish v3.1068.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/0a3246f174335af55a6981b4891f0f4c10dfe4c4"><code>0a3246f</code></a>
Publish v3.1067.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/4b11912aef8adc845f81b7e9922bd180c5cf1d90"><code>4b11912</code></a>
Publish v3.1066.0</li>
<li><a
href="https://github.com/aws/aws-sdk-js-v3/commit/e4ef6c57d8fd97d15e0a7a27a24396990d704307"><code>e4ef6c5</code></a>
test: use crypto.randomUUID for resource names in e2e tests (<a
href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8091">#8091</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/aws/aws-sdk-js-v3/commits/v3.1072.0/clients/client-s3">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 15:30:29 -07:00
dependabot[bot] ec65aba8ec build(deps): bump actions/upload-artifact from 4 to 7 (#7743)
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 4 to 7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>v7 What's new</h2>
<h3>Direct Uploads</h3>
<p>Adds support for uploading single files directly (unzipped). Callers
can set the new <code>archive</code> parameter to <code>false</code> to
skip zipping the file during upload. Right now, we only support single
files. The action will fail if the glob passed resolves to multiple
files. The <code>name</code> parameter is also ignored with this
setting. Instead, the name of the artifact will be the name of the
uploaded file.</p>
<h3>ESM</h3>
<p>To support new versions of the <code>@actions/*</code> packages,
we've upgraded the package to ESM.</p>
<h2>What's Changed</h2>
<ul>
<li>Add proxy integration test by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://redirect.github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
<li>Upgrade the module to ESM and bump dependencies by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/762">actions/upload-artifact#762</a></li>
<li>Support direct file uploads by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/764">actions/upload-artifact#764</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Link"><code>@​Link</code></a>- made
their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v6...v7.0.0">https://github.com/actions/upload-artifact/compare/v6...v7.0.0</a></p>
<h2>v6.0.0</h2>
<h2>v6 - What's new</h2>
<blockquote>
<p>[!IMPORTANT]
actions/upload-artifact@v6 now runs on Node.js 24 (<code>runs.using:
node24</code>) and requires a minimum Actions Runner version of 2.327.1.
If you are using self-hosted runners, ensure they are updated before
upgrading.</p>
</blockquote>
<h3>Node.js 24</h3>
<p>This release updates the runtime to Node.js 24. v5 had preliminary
support for Node.js 24, however this action was by default still running
on Node.js 20. Now this action by default will run on Node.js 24.</p>
<h2>What's Changed</h2>
<ul>
<li>Upload Artifact Node 24 support by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/719">actions/upload-artifact#719</a></li>
<li>fix: update <code>@​actions/artifact</code> for Node.js 24 punycode
deprecation by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/744">actions/upload-artifact#744</a></li>
<li>prepare release v6.0.0 for Node.js 24 support by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/745">actions/upload-artifact#745</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0">https://github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0</a></p>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<p><strong>BREAKING CHANGE:</strong> this update supports Node
<code>v24.x</code>. This is not a breaking change per-se but we're
treating it as such.</p>
<ul>
<li>Update README.md by <a
href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/681">actions/upload-artifact#681</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/712">actions/upload-artifact#712</a></li>
<li>Readme: spell out the first use of GHES by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/727">actions/upload-artifact#727</a></li>
<li>Update GHES guidance to include reference to Node 20 version by <a
href="https://github.com/patrikpolyak"><code>@​patrikpolyak</code></a>
in <a
href="https://redirect.github.com/actions/upload-artifact/pull/725">actions/upload-artifact#725</a></li>
<li>Bump <code>@actions/artifact</code> to <code>v4.0.0</code></li>
<li>Prepare <code>v5.0.0</code> by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/734">actions/upload-artifact#734</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/upload-artifact/commit/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"><code>043fb46</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/797">#797</a>
from actions/yacaovsnc/update-dependency</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/634250c1388765ea7ed0f053e636f1f399000b94"><code>634250c</code></a>
Include changes in typespec/ts-http-runtime 0.3.5</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/e454baaac2be505c9450e11b8f3215c6fc023ce8"><code>e454baa</code></a>
Readme: bump all the example versions to v7 (<a
href="https://redirect.github.com/actions/upload-artifact/issues/796">#796</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/74fad66b98a6d799dc004d3353ccd0e6f6b2530e"><code>74fad66</code></a>
Update the readme with direct upload details (<a
href="https://redirect.github.com/actions/upload-artifact/issues/795">#795</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f"><code>bbbca2d</code></a>
Support direct file uploads (<a
href="https://redirect.github.com/actions/upload-artifact/issues/764">#764</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/589182c5a4cec8920b8c1bce3e2fab1c97a02296"><code>589182c</code></a>
Upgrade the module to ESM and bump dependencies (<a
href="https://redirect.github.com/actions/upload-artifact/issues/762">#762</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/47309c993abb98030a35d55ef7ff34b7fa1074b5"><code>47309c9</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/754">#754</a>
from actions/Link-/add-proxy-integration-tests</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/02a8460834e70dab0ce194c64360c59dc1475ef0"><code>02a8460</code></a>
Add proxy integration test</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/b7c566a772e6b6bfb58ed0dc250532a479d7789f"><code>b7c566a</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/745">#745</a>
from actions/upload-artifact-v6-release</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/e516bc8500aaf3d07d591fcd4ae6ab5f9c391d5b"><code>e516bc8</code></a>
docs: correct description of Node.js 24 support in README</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/upload-artifact/compare/v4...v7">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:28:39 -07:00
dependabot[bot] 3d256186d3 build(deps): bump actions/download-artifact from 4 to 8 (#7742)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 4 to 8.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v8.0.0</h2>
<h2>v8 - What's new</h2>
<blockquote>
<p>[!IMPORTANT]
actions/download-artifact@v8 has been migrated to an ESM module. This
should be transparent to the caller but forks might need to make
significant changes.</p>
</blockquote>
<blockquote>
<p>[!IMPORTANT]
Hash mismatches will now error by default. Users can override this
behavior with a setting change (see below).</p>
</blockquote>
<h3>Direct downloads</h3>
<p>To support direct uploads in <code>actions/upload-artifact</code>,
the action will no longer attempt to unzip all downloaded files.
Instead, the action checks the <code>Content-Type</code> header ahead of
unzipping and skips non-zipped files. Callers wishing to download a
zipped file as-is can also set the new <code>skip-decompress</code>
parameter to <code>true</code>.</p>
<h3>Enforced checks (breaking)</h3>
<p>A previous release introduced digest checks on the download. If a
download hash didn't match the expected hash from the server, the action
would log a warning. Callers can now configure the behavior on mismatch
with the <code>digest-mismatch</code> parameter. To be secure by
default, we are now defaulting the behavior to <code>error</code> which
will fail the workflow run.</p>
<h3>ESM</h3>
<p>To support new versions of the @actions/* packages, we've upgraded
the package to ESM.</p>
<h2>What's Changed</h2>
<ul>
<li>Don't attempt to un-zip non-zipped downloads by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/460">actions/download-artifact#460</a></li>
<li>Add a setting to specify what to do on hash mismatch and default it
to <code>error</code> by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/461">actions/download-artifact#461</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v7...v8.0.0">https://github.com/actions/download-artifact/compare/v7...v8.0.0</a></p>
<h2>v7.0.0</h2>
<h2>v7 - What's new</h2>
<blockquote>
<p>[!IMPORTANT]
actions/download-artifact@v7 now runs on Node.js 24 (<code>runs.using:
node24</code>) and requires a minimum Actions Runner version of 2.327.1.
If you are using self-hosted runners, ensure they are updated before
upgrading.</p>
</blockquote>
<h3>Node.js 24</h3>
<p>This release updates the runtime to Node.js 24. v6 had preliminary
support for Node 24, however this action was by default still running on
Node.js 20. Now this action by default will run on Node.js 24.</p>
<h2>What's Changed</h2>
<ul>
<li>Update GHES guidance to include reference to Node 20 version by <a
href="https://github.com/patrikpolyak"><code>@​patrikpolyak</code></a>
in <a
href="https://redirect.github.com/actions/download-artifact/pull/440">actions/download-artifact#440</a></li>
<li>Download Artifact Node24 support by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/415">actions/download-artifact#415</a></li>
<li>fix: update <code>@​actions/artifact</code> to fix Node.js 24
punycode deprecation by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/451">actions/download-artifact#451</a></li>
<li>prepare release v7.0.0 for Node.js 24 support by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/452">actions/download-artifact#452</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/patrikpolyak"><code>@​patrikpolyak</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/440">actions/download-artifact#440</a></li>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/415">actions/download-artifact#415</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v6.0.0...v7.0.0">https://github.com/actions/download-artifact/compare/v6.0.0...v7.0.0</a></p>
<h2>v6.0.0</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/download-artifact/commit/3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c"><code>3e5f45b</code></a>
Add regression tests for CJK characters (<a
href="https://redirect.github.com/actions/download-artifact/issues/471">#471</a>)</li>
<li><a
href="https://github.com/actions/download-artifact/commit/e6d03f67377d4412c7aa56a8e2e4988e6ec479dd"><code>e6d03f6</code></a>
Add a regression test for artifact name + content-type mismatches (<a
href="https://redirect.github.com/actions/download-artifact/issues/472">#472</a>)</li>
<li><a
href="https://github.com/actions/download-artifact/commit/70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3"><code>70fc10c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/461">#461</a>
from actions/danwkennedy/digest-mismatch-behavior</li>
<li><a
href="https://github.com/actions/download-artifact/commit/f258da9a506b755b84a09a531814700b86ccfc62"><code>f258da9</code></a>
Add change docs</li>
<li><a
href="https://github.com/actions/download-artifact/commit/ccc058e5fbb0bb2352213eaec3491e117cbc4a5c"><code>ccc058e</code></a>
Fix linting issues</li>
<li><a
href="https://github.com/actions/download-artifact/commit/bd7976ba57ecea96e6f3df575eb922d11a12a9fd"><code>bd7976b</code></a>
Add a setting to specify what to do on hash mismatch and default it to
<code>error</code></li>
<li><a
href="https://github.com/actions/download-artifact/commit/ac21fcf45e0aaee541c0f7030558bdad38d77d6c"><code>ac21fcf</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/460">#460</a>
from actions/danwkennedy/download-no-unzip</li>
<li><a
href="https://github.com/actions/download-artifact/commit/15999bff51058bc7c19b50ebbba518eaef7c26c0"><code>15999bf</code></a>
Add note about package bumps</li>
<li><a
href="https://github.com/actions/download-artifact/commit/974686ed5098c7f9c9289ec946b9058e496a2561"><code>974686e</code></a>
Bump the version to <code>v8</code> and add release notes</li>
<li><a
href="https://github.com/actions/download-artifact/commit/fbe48b1d2756394be4cd4358ed3bc1343b330e75"><code>fbe48b1</code></a>
Update test names to make it clearer what they do</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/download-artifact/compare/v4...v8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=4&new-version=8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 15:13:33 -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
dependabot[bot] b29b47ae4a build(deps-dev): bump @types/multer from 2.0.0 to 2.1.0 (#7751)
Bumps
[@types/multer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/multer)
from 2.0.0 to 2.1.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/multer">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 15:12:24 -07:00
dependabot[bot] 0936990a58 build(deps): bump docker/setup-buildx-action from 3 to 4 (#8155)
Bumps
[docker/setup-buildx-action](https://github.com/docker/setup-buildx-action)
from 3 to 4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/setup-buildx-action/releases">docker/setup-buildx-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<ul>
<li>Node 24 as default runtime (requires <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Actions
Runner v2.327.1</a> or later) by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/483">docker/setup-buildx-action#483</a></li>
<li>Remove deprecated inputs/outputs by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/464">docker/setup-buildx-action#464</a></li>
<li>Switch to ESM and update config/test wiring by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/481">docker/setup-buildx-action#481</a></li>
<li>Bump <code>@​actions/core</code> from 1.11.1 to 3.0.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/475">docker/setup-buildx-action#475</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.63.0 to 0.79.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/482">docker/setup-buildx-action#482</a>
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/485">docker/setup-buildx-action#485</a></li>
<li>Bump js-yaml from 4.1.0 to 4.1.1 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/452">docker/setup-buildx-action#452</a></li>
<li>Bump lodash from 4.17.21 to 4.17.23 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/472">docker/setup-buildx-action#472</a></li>
<li>Bump minimatch from 3.1.2 to 3.1.5 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/480">docker/setup-buildx-action#480</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.12.0...v4.0.0">https://github.com/docker/setup-buildx-action/compare/v3.12.0...v4.0.0</a></p>
<h2>v3.12.0</h2>
<ul>
<li>Deprecate <code>install</code> input by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/455">docker/setup-buildx-action#455</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.62.1 to 0.63.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/434">docker/setup-buildx-action#434</a></li>
<li>Bump brace-expansion from 1.1.11 to 1.1.12 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/436">docker/setup-buildx-action#436</a></li>
<li>Bump form-data from 2.5.1 to 2.5.5 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/432">docker/setup-buildx-action#432</a></li>
<li>Bump undici from 5.28.4 to 5.29.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/435">docker/setup-buildx-action#435</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.11.1...v3.12.0">https://github.com/docker/setup-buildx-action/compare/v3.11.1...v3.12.0</a></p>
<h2>v3.11.1</h2>
<ul>
<li>Fix <code>keep-state</code> not being respected by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/429">docker/setup-buildx-action#429</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.11.0...v3.11.1">https://github.com/docker/setup-buildx-action/compare/v3.11.0...v3.11.1</a></p>
<h2>v3.11.0</h2>
<ul>
<li>Keep BuildKit state support by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/427">docker/setup-buildx-action#427</a></li>
<li>Remove aliases created when installing by default by <a
href="https://github.com/hashhar"><code>@​hashhar</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/139">docker/setup-buildx-action#139</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.56.0 to 0.62.1 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/422">docker/setup-buildx-action#422</a>
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/425">docker/setup-buildx-action#425</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.10.0...v3.11.0">https://github.com/docker/setup-buildx-action/compare/v3.10.0...v3.11.0</a></p>
<h2>v3.10.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.54.0 to 0.56.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/408">docker/setup-buildx-action#408</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.9.0...v3.10.0">https://github.com/docker/setup-buildx-action/compare/v3.9.0...v3.10.0</a></p>
<h2>v3.9.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.48.0 to 0.54.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/402">docker/setup-buildx-action#402</a>
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/404">docker/setup-buildx-action#404</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.8.0...v3.9.0">https://github.com/docker/setup-buildx-action/compare/v3.8.0...v3.9.0</a></p>
<h2>v3.8.0</h2>
<ul>
<li>Make cloud prefix optional to download buildx if driver is cloud by
<a href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/390">docker/setup-buildx-action#390</a></li>
<li>Bump <code>@​actions/core</code> from 1.10.1 to 1.11.1 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/370">docker/setup-buildx-action#370</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.39.0 to 0.48.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/389">docker/setup-buildx-action#389</a></li>
<li>Bump cross-spawn from 7.0.3 to 7.0.6 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/382">docker/setup-buildx-action#382</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.7.1...v3.8.0">https://github.com/docker/setup-buildx-action/compare/v3.7.1...v3.8.0</a></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5"><code>d7f5e7f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/489">#489</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/92bc5c9777806d0a73d9d668ba2114fa1177f164"><code>92bc5c9</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/da11e35abee0f20cb4f1c1b7c461d37c29be52f5"><code>da11e35</code></a>
build(deps): bump <code>@​docker/actions-toolkit</code> from 0.79.0 to
0.90.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/f021e162ef95b6fba51af1c6674f537f25bce851"><code>f021e16</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/492">#492</a>
from docker/dependabot/npm_and_yarn/undici-6.24.1</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/b5af94fab700aee0c64d6077e0e34ae987815b67"><code>b5af94f</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/16ad9776a801d0c47f0a05f007b88a3789aa8ab6"><code>16ad977</code></a>
build(deps): bump undici from 6.23.0 to 6.25.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/d7a12d7df895b33bd02a9b4bf62a12f2b9a24458"><code>d7a12d7</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/495">#495</a>
from docker/dependabot/npm_and_yarn/glob-10.5.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/28ff27de4eed7518d361591f2cd1dfb69c34a7cb"><code>28ff27d</code></a>
build(deps): bump glob from 10.3.12 to 13.0.6</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/daf436b50e13d9053b9730cbc16516891878b019"><code>daf436b</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/496">#496</a>
from docker/dependabot/npm_and_yarn/fast-xml-parser-5...</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/9725348367859764880f2f2e688a6b0c353e3f35"><code>9725348</code></a>
chore: update generated content</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/setup-buildx-action/compare/v3...v4">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:03:53 -07:00
Nicky Leach 6cfc6731d9 test(recovery): fix race condition in workspace validation comment check (#8294)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The heartbeat service manages agent run lifecycles, including
workspace validation before launching git-sensitive local adapters
> - When workspace validation fails, `escalateStrandedAssignedIssue` in
the recovery service sets the issue to `"blocked"` and then
asynchronously posts a system comment
> - A test added in PR #7644 verifies the comment appears, but queried
the database immediately after `waitForValue` resolved the issue status
— creating a race between the status write and the comment write
> - The test was passing before PR #8284 (pnpm lockfile refresh) but
began failing after, suggesting the lockfile update shifted async
scheduling enough to expose the window
> - This pull request wraps the comment check in `waitForValue`,
consistent with two identical polling patterns already used in the same
test file (lines 1159-1162 and 1232-1235)
> - The benefit is a consistently-passing test that unblocks dependabot
PR #8155 from auto-merging via CI

## Linked Issues or Issue Description

Refs PAP-72. Unblocks PAP-68 (dependabot PR #8155 which has auto-merge
enabled and was blocked by this test failure).

## What Changed

- `server/src/__tests__/heartbeat-process-recovery.test.ts`: replaced
direct `db.select()` + `expect(comments.some(...))` with a
`waitForValue` polling loop that waits until a comment containing
`"workspace failed validation"` appears, then asserts it is truthy
- No production code changed

## Verification

The specific test `blocks a git-sensitive local adapter before launch
when a project-workspace-linked issue is missing its project id`
previously failed with:

```
AssertionError: expected false to be true
src/__tests__/heartbeat-process-recovery.test.ts:1429:94
```

After this fix: the test polls with a 3-second timeout and returns once
the comment row exists. The comment IS written by
`escalateStrandedAssignedIssue` — this was purely a timing issue in the
test assertion. CI on this PR serves as the confirmation run.

## Risks

Low risk — test-only change. No production code is modified. The
`waitForValue` helper is already used 10+ times in the same test file
with the same 3-second timeout; this use follows the identical pattern.

## Model Used

- Provider: Anthropic
- Model: Claude Sonnet 4.6 (`claude-sonnet-4-6`)
- Context window: 200k tokens
- Tool use: yes (file read, bash, edit tools)
- Reasoning mode: extended thinking

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-18 14:52:56 -07:00
Devin Foley 8a062be94d docs: forbid internal Paperclip issue references in PRs (#8293)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Contributions flow through GitHub PRs against
`paperclipai/paperclip`, but most contributors author their work inside
their own private Paperclip instance
> - Those instances mint instance-local issue ids and deep links
(`PAPA-123`, `/PAP/issues/...`, `agent://...`, localhost/tailnet URLs)
that only the author can open
> - When contributors paste those references into a public PR, reviewers
hit clutter and broken links and have to ask for cleanup
> - There was no written guidance telling contributors (human or agent)
to keep those references out
> - This pull request adds that guidance to `CONTRIBUTING.md` and
surfaces it as a PR-template checklist item plus an inline hint
> - The benefit is cleaner PRs that reference only public, openable
GitHub issues/PRs, with internal context restated in plain English

## Linked Issues or Issue Description

Fixes: #8292

## What Changed

- `CONTRIBUTING.md`: new **No Internal Issue References** subsection
explaining what to leave out (internal ticket ids, instance UI/deep
links, localhost/tailnet URLs) and to restate useful context in plain
English; added a cross-reference sentence from the existing "Link Issues
or Describe Them In-PR" guidance.
- `.github/PULL_REQUEST_TEMPLATE.md`: new checklist item, plus an inline
hint in the Linked Issues comment block, directing contributors to
reference only public GitHub issues/PRs.

## Verification

Docs-only change. Rendered Markdown locally and confirmed the new
`#no-internal-issue-references` anchor resolves from the cross-reference
link, and that the template checklist item appears in the rendered list.
No code paths affected.

## Risks

Low risk — documentation and PR-template text only; no runtime, build,
or schema impact. An optional automated CI gate was intentionally
deferred to a follow-up to avoid regex false positives.

## Model Used

Claude Opus 4.7 (claude-opus-4-7), extended thinking, agentic tool use
via Claude Code.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] I have run tests locally and they pass
- [ ] 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
- [ ] 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 14:37:21 -07:00
dependabot[bot] 83a293b161 build(deps): bump actions/checkout from 4 to 6 (#8154)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to
6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>v6-beta by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2298">actions/checkout#2298</a></li>
<li>update readme/changelog for v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2311">actions/checkout#2311</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v5.0.0...v6.0.0">https://github.com/actions/checkout/compare/v5.0.0...v6.0.0</a></p>
<h2>v6-beta</h2>
<h2>What's Changed</h2>
<p>Updated persist-credentials to store the credentials under
<code>$RUNNER_TEMP</code> instead of directly in the local git
config.</p>
<p>This requires a minimum Actions Runner version of <a
href="https://github.com/actions/runner/releases/tag/v2.329.0">v2.329.0</a>
to access the persisted credentials for <a
href="https://docs.github.com/en/actions/tutorials/use-containerized-services/create-a-docker-container-action">Docker
container action</a> scenarios.</p>
<h2>v5.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v5...v5.0.1">https://github.com/actions/checkout/compare/v5...v5.0.1</a></p>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
<li>Prepare v5.0.0 release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p>
<h2>v4.3.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v4.3.1">https://github.com/actions/checkout/compare/v4...v4.3.1</a></p>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/checkout/commit/df4cb1c069e1874edd31b4311f1884172cec0e10"><code>df4cb1c</code></a>
Update changelog for v6.0.3 (<a
href="https://redirect.github.com/actions/checkout/issues/2446">#2446</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/1cce3390c2bfda521930d01229c073c7ff920824"><code>1cce339</code></a>
Fix checkout init for SHA-256 repositories (<a
href="https://redirect.github.com/actions/checkout/issues/2439">#2439</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/900f2210b1d28bbbd0bd22d17926b9e224e8f231"><code>900f221</code></a>
fix: expand merge commit SHA regex and add SHA-256 test cases (<a
href="https://redirect.github.com/actions/checkout/issues/2414">#2414</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/0c366fd6a839edf440554fa01a7085ccba70ac98"><code>0c366fd</code></a>
Update changelog (<a
href="https://redirect.github.com/actions/checkout/issues/2357">#2357</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/de0fac2e4500dabe0009e67214ff5f5447ce83dd"><code>de0fac2</code></a>
Fix tag handling: preserve annotations and explicit fetch-tags (<a
href="https://redirect.github.com/actions/checkout/issues/2356">#2356</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/064fe7f3312418007dea2b49a19844a9ee378f49"><code>064fe7f</code></a>
Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID is
set (...</li>
<li><a
href="https://github.com/actions/checkout/commit/8e8c483db84b4bee98b60c0593521ed34d9990e8"><code>8e8c483</code></a>
Clarify v6 README (<a
href="https://redirect.github.com/actions/checkout/issues/2328">#2328</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/033fa0dc0b82693d8986f1016a0ec2c5e7d9cbb1"><code>033fa0d</code></a>
Add worktree support for persist-credentials includeIf (<a
href="https://redirect.github.com/actions/checkout/issues/2327">#2327</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5"><code>c2d88d3</code></a>
Update all references from v5 and v4 to v6 (<a
href="https://redirect.github.com/actions/checkout/issues/2314">#2314</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/1af3b93b6815bc44a9784bd300feb67ff0d1eeb3"><code>1af3b93</code></a>
update readme/changelog for v6 (<a
href="https://redirect.github.com/actions/checkout/issues/2311">#2311</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/checkout/compare/v4...v6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4&new-version=6)](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 13:59:25 -07:00
dependabot[bot] 0ec4f248af build(deps): bump docker/login-action from 3 to 4 (#8156)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - CI/CD pipelines use GitHub Actions to automate builds and
deployments of services
> - The `agent-runtime-images` workflow uses `docker/login-action` for
authenticating with Docker registries before pushing images
> - `docker/login-action` v3 is now superseded; v4 was released with
Node 24 as the default runtime and updated internal dependencies
(`@actions/core`, AWS SDK, `@docker/actions-toolkit`)
> - This pull request bumps `docker/login-action` from v3 to v4 in the
`agent-runtime-images.yml` workflow
> - The benefit is staying on a supported runtime version and receiving
upstream security and dependency updates

## Linked Issues or Issue Description

Automated dependency bump — no upstream issue. The underlying need is
routine dependency maintenance:

- **Change type:** Dependency version bump (GitHub Actions)
- **Scope:** Single workflow file, single-line version tag change
- **Motivation:** v4 modernizes the action runtime to Node 24 and
receives updated `@actions/core` (3.x) and AWS SDK dependencies with
security patches

## What Changed

- Bumps `docker/login-action` from `v3` → `v4` in
`.github/workflows/agent-runtime-images.yml`
- v4 switches to Node 24 as the default Actions runtime (requires runner
v2.327.1+; GitHub-hosted runners satisfy this automatically)
- No changes to the action's inputs, outputs, or behavior — the API is
fully backward-compatible

## Verification

- All CI checks pass (green) on this PR
- No input/output interface changes; the login step behavior is
identical
- GitHub-hosted runners automatically meet the Node 24 runtime
requirement (runner v2.327.1+)

## Risks

Low risk. This is a one-line version bump on a widely-used, officially
maintained Docker action. The v4 release has no breaking changes to
inputs or outputs. The only new requirement (Node 24 / runner v2.327.1+)
is satisfied by GitHub-hosted runners automatically.

## Model Used

None — automated Dependabot bump. PR description updated by Claude
Sonnet 4.6 (Anthropic, 200k context, tool use enabled) to satisfy the PR
template requirement.

## 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
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 13:47:55 -07:00