Commit Graph

2996 Commits

Author SHA1 Message Date
Dotta 97e0752158
Fix work timeline visible stats and kickoff attribution (#9271)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The work timeline helps operators understand what agents did, when
they did it, and who kicked off each run
> - Timeline statistics should describe the window the operator is
viewing, not hidden work outside the viewport
> - Kickoff chips should point to the run that was actually closest to
the triggering edge, not stale later runs on the same issue
> - This pull request scopes timeline summary stats to the visible
window and deduplicates kickoff attribution to the nearest matching run
> - The benefit is that operators get a more accurate, less misleading
timeline while scanning agent work

## Linked Issues or Issue Description

No matching public GitHub issue was found. Public duplicate search found
no open PR for "work timeline visible window kickoff".

### What happened?

Work timeline summary stats could count hidden spans outside the
selected visible window, and kickoff attribution could appear on a stale
matching run instead of the closest run associated with the edge.

### Expected behavior

Visible timeline stats should reflect only the current visible range,
and each kickoff edge should attach to the nearest matching run.

### Steps to reproduce

1. View a work timeline with agent spans that begin before or end after
the selected visible window.
2. Compare the summary stats against only the spans visible in the
viewport.
3. View repeated runs for the same actor and issue that share a kickoff
edge.
4. Check which run gets the kickoff chip.

### Paperclip version or commit

Current `origin/master` before this PR.

### Deployment mode

Board UI.

## What Changed

- Filters timeline summary stats to the visible time window.
- Passes visible-window metadata into the work timeline chart and page
state.
- Assigns each kickoff edge to only the closest matching run, with
deterministic tie-breaking.
- Adds focused regression coverage for visible stats and stale kickoff
attribution.

## Verification

- `pnpm exec vitest run
ui/src/components/timeline/WorkTimelineChart.test.tsx
ui/src/lib/timeline/layout.test.ts ui/src/pages/Timeline.test.tsx` -- 38
tests passed.
- `pnpm check:token-gates` -- all gates clean.
- `git diff --check origin/master...HEAD` -- passed.

## Visual Evidence

Public review artifacts for the user-visible timeline behaviours. The
SVGs use sanitized run labels and no internal Paperclip issue
identifiers.

![Visible-window stat panel before and after
scroll](5f33032ee3/visible-window-stats.svg)

![Kickoff attribution before and after stale-chip
fix](3e0ac8de60/kickoff-attribution.svg)

Artifact gist:
https://gist.github.com/cryppadotta/dc2645d54c4bc56ffc0323224b3ea4bf

## Risks

- Low risk. The change affects timeline rendering and summary
calculations only; the main risk is a subtle difference in which run
gets a kickoff chip when multiple runs are very close together.

> 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. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex coding agent based on GPT-5, tool-enabled shell workflow.
Exact hosted model variant and context window were not exposed by the
runtime.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-09 08:30:46 -05:00
Dotta 7cf0d3ebb0
Require health readiness for Paperclip dev services (#9269)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents often run against managed workspace runtime services,
including reusable Paperclip dev servers
> - A running process and an open root URL are not enough to prove the
Paperclip API is actually ready
> - If the API health endpoint is still failing, agents can reuse a
service that looks alive but cannot safely serve the board or API
clients
> - This pull request makes Paperclip dev runtime readiness probe the
resolved `/api/health` endpoint
> - The benefit is that runtime service reuse waits for the same health
signal operators and agents depend on

## Linked Issues or Issue Description

No matching public GitHub issue was found. Public duplicate search found
no open PR for "workspace runtime health readiness".

Bug report:

### What happened?

A managed Paperclip dev runtime service could satisfy HTTP readiness at
the exposed base URL even when the Paperclip health endpoint was
returning an unhealthy status.

### Expected behavior

Paperclip dev runtime services should not be considered ready until
their health endpoint succeeds.

### Steps to reproduce

1. Start a workspace runtime service named `paperclip-dev` whose base
URL responds successfully.
2. Make that same service return HTTP 503 from `/api/health`.
3. Ask Paperclip to ensure the runtime service for a run.
4. Observe that the service can be reused even though the API health
endpoint is not ready.

### Paperclip version or commit

Current `origin/master` before this PR.

### Deployment mode

Local workspace runtime service management.

## What Changed

- Resolve Paperclip dev runtime readiness checks to the service health
URL before polling.
- Surface readiness errors with the actual health URL that failed.
- Add a regression test that fails when `/api/health` returns HTTP 503
even if the service process is running.

## Verification

- `pnpm exec vitest run server/src/__tests__/workspace-runtime.test.ts`
— 81 tests passed.
- `git diff --check origin/master...HEAD` — passed.

## Risks

- Low to medium risk. This tightens readiness for Paperclip dev runtime
services, so a service that previously looked ready while unhealthy will
now fail fast instead of being reused.

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

## Model Used

OpenAI Codex coding agent based on GPT-5, tool-enabled shell workflow.
Exact hosted model variant and context window were not exposed by the
runtime.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-09 08:25:59 -05:00
Nicky Leach 3e63a7e3e5
Fail fast stalled Daytona Git network commands
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Daytona sandbox provider executes agent commands inside
ephemeral Daytona workspaces via `executeCommand`
> - Git operations inside these workspaces can block indefinitely when
remotes are unreachable or when git prompts for credentials
interactively (e.g. via askpass or terminal prompts)
> - When git blocks, it consumes the full 900s adapter RPC ceiling,
which surfaces as a hard timeout crash on the Paperclip side rather than
an actionable error
> - This PR adds noninteractive credential defaults and a 120s cap on
detected Git network subcommands so stalled operations fail fast with a
useful message
> - The benefit is that engineers and agents see an actionable error
pointing at missing credentials or unreachable remotes instead of an
opaque 900s RPC crash

## Linked Issues or Issue Description

<!-- No public GitHub issue exists for this internal infrastructure fix.
Describing the issue inline. -->

**Bug: Daytona sandbox Git network commands stall for up to 900
seconds**

**What happened?**
`executeCommand` hangs for the full 900 s adapter RPC ceiling when a
Daytona workspace git network command (push/fetch/pull/clone) prompts
for credentials interactively or the remote is unreachable. The command
blocks silently for up to 900 s then crashes with a generic timeout
error that names no actionable root cause.

**Steps to reproduce**
Run any agent handoff that includes a `git push`, `git fetch`, or `git
pull` to a remote inside a Daytona workspace where the remote is
unreachable or credentials are missing.

**Expected behavior**
Command fails fast (within ~120 s) with an actionable error naming the
unreachable remote or the missing noninteractive credential.

**Deployment mode**
Daytona sandbox provider (`packages/plugins/sandbox-providers/daytona`).
Root cause: Daytona one-shot execution wrappers did not set
`GIT_TERMINAL_PROMPT=0`, `GCM_INTERACTIVE=Never`, or disabled askpass
helpers, so git blocked waiting for interactive terminal input; no
per-operation timeout existed for network-bound git subcommands.

## What Changed

- Added `GIT_TERMINAL_PROMPT=0`, `GCM_INTERACTIVE=Never`,
`GIT_ASKPASS=echo`, `SSH_ASKPASS=echo`, `SSH_ASKPASS_REQUIRE=force` to
all Daytona one-shot execution wrapper invocations so git never blocks
waiting for a credential prompt; callers may override via the `env`
parameter
- Detects Git network subcommands (`push`, `fetch`, `pull`, `ls-remote`,
`clone`, `remote update`, `submodule update`) and caps their timeout at
120 s instead of the full 900 s adapter RPC ceiling
- Returns an actionable timeout message that names the unreachable
remote or the missing noninteractive credential rather than propagating
the raw SDK error
- Adds two new Vitest tests: one verifying noninteractive credential
defaults are injected, one verifying the 120 s network cap and the
improved timeout message

## Verification

- `corepack pnpm exec vitest run
packages/plugins/sandbox-providers/daytona/src/plugin.test.ts --config
packages/plugins/sandbox-providers/daytona/vitest.config.ts` — 40 tests
pass
- `corepack pnpm exec tsc -p tsconfig.json --noEmit` from
`packages/plugins/sandbox-providers/daytona` — clean
- `corepack pnpm check:no-git-push` — clean

> **Known CI note:** The standalone provider package is intentionally
excluded from the root workspace. Direct `corepack pnpm test` from the
provider directory fails before running tests due to Vitest
tsconfig-root resolution in a grafted checkout. The root-config Vitest
invocation above is the passing test signal.

## Risks

- **Low overall risk.** The new `GIT_TERMINAL_PROMPT=0` / askpass
defaults only affect Daytona one-shot execution; they do not touch any
shared git config or host environment.
- Callers that previously relied on interactive credential prompts
inside Daytona (an unlikely pattern for agent workspaces) will now fail
fast instead of prompting — this is the intended behavior.
- The 120 s network timeout applies only when the command string starts
with a recognized git network subcommand, so non-network git operations
and all non-git commands are unaffected.
- No PII, telemetry schema, crypto, auth flow, or new external endpoint
changes.

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`) — extended thinking mode, tool
use, code execution. Anthropic Claude running via Paperclip Claude Code
adapter.

## Checklist

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

---------

Co-authored-by: Harold Kim <harold.kim@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-09 02:46:15 -07:00
Nicky Leach cf8b6e1bdd
chore: trigger Docker build-and-push for lockfile refresh (post #9252)
Empty commit to trigger Docker workflow on the fixed lockfile lineage (ea30144). The Refresh Lockfile bot push did not retrigger Docker per GitHub's workflow isolation policy.
2026-07-08 22:33:54 -07:00
github-actions[bot] ea301442e8
chore(lockfile): refresh pnpm-lock.yaml (#9252)
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-07-08 22:15:41 -07:00
Nicky Leach 719da5f9b5
Harden environment deletion and expose delete blast radius (#9250)
## Thinking Path

> - Paperclip manages AI agents that each have an associated execution
environment (local, Kubernetes, etc.)
> - Instance administrators can create and delete environments;
currently the DELETE endpoint has no protection against deleting managed
or in-use environments
> - Deleting the managed local environment or the instance-default
environment would break all agents using those environments with no path
to recovery
> - The endpoint also suffered a TOCTOU race: a check-then-delete
pattern allowed the managed-local or default guard to pass if the
environment's role changed between the read and the delete
> - This pull request adds a blast-radius read endpoint so admins can
preview impact, hard-blocks the dangerous deletes atomically, cleans up
all dependent references after a valid delete, and fixes a concurrent
creation race in ensureLocalEnvironment

## Linked Issues or Issue Description

Fixes #9251

## What Changed

- **New endpoint** `GET /api/environments/:id/delete-blast-radius`
(instance-admin gated): returns reference counts (agent defaults,
workspace selections, issue selections, project selections, secret
bindings, active leases, active setup sessions) and blocking reasons —
no config, env-var values, or secret data returned.
- **Atomic delete guard** `environmentService.removeIfDeletable(id)`:
performs the DELETE with an inline `WHERE driver != 'local' AND NOT
EXISTS (instanceSettings where defaultEnvironmentId = id)` predicate,
eliminating the TOCTOU race between the app-level check and the DB
write.
- **Route hardening**: `DELETE /environments/:id` now calls
`getDeleteBlastRadius` first (app-level check + logging), then calls
`removeIfDeletable` (atomic guard). If the atomic guard returns null the
route fetches a fresh blast-radius snapshot and rejects with a 409
Conflict carrying `deleteBlockedReasons`.
- **Reference cleanup on valid delete**: after a successful delete, the
route clears environment selections on all company execution workspaces,
issues, and projects; syncs env-var secret bindings to `{}` (removing
bindings for the deleted environment); syncs config secret refs to `[]`
for the environment target; and removes the SSH private-key secret if
one was stored.
- **Race fix in `ensureLocalEnvironment`**: the insert-or-nothing path
now catches a `environments_name_idx` unique-constraint violation and
falls through to the existing SELECT, treating the name conflict as
idempotent.
- **Shared types**: `EnvironmentDeleteBlastRadius` and
`EnvironmentDeleteBlockedReason` exported from `@paperclipai/shared`.
- **OpenAPI**: registers the new blast-radius endpoint; updates the
delete-environment response schema to document 403/404/409.
- **Tests**: 56 existing environment-route and service tests continue to
pass; new service-level regression tests assert the atomic guard rejects
`local`-driver environments and instance-default environments and
succeeds for deletable ones.

## Verification

```
corepack pnpm exec vitest run \
  server/src/__tests__/environment-routes.test.ts \
  server/src/__tests__/environment-service.test.ts
# 56 tests, all passing
corepack pnpm --filter @paperclipai/shared typecheck
node scripts/ensure-plugin-build-deps.mjs
cd server && ../node_modules/.bin/tsc --noEmit
```

## Risks

- **Blast-radius endpoint auth**: guarded by
`assertCanAccessInstanceEnvironments`, the same gate as the existing
environment-list and delete routes. Non-admin callers receive 401/403
before any data is returned.
- **Atomic guard may reject a delete that the app-level check passed**:
this is intentional — it means the environment became protected between
the read and the write. The caller receives a fresh blast-radius
snapshot explaining why.
- **Secret cleanup ordering**: cleanup runs after the atomic DELETE
succeeds, in parallel across companies. If cleanup partially fails the
environment row is already gone; partial-cleanup state is recoverable by
re-running the sync operations. Risk: low — these are idempotent
upsert/sync operations.
- **ensureLocalEnvironment race fix**: swapping a unique-constraint
error for an idempotent SELECT adds one extra query on the conflict
path. This path is rare (only fires during concurrent boot) and is
significantly safer than the previous behavior.
- **No migration**: all changes are application-level; no schema changes
required.

## Model Used

- Provider: Anthropic
- Model: claude-sonnet-4-6 (Claude Sonnet 4.6)
- Context window: 200k tokens
- Mode: agentic tool use via Paperclip agent system (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. `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
- [ ] 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: Priya Raman <priya.raman@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Harold Kim <harold.kim@paperclip.ing>
2026-07-08 22:04:22 -07:00
Nicky Leach 1b16f9611c
feat(telemetry): document credential health retention (#9248)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The shared telemetry package (`packages/shared/src/telemetry`)
defines the public contract for first-party telemetry events — event
names, dimension shapes, and now retention windows
> - A new telemetry event, `codex.credential_health`, carries
credential-observability fields (enums, booleans, counts, coarse
buckets) — no token material and no PII
> - The retention window for this event and its class was undocumented
at the contract level, leaving data-infra and reviewers without a
discoverable source of truth
> - This pull request adds `retention.ts` as the canonical
retention-contract surface, assigns `codex.credential_health` to the
`operational_enum_count` class (90-day window), exports the contract
from the shared package, and updates the README
> - The benefit is that the retention window is discoverable from the
event definition rather than being implicit pipeline knowledge, and the
no-token/no-PII note is locked in a contract test rather than relying on
prose

## Issue Description

No public GitHub issue exists for this change. Inline description
follows the [feature request
template](.github/ISSUE_TEMPLATE/feature_request.yml):

### Problem or motivation

`packages/shared/src/telemetry/` applies a 90-day retention window to
`codex.credential_health` events at the pipeline level, but this policy
is not stated anywhere in the shared telemetry contract. Without a
discoverable retention declaration, reviewers and data-infra must read
pipeline configuration to understand retention behaviour — there is no
contract-level source of truth. The `codex.credential_health` event
carries only enums, booleans, counts, and coarse buckets — no token
material and no PII.

### Proposed solution

Add a `retention.ts` module to the shared telemetry package that defines
the `operational_enum_count` retention class (90-day window) and maps
`codex.credential_health` to it. Export the contract from the package
index and add a focused contract test. Update the README with a
Retention section and a pointer in the Public Sources table. This is
additive documentation only — no runtime paths change.

### Alternatives considered

Keep retention implicit in pipeline configuration only. Rejected: this
leaves no discoverable, versioned contract for reviewers or data-infra,
and means every consumer must read pipeline config to understand
retention semantics. A schema-level declaration is the correct long-term
home.

### Roadmap alignment

Aligns with the telemetry contract hardening track — making implicit
operational knowledge explicit and testable at the shared-package level.

## What Changed

- **`packages/shared/src/telemetry/retention.ts`** (new): defines
`RETENTION_DAYS` (class → days) and `EVENT_RETENTION_CLASS` (event name
→ class). `operational_enum_count` is the only class: 90-day window for
enum/count/bucket events with no token material or PII.
`codex.credential_health` is the first entry. The `string` key type is
intentional to accommodate cross-system events (e.g. the Codex CLI) not
yet promoted to the first-party `PaperclipEventName` schema.
- **`packages/shared/src/telemetry/retention.test.ts`** (new): three
focused assertions — `operational_enum_count` is 90 days,
`codex.credential_health` is assigned that class, and the resolved
window is 90 days.
- **`packages/shared/src/telemetry/index.ts`**: exports
`RETENTION_DAYS`, `EVENT_RETENTION_CLASS`, and `RetentionClass` from the
shared package.
- **`packages/shared/src/telemetry/README.md`**: adds `retention.ts` to
the Public Sources table and a new Retention section with a class
reference table and guidance for future assignments.

## Verification

- `git diff --check` passes (no whitespace errors)
- `pnpm --filter @paperclipai/shared exec vitest run
src/telemetry/retention.test.ts src/telemetry/readme-contract.test.ts` —
runs the new contract tests and the existing readme-contract test
- `pnpm --filter @paperclipai/shared typecheck` — confirms the new
exports compile cleanly
- CI gates green

## Risks

Low risk. This is a documentation-only addition:
- No new telemetry event, dimension, emitter, or schema change
- No runtime code paths changed
- The new file is tree-shaken away in any consumer that doesn't import
from it
- `satisfies Record<string, number>` on `RETENTION_DAYS` ensures the
type stays correct as new classes are added

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`) — Anthropic, 200k context
window, tool use enabled, no extended thinking mode. Used for code
authoring and PR composition.

## Checklist

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

---------

Co-authored-by: Harold Kim <harold.kim@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Harold Kim <harold-kim@paperclip.ing>
2026-07-08 21:27:39 -07:00
Devin Foley eedc7ddef2
Make ACP the default engine for local adapters (#9238)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Adapter packages are the bridge between the control plane and local
agent harnesses such as Claude Code, Codex, and Gemini CLI.
> - ACP support was concentrated in a separate `acpx_local` adapter,
which made ACP feel like a separate agent choice instead of an execution
capability of the harness adapters.
> - Claude, Codex, and Gemini now have ACP-capable harnesses, so the
native adapter should own ACP selection, fallback, config, transcript
parsing, and environment diagnostics.
> - The standalone ACPX adapter still needs a compatibility path for
existing rows, but it should not be offered as an active adapter for new
agents.
> - This pull request moves the shared ACP runtime into
`@paperclipai/acpx-engine`, wires Claude/Codex/Gemini local adapters to
prefer ACP when prerequisites are available, and retires `acpx_local` to
a tombstone.
> - The benefit is one adapter per harness, richer ACP transcripts by
default where possible, and a migration path for existing Claude/Codex
ACPX agents.

## Linked Issues or Issue Description

Closes #5932 — the broken default `acpx_local` Claude path is replaced
by native `claude_local` ACP support, existing Claude/Codex ACPX rows
migrate to native adapters, and new agents no longer choose the
standalone ACPX adapter.

Refs #4893 — original merged ACPX local adapter runtime that this PR
replaces with native per-harness ACP engines.
Refs #6590 — prior ACPX-Claude seamlessness work folded into the new
native Claude ACP path.
Refs #197 — related open generic ACP/Kiro adapter work; this PR does not
close it because Kiro/custom generic ACP remains a separate adapter
decision.
Refs #7018 — related Kimi-specific `acpx_local` shell failure; this PR
retires the built-in standalone adapter but does not add a native Kimi
adapter.
Refs #8864 — related ACPX prompt/API guidance PR; this PR moves runtime
guidance into the shared/native ACP engine path instead of the old
standalone adapter.
Refs #8881 — related `acpx_local` POSIX shell failure from the old
`acpx` pin; this PR updates ACP dependencies but does not claim
custom/OMP ACP support as a first-class native adapter.
Refs #8964 — related open `acpx_local` stderr cleanup PR; this PR makes
the old runtime path obsolete for new agents but keeps it as a
non-closing reference.

Problem description:

- The standalone `acpx_local` adapter duplicates Claude/Codex agent
choices that already have first-class local adapters.
- ACP should be an execution engine capability of each harness adapter
when the underlying harness supports ACP.
- Existing `acpx_local` agents should either migrate to native harness
adapters or fail with an explicit retirement message instead of silently
falling back to the process adapter.

## What Changed

- Added `@paperclipai/acpx-engine` as the shared ACP execution,
session-codec, CLI formatter, and UI parser package.
- Wired `claude_local`, `codex_local`, and `gemini_local` to auto-select
ACP by default when prerequisites pass, with `engine=cli` opt-out and
`engine=acp` strict mode.
- Added ACP config schema/UI fields, environment checks, session-codec
preservation, transcript parsing, and adapter capability metadata for
the native adapters.
- Retired `acpx_local` to a server tombstone, removed its
UI/package/runtime image surface, and added a migration for existing
Claude/Codex ACPX agents.
- Updated package manifests, lockfile, release tooling, docs, Kubernetes
sandbox defaults, and tests.

## Verification

- `corepack pnpm --filter @paperclipai/acpx-engine typecheck`
- `corepack pnpm --filter @paperclipai/adapter-claude-local typecheck`
- `corepack pnpm --filter @paperclipai/adapter-codex-local typecheck`
- `corepack pnpm --filter @paperclipai/adapter-gemini-local typecheck`
- `corepack pnpm --filter @paperclipai/acpx-engine exec vitest run`
- `corepack pnpm --filter @paperclipai/adapter-claude-local exec vitest
run src/server/acp.test.ts src/server/execute.acp-fallback.test.ts
src/ui/build-config.test.ts`
- `corepack pnpm --filter @paperclipai/adapter-codex-local exec vitest
run src/server/acp.test.ts src/ui/build-config.test.ts`
- `corepack pnpm --filter @paperclipai/adapter-gemini-local exec vitest
run src/server/acp.test.ts src/ui/build-config.test.ts
src/ui/parse-stdout.test.ts`
- `corepack pnpm --filter @paperclipai/plugin-sdk ensure-build-deps &&
corepack pnpm --filter @paperclipai/server exec tsc --noEmit`
- `corepack pnpm --filter @paperclipai/server exec vitest run
src/__tests__/adapter-routes.test.ts
src/__tests__/adapter-session-codecs.test.ts
src/__tests__/adapter-models.test.ts`
- `corepack pnpm --filter @paperclipai/ui typecheck`
- `corepack pnpm --filter @paperclipai/ui exec vitest run
src/adapters/metadata.test.ts
src/adapters/adapter-display-registry.test.ts
src/components/AgentConfigForm.test.ts
src/components/AgentConfigForm.render.test.tsx
src/components/transcript/RunTranscriptView.test.tsx`
- `node --test scripts/bootstrap-npm-package.test.mjs
scripts/release-package-map.test.mjs
scripts/verify-release-registry-state.test.mjs`

Note: the server typecheck script calls `pnpm` internally; this dev
shell exposes pnpm through Corepack only, so I ran the two script steps
manually with `corepack pnpm`.

## Risks

- Migration changes existing `acpx_local` Claude/Codex agents to native
adapter types and clears old ACPX task sessions/runtime state.
- Custom ACP commands remain on the retired tombstone and will need a
separate future adapter/plugin path.
- ACP auto-selection depends on local Node and ACP server command
prerequisites; remote and unsupported environments fall back to CLI
unless `engine=acp` is explicit.
- `@paperclipai/acpx-engine` is a new public package and needs npm
trusted-publishing bootstrap before release automation can publish it.

> 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 coding agent. Exact hosted model build and
context-window size are not exposed in this runtime. Tool use included
shell execution, repository editing, GitHub CLI operations, and local
test/typecheck execution.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 19:05:03 -07:00
Nicky Leach 187a929d97
docs: explain Codex and Claude credential ownership
Squash-merges the adapter credential ownership doc PR.

- Documents codex_local host-owns-auth topology and CODEX_HOME auth precedence
- Documents claude_local snapshot-owns-auth topology (sandbox targets only)
- Adds API-key vs ChatGPT-subscription guidance for high-concurrency fleets
- Adds deferred config-validation warning spec for sandbox credential mismatches
- Fixes: SSH scope mismatch (Greptile P1) and codex auth.json materialization note (Greptile P2)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-08 18:09:40 -07:00
Nicky Leach 3288ec4f47
chore: ignore materialized Paperclip runtime directory
Adds .paperclip-runtime/ to .gitignore so the materialized adapter credentials directory is never accidentally committed.
2026-07-08 17:59:43 -07:00
scotttong c90e66bdd6
feat(ui): design-system component convergence — Card/Badge adoption, multiplicative radius ladder, unified list surfaces (#9240)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its UI is governed by a design system (`DESIGN.md` + the token layer
in `ui/src/index.css`, merged in #9134) whose first principle is "one
way to say each thing" — one Card, one Badge, one nav row
> - After the token extraction landed, ~35 files still hand-rolled card
containers, ~45 files hand-rolled pill spans, the sidebar agents section
duplicated the nav-row chrome, and the inbox and tasks lists rendered
the same task rows two subtly different ways
> - Each divergence is a place where a future design change (radius,
hover language, status vocabulary) silently misses surfaces, defeating
the "edit tokens + run checks" model the design system exists for
> - This pull request converges those surfaces onto the shared
primitives, codifies the radius scale as the modern multiplicative
shadcn ladder, and unifies the row/hover/tree-guide language across the
inbox and tasks lists — every visible delta was human-reviewed
screen-by-screen against a live instance across nine feedback rounds
> - The benefit is that the app's look is now steerable from single
knobs (one `--radius` anchor, one Card, one Badge, one row component),
and the visual regression suite covers the result (514 snapshots
including a new AgentDetail page story)

## Linked Issues or Issue Description

No public GitHub issue exists for this work; describing per the feature
template:

- **Problem**: after the design-token foundation (#9134),
component-level drift remained — hand-rolled cards/pills, duplicated
sidebar row chrome, and two different renderings of task rows (inbox vs
tasks list) meant design changes had to be applied per-surface and
frequently missed spots (e.g. status glyphs rendered 16px in the inbox
but 20px in the tasks list because a slot override silently beat the
component default).
- **Proposed behavior**: all card-shaped containers render via `Card`,
all label pills via `Badge`, sidebar rows via `SidebarNavItem`, and both
task-list surfaces via one `IssueRow` configuration; the radius scale is
a single multiplicative ladder anchored at `--radius: 0.5rem`.
- **Alternatives considered**: converting interactive
`<button>`/`<Link>` cards to `Card` divs (rejected — breaks semantics;
documented inline with `design-allow` comments instead); keeping the
legacy additive radius ladder (rejected in favor of the standard shadcn
multiplicative mapping).

## What Changed

- `Card` adoption across ~35 files (settings pages, auth/board flows,
dashboards, list containers, KPI tiles); non-adoptable sites
(interactive cards, `<li>` rows, class-string props, chart tooltip)
carry documented `design-allow(card-pattern)` comments
- `Card` gains an `interactive` prop — one quiet hover affordance for
clickable cards (cursor, border darken, shadow lift, focus ring),
applied to skills tiles, artifact cards, and the company selector; cards
carry no resting shadow
- `Badge` adoption for 113 hand-rolled pill spans across ~45 files;
`PropertyChip` wraps `Badge` internally; `StatusBadge`, external-object
chips, and match chips stay bespoke by documented decision (WCAG-tuned
status mechanics)
- Radius ladder becomes the multiplicative shadcn mapping
(`sm/md/lg/xl/2xl/3xl/4xl = 0.6/0.8/1.0/1.4/1.8/2.2/2.6 × --radius`,
anchor `0.5rem`); every card surface unifies on `rounded-lg`; the
orphaned 8px literal token is deleted
- Sidebar: agent rows render via `SidebarNavItem` (new additive props:
`iconNode`, `active`, `trailing`, `liveAccessory`); live dots use
`--status-agent-running`; one row rhythm and inset rounded pill
highlight; right-aligned trailing badges; every labeled section is
collapsible
- Inbox + tasks lists unified: md status glyphs, `accent/50` rounded row
hovers, vertical tree guides under parent rows (opaque underlay so
dark-mode translucent borders don't stack), no horizontal dividers under
expanded parents; the swipe-to-archive reveal layer shows only
mid-swipe; board toggle uses the `SquareKanban` glyph
- Kanban: every column carries a status-hued tint; lanes default
expanded (including empty); compact mode collapses empty lanes to
labeled rails (fixes a clipped, label-less empty-column state)
- Storybook: new AgentDetail page story (realistic fixtures, light+dark)
joins the visual suite; suite captures with `reducedMotion: 'reduce'`
and the ux-lab reasoning ticker honors `prefers-reduced-motion`; a stale
lexical alias in `storybook/main.ts` is fixed (build was broken since
the lexical 0.46 bump)
- Keyboard navigation, from live review of the unified lists: inbox
navigation keys work on every tab (archive keys stay scoped to the
archivable tab); keyboard-driven scrolling no longer hands the selection
to whatever row lands under the stationary cursor (hover selects only
after real pointer movement); the tasks list view gains the same j/k /
arrows / Enter selection model as the inbox; and the `g` then `i`
go-to-inbox chord works app-wide instead of only on the issue detail
page
- Token gates restored to 3/3 CLEAN (tokenized a post-#9134 regression
in the recovery card); decisions recorded in
`doc/design/DECISION-SHEET.md` and `doc/design/COMPONENT-INVENTORY.md`
(investigation verdicts: FileTree vs WorkspaceFileBrowser and the four
entity pickers stay separate — evidence included)

## Verification

- `pnpm check:token-gates` → 3/3 CLEAN
- `pnpm typecheck` → green (all packages)
- `cd ui && npx vitest run` → 2106/2106 (assertions updated in lockstep
where they documented superseded decisions; new tests for the global
go-to-inbox chord)
- `pnpm --filter @paperclipai/ui build` → exit 0
- `pnpm build-storybook` → succeeds (also fixes the lexical-alias break
on master)
- Visual regression: 514-snapshot Playwright suite green against the
updated baseline (zero diffs from the keyboard-navigation round — those
changes are purely behavioral). Note: baselines live outside git per the
suite design and the baseline-manifest archive is not yet published, so
CI cannot run this suite — it was run locally throughout; every visible
delta was reviewed screen-by-screen in a live instance across nine
review rounds. Review evidence (before/after triplets) intentionally
kept out of the repo for size; available on request.
- Manual: exercised dashboard, tasks (list + board), inbox, agents,
skills, costs, settings, and artifact surfaces in light and dark themes

## Risks

- Wide but shallow visual surface: most changes are class-string
substitutions with behavior preserved (props, handlers, roles, test
ids). The riskiest areas — dnd-kit card refs (React 19 ref-as-prop),
inbox swipe-to-archive, and sidebar overlays — are covered by existing
unit tests (all green) and were manually exercised.
- Intentional visual deltas (rounded cards, tinted kanban columns, md
status glyphs, unified hovers) are design decisions recorded in
`doc/design/DECISION-SHEET.md`; each maps to a re-baselined snapshot set
locally.
- The visual suite cannot yet run in CI (unpublished baseline archive —
pre-existing condition from #9134); until that lands, snapshot coverage
is local-only.

## Model Used

- Claude Fable 5 (`claude-fable-5`, Anthropic) via Claude Code — agentic
coding with tool use (file editing, test execution, Playwright
screenshot verification); extended thinking enabled.

## Checklist

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

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 17:15:45 -07:00
Devin Foley cc17f29e7e
fix(timeouts): raise sandbox wall-clock backstop to 4h and make acpx_local timeouts self-describing (#9232)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agent runs execute through adapters (e.g. `acpx_local`), which can
run locally, over SSH, or inside sandbox execution targets, each with a
wall-clock execution timeout
> - Sandbox-backed runs defaulted to a 30-minute wall-clock backstop
(`DEFAULT_REMOTE_SANDBOX_ADAPTER_TIMEOUT_SEC = 1800`), which kills
healthy long agent runs that are still making progress — long before the
recovery watchdog's 4h critical threshold would even consider them stuck
> - On top of that, `acpx_local` resolved its timeout directly from
`adapterConfig.timeoutSec` instead of the shared execution-target
resolver, and its timeout failures surfaced as a bare `Timed out after
Ns` — giving operators no clue which timer fired or which knob raises it
> - This pull request raises the sandbox backstop to 4h (aligned with
the recovery watchdog), routes `acpx_local` through the shared timeout
resolver, logs the effective timeout and its source at run start, and
makes every timeout error message self-describing
> - The benefit is that long-running sandbox agent runs no longer die at
30 minutes, and when a wall-clock timeout does fire, the run log states
exactly which timer fired and how to configure it

## Linked Issues or Issue Description

Refs #4535 (related: wall-clock execution timeouts killing agent runs
that are still making progress — that issue covers a different hardcoded
600s timer, but the operator pain is the same).

No exact public issue exists for this one, so describing it in-PR:

**Bug:** A long sandbox-backed `acpx_local` agent run was killed with a
bare `Timed out after 1800s` even though the agent was actively working.

- **What happened:** The run hit the 30-minute
`DEFAULT_REMOTE_SANDBOX_ADAPTER_TIMEOUT_SEC` backstop. `acpx_local`
never consulted the shared execution-target timeout resolution (it read
`adapterConfig.timeoutSec` directly, default 0), so on sandbox targets
the sandbox-provider default applied with no adapter-level say. The
resulting error named neither the timer that fired nor the knob that
controls it.
- **Expected:** Healthy long runs should not be killed by a 30-minute
wall-clock backstop when the recovery watchdog only treats runs as
critically stuck after 4h of output silence; and any timeout error
should say which timeout fired and how to raise it.
- **Impact:** Long, legitimate agent runs in sandboxes fail mid-work;
operators waste time reverse-engineering which of several timers
produced "Timed out after Ns".

## What Changed

- `packages/adapter-utils/src/execution-target.ts`
- `DEFAULT_REMOTE_SANDBOX_ADAPTER_TIMEOUT_SEC` raised from `1_800` to
`14_400` (4h), with a comment explaining it intentionally matches the
recovery watchdog's `ACTIVE_RUN_OUTPUT_CRITICAL_THRESHOLD_MS` (4h) so
the adapter backstop never fires before the watchdog path.
Output-inactivity monitors remain the primary hang detectors.
- New `resolveAdapterExecutionTargetTimeout(target,
configuredTimeoutSec)` returns `{ timeoutSec, source }` where `source`
is `configured` / `sandbox_default` / `unlimited`. The existing
`resolveAdapterExecutionTargetTimeoutSec` is preserved as a thin
wrapper, so current callers are unaffected.
- New `formatAdapterExecutionTimeoutErrorMessage(resolution)` and
`formatAdapterExecutionTimeoutStartLogLine(resolution)` produce
self-describing messages that name the timer that fired and the
`adapterConfig.timeoutSec` knob that controls it.
- `packages/adapters/acpx-local/src/server/execute.ts`
- `buildRuntime` now resolves the wall-clock timeout through the shared
resolver: sandbox targets default to the 4h backstop, local/SSH keep the
historical "0 = no adapter timeout", and a configured
`adapterConfig.timeoutSec` always wins.
- The executor logs the effective timeout and its source at run start
(`[paperclip] Adapter execution timeout: …`), so a later timeout is
diagnosable from the run log alone.
- All three bare timeout messages (timer cancel reason, turn result
`errorMessage`, catch-path `messageOverride`) now use the
self-describing format.
- `packages/adapters/acpx-local/src/index.ts` — the adapter
configuration doc for `timeoutSec` states the sandbox default and that
the output-inactivity monitor remains the primary hang detector.
- Tests: `packages/adapter-utils/src/execution-target-sandbox.test.ts`
and `packages/adapters/acpx-local/src/server/execute.test.ts` (see
Verification).

## Verification

- `pnpm --filter @paperclipai/adapter-utils typecheck` — passes
- `pnpm --filter @paperclipai/adapter-acpx-local typecheck` — passes
- `npx vitest run
packages/adapter-utils/src/execution-target-sandbox.test.ts
packages/adapters/acpx-local/src/server/execute.test.ts` — 2 files, 40
tests, all pass
- New/updated test coverage:
- sandbox default resolves to 4h (and the constant is asserted to be `4
* 60 * 60`)
- `resolveAdapterExecutionTargetTimeout` reports `configured` /
`sandbox_default` / `unlimited` sources with the correct precedence
(configured > sandbox default; local/SSH stay unlimited)
- exact wording of the self-describing error message and the
start-of-run log line
- `acpx_local` runtime picks up the sandbox default into `timeoutMs`,
keeps the unlimited local default, honors configured-over-default
precedence, emits the start-of-run log line, and surfaces the
self-describing `errorMessage`/cancel reason when the wall-clock timer
kills a turn

## Risks

- **Behavioral shift:** sandbox-backed adapter runs that previously hit
the 30-minute backstop now run up to 4h before the adapter kills them.
Genuinely hung runs are still caught much earlier by the adapters'
output-inactivity monitors and by the recovery watchdog; the wall-clock
timer is a last-resort kill switch. Operators who relied on the
30-minute default can restore it explicitly via
`adapterConfig.timeoutSec`.
- **Error-message consumers:** any tooling that pattern-matched the
exact `Timed out after Ns` string from `acpx_local` will see the new
self-describing message instead.
- No API or schema changes; `resolveAdapterExecutionTargetTimeoutSec`
keeps its exact signature and behavior (modulo the raised sandbox
default).

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

## Model Used

- Claude (Anthropic) via Claude Code CLI — model ID `claude-fable-5`,
extended thinking enabled, agentic tool use (file edits, shell, test
execution)

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 13:50:00 -07:00
Dotta 4a7a732476
feat(skills): add company skill fork prechecks (#9235)
Adds company skill fork precheck metadata, fork result/reassignment contracts, selected-agent reassignment during fork creation, and targeted server/shared test coverage.
2026-07-08 14:22:39 -05:00
Dotta f616b6746c
fix(server): clean heartbeat run scratch directories (#9234)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-08 13:38:36 -05:00
Nicky Leach 38cca22b09
fix(server): avoid accepted-plan workspace branch freeze before child realization (#9233)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents tackle complex tasks via *plan* flows: a planner decomposes
work into child issues, which are accepted by the board and then
executed
> - When a plan is accepted, `createChild` in `issues.ts` inserts child
issues pre-bound to the parent's already-realized execution workspace —
carrying over its concrete branch ref
> - If the repository's base ref advances between plan acceptance and a
child's first heartbeat, the child inherits a stale branch that no
longer matches the current base
> - At first heartbeat the workspace validator detects the mismatch and
freezes the child ("branch freeze"), blocking it from starting any work
> - The real fix is to strip the concrete workspace binding when
creating accepted-plan children: they should receive only the unresolved
*intent* (mode, baseRef, branchTemplate) and realize a fresh workspace
from the current base on their own first heartbeat
> - This PR implements that strip, adds a regression test that proves a
post-base-advance child realizes cleanly, and also fixes
`parseIssueExecutionWorkspaceSettings` so `environmentId` is not
silently dropped on update round-trips (a latent bug that was masking
the original fix)

## Linked Issues or Issue Description

No public GitHub issue exists for this bug. Bug description follows the
bug-report template:

**What happened:** Accepted-plan decomposition pre-binds child issues to
the parent's realized execution workspace branch (`executionWorkspaceId`
+ `executionWorkspaceBranch`). When `origin/master` advances between
plan acceptance and the child's first heartbeat, the workspace branch
interlock fires and the child is permanently frozen before it can start.

**Expected behavior:** Accepted-plan children should receive only
unresolved workspace intent (mode, git strategy fields) and realize a
fresh isolated worktree from the current base on first heartbeat. A
base-ref advance between acceptance and first-run should be transparent.

**Steps to reproduce:**
1. Accept a plan that decomposes into one or more child issues
(isolated_workspace + git_worktree mode).
2. Allow `origin/master` to advance (new merge).
3. Observe the first child heartbeat: workspace validation fails with a
branch-freeze error.

**Paperclip version:** current `master` (pre-fix).

**Deployment mode:** any (affects all modes that use isolated workspace
+ git worktree strategy).

Supersedes #9227 (earlier attempt, now closed — the fix was incomplete
because `environmentId` was silently dropped during
`parseIssueExecutionWorkspaceSettings` update round-trips, causing the
child workspace to lose its environment binding; this PR includes that
fix).

## What Changed

- **`server/src/issues.ts` — `createChild` / accepted-plan decomposition
path:** strip resolved workspace fields (`executionWorkspaceId`,
concrete branch) when creating accepted-plan children; preserve only
unresolved intent fields (`mode`, `baseRef`, `branchTemplate`,
`environmentId`, runtime/provisioning settings).
- **`server/src/execution-workspace-policy.ts` —
`parseIssueExecutionWorkspaceSettings`:** preserve `environmentId`
through update round-trips (was silently dropped, causing environment to
detach on any workspace settings update).
-
**`server/src/__tests__/heartbeat-accepted-plan-workspace-refresh.test.ts`:**
new regression test — accepted-plan child created after `origin/master`
moves realizes a fresh isolated worktree from the moved base and passes
workspace execution.
- **`server/src/__tests__/issues-service.test.ts`:** extended
workspace-linkage and `createChild` tests covering the accepted-plan
strip and the unchanged direct-child path.

## Verification

```sh
pnpm exec vitest run server/src/__tests__/heartbeat-accepted-plan-workspace-refresh.test.ts
pnpm exec vitest run server/src/__tests__/issues-service.test.ts -t "workspace linkage|accepted plan decomposition|createChild applies"
pnpm --filter @paperclipai/server typecheck
```

All three pass on this branch.

## Risks

**Low.** The change is scoped to the accepted-plan `createChild` code
path. The direct child / follow-up issue creation path (normal non-plan
decomposition) is unchanged and covered by existing tests. The
`parseIssueExecutionWorkspaceSettings` fix is additive — it now
preserves a field that was previously silently dropped, so no consumer
loses data.

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`), Anthropic, 200K context window,
extended tool use + code generation.

## 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 (supersedes #9227)
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 11:07:36 -07:00
Nicky Leach 88bf71b84e
Reject projectless isolated git worktree tasks (#9231)
## Thinking Path

> - Paperclip is an open-source platform for orchestrating AI agents;
agents run inside execution workspaces that range from a shared
container to full git worktrees cloned from a project repository.
> - Isolated git-worktree workspaces require a project to determine
which repository to clone — without a project the worktree base path
cannot be computed.
> - A task pinned to `isolated_workspace` + `git_worktree` with no
project was previously accepted at creation time but failed late at
dispatch with the opaque `workspace_validation_failed` /
`git_worktree_base_agent_home` error — only after the heartbeat
attempted to provision the workspace.
> - Fail-closed validation should happen in two places: (1) explicit
create/update pins that contradict the requirement are rejected at the
HTTP layer with a structured 422; (2) rows that reach the heartbeat
dispatcher with this invalid combination (e.g. through inheritance or a
retroactively-removed project) are blocked before any heartbeat run or
adapter spawn.
> - This PR adds the shared detection policy, the create/update guard in
the issues service, and the heartbeat pre-dispatch guard, together with
focused unit tests for all three layers.
> - The benefit is deterministic early failure with a clear remediation
message instead of a late, cryptic runtime error.

## Linked Issues or Issue Description

No upstream public GitHub issue — describing the problem inline
(bug-report format).

**What happened?**
Creating an issue with `executionWorkspaceSettings: { mode:
"isolated_workspace", type: "git_worktree" }` and no `projectId` was
accepted without error. The issue then became blocked at dispatch time
with the opaque message `git_worktree_base_agent_home` /
`workspace_validation_failed` — surfaced only after the heartbeat
attempted to provision the workspace.

**Expected behavior**
The platform should reject the invalid combination at create/update time
with a structured 422 that includes a clear remediation message, before
any heartbeat resource is consumed.

**Steps to reproduce**
1. Call `POST /api/issues` (or `PATCH /api/issues/:id`) with
`executionWorkspaceSettings: { mode: "isolated_workspace", type:
"git_worktree" }` and omit `projectId` (or set it to `null`).
2. Observe: request succeeds (200/201).
3. Assign the issue to an agent and watch it enter `blocked` with a
cryptic `workspace_validation_failed` error at dispatch.

**Related prior fix** — Refs #4844 (`fix(validator): reject static cwd
combined with git_worktree strategy`) — same validation area, different
dimension (static cwd vs. missing project).

**Paperclip version / commit**
Latest `master` (pre-this-PR).

**Deployment mode**
Standard (app-global server).

## What Changed

- **`execution-workspace-policy.ts`** — new shared
`detectWorkspaceWorktreeRequiresProject` function returning a stable
`workspace_worktree_requires_project` policy violation when an isolated
git-worktree task has no project, project workspace, or reusable
execution workspace; exports canonical remediation text used by both the
HTTP guard and the heartbeat guard.
- **`issues.ts`** — create and update paths check the new policy before
persisting; explicit pins to `isolated_workspace` / `operator_branch` +
`git_worktree` with no project are rejected with a 422 including the
policy code and remediation text.
- **`heartbeat.ts`** — pre-dispatch preflight checks the same policy for
rows that reach the heartbeat with the invalid combination (e.g. through
inheritance); such rows are marked `blocked` with a skipped wakeup
request, durable issue comment, and activity log before any heartbeat
run or adapter spawn.
- **`execution-workspace-policy.test.ts`** — focused policy-layer unit
tests for detection logic and remediation text.
- **`issues-service.test.ts`** — create/update 422 guard tests for the
new policy.
- **`heartbeat-workspace-branch-containment.test.ts`** — pre-dispatch
blocking test for inherited/ambiguous invalid rows; also fixes a cleanup
race in the existing test suite.

## Verification

```sh
pnpm exec vitest run \
  server/src/__tests__/execution-workspace-policy.test.ts \
  server/src/__tests__/issues-service.test.ts \
  server/src/__tests__/heartbeat-workspace-branch-containment.test.ts

pnpm --filter @paperclipai/server typecheck

# Targeted regression
pnpm exec vitest run \
  server/src/__tests__/heartbeat-workspace-branch-containment.test.ts \
  -t "blocks projectless isolated git-worktree issues before dispatch"
```

All three test files and typecheck passed locally before this PR was
opened.

## Risks

**Low risk.** The policy detection function is pure with no side
effects. The create/update guard only triggers on explicit
`isolated_workspace` or `operator_branch` + `git_worktree` pins combined
with a missing project — it does not fire on inherited settings (handled
by the heartbeat preflight), so there is no false-positive rejection
risk for valid tasks. The heartbeat guard fires before any resource is
provisioned; the only behavioral change for already-invalid rows is that
they receive a clear `blocked` status and durable comment instead of a
late cryptic error.

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`), 200k context window, tool use
enabled (agentic coding). Used to implement all server-side changes and
tests in this 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
- [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
- [ ] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 10:31:37 -07:00
Nicky Leach 11177c2665
Fix resolved blocker wake reconciliation (#9229)
## Thinking Path

> - Paperclip is an open source platform for managing AI agent companies
— agents pick up issues, do work, and release checkouts in a heartbeat
loop
> - Issue dependency resolution is handled by `issue_blockers_resolved`
wakes: when a blocking issue reaches `done`, dependent blocked issues
should be woken so they can resume
> - The workspace-finalize path maintained its own special-case loop to
retry missed dependency wakes at run completion, duplicating logic that
already exists in the shared level-triggered reconciliation backstop
> - Additionally, the resolved-blocker reconciliation sweep was gated
behind the broader liveness auto-recovery escalation setting — so
instances that disabled auto-escalation creation also lost the baseline
reconciliation sweep
> - This PR routes the workspace-finalize retry through the shared
backstop and decouples the reconciliation sweep from the escalation
creation gate
> - The benefit is simpler code (one authoritative path instead of two),
and correct behaviour on instances where escalation creation is disabled

## Linked Issues or Issue Description

No existing GitHub issue. Describing inline:

**Bug (blocker wake reconciliation):** `issue_blockers_resolved` wakes
can be missed when:

1. A `workspace_finalize` heartbeat retries dependency resolution using
its own inline loop instead of the shared level-triggered backstop,
making them diverge over time.
2. The `blockedByIssueIds` dependency is set (or the issue is moved to
`blocked`) *after* the blocker already reached `done` — the PATCH-time
wake fires on a non-blocked issue and the dependency reconciliation
never catches up.
3. An assignee briefly becomes `null` between the blocker reaching
`done` and the reconciliation sweep running — the sweep skips the issue
and never retries.

Related PRs:
- Refs #8009 — adds dedup for `issue_blockers_resolved` re-fires
(complementary; prevents over-firing; this PR ensures under-firing is
caught)
- Refs #6522 — `auto-unblock dependents with no assignee` (related
no-assignee edge case)

## What Changed

- **`server/src/services/heartbeat.ts`** — remove the inline
dependency-wake retry loop from the `workspace_finalize` path; delegate
to the shared `reconcileResolvedDependencyWakeups` helper instead
- **`server/src/services/recovery/service.ts`** — split the
resolved-blocker wake reconciliation sweep out from under the
`liveness_escalation_auto_recovery` feature flag; the sweep runs
unconditionally while escalation *creation* remains behind the flag
- **`server/src/__tests__/issue-dependency-wakeups-routes.test.ts`** —
regression: `blockedBy` set after blocker already done still triggers a
reconciliation wake
- **`server/src/__tests__/heartbeat-issue-liveness-escalation.test.ts`**
— regression: assignee-null churn before reconciliation; stale skipped
dependency wakes do not suppress a fresh reconciliation wake

## Verification

```
pnpm exec vitest run \
  server/src/__tests__/issue-dependency-wakeups-routes.test.ts \
  server/src/__tests__/heartbeat-issue-liveness-escalation.test.ts
```

23 tests, all passing locally. `pnpm --filter @paperclipai/server
typecheck` clean.

## Risks

Low risk. Bounded blast radius:
- The reconciliation sweep only considers non-hidden `blocked` issues
with an agent assignee
- Uses keyset pagination with an existing 500-candidate cap
- Reuses dependency readiness/finalize gating logic unchanged
- Skips issues with existing active/queued runs and pending interactions
- Deduplicates against live/completed `issue_blockers_resolved` wakes
(skipped/cancelled wakes intentionally do not suppress a fresh
reconciliation)
- Observability: healed reconciliations emit
`issue.blockers_resolved_wake_emitted` activity and log the healed issue
ids and source

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`) with tool use and extended
context. Paperclip AI agent runtime.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 09:32:12 -07:00
Devin Foley e68ee09809
perf(release): batch npm registry version queries (#9202)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The release subsystem publishes the public workspace packages and
also powers release-related CI validation.
> - The release flow currently asks npm for package versions one package
at a time in multiple places.
> - That serial registry latency slows the PR Canary Dry Run path and
real release invocations even though the checks are independent.
> - This pull request batches npm registry version lookups with bounded
concurrency and reuses the result for version calculation.
> - The benefit is shorter non-build release-script time while
preserving the fresh target-version existence check before publishing.

## Linked Issues or Issue Description

- No public GitHub issue exists for this release-script performance
cleanup.

### Problem or motivation

Release validation spends avoidable time on repeated serial `npm view`
calls across the public package set. The slow path affects PR release
validation and real release invocations because version discovery waits
on independent registry reads one at a time.

### Proposed solution

Fetch package version maps concurrently with bounded parallelism, reuse
that map for stable/canary version calculation, and keep a fresh
parallel absence check for the target publish version.

### Alternatives considered

Keeping the existing serial shell loop is simpler, but it preserves the
CI latency cost. Caching the final target-version existence check was
rejected because release publish safety should still query npm freshly
before publishing.

### Roadmap alignment

This is a small release-tooling performance improvement. It does not
duplicate any planned core product work found in `ROADMAP.md`.

## What Changed

- Added `scripts/release-registry-versions.mjs` to fetch npm package
version maps and assert target-version absence with bounded parallelism.
- Updated `scripts/release.sh` to prefetch package versions once and to
batch the final target-version absence check.
- Updated `next_stable_version` and `next_canary_version` to use the
prefetched version map when present, with the existing per-package npm
fallback preserved.
- Added release-registry helper coverage and included it in `pnpm run
test:release-registry`.
- Hardened the release publish helper tests so their fake `pnpm`/`npm`
fixture PATH is preserved under non-login shell execution.

## Verification

- `node --test scripts/release-registry-versions.test.mjs`
- `pnpm run test:release-registry`
- `bash -n scripts/release.sh scripts/release-lib.sh`
- `git diff --check`
- Safety scan before push: searched changed files for common
key/token/password patterns and PII markers; only benign script-name
text matched (`secrets:migrate-inline-env`).
- Remote PR checks on the latest head passed, including `Typecheck +
Release Registry`, `Canary Dry Run`, build, tests, e2e, policy, security
scans, and commitperclip review.
- Greptile reviewed the latest head with Confidence Score 5/5 and no
blocking issues.

## Risks

- Low risk. The release version helpers keep their original npm fallback
when no prefetched version map is supplied.
- The existence check remains fresh and uncached before publish, but now
reports all matching package/version pairs from a parallel check.
- If npm has transient failures during the prefetch step, missing or
failed packages still map to an empty version list, matching the old
helper behavior.

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

## Model Used

- OpenAI Codex coding agent using GPT-5, with shell/tool execution in
the local repository.

## Checklist

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

---------

Co-authored-by: Claude <noreply@paperclip.ing>
2026-07-08 08:04:39 -07:00
Dotta 562567fcd6
[codex] Improve work timeline activity story (#9222)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The work timeline helps operators understand when agent and user
activity actually happened across a project.
> - The timeline view needs clearer interaction context so activity is
easier to inspect and reason about.
> - The existing story coverage did not fully exercise the denser
activity states needed to review this UI safely.
> - This pull request expands the work timeline data shape, service
behavior, UI rendering, tests, and Storybook story so the activity
timeline is easier to verify.
> - The benefit is a more inspectable timeline for project activity,
backed by targeted server and UI coverage.

## Linked Issues or Issue Description

No public GitHub issue found, so this PR describes the feature inline
following the feature request template.

**Subsystem affected**

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

**Problem or motivation**

Project operators need a clearer timeline view that shows when work
activity happened, how much agent time is represented inside the
selected window, and enough realistic activity states for safe visual
review. Sparse mock data and unbounded summary calculations make it
harder to trust the timeline when inspecting historical or capped
windows.

**Proposed solution**

Enrich the work timeline activity data returned by the service, render
clearer top-level timeline summary stats, clamp duration calculations to
the returned window, prorate token totals for partially visible spans,
and add Storybook/test coverage with realistic timeline activity data.

**Alternatives considered**

Keeping the existing sparse timeline story was considered, but it would
leave dense activity layouts and selected-window summary behavior
under-reviewed. Counting full span usage for partially visible spans was
also considered, but it makes historical windows report activity outside
the displayed range.

**Roadmap alignment**

Searched `ROADMAP.md` for timeline/activity references and found no
conflicting planned core work.

**Additional context**

This PR does not include migrations and does not commit generated design
screenshots or images.

## What Changed

- Extended shared work timeline activity types and server timeline
service behavior.
- Updated the timeline page and work timeline chart for richer activity
rendering.
- Clamped timeline runtime summary calculations to the returned window
and prorated summary token usage for clipped spans.
- Added and updated targeted server/UI tests for timeline activity
behavior.
- Added Storybook timeline mock coverage and Storybook preview setup
needed by the story.

## Verification

- `git rebase origin/master` completed cleanly after fetching
`paperclipai/paperclip:master`.
- `git diff --check origin/master...HEAD`
- `pnpm exec vitest run
server/src/__tests__/work-timeline-service.test.ts
ui/src/components/timeline/WorkTimelineChart.test.tsx
ui/src/pages/Timeline.test.tsx` — latest run: 3 files passed, 28 tests
passed.
- Greptile review completed at 5/5 with no unresolved Greptile threads
after fixes.
- GitHub checks completed green on the latest head SHA; Storybook visual
regression was skipped by the workflow.
- `pnpm check:token-gates` currently fails locally on existing
`origin/master` violations in `ui/src/components/ActivityCharts.tsx` and
`ui/src/components/IssueRecoveryActionCard.tsx`; this PR does not modify
those files.

## Risks

Low to moderate risk. The change affects the work timeline service
response shape and timeline UI rendering, so regressions would likely
show up as missing/incorrect timeline activity display. Targeted service
and UI tests cover the changed behavior. No migrations are included.

## Model Used

OpenAI Codex running GPT-5 as a tool-enabled coding agent with local
shell and GitHub CLI access. Exact runtime model ID/context-window size
was not exposed by the environment.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 08:59:24 -05:00
Dotta d3919713bc
[codex] Document Storybook visual baseline platform lock (#9216)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Storybook visual baselines protect UI surfaces from unintended
visual drift.
> - Pixel-perfect screenshot baselines are sensitive to OS, font
rasterization, and browser environment.
> - The suite already stores external baseline artifacts and has an
opt-in CI path.
> - Local runs on non-matching platforms can report false-positive diffs
unless the platform lock is explicit.
> - This pull request documents the Linux/Ubuntu baseline constraint and
makes the local static server port explicit.
> - The benefit is clearer visual-review guidance and more predictable
Playwright web server startup.

## Linked Issues or Issue Description

No public GitHub issue exists.

### What happened?

The Storybook visual baseline suite requires a matching Linux capture
environment for pixel-exact comparisons, but the docs did not clearly
warn local users that non-Linux environments can produce false-positive
diffs. The Playwright web server command also relied on the static
server's default port instead of passing the configured port explicitly.

### Expected behavior

Developers should see clear Linux/Ubuntu baseline guidance before
running the visual suite locally, and Playwright should start the
Storybook static server on the same explicit port that the test config
expects.

### Steps to reproduce

1. Review the Storybook visual docs before this PR.
2. Run or inspect the Storybook visual Playwright config.
3. Notice the missing platform guidance and implicit static server port
coupling.

### Paperclip version or commit

Reproducible on `master` before this branch.

### Deployment mode

Local dev (pnpm dev) / built from source.

## What Changed

- Documents the Linux/Ubuntu-only baseline limitation in the developer
docs and visual-suite README.
- Adds `--port` parsing and validation to the Storybook static server
helper.
- Adds regression coverage for `--port` followed by another flag.
- Passes the Playwright web server port explicitly from the Storybook
visual config.

## Verification

- Passed: `node --check scripts/serve-storybook-static.mjs`
- Passed: `node --test
scripts/__tests__/serve-storybook-static.test.mjs`
- Passed: `node --test
scripts/__tests__/storybook-visual-baseline.test.mjs`
- Greptile: 5/5 with no unresolved review threads after commit
`94a649755a2ae7c4a34a3e8a1f16ec4d26d738fd`.
- Not run: full `pnpm test:storybook-visual`, because it builds
Storybook and runs the browser visual suite; this PR only changes docs
plus server port plumbing.

## Risks

Low risk. The server still defaults to port 6106 when no explicit port
is provided, and invalid port values now fail fast with a clear error
before the Playwright server waits for an unreachable URL.

## Model Used

OpenAI GPT-5 Codex coding agent with local command execution and
repository editing tools.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 07:23:02 -05:00
Dotta 5d0de3499d
[codex] Fix collapsed starred project indentation (#9215)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board sidebar is a high-frequency navigation surface for
companies, projects, and work queues.
> - Starred projects render as child rows under Projects in the expanded
sidebar.
> - The collapsed rail should align every nav icon in the same rail
column.
> - The starred-project child indent was still applied in the collapsed
rail, which pushed the project glyph out of alignment.
> - This pull request keeps the expanded hierarchy indent while removing
it only for the collapsed rail.
> - The benefit is a cleaner collapsed sidebar without changing expanded
sidebar hierarchy.

## Linked Issues or Issue Description

No public GitHub issue exists.

## What happened?

In the collapsed sidebar rail, starred project rows kept the expanded
child indentation. That pushed the project glyph out of alignment with
the rest of the collapsed sidebar icons.

## Expected behavior

Collapsed starred project icons should align with the other sidebar rail
icons while the expanded sidebar should keep the child-row indentation
under Projects.

## Steps to reproduce

1. Open Paperclip with at least one starred project.
2. Collapse the sidebar into rail mode.
3. Compare the starred project glyph position with the other collapsed
sidebar glyphs.

## Paperclip version or commit

Reproduced on the PR base before this branch; fixed on commit
e57d14343d with CI cleanup on commit
12aafe8959.

## Deployment mode

Local dev (`pnpm dev`).

## What Changed

- Applies the starred-project left padding only when the sidebar is not
in rail mode.
- Adds a regression test covering expanded and collapsed starred-project
rendering.
- Makes the heartbeat worktree suppression test cleanup tolerate late
heartbeat run events before deleting heartbeat runs.

## Verification

- Passed: `pnpm exec vitest run
ui/src/components/SidebarStarredProjects.test.tsx`
- Passed: `pnpm exec vitest run
server/src/__tests__/heartbeat-worktree-suppression.test.ts`
- Passed: PR #9215 latest-head GitHub checks on commit
`12aafe8959351826038baf0c1e401fb44913c67c`
- Passed: Greptile 5/5 with no inline comments or unresolved review
threads on commit `12aafe8959351826038baf0c1e401fb44913c67c`
- Known existing baseline failure: `pnpm check:token-gates` reports
violations in `ui/src/components/ActivityCharts.tsx` and
`ui/src/components/IssueRecoveryActionCard.tsx`, which this PR does not
touch.

## Risks

Low risk. The UI change adjusts one conditional class on starred project
links and preserves the expanded sidebar layout. The server test change
is cleanup-only and does not alter production behavior.

## Model Used

OpenAI GPT-5 Codex coding agent with local command execution and
repository editing tools.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-08 07:19:40 -05:00
Dotta 555391fed7
fix: run restart recovery, workspace self-heal, quota-aware retries, failed-run metrics (#9183)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run in heartbeat runs orchestrated by the server; run
lifecycle, retry scheduling, and the dashboard's run-activity metrics
are the subsystems involved
> - A spike in "failed" tasks traced to three causes: server restarts
killing in-flight runs and mislabeling them as failures, deterministic
workspace-validation loops when a worktree's branch diverged, and
provider quota/usage-limit errors being classified as generic transient
failures (putting agents into error state and polluting metrics)
> - Killed-then-recovered runs and quota waits are not product failures,
so both the runtime behavior and the reporting needed to distinguish
them
> - This pull request drains runs gracefully on shutdown with idempotent
restart retries, self-heals workspace branch mismatches, adds a
quota-aware failure class with reset-time retry, separates recovered
restart kills from true failures on the dashboard, and documents restart
hygiene for operators
> - The benefit is fewer spurious failures, automatic recovery instead
of manual repair, and dashboard metrics that reflect real failure rates

## Linked Issues or Issue Description

No public GitHub issue exists; describing the bug inline per the
bug-report template:

**What happened?**

In-flight heartbeat runs are marked `failed` when the server restarts,
even though a retry later succeeds. Worktrees whose checked-out branch
diverges from the issue branch fail workspace validation on every
subsequent run with no recovery path. Provider quota/usage-limit
responses are treated as generic transient upstream errors, putting
agents into an error state and retrying before the quota window resets.
The dashboard counts all of these as true failures, inflating failure
metrics.

**Expected behavior**

Graceful shutdown should interrupt (not fail) running runs and chain
exactly one recovery retry. Workspace validation should repair
recoverable branch mismatches automatically. Quota errors should get
their own error class with the retry scheduled at the provider reset
time and the agent left idle. The dashboard should report recovered
restart kills separately from true failures.

**Steps to reproduce**

1. Start a heartbeat run, then restart the server (SIGTERM) while it is
in flight — the run lands as `failed` with a process-loss error code
even when its retry succeeds
2. Check out an issue whose worktree branch has diverged (e.g. after a
force-moved branch) — every subsequent run fails
`workspace_validation_failed` deterministically
3. Drive an agent into a provider usage-limit window — the run fails as
a generic transient upstream error and the agent enters an error state
instead of idling until the reset time

**Paperclip version or commit**

master (base c07e650cd)

**Deployment mode**

Self-hosted dev plane (Linux, node server + embedded Postgres)

## What Changed

- Graceful shutdown (SIGTERM hook) now marks in-flight runs
`interrupted` instead of `failed` and enqueues an idempotent
process-loss retry (pre-insert existence check on `retryOfRunId`
prevents duplicates; bursts chain exactly one retry per interrupted run)
- Run-liveness classification routes `interrupted` to `needs_followup`
rather than `failed`
- Workspace validation self-heals branch mismatch / missing-branch
states instead of failing deterministically on every run
- New `provider_quota` error class: session/usage-limit responses
schedule the retry at the provider reset time and leave the agent idle
(not errored); fixes a case where a quota-terminated run with subtype
`success` was misclassified as failed; HTTP 529 remains transient
- Dashboard run-activity query separates recovered restart kills from
true failures via a recursive CTE over `retry_of_run_id` (ancestors of a
succeeded retry count as recovered), adds a per-day failed-by-error-code
breakdown, and binds the window start as a timestamptz string
- Activity charts UI: amber "Recovered" segment with legend and per-day
error-code tooltip; success-rate chart counts recovered runs as
successes
- New ops runbook: `docs/deploy/dev-plane-restart-hygiene.md`

## Verification

- Greptile follow-up fixes on `992705edd`: `pnpm exec vitest run
server/src/__tests__/server-startup-feedback-export.test.ts
server/src/__tests__/heartbeat-workspace-branch-containment.test.ts
server/src/__tests__/heartbeat-workspace-session.test.ts
server/src/__tests__/heartbeat-process-recovery.test.ts
server/src/__tests__/heartbeat-workspace-finalize-branch.test.ts` (209
tests); `pnpm --filter @paperclipai/server typecheck`; `git diff
--check`
- Post-rebase CI fixes: `pnpm exec vitest run
server/src/__tests__/heartbeat-retry-scheduling.test.ts`; `pnpm exec
vitest run server/src/__tests__/heartbeat-retry-scheduling.test.ts
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/heartbeat-workspace-branch-containment.test.ts
server/src/__tests__/heartbeat-workspace-finalize-branch.test.ts
server/src/__tests__/heartbeat-workspace-session.test.ts` (227 tests);
`pnpm --filter @paperclipai/server typecheck`
- `npm test` server suites covering the changes:
`heartbeat-process-recovery`, `heartbeat-stop-metadata`,
`heartbeat-retry-scheduling` (95 tests), quota parse +
execute/retry-scheduling suites (100 tests), workspace self-heal suites
(200 tests), dashboard run-activity tests (3 tests) — all green,
typecheck exit 0
- Dashboard CTE cross-checked against a real development database: two
restart-burst days moved from 17 to 8 and 19 to 6 true failures once
recovered kills were separated, matching manual retry-chain inspection
- Screenshot verification of the real ActivityCharts component
(recovered segment + tooltip) during QA

## Risks

- Behavioral shift: runs killed by a restart no longer surface as
`failed`; anyone consuming raw run statuses will see `interrupted` (new
status value) — dashboards/queries in this repo were updated accordingly
- Retry chaining on repeated restarts is bounded (one chained retry per
interruption) but a pathological restart loop still delays work rather
than failing it; the runbook covers operator hygiene for that case
- Dashboard query adds a recursive CTE; cost is bounded by the
day-window row count and was verified against production-sized data
- No schema migrations; low migration risk

## Model Used

- Claude (Anthropic) — claude-fable-5 via Claude Code / Paperclip agent
harness, extended thinking with tool use; implementation commits also
produced with Codex CLI (GPT-5 class) agents under the same harness

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 20:30:09 -05:00
tmartin2113 3b16ac3804
fix(server): use run.id for activity_log in heartbeat invoke/resume (#3424)
## Summary

- The heartbeat invoke and resume endpoints log activity with
`actor.runId` (the caller's auto-generated run ID from JWT), which
hasn't been registered in `heartbeat_runs` yet
- This causes a FK constraint violation: `activity_log.run_id →
heartbeat_runs.id`
- Fix: use `run.id` (the newly created heartbeat_run) instead, which is
guaranteed to exist in the table

## Test plan

- [ ] Trigger a heartbeat invoke via the API — verify no FK constraint
error in logs
- [ ] Trigger a heartbeat resume — verify activity_log row is created
successfully
- [ ] Verify existing activity_log queries still return correct results

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

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-07-07 18:48:08 -05:00
Nicky Leach 4f5abf6007
feat(recovery-card): W7 reconcile-forward + break-glass actions
Adds the task-page recovery affordance for workspace branch divergence: reconcile-forward when ancestry is safe, and a break-glass override flow that requires explicit confirmation and a reason.

Includes client wiring for the existing reconcile-branch endpoint, issue-detail refresh after successful reconciliation, runtime-management gating for break-glass, and tests for action visibility, payloads, permission gating, and workspace-target selection.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-07 15:17:16 -07:00
Dotta 83f5f59842
[codex] Hide goals sidebar link behind experiment (#9189)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board sidebar is the primary navigation surface for operators
scanning companies, projects, tasks, agents, and related control-plane
tools.
> - Goals still has a route and product surface, but keeping the
top-level sidebar link always visible makes it part of the default
navigation whether or not that surface is ready for every operator.
> - Instance experimental settings already provide a controlled place to
expose optional UI surfaces while they are being evaluated.
> - This pull request adds a dedicated experimental setting for
restoring the Goals sidebar link.
> - The benefit is a quieter default sidebar with an explicit escape
hatch for operators who still need the Goals entry point.

## Linked Issues or Issue Description

No public GitHub issue exists for this internal task, so the feature
request is described inline.

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

**Problem or motivation**
The Goals route remains available, but the top-level Goals sidebar entry
makes that surface part of the default operator navigation. While the
goals surface is still being evaluated, operators need a quieter default
sidebar without losing an escape hatch for teams that still rely on the
link.

**Proposed solution**
Add a boolean instance experimental setting, `enableGoalsSidebarLink`,
default it to `false`, and render the Goals sidebar link only when the
setting is enabled. Expose the toggle in Instance Experimental Settings
so operators can restore the link without changing routes or rebuilding
the app.

**Alternatives considered**
- Remove the Goals route entirely: rejected because this task only asks
to hide the sidebar entry point and preserve access for teams evaluating
goals.
- Keep the sidebar link always visible: rejected because it does not
provide the requested quieter default navigation.
- Hard-code a local UI flag: rejected because instance experimental
settings already provide the expected operator-controlled pattern.

**Roadmap alignment**
Checked `ROADMAP.md`; no overlapping goals/sidebar/experimental roadmap
entry was found.

**Additional context**
The `/goals` route is preserved. This PR only gates the sidebar
navigation item.

## What Changed

- Added `enableGoalsSidebarLink` to the shared instance experimental
settings type and validator, defaulting to `false`.
- Normalized the new setting in the server instance settings service.
- Hid the Goals sidebar nav item unless the new setting is enabled.
- Added a Goals Sidebar Link toggle to the Instance Experimental
Settings page.
- Updated shared, server, sidebar, and settings page tests for the new
setting.

## Verification

- `pnpm exec vitest run packages/shared/src/validators/instance.test.ts
server/src/__tests__/instance-settings-service.test.ts
server/src/__tests__/instance-settings-routes.test.ts
ui/src/components/Sidebar.test.tsx
ui/src/pages/InstanceExperimentalSettings.test.tsx`
- `git diff --check origin/master...HEAD`
- `git merge-tree --write-tree HEAD origin/master`
- Searched for duplicate/related PRs by title and
`enableGoalsSidebarLink`; none found.
- Checked `ROADMAP.md` for overlapping goals/sidebar/experimental
entries; none found.

## Risks

Low risk. The main behavior shift is that operators who depended on the
sidebar Goals link need to enable the new experimental toggle. The
`/goals` route itself is not removed.

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

## Model Used

OpenAI Codex, GPT-5-based Paperclip CodexCoder session with repository
tool access and command execution. Exact API model identifier and
context window were not exposed by the Paperclip harness.

## Checklist

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

> - Paperclip is the open source app people use to manage AI agents for
work
> - Its UI is the operator's daily surface: task lists, boards, budgets,
agent status — all built on shadcn components and Tailwind
> - Visual values (colors, spacing, type sizes, radii) were hardcoded at
~1,600 call sites: the same "small gray label" was 9/10/11px depending
on the file, charts disagreed with chips about status colors, two
toggle-switch implementations coexisted in two greens, and there was no
visual regression coverage
> - This made the UI drift-prone and made any restyle a
hundreds-of-files project, which discourages design iteration
> - This pull request extracts visual values into a single token layer
in `ui/src/index.css`, adds a Storybook visual regression suite backed
by external immutable baseline archives, and then applies a deliberate
retune reviewed change-by-change on screenshot diffs
> - The benefit is that Paperclip's look becomes a config surface:
retheming is a token edit reviewed as a snapshot diff, drift is blocked
by a token gate, and future UI PRs can prove exactly what changed
visually without committing hundreds of PNGs

## Linked Issues or Issue Description

No existing public issue covers this work (searched "design tokens",
"visual regression", "design system" across issues and PRs). Related in
spirit: Refs #8982 (theming a hardcoded panel — a one-off instance of
the same problem class this PR addresses systematically).

**Problem (feature-request form):** UI visual values are hardcoded per
call site with no source of truth and no regression coverage;
consistency depends on reviewer memory, and restyling requires mass file
edits.
**Proposed solution (this PR):** a single token layer + enforcement gate
+ externally stored visual snapshot suite, then an intentional restyle
on top of that foundation.

## What Changed

- **Token extraction (zero visual change, machine-verified during
development):** committed codemods (`scripts/codemod-*.mjs`) moved
~1,600 hardcoded color/type/spacing/radius/shadow/misc values into named
tokens in a non-inline `:root` block of `ui/src/index.css`.
- **Visual regression suite:** `pnpm test:storybook-visual` covers 255
stories × light/dark = 510 Playwright screenshots at `maxDiffPixels: 0`,
plus new primitive-coverage stories and deterministic-render fixes.
- **External visual baselines:** committed PNG snapshots were removed.
`tests/storybook-visual/baseline-manifest.json` pins an immutable
archive URL/hash/size/count, and `scripts/storybook-visual-baseline.mjs`
handles `download`, `verify`, `pack`, and trusted maintainer `upload`
flows.
- **Opt-in visual CI artifacts:** added a `Storybook Visual` workflow
that runs on manual dispatch or PRs labeled `storybook-visual`,
downloads/verifies the baseline, runs Playwright, and uploads Playwright
report/test-result artifacts for review. Normal PR runs do not mutate
baseline objects.
- **Token gate:** `pnpm check:token-gates` — zero hex literals, zero
arbitrary bracket values, zero raw font-sizes in `ui/src/components/**`
and `ui/src/pages/**`, with a documented inline allowlist for legitimate
opt-outs.
- **Theme retune (intentional, snapshot-reviewed):** new base theme
values; radius ladder derived from a single `--radius` knob; micro-type
cluster collapsed to a named ladder (`--text-nano/micro/compact` +
Tailwind `text-xs`/`text-sm`); letter-spacing collapsed to named steps.
- **One status-color vocabulary:** charts, quota/budget bar fills,
RUNNING/live chips, and liveness indicators all use the canonical
`--status-*` hues. Light-mode legibility fixes for red alert surfaces
that used dark-tuned text classes.
- **One switch:** `ToggleSwitch` restyled to the registry capsule form,
second hand-rolled implementation removed, and all call sites unified.
- **Docs:** `DESIGN.md` is the design contract; `doc/design/` holds
audit reports, decision logs, and updated guidance for external baseline
review/update workflows.
- Dead code removed (`agentStatusBadge` duplicate map), byte-identical
contrast constants consolidated, semantic renames
(`--project-seed`/`--project-none`, `--liveness-blue`).

## Verification

- `pnpm check:token-gates` — 3/3 gates CLEAN during the design-system
run
- `pnpm typecheck` && `pnpm --filter @paperclipai/ui build` — green
during the design-system run
- `node --test scripts/__tests__/storybook-visual-baseline.test.mjs` —
pass after external-baseline rework
- `pnpm exec tsc --noEmit --pretty false --module NodeNext
--moduleResolution NodeNext --target ES2022 --types
node,@playwright/test tests/storybook-visual/playwright.config.ts
tests/storybook-visual/storybook-visual.spec.ts` — pass after
external-baseline rework
- `git diff --check origin/pr/9134..HEAD` — pass after external-baseline
rework
- `find tests/storybook-visual -type f -name '*.png' -print | wc -l` —
`0`
- `node scripts/storybook-visual-baseline.mjs verify` — intentionally
fails closed until the first trusted maintainer publishes the baseline
archive and updates `baseline-manifest.json`

## Risks

- **Large but shallow:** the PR still touches many UI files due to
mechanical token extraction and retune work, but committed PNG snapshot
churn has been removed from the branch.
- **Baseline publication required before the visual suite can pass in
clean clones:** the manifest currently has placeholder archive metadata.
A trusted maintainer must publish the first immutable archive, then
update `baseline-manifest.json`.
- **Rendering platform variance:** the external baseline should be
captured in the documented Linux/Chromium environment. Future CI runs
verify against the pinned archive and fail closed on checksum/count
mismatch.
- **Visual CI is opt-in while stabilizing:** add the `storybook-visual`
label or dispatch the workflow manually to produce downloadable
Playwright report/test-result artifacts.
- **Scheduled follow-ups, deliberately out of scope:** Tailwind palette
classes map to semantic tokens in a dedicated pass; card/pill component
consolidation; ESLint ratchet. Tracked in
`doc/design/DECISION-SHEET.md`.

## Model Used

Claude Fable 5 (Anthropic, `claude-fable-5`, Mythos-class tier) with
extended thinking, running in Claude Code with tool use; mechanical
phases delegated to Claude Sonnet subagents. Follow-up external-baseline
rework assisted by OpenAI Codex (`gpt-5` coding agent with repository,
terminal, and GitHub tool use). All bulk rewrites executed via
deterministic, idempotent scripts committed in `scripts/`; intentional
visual changes were human-reviewed on screenshot contact sheets.

## 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 targeted local verification and documented the
intentional baseline-publication failure above
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green *(pending new CI run after this
rework)*
- [ ] 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

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Dotta <bippadotta@protonmail.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 16:22:16 -05:00
Nicky Leach bb87047fe6
Add auto-forward execution workspace branch reconciliation (#9172)
## Thinking Path

> - Paperclip manages execution workspaces for AI agent runs, each
associated with a git branch so the agent always works in a known code
state.
> - Workspace runtime reconciles an agent's checkout branch against the
workspace's recorded branch when a heartbeat resumes; without
forward-ancestry detection, any divergence fails closed and blocks the
run.
> - When the workspace branch has moved forward (e.g. after a feature
merge), the recorded branch is an ancestor of the current HEAD — a safe,
forward-only case that the previous implementation refused even though
it carries no safety risk.
> - The gap means legitimate forward-advancing deployments require
manual operator intervention to unblock agents every time, creating
operational friction and interrupting automated workflows.
> - This pull request adds a flag-gated reconcile-forward path that
detects when the current branch is a strict forward descendant of the
workspace branch and auto-reconciles, while preserving fail-closed
behavior for all non-forward or flag-off cases.
> - It also threads the active execution workspace id through restore
and finalize call sites so the reconcile verdict can be persisted
durably across heartbeats.
> - The benefit is that agents resume automatically from
forward-advancing workspace branches without operator intervention,
while adversarial and backward branch changes continue to fail closed.

## Linked Issues or Issue Description

This PR adds an auto-forward reconcile path for execution workspace
branch tracking. When a workspace's recorded branch is a strict ancestor
of the current HEAD (a forward-only advancement), the runtime now
auto-reconciles rather than hard-blocking. The feature is gated behind
an explicit runtime flag, defaults to off, and falls back to fail-closed
behavior for all non-forward or flag-off cases.

The prior implementation treated all branch divergences identically: any
mismatch between the recorded workspace branch and the current HEAD
failed closed. This prevented agents from resuming after routine forward
deployments (e.g. after a feature branch merges into the workspace
branch), requiring manual operator action to unblock every affected run.

## What Changed

- Added `reconcileForward` flag-gated path in workspace runtime
reconciliation logic that allows auto-reconciliation when the workspace
branch is a strict ancestor of the current HEAD.
- Threaded active execution workspace id through `restore` and
`finalize` call sites so reconcile verdicts are persisted durably.
- Added `plainLanguageReason` and `ancestryVerdict` evidence fields to
the reconciliation result structure for operator visibility.
- Stabilized a branch containment test that exposed a late run-linked
activity FK cleanup race during the focused Vitest rerun.
- All new paths remain fail-closed when the flag is off or when the
branch relationship is not strictly forward.

## Verification

```bash
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck
pnpm exec vitest run \
  server/src/__tests__/workspace-runtime.test.ts \
  server/src/__tests__/heartbeat-workspace-branch-containment.test.ts \
  server/src/__tests__/execution-workspaces-service.test.ts
git diff --check origin/master..HEAD
```

All 3 test files / 98 tests pass. Typecheck passes for both shared and
server packages.

> **Note:** This is a stacked PR on top of PR #9170 (Add execution
workspace branch reconciliation route). The diff shown targets that
branch; the combined change builds on the reconciliation route
infrastructure it provides.

## Risks

- **Flag-off default:** The reconcile-forward path is off by default. No
behavior change for existing workspaces unless the flag is explicitly
enabled by an operator.
- **Ancestry check correctness:** The forward-only guard uses git
ancestry verification; a branch that is not a strict ancestor of HEAD
remains fail-closed. Adversarial or concurrent branch resets are not
auto-reconciled.
- **FK cleanup race (stabilized):** A late run-linked activity FK
cleanup race in the containment test was exposed during the Vitest
rerun. The stabilization commit addresses the non-deterministic ordering
without changing production behavior.
- **Stacking dependency:** This PR must not be merged before PR #9170
merges, as it is built on top of the reconciliation route
infrastructure.

## Model Used

- Provider: Anthropic
- Model: Claude Sonnet 4.6 (`claude-sonnet-4-6`)
- Context: 200k token context window
- Mode: Agentic tool use with code execution and git 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] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 14:12:17 -07:00
Nicky Leach f17202b571
Add execution workspace branch reconciliation route (#9170)
## Thinking Path

> - Paperclip is an open-source app that lets teams run AI agents for
work tasks; each agent session uses an execution workspace — a git
checkout — to track the agent's active code state.
> - Every execution workspace has an expected target branch
(`PAPERCLIP_WORKSPACE_BRANCH`). The workspace git HEAD should always
point to that branch so agents commit in the right place.
> - When workspace git HEAD diverges from the expected branch — for
example after a harness branch-name fix or an accidental `checkout -b`
during a CI-retrigger — the discrepancy must be corrected before agents
can continue safely.
> - Operators (board users) need a controlled, audited path to reconcile
a workspace's live branch back to the expected target, with an override
escape-hatch for cases where the normal forward path is blocked.
> - This pull request adds a board-only `POST
/api/execution-workspaces/:id/reconcile-branch` service operation and
route that validates safety preconditions, resolves matching
recovery-action fingerprints, posts source-issue audit comments, and
records the reconciliation outcome.
> - The benefit is that operators can correct branch divergence through
the API with a full audit trail, instead of via raw database edits.

## Linked Issues or Issue Description

No public GitHub issue exists for this change. Context below follows the
feature-request template format.

**Subsystem affected**

server/ — REST API & orchestration services; packages/shared — request
validation.

**Problem or motivation**

Execution workspaces have an expected branch record that must match the
checked-out worktree branch. When the live git branch and stored branch
record drift apart, operators currently lack a first-class, audited API
to reconcile the record. The fallback is manual database repair or
workspace replacement, both of which are risky and hard to audit.

**Proposed solution**

Add a board-only execution workspace branch reconciliation operation.
`forward` mode re-inspects the server-side git state and only updates
the branch record when the stored branch is an ancestor of the
checked-out branch. `override` mode is a break-glass path that requires
board access and an operator reason. Both modes require a clean, idle
workspace, write audit details, post a source-issue audit comment, and
resolve the matching workspace-validation recovery action.

**Alternatives considered**

Manual database edit (no durable audit trail and easy to mistype),
recreating the workspace (heavier operational disruption), or trusting
client-supplied ancestry evidence (unsafe because the server must verify
the git state itself).

**Roadmap alignment**

This is incremental hardening for execution-workspace recovery and
operator controls. It does not duplicate a public roadmap item.

**Additional context**

The endpoint is intended for operator recovery, not normal agent control
flow, so the generated OpenAPI metadata and runtime route both classify
it as board-only.
## What Changed

- Added `reconcileExecutionWorkspaceBranchSchema` discriminated-union
validator (`forward` with optional reason, `override` requiring a
non-empty reason string) to
`packages/shared/src/validators/execution-workspace.ts`
- Exported `ReconcileExecutionWorkspaceBranch` type and the new schema
from the shared package index
- Added board-only reconcile-branch service operation in the execution
workspaces service: safety checks, recovery-action fingerprint
resolution, source-issue audit comment, and outcome recording
- Added clean-worktree and stopped-runtime-service preconditions before
branch-record mutation.
- Marked the reconcile route as board-only in OpenAPI generated auth
metadata.
- Added `POST /api/execution-workspaces/:id/reconcile-branch` route
wired to the new service operation with board-permission gate
- Extended `execution-workspaces-routes.test.ts` and
`execution-workspaces-service.test.ts` to cover: safety-check rejection,
override-reason validation, audit-comment posting, and recovery-action
fingerprint resolution (2 files / 19 tests)

## Verification

```sh
pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck
pnpm exec vitest run server/src/__tests__/execution-workspaces-routes.test.ts server/src/__tests__/execution-workspaces-service.test.ts
pnpm exec vitest run server/src/__tests__/execution-workspaces-service.test.ts server/src/__tests__/openapi-routes.test.ts
```

## Risks

- **Board-only gate:** the operation is gated behind the board
permission; no agent can trigger it without operator authorization.
- **Override requires reason:** the `override` mode requires a non-empty
reason string so every bypass is audited.
- **Idempotent recovery-action resolution:** re-running with the same
fingerprint is safe; duplicate resolution is a no-op.
- **No execution-state mutation:** the route records a reconciliation
intent and updates the branch record; it does not restart the workspace
or modify running agent state.
- Overall risk: **low**.

## Model Used

- Provider: Anthropic
- Model ID: `claude-sonnet-4-6` (Claude Sonnet 4.6)
- Context window: 200 K tokens
- Capabilities: tool use, code execution, multi-turn context

Follow-up safety commit:
- Provider: OpenAI
- Model ID: `codex` / GPT-5 with tool use and code execution

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 13:41:23 -07:00
Dotta 329b229591
Fix annotation selection in routine editor (#9182)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The issue and routine editor surfaces share document annotation
behavior for commentable text.
> - The annotation layer currently observes document selections inside
its container and converts those selections into pending comment
anchors.
> - Routine editor fields can live inside that same annotated document
container while still needing normal native text selection behavior.
> - When a user selects text inside an editable routine field, the
annotation layer should leave that selection alone instead of preparing
a comment.
> - This pull request teaches the annotation layer to ignore selections
touching editable controls and covers that case with focused component
tests.
> - The benefit is that routine editing remains editable text UX, while
document annotation selection continues to work for normal read-only
document text.

## Linked Issues or Issue Description

No public GitHub issue exists for this bug. Inline bug report follows.

### Pre-submission checklist

- [x] I have searched existing open and closed issues and this is not a
duplicate.
- [x] I am on current `master` for this PR branch.
- [x] I have confirmed the error originates in Paperclip itself, not in
an agent adapter, API provider, or local configuration.

### What happened?

Selecting text inside an editable routine field could be interpreted as
a document annotation selection. That meant the annotation layer could
prepare a pending comment anchor or show annotation affordances while
the user was just selecting text to edit routine content.

### Expected behavior

Editable controls should keep native text selection behavior. Selecting
text inside `input`, `textarea`, `select`, or contenteditable routine
editor regions should not build a document annotation anchor or show the
document annotation toolbar.

### Steps to reproduce

1. Render document annotation behavior around a document/editor
container that also contains an editable routine text region.
2. Select text inside the editable region.
3. Observe that the document annotation layer treats the selection as
commentable text instead of ignoring it.

### Paperclip version or commit

Reproduced and fixed against `master` at `5356b7d73`, with PR head
`4f53f83f1`.

### Deployment mode

Local dev / component test environment.

### Installation method

Built from source.

### Agent adapter(s) involved

Not adapter-specific; core UI behavior.

### Database mode

Not database-related.

### Access context

Board / human operator UI behavior.

### Relevant logs or output

No runtime logs. Regression coverage is in
`ui/src/components/DocumentAnnotationLayer.test.tsx`.

### Relevant config

Not applicable.

### Additional context

Root cause: `DocumentAnnotationLayer` filtered selections by container
membership, but did not exclude editable controls or all valid
contenteditable hosts before building a pending annotation anchor.

### Privacy checklist

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

## What Changed

- Added an editable-selection guard in `DocumentAnnotationLayer` that
ignores selections touching `input`, `textarea`, `select`, or
contenteditable elements.
- Covered both `contenteditable="true"` and bare/empty `contenteditable`
hosts so routine editor selections do not build annotation anchors.
- Added focused regression tests proving editable selections do not call
the annotation anchor helpers or show the annotation toolbar.

## Verification

- `pnpm vitest run ui/src/components/DocumentAnnotationLayer.test.tsx`
- `git diff --check`
- GitHub PR checks are green for head `4f53f83f1`, including policy,
review, typecheck/release registry, build, general tests, serialized
suites, e2e, canary dry run, security checks, and Greptile.

## Risks

Low risk. The change only narrows annotation capture when a selection
touches an editable element inside the annotation container. Normal
read-only document annotation selections still use the existing
anchor-building path.

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

## Model Used

OpenAI Codex coding agent based on GPT-5, with shell, Git, Vitest, and
GitHub connector/CLI tool use. The exact hosted runtime model identifier
is not exposed in this session.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 15:17:38 -05:00
dependabot[bot] bdd3aa2110
build(deps): bump sharp from 0.35.2 to 0.35.3 (#9061)
Bumps [sharp](https://github.com/lovell/sharp) from 0.35.2 to 0.35.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lovell/sharp/releases">sharp's
releases</a>.</em></p>
<blockquote>
<h2>v0.35.3</h2>
<ul>
<li>
<p>Tighten verification of <code>text</code> dimensions, TIFF tile
dimensions and <code>extend</code> values.</p>
</li>
<li>
<p>Improve code bundler support by resolving path to libvips binary.</p>
</li>
<li>
<p>Increase default concurrency when use of
<code>MALLOC_ARENA_MAX</code> is detected.</p>
</li>
<li>
<p>Emit warning about binaries provided by Electron for use on
Linux.</p>
</li>
<li>
<p>Add <code>hasAlpha</code> property to output <code>info</code>.
<a
href="https://redirect.github.com/lovell/sharp/issues/4500">#4500</a></p>
</li>
<li>
<p>TypeScript: Return more precise
<code>Buffer&lt;ArrayBuffer&gt;</code> from <code>toBuffer</code>.
<a href="https://redirect.github.com/lovell/sharp/pull/4520">#4520</a>
<a href="https://github.com/Andarist"><code>@​Andarist</code></a></p>
</li>
<li>
<p>Bound <code>clahe</code> width and height to avoid signed overflow.
<a href="https://redirect.github.com/lovell/sharp/pull/4551">#4551</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Bound <code>trim</code> margin to avoid signed overflow.
<a href="https://redirect.github.com/lovell/sharp/pull/4552">#4552</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Reject infinite values when validating numbers.
<a href="https://redirect.github.com/lovell/sharp/pull/4553">#4553</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Bound extract region to libvips coordinate limit.
<a href="https://redirect.github.com/lovell/sharp/pull/4555">#4555</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Verify background colour values are numbers.
<a href="https://redirect.github.com/lovell/sharp/pull/4556">#4556</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Bound create and raw input dimensions to coordinate limit.
<a href="https://redirect.github.com/lovell/sharp/pull/4558">#4558</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
<li>
<p>Tighten recomb and affine matrix verification.
<a href="https://redirect.github.com/lovell/sharp/pull/4560">#4560</a>
<a
href="https://github.com/chatman-media"><code>@​chatman-media</code></a></p>
</li>
<li>
<p>Verify cache memory limit to avoid overflow.
<a href="https://redirect.github.com/lovell/sharp/pull/4561">#4561</a>
<a
href="https://github.com/metsw24-max"><code>@​metsw24-max</code></a></p>
</li>
</ul>
<h2>v0.35.3-rc.2</h2>
<ul>
<li>Tighten verification of <code>text</code> dimensions, TIFF tile
dimensions and <code>extend</code> values.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1018449164"><code>1018449</code></a>
Release v0.35.3</li>
<li><a
href="ba303a799d"><code>ba303a7</code></a>
Prerelease v0.35.3-rc.2</li>
<li><a
href="4f94fc5162"><code>4f94fc5</code></a>
Upgrade to sharp-libvips v1.3.2</li>
<li><a
href="c5e7a3ff20"><code>c5e7a3f</code></a>
Bump devDeps, fix Deno/Windows smoke tests</li>
<li><a
href="9a8d002688"><code>9a8d002</code></a>
Docs: Add changelog entry and note about transferable <a
href="https://redirect.github.com/lovell/sharp/issues/4520">#4520</a></li>
<li><a
href="8694db0bac"><code>8694db0</code></a>
TypeScript: Return more precise <code>Buffer\&lt;ArrayBuffer&gt;</code>
from <code>toBuffer</code> (<a
href="https://redirect.github.com/lovell/sharp/issues/4520">#4520</a>)</li>
<li><a
href="e000d0b5e1"><code>e000d0b</code></a>
Prerelease v0.35.3-rc.1</li>
<li><a
href="9554ca9553"><code>9554ca9</code></a>
Prerelease v0.35.3-rc.0</li>
<li><a
href="6a29fd55db"><code>6a29fd5</code></a>
Emit warning about native binaries on Linux Electron</li>
<li><a
href="540d2eada4"><code>540d2ea</code></a>
Increase default concurrency when use of MALLOC_ARENA_MAX detected</li>
<li>Additional commits viewable in <a
href="https://github.com/lovell/sharp/compare/v0.35.2...v0.35.3">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 13:03:30 -07:00
dependabot[bot] a058f761f3
build(deps-dev): bump rollup from 4.61.1 to 4.62.2 (#9070)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

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

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

---

[//]: # (dependabot-end)

Bumps [rollup](https://github.com/rollup/rollup) from 4.61.1 to 4.62.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rollup/rollup/releases">rollup's
releases</a>.</em></p>
<blockquote>
<h2>v4.62.2</h2>
<h2>4.62.2</h2>
<p><em>2026-06-19</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Do not add spurious side-effect-free external imports to chunks when
using minChunkSize (<a
href="https://redirect.github.com/rollup/rollup/issues/6411">#6411</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6411">#6411</a>:
Skip side-effect-free external imports when hoisting is disabled (<a
href="https://github.com/morgan-coded"><code>@​morgan-coded</code></a>,
<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6416">#6416</a>:
refactor(rust/parser_ast): extract property AstConverter write buffer
kind logic to new method (<a
href="https://github.com/fabianbernhart"><code>@​fabianbernhart</code></a>,
<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>v4.62.1</h2>
<h2>4.62.1</h2>
<p><em>2026-06-19</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Preserve multipart file extensions when deconflicting output chunks
(<a
href="https://redirect.github.com/rollup/rollup/issues/6408">#6408</a>)</li>
<li>Fix an issue where getLogFilter would match additional logs (<a
href="https://redirect.github.com/rollup/rollup/issues/6415">#6415</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6393">#6393</a>:
Use import attributes for importing JSON (<a
href="https://github.com/selfisekai"><code>@​selfisekai</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6408">#6408</a>:
fix: insert conflict numbers before first extension in multi-extension
filenames (<a
href="https://github.com/LeSingh1"><code>@​LeSingh1</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6415">#6415</a>:
fix: advance value past wildcard prefix before suffix check in
getLogFilter (<a
href="https://github.com/JSap0914"><code>@​JSap0914</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6417">#6417</a>:
chore(deps): update msys2/setup-msys2 digest to 66cd2cc (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6418">#6418</a>:
fix(deps): update minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6419">#6419</a>:
chore(deps): update dependency eslint-plugin-unicorn to v66 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6420">#6420</a>:
chore(deps): lock file maintenance minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>v4.62.0</h2>
<h2>4.62.0</h2>
<p><em>2026-06-13</em></p>
<h3>Features</h3>
<ul>
<li>Ensure that shared dependencies between manual chunks and entry
points receive a serparate chunk (<a
href="https://redirect.github.com/rollup/rollup/issues/6374">#6374</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6374">#6374</a>:
Extract the static dependencies imported by manual chunks into separate
chunks (<a
href="https://github.com/TrickyPi"><code>@​TrickyPi</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6405">#6405</a>:
fix(deps): update minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6406">#6406</a>:
chore(deps): pin dependency concurrently to v9 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6407">#6407</a>:
chore(deps): lock file maintenance minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6409">#6409</a>:
chore(deps): update minor/patch updates to v6.2.0 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rollup/rollup/blob/master/CHANGELOG.md">rollup's
changelog</a>.</em></p>
<blockquote>
<h2>4.62.2</h2>
<p><em>2026-06-19</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Do not add spurious side-effect-free external imports to chunks when
using minChunkSize (<a
href="https://redirect.github.com/rollup/rollup/issues/6411">#6411</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6411">#6411</a>:
Skip side-effect-free external imports when hoisting is disabled (<a
href="https://github.com/morgan-coded"><code>@​morgan-coded</code></a>,
<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6416">#6416</a>:
refactor(rust/parser_ast): extract property AstConverter write buffer
kind logic to new method (<a
href="https://github.com/fabianbernhart"><code>@​fabianbernhart</code></a>,
<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>4.62.1</h2>
<p><em>2026-06-19</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Preserve multipart file extensions when deconflicting output chunks
(<a
href="https://redirect.github.com/rollup/rollup/issues/6408">#6408</a>)</li>
<li>Fix an issue where getLogFilter would match additional logs (<a
href="https://redirect.github.com/rollup/rollup/issues/6415">#6415</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6393">#6393</a>:
Use import attributes for importing JSON (<a
href="https://github.com/selfisekai"><code>@​selfisekai</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6408">#6408</a>:
fix: insert conflict numbers before first extension in multi-extension
filenames (<a
href="https://github.com/LeSingh1"><code>@​LeSingh1</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6415">#6415</a>:
fix: advance value past wildcard prefix before suffix check in
getLogFilter (<a
href="https://github.com/JSap0914"><code>@​JSap0914</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6417">#6417</a>:
chore(deps): update msys2/setup-msys2 digest to 66cd2cc (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6418">#6418</a>:
fix(deps): update minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6419">#6419</a>:
chore(deps): update dependency eslint-plugin-unicorn to v66 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6420">#6420</a>:
chore(deps): lock file maintenance minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>4.62.0</h2>
<p><em>2026-06-13</em></p>
<h3>Features</h3>
<ul>
<li>Ensure that shared dependencies between manual chunks and entry
points receive a serparate chunk (<a
href="https://redirect.github.com/rollup/rollup/issues/6374">#6374</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6374">#6374</a>:
Extract the static dependencies imported by manual chunks into separate
chunks (<a
href="https://github.com/TrickyPi"><code>@​TrickyPi</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6405">#6405</a>:
fix(deps): update minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6406">#6406</a>:
chore(deps): pin dependency concurrently to v9 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6407">#6407</a>:
chore(deps): lock file maintenance minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6409">#6409</a>:
chore(deps): update minor/patch updates to v6.2.0 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6410">#6410</a>:
chore(deps): lock file maintenance minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6412">#6412</a>:
fix(deps): update minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6413">#6413</a>:
chore(deps): update dependency eslint-plugin-unicorn to v65 (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8faa187773"><code>8faa187</code></a>
4.62.2</li>
<li><a
href="a38a795c48"><code>a38a795</code></a>
refactor(rust/parser_ast): extract property AstConverter write buffer
kind lo...</li>
<li><a
href="6cc5c316bb"><code>6cc5c31</code></a>
Skip side-effect-free external imports when hoisting is disabled (<a
href="https://redirect.github.com/rollup/rollup/issues/6411">#6411</a>)</li>
<li><a
href="caacf701b8"><code>caacf70</code></a>
4.62.1</li>
<li><a
href="d1e8297966"><code>d1e8297</code></a>
Add missing ignore</li>
<li><a
href="1ba1fc2387"><code>1ba1fc2</code></a>
fix: insert conflict numbers before first extension in multi-extension
filena...</li>
<li><a
href="532bd0ade7"><code>532bd0a</code></a>
Use import attributes for importing JSON (<a
href="https://redirect.github.com/rollup/rollup/issues/6393">#6393</a>)</li>
<li><a
href="2cd8194aa8"><code>2cd8194</code></a>
fix: advance value past wildcard prefix before suffix check in
getLogFilter (...</li>
<li><a
href="dfac590bd5"><code>dfac590</code></a>
fix(deps): update minor/patch updates (<a
href="https://redirect.github.com/rollup/rollup/issues/6418">#6418</a>)</li>
<li><a
href="1d6db3d325"><code>1d6db3d</code></a>
chore(deps): update dependency eslint-plugin-unicorn to v66 (<a
href="https://redirect.github.com/rollup/rollup/issues/6419">#6419</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rollup/rollup/compare/v4.61.1...v4.62.2">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 13:02:36 -07:00
Nicky Leach 2ef70c3673
build(deps): upgrade lexical family to 0.46.0 and pin via overrides (fixes dual-version getType crash) (#9180) 2026-07-07 13:00:26 -07:00
Zak 6d103b8358
fix: system-authored comments display as 'You' instead of 'Paperclip' (#6330)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - The issue chat thread renders comments from agents, users, and the
system itself
> - When Paperclip's internal recovery system posts a comment (e.g.,
stranded issue recovery), it creates a comment with `author_type:
"system"`, no agent ID, and no user ID
> - The UI function `authorNameForComment` falls back to `"You"` when
both author IDs are null
> - This PR returns `"Paperclip"` instead for system notices
> - The benefit: system comments are clearly attributed to Paperclip,
not the logged-in viewer

## What Changed

- `ui/src/lib/issue-chat-messages.ts`: In `authorNameForComment`, the
null-userId fallback now checks `options?.isSystemNotice` and returns
`"Paperclip"` instead of `"You"` for system-authored comments. One-line
change.

## Verification

- 82/82 existing tests pass (issue-chat-messages 20,
IssueChatThreadSystemNotice 11, IssueChatThread 51)
- Manual repro: view any issue with a system-authored comment (stranded
issue recovery moves issue to blocked). Before: author "You". After:
author "Paperclip".

## Risks

Low risk. One-line change. Only affects system-authored comments with no
user/agent ID. The `isSystemNotice` flag is already computed upstream
(`comment.authorType === "system"`) and passed into this function.

## Model Used

zai/glm-5.1 (200K context). Investigation and code tracing assisted by
the model.

## Checklist

- [x] Thinking path included
- [x] Model specified
- [x] Checked ROADMAP.md — bug fix, not a feature
- [x] Tests pass locally (82/82)
- [x] Risks documented
- [x] Will address all reviewer comments
2026-07-07 14:47:39 -05:00
Devin Foley bdffd26ad3
fix(ui): pass company context to custom image setup (#9028)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Environment settings let board users configure sandbox execution
targets for agent runs
> - Sandbox custom-image setup is company-scoped because the backend
resolves provider secrets and access through company context
> - The browser UI already knows the selected company, but the
custom-image setup calls were not passing it to routes whose OpenAPI
contract includes `companyId`
> - In multi-company authenticated deployments, the backend cannot
safely infer company context and returns a `companyId query parameter is
required` error
> - This pull request passes the selected company id through the
custom-image overview, setup, rollback, and disable UI paths
> - The benefit is that custom-image setup works consistently in
multi-company instances while preserving backend company-boundary checks

## Linked Issues or Issue Description

- No public issue is filed for this regression.
- Related prior work: #8911
- Bug summary: after the browser SSH terminal custom-image setup flow
shipped, opening custom-image setup in an authenticated multi-company
instance could show `companyId query parameter is required for
environment customImage setup` instead of starting the setup session.
- Expected behavior: the environment settings UI should send the
selected company context to company-scoped custom-image endpoints.
- Reproduction shape: run Paperclip in authenticated/private mode with
more than one company, open a sandbox environment's edit dialog, and use
the custom-image setup controls.

## What Changed

- Added company-id query construction for custom-image overview, setup,
rollback, and disable calls in the UI environment API wrapper.
- Passed the selected company id into the custom-image panel used by the
environment edit dialog.
- Updated the environment page tests so the regression fails if company
context is dropped again.

## Verification

- `pnpm exec vitest run ui/src/pages/CompanyEnvironments.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- `git diff --check`
- Also applied the same patch to a local dev checkout serving port 3100
and confirmed `/api/health` still returns `ok` after the dev watcher
reload.

## Risks

- Low risk: this only adds the selected company id to UI calls for
endpoints that already declare or require company context.
- If the selected company id is stale or invalid, the existing
server-side company access checks still reject the request.

## Model Used

- OpenAI Codex CLI using GPT-5, with tool-enabled repository inspection,
editing, shell command execution, and local test execution. Context
window size is not exposed in this environment.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 12:02:27 -07:00
dependabot[bot] 5356b7d737
build(deps): bump @tanstack/react-query from 5.90.21 to 5.101.2 (#9067)
Bumps
[@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query)
from 5.90.21 to 5.101.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/TanStack/query/releases">@​tanstack/react-query's
releases</a>.</em></p>
<blockquote>
<h2><code>@​tanstack/react-query-devtools</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [<a
href="f5bf180d93"><code>f5bf180</code></a>,
<a
href="25cdd975fe"><code>25cdd97</code></a>,
<a
href="ecd89c8faf"><code>ecd89c8</code></a>,
<a
href="01c763444e"><code>01c7634</code></a>,
<a
href="49012dbd51"><code>49012db</code></a>]:
<ul>
<li><code>@​tanstack/query-devtools</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</li>
<li><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</li>
</ul>
</li>
</ul>
<h2><code>@​tanstack/react-query-next-experimental</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</li>
</ul>
</li>
</ul>
<h2><code>@​tanstack/react-query-persist-client</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-persist-client-core</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</li>
<li><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</li>
</ul>
</li>
</ul>
<h2><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</li>
</ul>
</li>
</ul>
<h2><code>@​tanstack/react-query-devtools</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-devtools</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</li>
<li><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</li>
</ul>
</li>
</ul>
<h2><code>@​tanstack/react-query-next-experimental</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</li>
</ul>
</li>
</ul>
<h2><code>@​tanstack/react-query-persist-client</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-persist-client-core</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</li>
<li><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</li>
</ul>
</li>
</ul>
<h2><code>@​tanstack/react-query</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [<a
href="9eff92ed86"><code>9eff92e</code></a>]:</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md">@​tanstack/react-query's
changelog</a>.</em></p>
<blockquote>
<h2>5.101.2</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.101.2</li>
</ul>
</li>
</ul>
<h2>5.101.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [<a
href="9eff92ed86"><code>9eff92e</code></a>]:
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.101.1</li>
</ul>
</li>
</ul>
<h2>5.101.0</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.101.0</li>
</ul>
</li>
</ul>
<h2>5.100.14</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p>fix(react-query): do not go into optimistic fetching state when not
subscribed (<a
href="https://redirect.github.com/TanStack/query/pull/10759">#10759</a>)</p>
</li>
<li>
<p>Updated dependencies []:</p>
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.100.14</li>
</ul>
</li>
</ul>
<h2>5.100.13</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies [<a
href="d423168f62"><code>d423168</code></a>]:
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.100.13</li>
</ul>
</li>
</ul>
<h2>5.100.12</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.100.12</li>
</ul>
</li>
</ul>
<h2>5.100.11</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies []:
<ul>
<li><code>@​tanstack/query-core</code><a
href="https://github.com/5"><code>@​5</code></a>.100.11</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="610e8d1684"><code>610e8d1</code></a>
ci: Version Packages (<a
href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10996">#10996</a>)</li>
<li><a
href="1f84256a2e"><code>1f84256</code></a>
docs: document the <code>select</code> typing caveat for
parallel-queries hooks (<a
href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10984">#10984</a>)</li>
<li><a
href="b80929716f"><code>b809297</code></a>
ci: Version Packages (<a
href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10977">#10977</a>)</li>
<li><a
href="ccc843ea44"><code>ccc843e</code></a>
test({react,preact}-query/useQueries): move type-only tests to
'useQueries.te...</li>
<li><a
href="415461346f"><code>4154613</code></a>
test({react,preact}-query/useMutation): split 'should handle conditional
logi...</li>
<li><a
href="8bb5fdea3e"><code>8bb5fde</code></a>
test({react,preact}-query/useMutation): split 'should pass meta to
mutation' ...</li>
<li><a
href="87426a3016"><code>87426a3</code></a>
test(react-query): replace deprecated 'toBeCalledTimes' with
'toHaveBeenCalle...</li>
<li><a
href="feb1efd804"><code>feb1efd</code></a>
test(*): move 'vi.useRealTimers' to the end of 'afterEach' so cleanup
runs un...</li>
<li><a
href="f3d8d2abbf"><code>f3d8d2a</code></a>
ci: Version Packages (<a
href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10774">#10774</a>)</li>
<li><a
href="532bb298fb"><code>532bb29</code></a>
fix(tests): disable local coverage instrumentation (<a
href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10776">#10776</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.2/packages/react-query">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 10:14:51 -07:00
dependabot[bot] aac7e2ed15
build(deps): bump acpx from 0.11.2 to 0.12.0 (#9062)
Bumps [acpx](https://github.com/openclaw/acpx) from 0.11.2 to 0.12.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/openclaw/acpx/releases">acpx's
releases</a>.</em></p>
<blockquote>
<h2>acpx 0.12.0</h2>
<h2>v0.12.0</h2>
<h3>Changes</h3>
<ul>
<li>Agents/built-ins: add Grok Build via <code>grok agent stdio</code>,
including cached-login and <code>XAI_API_KEY</code> authentication
selection. Thanks <a
href="https://github.com/TheAngryPit"><code>@​TheAngryPit</code></a>.
(<a
href="https://redirect.github.com/openclaw/acpx/pull/426">#426</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li>CLI/queue: drain active turns before releasing queue-owner leases
and preserve typed retryable shutdown responses while terminating agent
bridges. Thanks <a
href="https://github.com/superWorldSavior"><code>@​superWorldSavior</code></a>.
(<a
href="https://redirect.github.com/openclaw/acpx/pull/430">#430</a>)</li>
<li>CLI/quiet output: emit exactly one structured stderr diagnostic for
direct and queued prompt failures without adding diagnostics to stdout.
Thanks <a
href="https://github.com/superWorldSavior"><code>@​superWorldSavior</code></a>.
(<a
href="https://redirect.github.com/openclaw/acpx/pull/431">#431</a>)</li>
</ul>
<h3>Verification</h3>
<ul>
<li>npm: <a
href="https://www.npmjs.com/package/acpx/v/0.12.0">https://www.npmjs.com/package/acpx/v/0.12.0</a></li>
<li>Registry tarball: <a
href="https://registry.npmjs.org/acpx/-/acpx-0.12.0.tgz">https://registry.npmjs.org/acpx/-/acpx-0.12.0.tgz</a></li>
<li>Integrity:
<code>sha512-APYpN04XFWrCGuSBvM4HTKWWFH8uSIuzc+qI7aCGeVdP9o4euZeBosFEkmNUHvBOop0XBemg6d8RsNvzXN3Mgw==</code></li>
<li>Candidate CI: <a
href="https://github.com/openclaw/acpx/actions/runs/28718352566">https://github.com/openclaw/acpx/actions/runs/28718352566</a></li>
<li>Trusted publish: <a
href="https://github.com/openclaw/acpx/actions/runs/28718550655">https://github.com/openclaw/acpx/actions/runs/28718550655</a></li>
<li>Full local tests, coverage, docs, conformance, mutation, security
audits, packed-install CLI smoke, runtime export smoke, lifecycle proof,
and fresh autoreview passed before tagging.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/openclaw/acpx/blob/main/CHANGELOG.md">acpx's
changelog</a>.</em></p>
<blockquote>
<h2>2026.7.4 (v0.12.0)</h2>
<h3>Changes</h3>
<ul>
<li>Agents/built-ins: add Grok Build via <code>grok agent stdio</code>,
including cached-login and <code>XAI_API_KEY</code> authentication
selection. Thanks <a
href="https://github.com/TheAngryPit"><code>@​TheAngryPit</code></a>.</li>
</ul>
<h3>Breaking</h3>
<h3>Fixes</h3>
<ul>
<li>
<p>CLI/queue: drain active turns before releasing queue-owner leases and
preserve typed retryable shutdown responses while terminating agent
bridges. Thanks <a
href="https://github.com/superWorldSavior"><code>@​superWorldSavior</code></a>.</p>
</li>
<li>
<p>CLI/quiet output: emit exactly one structured stderr diagnostic for
direct and queued prompt failures without adding diagnostics to stdout.
Thanks <a
href="https://github.com/superWorldSavior"><code>@​superWorldSavior</code></a>.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6a24a546d2"><code>6a24a54</code></a>
chore(release): prepare acpx 0.12.0</li>
<li><a
href="ffd8549355"><code>ffd8549</code></a>
fix: surface quiet-mode failures on stderr (<a
href="https://redirect.github.com/openclaw/acpx/issues/431">#431</a>)</li>
<li><a
href="87327c6e4a"><code>87327c6</code></a>
fix: make queue owner shutdown lossless (<a
href="https://redirect.github.com/openclaw/acpx/issues/430">#430</a>)</li>
<li><a
href="7d05c37b47"><code>7d05c37</code></a>
feat: add Grok Build ACP agent (<a
href="https://redirect.github.com/openclaw/acpx/issues/426">#426</a>)</li>
<li><a
href="95d75cd000"><code>95d75cd</code></a>
chore(deps): bump tsx to 4.23.0 (<a
href="https://redirect.github.com/openclaw/acpx/issues/429">#429</a>)</li>
<li><a
href="bce1c96d9d"><code>bce1c96</code></a>
chore(deps-dev): update development toolchain (<a
href="https://redirect.github.com/openclaw/acpx/issues/428">#428</a>)</li>
<li><a
href="8a643e725a"><code>8a643e7</code></a>
chore(deps-dev): refresh TypeScript native preview (<a
href="https://redirect.github.com/openclaw/acpx/issues/427">#427</a>)</li>
<li><a
href="a18bf74c4b"><code>a18bf74</code></a>
chore(deps): bump <code>@​agentclientprotocol/sdk</code> from 0.28.1 to
1.1.0 (<a
href="https://redirect.github.com/openclaw/acpx/issues/421">#421</a>)</li>
<li><a
href="1d882575e3"><code>1d88257</code></a>
chore(deps-dev): bump the development group with 7 updates</li>
<li><a
href="c2689c025f"><code>c2689c0</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 25.9.3 to
26.0.1</li>
<li>Additional commits viewable in <a
href="https://github.com/openclaw/acpx/compare/v0.11.2...v0.12.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-07-07 10:05:10 -07:00
dependabot[bot] 077ba611fa
build(deps-dev): bump @types/multer from 2.1.0 to 2.2.0 (#9065)
Bumps
[@types/multer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/multer)
from 2.1.0 to 2.2.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.1.0&new-version=2.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 10:03:47 -07:00
dependabot[bot] faaa9b22e5
build(deps-dev): bump storybook from 10.4.2 to 10.4.6 (#9063)
Bumps
[storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core)
from 10.4.2 to 10.4.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/releases">storybook's
releases</a>.</em></p>
<blockquote>
<h2>v10.4.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>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">storybook's
changelog</a>.</em></p>
<blockquote>
<h2>10.4.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>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5496a4270d"><code>5496a42</code></a>
Bump version from &quot;10.4.5&quot; to &quot;10.4.6&quot; [skip
ci]</li>
<li><a
href="a80a5afddd"><code>a80a5af</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34985">#34985</a>
from TheSeydiCharyyev/fix/issue-34951-partial-globals</li>
<li><a
href="5b929cadfb"><code>5b929ca</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35157">#35157</a>
from Kakadus/update-esbuild</li>
<li><a
href="48e7b20074"><code>48e7b20</code></a>
Bump version from &quot;10.4.4&quot; to &quot;10.4.5&quot; [skip
ci]</li>
<li><a
href="730f744aa6"><code>730f744</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35094">#35094</a>
from storybookjs/jeppe-cursor/a236965c</li>
<li><a
href="dc88f70020"><code>dc88f70</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35053">#35053</a>
from storybookjs/sidnioulz/double-gate-ai-optin</li>
<li><a
href="5adebe753f"><code>5adebe7</code></a>
Bump version from &quot;10.4.3&quot; to &quot;10.4.4&quot; [skip
ci]</li>
<li><a
href="ce1491d9e4"><code>ce1491d</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35085">#35085</a>
from badams/fix/telemetry-fetch-timeout</li>
<li><a
href="624e6187fd"><code>624e618</code></a>
Bump version from &quot;10.4.2&quot; to &quot;10.4.3&quot; [skip
ci]</li>
<li><a
href="c898822822"><code>c898822</code></a>
Merge pull request <a
href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34496">#34496</a>
from NYCU-Chung/fix/docs-blocks-custom-mdx</li>
<li>Additional commits viewable in <a
href="https://github.com/storybookjs/storybook/commits/v10.4.6/code/core">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=storybook&package-manager=npm_and_yarn&previous-version=10.4.2&new-version=10.4.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-07-07 10:02:51 -07:00
dependabot[bot] f10464fee4
build(deps): bump @radix-ui/react-slot from 1.2.4 to 1.3.0 (#9066)
Bumps
[@radix-ui/react-slot](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slot)
from 1.2.4 to 1.3.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/radix-ui/primitives/blob/main/packages/react/slot/CHANGELOG.md">@​radix-ui/react-slot's
changelog</a>.</em></p>
<blockquote>
<h2>1.3.0</h2>
<h3>Added generic type arguments for <code>SlotProps</code> and
<code>createSlot</code></h3>
<p><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.</p>
<pre lang="tsx"><code>const Slot = createSlot&lt;HTMLButtonElement,
MyCustomButtonProps&gt;('Slot');
</code></pre>
<h2>1.2.5</h2>
<ul>
<li>Fixed infinite re-render loop in React 19 caused by
<code>Slot</code> creating a new ref callback on every render</li>
<li>Added support for nested <code>Slottable</code> via a render prop,
so a slotted element can be wrapped while still merging Slot props and
refs onto it</li>
<li>Added repository.directory to all package.json files</li>
<li>Improved error messages for invalid slot children</li>
<li>Updated dependencies:
<code>@radix-ui/react-compose-refs@1.1.3</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slot">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​radix-ui/react-slot</code> since your current
version.</p>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 10:02:47 -07:00
dependabot[bot] 773bf45720
build(deps): bump @zed-industries/codex-acp from 0.12.0 to 0.16.0 (#9068)
Bumps
[@zed-industries/codex-acp](https://github.com/zed-industries/codex-acp)
from 0.12.0 to 0.16.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/zed-industries/codex-acp/releases">@​zed-industries/codex-acp's
releases</a>.</em></p>
<blockquote>
<h2>Release 0.16.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update Codex dependencies to rust-v0.137.0 by <a
href="https://github.com/benbrandt"><code>@​benbrandt</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/320">zed-industries/codex-acp#320</a></li>
<li>Use thread store for session listing by <a
href="https://github.com/benbrandt"><code>@​benbrandt</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/321">zed-industries/codex-acp#321</a></li>
<li>chore(acp): Update to ACP 0.14.0 by <a
href="https://github.com/mrjones2014"><code>@​mrjones2014</code></a> in
<a
href="https://redirect.github.com/zed-industries/codex-acp/pull/317">zed-industries/codex-acp#317</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/mrjones2014"><code>@​mrjones2014</code></a>
made their first contribution in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/317">zed-industries/codex-acp#317</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/zed-industries/codex-acp/compare/v0.15.0...v0.16.0">https://github.com/zed-industries/codex-acp/compare/v0.15.0...v0.16.0</a></p>
<h2>Release 0.15.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update Codex to 0.133.0 by <a
href="https://github.com/benbrandt"><code>@​benbrandt</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/303">zed-industries/codex-acp#303</a></li>
<li>Stop output buffer resend in terminal_interaction stdin path by <a
href="https://github.com/frozename"><code>@​frozename</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/270">zed-industries/codex-acp#270</a></li>
<li>fix: Detach pending permission request tasks on cancel by <a
href="https://github.com/benbrandt"><code>@​benbrandt</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/304">zed-industries/codex-acp#304</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/zed-industries/codex-acp/compare/v0.14.0...v0.15.0">https://github.com/zed-industries/codex-acp/compare/v0.14.0...v0.15.0</a></p>
<h2>Release 0.14.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump openssl from 0.10.78 to 0.10.79 in the cargo group across 1
directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/265">zed-industries/codex-acp#265</a></li>
<li>Update to codex 0.129 by <a
href="https://github.com/benbrandt"><code>@​benbrandt</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/268">zed-industries/codex-acp#268</a></li>
<li>Fix O(N²) memory growth in exec_command_output_delta fallback by <a
href="https://github.com/frozename"><code>@​frozename</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/269">zed-industries/codex-acp#269</a></li>
<li>Emit image generation tool calls by <a
href="https://github.com/benbrandt"><code>@​benbrandt</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/271">zed-industries/codex-acp#271</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/frozename"><code>@​frozename</code></a>
made their first contribution in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/269">zed-industries/codex-acp#269</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/zed-industries/codex-acp/compare/v0.13.0...v0.14.0">https://github.com/zed-industries/codex-acp/compare/v0.13.0...v0.14.0</a></p>
<h2>Release 0.13.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Upgrade to codex 0.128.0 by <a
href="https://github.com/benbrandt"><code>@​benbrandt</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/261">zed-industries/codex-acp#261</a></li>
<li>Reload auth file before failing check_auth() by <a
href="https://github.com/anvilpete"><code>@​anvilpete</code></a> in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/259">zed-industries/codex-acp#259</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/anvilpete"><code>@​anvilpete</code></a>
made their first contribution in <a
href="https://redirect.github.com/zed-industries/codex-acp/pull/259">zed-industries/codex-acp#259</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/zed-industries/codex-acp/compare/v0.12.0...v0.13.0">https://github.com/zed-industries/codex-acp/compare/v0.12.0...v0.13.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bb590500e8"><code>bb59050</code></a>
Bump version to 0.16.0</li>
<li><a
href="c81fa46d89"><code>c81fa46</code></a>
chore(acp): Update to ACP 0.14.0 (<a
href="https://redirect.github.com/zed-industries/codex-acp/issues/317">#317</a>)</li>
<li><a
href="4a853a1cf6"><code>4a853a1</code></a>
Use thread store for session listing (<a
href="https://redirect.github.com/zed-industries/codex-acp/issues/321">#321</a>)</li>
<li><a
href="9841e8b5a8"><code>9841e8b</code></a>
Update Codex dependencies to rust-v0.137.0 (<a
href="https://redirect.github.com/zed-industries/codex-acp/issues/320">#320</a>)</li>
<li><a
href="863d433fc9"><code>863d433</code></a>
v0.15.0</li>
<li><a
href="f67ca5f35f"><code>f67ca5f</code></a>
fix: Detach pending permission request tasks on cancel (<a
href="https://redirect.github.com/zed-industries/codex-acp/issues/304">#304</a>)</li>
<li><a
href="8aef91bc08"><code>8aef91b</code></a>
Stop output buffer resend in terminal_interaction stdin path (<a
href="https://redirect.github.com/zed-industries/codex-acp/issues/270">#270</a>)</li>
<li><a
href="0c2d8280f2"><code>0c2d828</code></a>
Update README.md</li>
<li><a
href="d9bf1c1579"><code>d9bf1c1</code></a>
Update Codex to 0.133.0 (<a
href="https://redirect.github.com/zed-industries/codex-acp/issues/303">#303</a>)</li>
<li><a
href="156cb0da12"><code>156cb0d</code></a>
Emit image generation tool calls (<a
href="https://redirect.github.com/zed-industries/codex-acp/issues/271">#271</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/zed-industries/codex-acp/compare/v0.12.0...v0.16.0">compare
view</a></li>
</ul>
</details>
<br />


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

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 10:02:43 -07:00
Dotta 390627b46e
[codex] Suppress worktree heartbeat scheduling (#9163)
Suppress heartbeat scheduling in worktree and restore runtimes while keeping routine ticks and setup cleanup active.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-07 09:27:46 -05:00
Dotta 57a7da81ee
[codex] Isolate run JWTs by control-plane instance (#9162)
Bind local agent run JWT signing and validation to the issuing Paperclip instance while preserving rollout compatibility for legacy tokens.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-07 09:27:19 -05:00
Dotta 09f503f216
[codex] Surface AWS secret provider create errors (#9161)
Preserve sanitized AWS Secrets Manager create errors and make rollback/cleanup failures explicit.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-07 09:26:41 -05:00
Dotta 6712bd2b9a
docs(release): v2026.707.0 changelog (#9093)
## Release changelog — v2026.707.0

Generated with the `release-changelog` skill from the diff between
**v2026.626.0** (last stable tag) and **origin/master**.

- **Version:** `v2026.707.0` (release date 2026-07-07)
- **Range:** 89 commits from 8 contributors (bots + founders excluded
from the Contributors list per skill rules)
- **Breaking changes:** none (no `BREAKING` signals; migrations are
additive/idempotent)
- **File:** `releases/v2026.707.0.md`

Re-cut over the current `origin/master` — 4 new commits landed since the
prior draft (optional Ramp skill #9157, faster issue-detail payloads
#9125, Work Timeline actor-avatar fix #9152, iOS inbox archive-gesture
fix #9154). All four are founder-authored, so the contributor count is
unchanged; commit count is now 89.

Issue: PAP-12779

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 08:48:32 -05:00
Dotta 72c42fad99
[codex] Add optional Ramp skill (#9157)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Skills are how operators give agents reusable, reviewable operating
instructions without baking every integration into core runtime code.
> - Finance setup is a sensitive workflow because account onboarding,
incorporation, cards, spend controls, and data sharing can all create
real-world effects.
> - Ramp publishes an agent-facing setup skill and playbooks, but
Paperclip needs a curated wrapper that makes those instructions
subordinate to Paperclip governance.
> - This pull request adds an optional Ramp catalog skill that fetches
Ramp's live entrypoint while preserving Paperclip approval gates.
> - The benefit is that companies can opt into Ramp setup assistance
while reviewers can see the source model, allowed hosts, and fail-closed
safety rules in one shipped catalog entry.

## Linked Issues or Issue Description

No public GitHub issue exists for this optional catalog skill.

Feature request context:

- **Problem / motivation:** Paperclip companies need a safe, installable
way for agents to follow Ramp's public agent setup flow without giving
those fetched instructions authority over financial, legal, credential,
or spend decisions.
- **Proposed solution:** Ship a markdown-only optional
`paperclipai:optional:finance:ramp` skill that points agents at Ramp's
live get-started skill, documents the thin-wrapper source model,
allowlists the Ramp host, and requires Paperclip approval for financial,
incorporation, credential, connector, third-party tool, and
money-movement actions.
- **Alternatives considered:** Vendoring a snapshot would reduce runtime
source drift but would stale quickly as Ramp updates its own onboarding
flow. The wrapper instead fetches fresh instructions while explicitly
failing closed on unclear provenance and keeping fetched instructions
subordinate to Paperclip instructions.
- **Roadmap alignment:** This fits the completed Skills Manager roadmap
area by adding a focused optional catalog skill rather than expanding
core workflow code.

## What Changed

- Added a markdown-only optional Ramp skill under the finance catalog.
- Documented the source model for live Ramp instructions, the allowed
host, provenance handling, community/unclear playbook approval
requirements, and safety rules.
- Added mandatory Paperclip approval gates for Ramp account setup,
incorporation/legal filings, CLI installers, connector/auth flows,
third-party browser/MCP/CLI tooling, financial data sharing, Agent
Cards, spend controls, and money movement.
- Updated the Skills Store guide to document thin fetch-and-follow
wrappers for curated optional skills.
- Regenerated the shipped skills catalog manifest.
- Added catalog tests for the Ramp entry, approval-gate wording,
mixed-provenance handling, and avoiding remote-fetch execution hard-stop
patterns.

## Verification

- `pnpm --filter @paperclipai/skills-catalog build:manifest`
- `pnpm --filter @paperclipai/skills-catalog validate`
- `pnpm --filter @paperclipai/skills-catalog test --
src/shipped-catalog.test.ts` — 1 file, 8 tests passed.
- `git diff --check`

## Risks

- Ramp-hosted instructions can change after install. The wrapper
mitigates this by keeping fetched content subordinate to Paperclip
instructions, limiting the source host, failing closed on unclear
provenance, and requiring scoped approvals before governed actions.
- The skill is markdown-only and optional, so it does not add executable
package code or install by default.
- The generated catalog manifest changes hashes for the shipped catalog
entry; catalog validation passed after regeneration.

## Model Used

OpenAI Codex, GPT-5-based coding agent, with repository file access,
shell execution, GitHub CLI/tooling, and medium-reasoning mode.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] 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-07-07 08:33:46 -05:00
Dotta 59092e85d5
[codex] Fix work timeline actor avatars (#9152)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The work timeline UI visualizes agent and human activity across
kickoff chips and the Gantt chart.
> - The timeline actor chips were falling back to generic initials or
blank circular avatars instead of using the richer identity data already
available elsewhere in the app.
> - Agent rows should match the sidebar identity treatment, and human
entries should use the user's configured avatar image when one exists.
> - This pull request teaches the timeline avatar renderer to prefer
configured agent icons and human avatar URLs, while preserving initials
as a fallback.
> - The benefit is a more recognizable work timeline that matches the
rest of the Paperclip UI.

## Linked Issues or Issue Description

No public GitHub issue exists for this UI bug. The underlying issue:
work timeline actor avatars did not consistently use the available actor
identity assets. Agents appeared as generic white-circle initials
instead of their configured sidebar icons, and human kickoff entries
appeared as initials even when the user had an avatar image.

Related prior timeline work: #8875 and #8880. No open duplicate PR was
found for this avatar correction.

## What Changed

- Updated the work timeline actor avatar renderer to show configured
agent icons for agent rows and chips.
- Updated human kickoff avatar rendering to prefer the user avatar image
and fall back to initials only when no image is available.
- Added regression coverage for agent sidebar-style icons and human
avatar images in `WorkTimelineChart`.

## Verification

- `pnpm exec vitest run
ui/src/components/timeline/WorkTimelineChart.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- `git diff --check origin/master...HEAD`

## Risks

Low risk. The change is scoped to work timeline avatar presentation and
preserves the existing initials fallback when configured icons or avatar
images are unavailable.

> 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 local tool-use mode with
shell, git, test execution, and GitHub connector access.

## Checklist

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

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board inbox is a high-frequency operator surface, especially on
mobile where row gestures are the primary way to dismiss handled work.
> - The existing swipe archive control shared one pending-state gate
across the inbox, so one archive request could make other inbox archive
controls feel stuck.
> - The touch handler also kept click suppression and archive timers
coupled too loosely, which made cancelled or partial iOS touch sequences
behave unpredictably.
> - This pull request keeps archive state per issue, makes swipe/cancel
cleanup explicit, and removes archived issues from every relevant inbox
query cache before navigation/refetch.
> - The benefit is that iOS users can archive from inbox/detail views
without the inbox getting into a weird pending or stale-cache state.

## Linked Issues or Issue Description

Bug report:

- Summary: On iOS/mobile, inbox swipe/archive interactions can leave the
inbox feeling stuck or stale after archiving a task.
- Expected: Archiving one inbox item should remove that item
optimistically, keep other archive controls usable, and recover cleanly
from partial or cancelled touch gestures.
- Actual: A pending archive globally disabled other archive controls,
touch cancellation could share the touch-end path, and issue-detail
archive navigation could happen before related inbox query caches were
cleaned up.
- Root cause: Archive pending state and inbox cache updates were handled
locally in multiple places instead of through reusable per-company cache
helpers, and the swipe component did not independently track live
offset, archive timers, and click-suppression timers.

## What Changed

- Split `SwipeToArchive` archive timeout handling from temporary click
suppression and added explicit touch-cancel/reset cleanup.
- Track swipe offset in a ref so commit threshold checks use the latest
touch position rather than potentially stale React state.
- Added shared inbox archive cache helpers for cancelling, snapshotting,
optimistic removal, rollback, and invalidation across inbox query
variants.
- Updated inbox archive mutations to disable only the row being archived
instead of every row while any archive request is pending.
- Updated issue-detail archive-from-inbox to remove the archived issue
from cached inbox variants before navigating back.
- Added focused tests for partial drags, cancelled touches, unmount
cleanup, per-row pending archive behavior, and detail-page cache removal
before navigation.

## Verification

- `pnpm exec vitest run ui/src/components/SwipeToArchive.test.tsx
ui/src/pages/Inbox.test.tsx ui/src/pages/IssueDetail.test.tsx`
  - 3 test files passed
  - 53 tests passed

## Risks

Low-to-medium risk. This changes mobile archive gesture state and
optimistic inbox cache handling, so the main risk is cache invalidation
missing an inbox query variant. The helper uses prefix-based React Query
APIs for the known inbox variants and still invalidates those variants
plus sidebar badges on settle.

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

## Model Used

OpenAI Codex, GPT-5 based coding agent, with repository tool use and
local command execution.

## Checklist

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

Related PR search performed with `gh search prs "inbox archive iOS
swipe" --repo paperclipai/paperclip` and `gh search prs "SwipeToArchive"
--repo paperclipai/paperclip`; existing related work includes #1857 and
#1860, but no duplicate of this regression fix was found.
2026-07-07 07:22:42 -05:00
Dotta 88ce6d3575
Speed up issue detail payloads (#9125)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators spend a lot of time in issue detail pages and agent
activity views while supervising work
> - Those views were receiving large embedded project, workspace,
runtime-service, and heartbeat context payloads
> - Large payloads make issue comments and page loads slower, especially
on active issues with workspaces and runtime metadata
> - This pull request trims the issue detail and activity ledger
response shapes to the fields those views need
> - The benefit is faster issue detail loading without changing the
underlying project, workspace, or run persistence model

## Linked Issues or Issue Description

No public GitHub issue was found for this exact problem, so this PR
describes the bug inline using the bug report template fields.

### Pre-submission checklist

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

### What happened?

Issue detail and related activity responses could include bulky embedded
metadata such as project environment values, workspace metadata, stopped
runtime services, and heartbeat context snapshots. On active issues with
workspaces and long activity history, that makes issue comments and page
loads slower than needed.

### Expected behavior

Issue detail endpoints should return bounded, UI-oriented embeds that
avoid shipping large or sensitive internal blobs when the full object
graph is not needed.

### Steps to reproduce

1. Create or open an issue with a project workspace and execution
workspace.
2. Ensure the workspace has runtime services and heartbeat runs with
context snapshots.
3. Inspect `GET /api/issues/:id` and the issue activity ledger payloads.
4. Observe that the response includes large embedded
project/workspace/runtime/run fields unrelated to rendering the issue
detail page.

### Paperclip version or commit

Reproduced against current `master` lineage before this change.

### Deployment mode

Local dev / server API behavior.

### Installation method

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

### Agent adapter(s) involved

Not adapter-specific (core API payload shape).

### Database mode

Not database-related; no migration.

### Access context

Board and agent-facing issue detail consumers can both benefit from
smaller payloads.

### Node.js version

Not version-specific.

### Operating system

Not OS-specific.

### Relevant logs or output

Not applicable.

### Relevant config (if applicable)

Not applicable.

### Additional context

Related search:
- Searched public GitHub issues for `currentExecutionWorkspace metadata
runtimeServices issue detail`; no matching issue found.
- Searched public GitHub PRs for `compact currentExecutionWorkspace
metadata runtimeServices`; no matching PR found.

### Privacy checklist

- [x] I have reviewed all pasted output for PII (usernames, file paths,
API keys, tokens, company names) and redacted where necessary.

## What Changed

- Added compact response shaping for issue detail project, project
workspace, execution workspace, and runtime-service embeds.
- Dropped large project `env`, workspace `metadata` / embedded runtime
service lists, execution workspace `metadata`, and non-active runtime
services from `GET /api/issues/:id` responses.
- Removed heartbeat `contextSnapshot` from the activity ledger query
result.
- Added focused route and activity-service tests covering the compact
response shape.

## Verification

- `pnpm exec vitest run
server/src/__tests__/issues-goal-context-routes.test.ts
server/src/__tests__/activity-service.test.ts --no-file-parallelism
--maxWorkers=1`
- `pnpm --filter @paperclipai/server typecheck`
- `git diff --check public/master..HEAD`
- Confirmed the branch is based on current
`paperclipai/paperclip:master` and contains no `pnpm-lock.yaml` or
`.github/workflows` changes.

## Risks

Low to medium risk. The persisted data model is unchanged, but consumers
relying on the full embedded project/workspace/runtime metadata from
`GET /api/issues/:id` will now need to fetch the dedicated resource
endpoint instead of depending on the issue detail payload.

> 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 with repository file access, shell
command execution, GitHub connector usage, and local test execution.
Context window and exact hosted model variant 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)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-07-07 06:28:54 -05:00
Dotta f42a66bf04
test: port pipelines tutorial e2e (#9149)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Pipelines are a control-plane workflow surface where operators need
confidence that setup, intake, board movement, review, and learning
flows keep working.
> - The tutorial flow is broad enough that regressions can slip through
unit tests when UI state, route behavior, and workflow fixtures drift
apart.
> - End-to-end coverage gives reviewers a realistic smoke path through
the pipelines tutorial experience.
> - This pull request ports the pipelines tutorial flow into Playwright
and updates the variable flow covered by the scenario.
> - The benefit is stronger browser-level regression coverage for a
high-value onboarding/workflow path.

## Linked Issues or Issue Description

No public GitHub issue exists. Inline feature request:

**Subsystem affected**

Cross-cutting: `tests/e2e`, server startup, and the pipelines UI
workflow.

**Problem or motivation**

The pipelines tutorial flow lacked focused browser-level regression
coverage for setup, intake, board movement, detail/review surfaces, and
learning flow behavior. This left a broad user-facing workflow dependent
on narrower unit coverage.

**Proposed solution**

Add a Playwright spec that boots a throwaway Paperclip instance and
exercises the tutorial flow across setup, intake, board movement, item
detail, review queue, learnings, agent fan-out, drift acknowledgement
gates, child-terminal gates, and stale approvals.

**Alternatives considered**

Unit tests alone are faster but do not validate the integrated browser
workflow. A release-smoke-only path would be broader than necessary for
this tutorial-specific coverage.

**Roadmap alignment**

This supports the roadmap theme of easier onboarding and stronger
first-run confidence without adding a new core feature surface.

**Additional context**

The local host used for this PR is missing Chromium’s `libatk-1.0.so.0`
dependency, so the full browser run needs CI or a machine with
Playwright system dependencies installed.

## What Changed

- Added a Playwright e2e spec covering the pipelines tutorial flow.
- Covered agent fan-out, drift acknowledgement gates, child-terminal
gates, stale approvals, setup/intake, board movement, item detail,
review queue, and learnings.
- Added Playwright config support needed by the new tutorial flow.
- Updated the tutorial variable flow assertions in the ported spec.

## Verification

- Attempted
`/srv/paperclip/home/paperclipai/paperclip/node_modules/.bin/playwright
test --config tests/e2e/playwright.config.ts
tests/e2e/pipelines-tutorial-flow.spec.ts`
- Local result: the throwaway Paperclip server booted and `covers agent
fan-out, drift acknowledgement gates, child-terminal gates, and stale
approvals` passed.
- Local blocker: the second Chromium test failed before executing
because this host is missing the Playwright system library
`libatk-1.0.so.0`. CI should run this on an image with browser
dependencies installed.

## Risks

Medium risk for CI duration/flakiness because this adds browser-level
coverage over a broad workflow. The test is intentionally scoped to one
spec file and uses the dedicated e2e config/server path.

> 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.5 coding agent with repository tool use and local
shell execution. Context window was not surfaced by the runtime.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 05:54:26 -05:00
Dotta 19454ce385
Deduplicate open watchdog review wakes (#9148)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Watchdogs keep issue execution moving by waking agents or creating
recovery paths when work stalls.
> - Open review states should generate useful follow-up, not repeated
duplicate wake requests for the same unresolved review condition.
> - Duplicate wakes create noise and can make the control plane look
busier without increasing progress.
> - This pull request deduplicates open watchdog review wake scheduling
and covers the behavior with scheduler tests.
> - The benefit is cleaner review wake behavior and fewer redundant
agent runs.

## Linked Issues or Issue Description

No public GitHub issue exists. Inline bug report:

**Pre-submission checklist**

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

**What happened?**

Watchdog scheduling could enqueue duplicate open review wake requests
while the same unresolved review condition was already pending.

**Expected behavior**

A watchdog should avoid scheduling redundant review wakes for the same
unresolved condition while preserving legitimate wake paths.

**Steps to reproduce**

1. Create an issue state that requires an open watchdog review wake.
2. Run the watchdog scheduler once and observe a wake request.
3. Run the scheduler again before resolving the original review
condition.
4. Observe whether a duplicate wake is created.

**Paperclip version or commit**

`master` at the PR base.

**Deployment mode**

Local dev (`pnpm dev`) and server deployments running watchdog
scheduling.

**Installation method**

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

**Agent adapter(s) involved**

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

**Database mode**

Not database-related beyond scheduler persistence.

**Access context**

Agent wake scheduling and board-visible review state.

**Relevant logs or output**

Covered by the added scheduler regression test.

**Relevant config (if applicable)**

Not applicable.

**Additional context**

This suppresses duplicate wake scheduling only while the open review
state is still unresolved.

**Privacy checklist**

- [x] I have reviewed all pasted output for PII (usernames, file paths,
API keys, tokens, company names) and redacted where necessary.

## What Changed

- Added deduplication logic for open watchdog review wake scheduling.
- Added scheduler regression coverage for duplicate open review wake
suppression.

## Verification

- `/srv/paperclip/home/paperclipai/paperclip/node_modules/.bin/vitest
run server/src/__tests__/task-watchdogs-scheduler.test.ts`

## Risks

Low-to-medium risk. The change intentionally suppresses duplicate wake
scheduling, so reviewers should confirm no legitimate repeated wake path
depends on creating multiple open requests for the same unresolved
review state.

> 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.5 coding agent with repository tool use and local
shell execution. Context window was not surfaced by the runtime.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-07 05:54:23 -05:00