Commit Graph
1165 Commits
Author SHA1 Message Date
DottaandPaperclip 176645187c Fix request storm polling and issue-list coalescing (#9190)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The board UI keeps issue, agent, activity, and run state fresh
through polling across several pages and sidebar surfaces
> - When multiple components or browser tabs poll the same company data
at the same time, the API can receive bursts of duplicate issue-list
requests
> - Those duplicate requests increase database and server load without
returning meaningfully different data
> - This pull request adds server-side compression/coalescing plus
client-side visibility-aware and cross-tab shared polling
> - The benefit is lower request volume during normal board usage while
preserving fresh UI data for active users

## Linked Issues or Issue Description

No exact public GitHub issue was found for this request.

Problem:
- The board can issue redundant polling requests for the same issue-list
data from multiple UI surfaces and tabs.
- In busy operator sessions, those bursts can trigger request-storm
behavior and unnecessary issue-list load.
- Expected behavior is to reuse identical in-flight work server-side and
reduce hidden-tab or duplicate-tab polling client-side while preserving
normal refresh behavior.

Related public context found during duplicate search:
- #8206 covers a different board UI 404-storm scope.
- #5165 covers separate issue-list behavior around page-size truncation.

## What Changed

- Added API compression middleware foundation and a company/created-at
index for heartbeat run access.
- Added server-side issue-list request storm detection and identical
in-flight request coalescing.
- Added UI fetch metadata, visibility-aware polling, and request
deduplication for issue/activity/client calls.
- Added cross-tab shared polling primitives and wired them into the
sidebar, inbox, dashboard, issue, project, routine, and agent surfaces.
- Resolved the latest `master` migration collision by keeping upstream
`0140_built_in_managed_resources.sql` and renumbering this branch's
heartbeat-run index migration to
`0141_heartbeat_runs_company_created_at_index.sql`; the SQL uses `CREATE
INDEX IF NOT EXISTS` for idempotency.
- Stabilized server heartbeat cleanup tests exposed by the PR check
matrix.
- Fixed the Greptile compression follow-up by weakening strong ETags on
encoded JSON responses and bypassing compression for streamed/download
responses.

## Verification

- `pnpm exec vitest run ui/src/components/IssuesList.test.tsx
ui/src/pages/Inbox.test.tsx` — passed after resolving the latest
`master` conflict in `IssuesList.tsx` and updating the 200-result cap
expectations.
- `pnpm check:token-gates` — passed after the UI conflict resolution.
- `jq -e '.entries | length as $n | (map(.idx) | unique | length == $n)
and (map(.tag) | unique | length == $n)'
packages/db/src/migrations/meta/_journal.json` — passed after
renumbering the migration to `0141`.
- `pnpm exec vitest run server/src/__tests__/api-compression.test.ts` -
passed after the compression follow-up.
- `pnpm exec vitest run
server/src/__tests__/issue-list-assignee-filter-routes.test.ts` - passed
after the compression follow-up.
- `pnpm --filter @paperclipai/server typecheck` - passed after the
compression follow-up.
- Greptile Review for head `8dbddac41ec273fda404100b4981ddb912fad57b` -
passed after the latest conflict/migration fix; all Greptile review
threads are resolved.
- `pnpm exec vitest run server/src/__tests__/api-compression.test.ts
server/src/__tests__/issue-list-assignee-filter-routes.test.ts
ui/src/api/client.test.ts ui/src/api/issues.test.ts
ui/src/lib/polling.test.ts ui/src/lib/cross-tab-poll.test.ts
ui/src/pages/Inbox.test.tsx ui/src/components/SidebarProjects.test.tsx
ui/src/components/SidebarAccountMenu.test.tsx
ui/src/lib/issueDetailCache.test.ts` — passed.
- `pnpm exec vitest run ui/src/api/client.test.ts` — passed.
- `pnpm exec vitest run ui/src/pages/Inbox.test.tsx
ui/src/components/SidebarProjects.test.tsx
ui/src/components/SidebarAccountMenu.test.tsx
ui/src/lib/issueDetailCache.test.ts` — passed.
- `pnpm exec vitest run
server/src/__tests__/heartbeat-worktree-suppression.test.ts` — passed.
- `pnpm exec vitest run
server/src/__tests__/low-trust-red-team-routes.test.ts` — passed.
- `pnpm exec vitest run
server/src/__tests__/heartbeat-workspace-finalize-branch.test.ts` —
passed.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- GitHub PR checks for head `8dbddac41ec273fda404100b4981ddb912fad57b`:
all GitHub Actions/status checks passed; Greptile, Superagent, Socket,
Snyk, build, typecheck/release registry, general tests, serialized
server suites, e2e, canary dry run, policy, and commitperclip review are
green; Storybook visual regression and security-review were
skipped/neutral by policy.
- Confirmed this branch does not include `pnpm-lock.yaml` or
`.github/workflows` changes.

## Risks

- Medium risk: issue-list coalescing changes request timing and cache
semantics for a hot API path.
- Medium risk: cross-tab polling uses browser coordination primitives,
so older or unusual browser environments need fallback behavior to stay
correct.
- Low migration risk: the new index migration is ordered after current
`master` and uses `CREATE INDEX IF NOT EXISTS`.

> 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, GPT-5-based model, tool-enabled with
shell/git execution. Exact hosted deployment identifier and
context-window size were not surfaced in the 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
- [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 17:38:34 -05:00
DottaandPaperclip 8b6a06ee25 [codex] Add built-in agents and Reflection Coach bundle (#9206)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators need first-party agent capabilities for repeatable company
work, not just manually created one-off agents.
> - Built-in agents need to behave like normal company-scoped agents
while preserving approval gates, permissions, budgets, and audit trails.
> - Reflection and coaching work also needs bundled instructions, skill
content, and a routine so the feature can be installed and reset
predictably.
> - The API, database, UI, portability, and tests all need to agree on
the built-in lifecycle from not provisioned through setup, approval,
ready, paused, and reset.
> - This pull request adds built-in agent provisioning and the
Reflection Coach bundle end-to-end.
> - The benefit is a safer first-party path for Paperclip-managed agents
without bypassing the same governance model used for operator-created
agents.

## Linked Issues or Issue Description

No public GitHub issue was found for this exact built-in agent and
Reflection Coach bundle work.

Problem/motivation:
- Paperclip did not have a first-party built-in agent lifecycle for
product-owned agents.
- Bundled agent resources such as default instructions, skills, and
routines needed managed ownership and reset semantics.
- Approval-gated companies needed built-in setup to preserve requested
adapter, budget, manager, and permission state through board approval.
- The board UI needed clear built-in badges, setup affordances,
readiness state, and bundle status without exposing secrets.

Proposed solution:
- Add a company-scoped built-in agent registry,
provisioning/reset/reconcile/status APIs, and Reflection Coach bundled
resources.
- Track bundled managed resources in the database with idempotent
migration behavior.
- Reuse existing agent approval, authorization, budget, and activity-log
paths instead of creating a bypass.
- Add UI setup, badges, gates, bundle panels, and route coverage for
built-in agents.

Duplicate search:
- Searched GitHub PRs for `built-in agents Reflection Coach
repo:paperclipai/paperclip`; only this PR was returned.
- Searched GitHub issues for the same query; no public issues were
returned.

## What Changed

- Added built-in agent definitions, lifecycle state derivation,
provisioning, reset, reconcile, status, and routine-control routes.
- Added the `built_in_managed_resources` migration and schema exports
for bundled instructions, skill, and routine ownership.
- Added the Reflection Coach built-in bundle with default instructions,
skill catalog content, routine template, default permissions, and
managed-resource drift handling.
- Added approval-aware provisioning behavior that preserves requested
adapter config, budgets, manager assignment, and built-in permissions
through hire approval.
- Added authorization and mutation gates for built-in agent and skill
changes, including consented Reflection Coach change paths.
- Added UI surfaces for built-in agent setup, roster/detail badges,
readiness gates, bundle status, routine controls, and route filtering.
- Added company import/export and validator coverage for built-in
managed resources and low-trust/red-team presets.
- Addressed Greptile follow-ups for pending approval reconciliation,
consent-gate error propagation, config-read authorization fallback,
approval-path manager preservation, and non-model adapter provisioning.

## Verification

Local verification:
- `git diff --check public/master..HEAD` passed.
- `pnpm check:token-gates` passed with all gates clean.
- `pnpm exec vitest run
ui/src/components/ConfigureBuiltInAgentModal.test.tsx` passed: 1 file, 4
tests.
- `pnpm exec vitest run ui/src/components/EntityRow.test.tsx
ui/src/pages/Agents.test.tsx ui/src/components/BuiltInAgentGate.test.tsx
ui/src/components/ConfigureBuiltInAgentModal.test.tsx
ui/src/components/BuiltInBundlePanel.test.tsx
ui/src/pages/InstanceExperimentalSettings.test.tsx
ui/src/pages/Routines.test.tsx` passed: 7 files, 64 tests.
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/built-in-agents.test.ts
src/__tests__/authorization-service.test.ts
src/__tests__/company-skills-routes.test.ts` passed: 3 files, 91 tests.
- `pnpm --filter @paperclipai/db check:migrations` passed.
- `pnpm -r typecheck` passed after the rebase; `pnpm --filter ui
typecheck` passed after the final UI review fix.

Remote verification on latest head
`1c61f693a4ec881d739022b0e75a8ca8bf8c2cd8`:
- Merge state: `CLEAN`.
- Greptile: `5/5`, zero unresolved Greptile threads.
- PR check rollup: all checks successful, neutral, or skipped as
expected.
- Passing gates include Build, Typecheck + Release Registry, all server
shards, all workspace shards, all serialized server suites, e2e, Canary
Dry Run, policy, review, verify, Socket, Superagent, and Snyk.

## Risks

- This adds a new managed-resource table and migration; the migration
uses idempotent create/add/index guards and passed migration safety
checks.
- Built-in agent provisioning touches approval and authorization paths;
tests cover pending approval preservation, stale retry rejection,
consent gates, and config-read fallback behavior.
- Reflection Coach creates managed instructions, skill, and routine
resources; drift/reset behavior is covered by service tests and redacted
API responses.
- Non-model adapter setup now provisions a `needs_setup` built-in row
before command/endpoint fields are complete; this matches the server
lifecycle and is covered by the setup modal regression test.

## Model Used

OpenAI Codex coding agent based on GPT-5. Exact hosted model ID,
context-window size, and reasoning-mode labels are not exposed in this
runtime; tool use, shell execution, GitHub CLI/API access, and local
code editing were enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (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 16:29:30 -05:00
scotttongandClaude Fable 5 53d09d4c34 fix(ui): inbox/task list parity, nesting alignment, hover perf, and routine detail polish (#9317)
## Thinking Path

> - Paperclip's UI is governed by the design system merged in #9134 and
the component convergence in #9240 — one Card, one Badge, one nav row,
one `IssueRow`, a single multiplicative radius ladder.
> - With those primitives in place, the remaining rough edges were
interaction and alignment details on the surfaces people use every day:
the inbox, the task list, the sidebar, and the routine/task detail
pages.
> - Each item here was reported from live use and fixed against a
running instance, then verified by measurement (pixel alignment, frame
timing) rather than by eye alone.
> - The result is that the inbox and task lists now behave as one system
(same hover, keyboard nav, tree-guide, and archive language), list
nesting reads correctly, list hover is smooth, and the routine detail
page scrolls and aligns like the rest of the app.

## Linked Issues or Issue Description

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

- **Problem**: after the design-system foundation (#9134) and component
convergence (#9240), the inbox/task lists still had interaction and
alignment gaps — hover lag on long lists, keyboard navigation that only
partly matched between the two lists, workspace/parent nesting whose
guides and chevrons didn't line up, an inbox that sat offset from the
task list, and a routine detail page with an odd double-scroll and a
bespoke sub-nav.
- **Proposed behavior**: the inbox and task lists share one interaction
contract (hover, keyboard nav, collapse, archive), list nesting aligns
to the status column with clean chevrons, list hover is CSS-only (no
per-hover re-render), and the routine detail page uses a fixed
header/sub-nav with a single scrolling content region and a sub-nav that
matches the primary nav.

## What Changed

- **List hover performance**: hover is now painted purely by CSS
`:hover` and records the hovered row in a ref, instead of writing
list-selection state on every `mouseenter` (which re-rendered 100–300
non-memoized rows per hover). Keyboard nav reads the ref so it still
continues from the hovered row; the keyboard band clears on the first
real mouse move so hover and keyboard selection never show two bands at
once. The row's `transition-colors` fade was removed so the highlight
snaps (no comet-tail). Measured on a 100-row scrub: worst frame **333 ms
→ 33 ms**, long frames (>50 ms) **12 → 0**, avg **41 → 60 fps**.
- **Inbox ↔ task-list parity**: keyboard navigation works on every inbox
tab (archive/read keys stay scoped to the archivable tab); group headers
and parent tasks collapse/expand with the arrow keys in both lists; the
task list gains the same j/k / arrows / Enter selection model as the
inbox; hover selection bands match; the `g` then `i` go-to-inbox chord
works app-wide.
- **List nesting & alignment**: the workspace group-header chevron lines
up exactly with the task chevrons below it (both lists); the
parent→child connector line drops from under the parent's **status
icon** rather than its chevron and breaks with a 14px gap around a
nested row's own chevron; and inbox rows line up with the task list
(read rows no longer reserve a mark-read column).
- **Inbox archive affordance**: moved from a bare `x` left of the status
icon to an `Archive` icon + label button on the right (before the
timestamp), revealed on row hover; the left slot now carries only the
unread dot; swipe-to-archive is unchanged.
- **Sidebar**: when no agent has a live run, the AGENTS section shows 3
recent agents (was 5) plus "See all agents"; the working-agents view is
unchanged.
- **Routine detail page**: the layout is bounded to the main scroll area
so the header (Run now + automation toggle) and the sub-nav stay fixed
and only the section content scrolls (was a page-level scroll competing
with a `sticky` sub-nav). The sub-nav items adopt the primary nav's
rhythm — row padding/height, inset rounded pill, type scale, and 16px
icons — and its background matches the main nav.
- **Task detail**: dropped the redundant `🔵` prefix the breadcrumb added
for live/in-progress tasks; the status glyph already conveys that state.

## Verification

- `pnpm check:token-gates` → 3/3 CLEAN
- `pnpm typecheck` → green (all packages)
- `cd ui && npx vitest run` → 2255/2255 (assertions updated in lockstep
where behavior changed)
- `pnpm --filter @paperclipai/ui build` → exit 0
- Storybook visual regression: run locally throughout (the
baseline-manifest archive is still unpublished, so CI cannot run this
suite — pre-existing condition from #9134). Every visible delta was
reviewed against a live instance and, where it was intentional (nesting
alignment, routine sub-nav restyle, unread-row shift), the affected
snapshots were re-baselined locally.
- Manual/measured: inbox + task lists (grouped and nested, light +
dark), hover-scrub frame timing, keyboard navigation, and the routine
detail scroll/alignment were exercised on a running instance.

## Risks

- Behavior-and-alignment changes concentrated in `IssueRow` /
`IssuesList` / `Inbox` (the shared task-row surfaces). The riskiest area
— the hover/keyboard-selection model — is covered by unit tests (updated
in lockstep) and was measured and driven live.
- The routine detail scroll change restructures that page's layout
container; verified the page's own scroll stays fixed while only the
section content scrolls.
- The visual suite cannot yet run in CI (unpublished baseline archive —
pre-existing); snapshot coverage is local-only until that lands.

## Model Used

- Claude Fable 5 (`claude-fable-5`, Anthropic) via Claude Code — agentic
coding with tool use (file editing, test execution, Playwright
measurement/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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:25:48 -07:00
Devin FoleyandPaperclip bc85b456a1 fix(ui): keep agent names visible on mobile agents index (#9236)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Agents index (`ui/src/pages/Agents.tsx`) is the main roster
view, with both a list layout and an org-tree layout
> - On mobile viewports the roster could render rows with no visible
agent names because shrink-resistant trailing controls competed with the
fixed-width title cell
> - A roster where names are unreadable is unusable on phones, and the
org-tree view had a related narrow-width overflow risk for deeply
indented names
> - This pull request lets the list title flex below `xl`, hides
nonessential row controls on mobile, keeps Join/Leave reachable, and
truncates org-tree names safely
> - The result is a readable agents index on mobile while preserving
desktop meta-column alignment and truncation

## Linked Issues or Issue Description

No existing public GitHub issue; describing the bug per the bug report
template:

**What happened?**

On a mobile-width viewport, the agents index showed rows where agent
names could become unreadable or disappear because trailing controls
consumed the available row width. In the org view, deeply indented names
could overflow the row.

**Expected behavior**

Agent names remain visible on every viewport, Join/Leave stays
reachable, and desktop rows continue to align and truncate as before.

**Steps to reproduce**

Open Paperclip in a browser at a narrow viewport, navigate to the Agents
index, and observe rows with long names or left-membership controls.

**Paperclip version or commit**

Reproducible on `master` prior to this fix.

**Deployment mode**

Local dev instance. The bug is viewport-width dependent, not
deployment-mode dependent.

## What Changed

- `EntityRow` now lets callers control title text, subtitle text, and
the meta spacer classes while keeping the default truncation behavior
unchanged.
- Agents list rows now use `flex-1 xl:flex-none xl:w-56`, so names get
mobile width while desktop meta columns keep their aligned fixed title
column.
- Long list-view names/subtitles wrap below `xl` but return to
truncation at `xl` and above.
- Join/Leave stays visible on mobile; run/status/star row controls stay
hidden on mobile to avoid squeezing names.
- Org-tree rows use `min-w-0 truncate`, so deep indentation shortens
names with an ellipsis instead of overflowing.
- Regression tests cover mobile name visibility, left-membership
dimming, responsive title/meta behavior, and mobile Join/Leave
reachability.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/EntityRow.test.tsx src/pages/Agents.test.tsx` — 2 files,
18 tests passed.
- `pnpm check:token-gates` — all gates clean.
- `git diff --cached | rg -n "(AKIA|ASIA|SECRET|TOKEN|PASSWORD|PRIVATE
KEY|BEGIN RSA|BEGIN
OPENSSH|api[_-]?key|bearer|paperclip_api_key|DATABASE_URL|postgres://|sk-[A-Za-z0-9]|xox[baprs]-)"`
— no matches before push.

## Risks

- Low risk: UI-only change scoped to the agents index. The main behavior
change is that nonessential row controls remain hidden on mobile while
Join/Leave remains available there and all controls remain available on
larger screens/detail pages.

## Model Used

- OpenAI GPT-5 via Codex (`codex_local` adapter), agentic code editing
and local/GitHub verification.

## Checklist

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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-09 13:37:17 -07:00
b13eb5b2b5 Skill Studio: three-pane skill IDE with sandboxed test runs (#9241)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Skills Manager gives operators a reusable skill layer, but
iteration still required manual edits, ad hoc prompts, and indirect run
inspection.
> - Skill authors need a focused workflow for editing skill files,
saving representative test inputs, and running those inputs through an
agent without exposing harness tasks as normal company work.
> - The backend therefore needs durable test inputs, reusable run
templates, hidden harness issues, scoped run execution, retention
metadata, and read-containment rules around hidden work.
> - The frontend needs a three-pane Studio that keeps skill files, saved
inputs/templates, and run output/history visible together while
preserving the existing design system and token rules.
> - This pull request ships that Skill Studio surface end to end:
database migrations, shared contracts, server APIs/services, hidden
harness execution behavior, UI routes/components, and focused tests.
> - The benefit is faster and safer skill iteration, with inspectable
outputs and fewer ways for internal harness work to leak into normal
task lists, costs, or adjacent read APIs.

## Linked Issues or Issue Description

No public GitHub issue exists for this feature. Feature request summary:

- Problem: Skill authors need to edit and test company skills in one
place instead of switching between the skill detail page, task creation,
run output, and manual prompt history.
- Proposed solution: Add a Skill Studio workbench with saved inputs,
reusable templates, hidden sandboxed test runs, live run status, output
inspection, run history, rerun/delete controls, and frontmatter-aware
editing.
- Expected users: Paperclip operators and agent-company maintainers who
create, fork, import, and tune skills.
- Related public PRs: Supersedes #9205, which was replaced so the public
PR branch name follows contributor policy.
- Duplicate search: searched public GitHub issues and PRs for "Skill
Studio"; no other active public issue or PR directly covers this
feature.

## What Changed

- Added database migrations for Skill Studio test inputs, test runs,
test run retention, and reusable run templates.
- Added shared Skill Studio types, validators, route helpers,
frontmatter utilities, and status handling.
- Added server services and routes for saved inputs, test runs,
templates, reruns, terminal-run deletion, hidden harness issue
execution, and run-detail hydration.
- Strengthened hidden-issue read containment across issue-adjacent
routes and cost rollups used by skill test harness work.
- Added the Skill Studio UI with skill file editing, frontmatter
editing, saved inputs, templates, run creation/cancel/rerun/delete
flows, output rendering, history, route support, and responsive pane
behavior.
- Added focused backend, shared, and UI tests for the new APIs, routing
logic, editor/run behavior, hidden-issue containment, and migration
safety.
- Rebased onto current `master`, removed the generated lockfile diff
from the PR, and verified no workflow files are changed.

## Verification

- [x] `pnpm --filter @paperclipai/db check:migrations`
- [x] `pnpm check:token-gates`
- [x] `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/company-skills-routes.test.ts
server/src/__tests__/company-skill-test-runs-service.test.ts
ui/src/lib/skill-studio.test.ts ui/src/pages/SkillStudio.test.tsx` — 5
files, 132 tests passed
- [x] Greptile review on the latest PR head
- [x] GitHub PR checks on the latest PR head

## Risks

- Medium risk because this is a broad feature touching database schema,
server orchestration, issue visibility, and a large UI surface.
- Hidden harness issue containment is security-sensitive; this PR
includes regression coverage for adjacent read paths and cost rollups.
- The new migrations are additive and use idempotent guards where
applicable, but deployed databases that previously tested draft
migration numbers should still be checked carefully.
- The UI depends on a new resizable panels package in `ui/package.json`;
the lockfile is intentionally left to repository automation.

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

## Model Used

OpenAI Codex, GPT-5 coding agent with shell, git, and GitHub CLI tool
use. Earlier feature commits include assistance from other Paperclip
coding agents; this PR preparation, rebase, cleanup commit, and PR body
were completed by OpenAI Codex in a Paperclip worktree.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 13:08:56 -05:00
DottaandPaperclip 1c75a46c10 feat(ui): add waiting-on-live-work blocked notice (#9298)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators rely on the issue detail thread to understand whether a
task is blocked, live, or waiting on another task.
> - A blocked issue can have a healthy blocker chain where downstream
work is actively running and the parent will resume automatically.
> - Showing that case with the same amber blocked notice as a stalled or
attention-needed blocker makes the state look more severe than it is.
> - The UI already receives blocker-attention state, blocker summaries,
and company live-run ids, so this can be clarified without a new API
shape.
> - This pull request adds a blue "Waiting on live work" notice for
covered blocker chains while preserving the existing amber notice for
the other blocked states.
> - The benefit is that operators can distinguish healthy queued work
from blocked work that needs intervention.

## Linked Issues or Issue Description

Refs #3820
Refs #8271
Related PR: #3877
Supersedes #9295

## What Changed

- Added a blue `IssueBlockedNotice` variant when
`blockerAttention.state` is `covered` and the blocker chain has live
work.
- Rendered blocker-chain progress as done, running, and queued steps,
including a "Now running" row for live terminal blockers.
- Preserved the existing amber blocked notice for stalled,
attention-needed, ordinary blocked, and successful-run handoff states.
- Plumbed the existing `liveIssueIds`, `blockedBy`, and
`blockerAttention` data from issue detail into the chat-thread blocked
notice.
- Added regression coverage around the covered live-work state, the
no-confirmed-live fallback, numeric step ordering, and amber fallback
states.
- Hardened a low-trust server route test cleanup helper so CI deletes
heartbeat run events before deleting heartbeat runs.

## Verification

- `pnpm check:token-gates`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm exec vitest run ui/src/components/IssueBlockedNotice.test.tsx`
- GitHub PR workflow is green on head
`52ab6d9076ce233c183bf7133fa666e8597b6765`.
- Greptile check is green on head
`52ab6d9076ce233c183bf7133fa666e8597b6765` with zero unresolved review
threads.

## Risks

Low runtime risk: the product change is frontend-only and uses data
already returned to the issue detail page. The main risk is visual
regression in the blocked notice; the change keeps non-covered states on
the existing amber path and adds focused regression coverage. The
server-side change is test-only cleanup for an existing CI shard
failure.

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

## Model Used

OpenAI Codex using GPT-5, tool-use enabled in a repository workspace.
The runtime did not expose a more specific model build id or
context-window size.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-09 10:59:18 -05:00
DottaandPaperclip 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](https://gist.githubusercontent.com/cryppadotta/dc2645d54c4bc56ffc0323224b3ea4bf/raw/5f33032ee33035d11334a907ebd5907d92fb3485/visible-window-stats.svg)

![Kickoff attribution before and after stale-chip
fix](https://gist.githubusercontent.com/cryppadotta/dc2645d54c4bc56ffc0323224b3ea4bf/raw/3e0ac8de60b56ff97b0ba48cfe897c0faa161ea9/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
Devin FoleyandPaperclip 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
scotttongandClaude Fable 5 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
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
DottaandPaperclip 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
Nicky LeachandPaperclip 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
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
Devin FoleyandPaperclip 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
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
696c694a58 feat(ui): recovery-card divergence diagnosis + one-click isolated re-issue
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents execute on isolated workspaces (git worktrees), each pinned
to a specific branch and commit at checkout time
> - When an agent's live checkout diverges from the recorded workspace
branch — either through a branch rename, a stale worktree, or a
concurrent git operation — Paperclip detects the mismatch and surfaces a
recovery card to the operator
> - But the existing recovery card showed a generic error with no
diagnostic context: it didn't display *which* branch was expected vs.
which was checked out, the commit SHAs involved, or whether the branches
share ancestry
> - Without that information operators cannot diagnose the root cause,
and the only recovery path was fully manual re-issue
> - This pull request extends `IssueRecoveryActionCard` for
`workspace_validation` / `git_worktree_branch_incoherence` recovery
kinds to render a divergence-diagnosis panel (expected branch, live
branch, short SHAs, ancestry-verdict badge, plain-language reason) and
adds a confirm-gated "Re-issue on isolated workspace" action that
creates a new task with `executionWorkspacePreference:
isolated_workspace` so the re-issued run cannot trip the same
branch-mismatch gate
> - The benefit is that operators can immediately see *why* a workspace
was declined and recover with a single click instead of having to
manually reconstruct the task

## Linked Issues or Issue Description

Refs #4757 (heartbeat re-wake doesn't reconcile working-tree HEAD
against ticket's expected branch — this PR surfaces the resulting
divergence to the operator and provides a one-click isolated re-issue
path)
Refs #8460 (workspace_validation_failed local-only project workspaces —
this PR extends the recovery card UI for this case)

**Subsystem affected:** ui/ — React + Vite board UI

**Problem or motivation:** When Paperclip records a workspace branch for
an agent run and the live checkout disagrees (diverged HEAD, renamed
branch, stale worktree), the issue recovery card surfaces a generic
`workspace_validation` error. The operator sees "run declined" but has
no visibility into the expected vs. actual branch, the relevant commit
SHAs, or whether the branches even share ancestry. There is no one-click
path to re-issue the task on a clean isolated workspace — the operator
must manually reconstruct the task from scratch.

**Proposed solution:** Extend `IssueRecoveryActionCard` to:
1. Render a divergence-diagnosis panel from the `recoveryEvidence`
field: expected branch, live branch, short SHAs for both, an
ancestry-verdict badge (`forward-only` / `diverged` / `ancestry
unknown`), and the server's `plainLanguageReason`.
2. Add Action 3 "Re-issue on isolated workspace" — a confirm-gated
button that calls `issuesApi.create` with `executionWorkspacePreference:
isolated_workspace` and `workspaceStrategy.baseRef` set to the live
branch (SHA fallback when detached). The current workspace is never
mutated.
3. Wire `onReissueIsolated` / `reissuePending` through `IssueChatThread`
→ `IssueDetail` so the operator sees an immediate success toast and is
navigated to the new task.

**Alternatives considered:** Showing divergence details only in a
tooltip (rejected — too easy to miss). Providing a "force-reset the
workspace" action (rejected — destructive, no audit trail, doesn't fix
stale-branch root cause). Isolated re-issue via isolated workspace was
the clearest safe path.

## What Changed

- `IssueRecoveryActionCard.tsx` — Added `DiagnosisPanel` sub-component
rendered for `workspace_validation` / `git_worktree_branch_incoherence`
recovery kinds: displays expected vs. live branch, short SHAs,
ancestry-verdict badge, and plain-language reason. Added Action 3
confirm-popover with `onReissueIsolated` callback and `reissuePending`
loading state. Kept existing Action 1 and Action 2 unchanged.
- `IssueChatThread.tsx` — Threaded `onReissueIsolated` and
`reissuePending` props down to `IssueRecoveryActionCard`.
- `IssueDetail.tsx` — Implemented `handleReissueIsolated`: calls
`issuesApi.create` with `executionWorkspacePreference:
isolated_workspace` + `workspaceStrategy.baseRef` derived from live
branch / SHA; shows a success toast and navigates to the new task on
completion.
- `IssueRecoveryActionCard.test.tsx` — Added 19 unit tests covering
diagnosis-panel rendering, verdict label rendering, base-ref derivation
(branch-first then detached-HEAD SHA fallback), and action gating.

## Verification

```bash
# Unit tests — 19/19 pass
pnpm vitest run ui/src/components/IssueRecoveryActionCard.test.tsx

# Typecheck — 0 new errors
pnpm typecheck
```

Manual browser validation deferred to QA — see Risks.

## Risks

- **Re-issue creates a new task** — the original task remains unchanged.
This is intentional (safe default), but operators should be aware both
tasks exist after re-issue.
- **Base-ref derivation falls back to the live HEAD SHA when detached.**
SHA-based worktrees are valid for isolated re-issue but may surprise
operators expecting a branch name.
- **Browser-level end-to-end validation not included here.** Toast,
navigation, and full create-flow are covered by integration QA in a
follow-up pass.
- **Low overall risk** — no new endpoints, no data mutations on existing
records, no PII or telemetry changes. Composes the existing
`issuesApi.create` endpoint; all new behavior is additive.

## Model Used

Claude Sonnet 4.6 (`claude-sonnet-4-6`) — Anthropic. 200k context
window, tool use, code execution. Extended thinking not used.

## 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
- [ ] 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: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-06 23:02:49 -07:00
5163208c3c Add workspace branch ancestry diagnostics (#9117)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run in git worktrees tied to a workspace branch; when the
actual branch diverges from the expected one (e.g. a parent feature
branch was renamed), Paperclip currently has no structured field to
report *why* the branch is incoherent or whether it can be
auto-reconciled
> - The workspace-incoherence fingerprint already captures SHA
mismatches, but there is no evidence field distinguishing "actual branch
is a descendant of expected" (safe to fast-forward) from "branches have
diverged" (needs human review) or "SHAs are unavailable" (unknown)
> - Operators and future recovery flows need a typed verdict to make
decisions without re-running git commands themselves
> - This pull request adds `ancestryVerdict` and `plainLanguageReason`
evidence fields computed via `git merge-base --is-ancestor`, and
scaffolds the off-by-default `enableWorkspaceBranchReconcileForward`
instance setting with no runtime behavior yet
> - The benefit is that future recovery logic can branch on a typed
verdict rather than parsing prose, while the fingerprint v1 payload
stays stable

## Linked Issues or Issue Description

No public GitHub issue pre-exists for this diagnostic addition.

**Problem or motivation**

When Paperclip detects that an agent's actual workspace branch differs
from the recorded expected branch, the current fingerprint carries only
raw SHAs. There is no typed field indicating whether the actual branch
is a descendant of the expected one (safe reconcile path) vs. a true
divergence (requires human intervention) vs. an indeterminate state
(missing SHAs or git errors). Downstream recovery logic cannot branch
safely without re-running git.

**Proposed solution**

Add `ancestryVerdict` and `plainLanguageReason` to the workspace
incoherence evidence type; compute via `git merge-base --is-ancestor`;
scaffold a feature-flag for future forward-reconcile behavior
(`enableWorkspaceBranchReconcileForward`, off by default, not yet read
by any runtime path).

**Alternatives considered**

Encoding the verdict in the existing fingerprint string was rejected
because the fingerprint is a stable identity hash, not a mutable
evidence bag. Changing it would break monitors keyed on the string.

**Roadmap alignment**

Supports future workspace auto-reconcile work; ROADMAP.md has no
conflicting entry for this diagnostic layer.

## What Changed

- `packages/shared/src/types/heartbeat.ts` adds `ancestryVerdict` and
`plainLanguageReason` fields to `WorkspaceIncoherenceEvidence`
- `packages/shared/src/types/instance.ts` adds
`enableWorkspaceBranchReconcileForward` boolean (off by default)
- `packages/shared/src/validators/instance.ts` exports the new flag from
the settings validator
- `server/src/services/workspace-runtime.ts` computes `ancestryVerdict`
via `git merge-base --is-ancestor`; falls back to `unknown` on missing
SHAs or command errors; excludes verdict fields from fingerprint v1
computation
- `server/src/services/instance-settings.ts` wires the new setting
through to the settings service
- Tests updated in `workspace-runtime.test.ts`,
`instance-settings-service.test.ts`, `instance-settings-routes.test.ts`,
and `instance.test.ts` (104 tests total)

## Verification

```bash
pnpm exec vitest run \
  server/src/__tests__/workspace-runtime.test.ts \
  server/src/__tests__/instance-settings-service.test.ts \
  server/src/__tests__/instance-settings-routes.test.ts \
  packages/shared/src/validators/instance.test.ts
# 104 tests pass

pnpm --filter @paperclipai/shared typecheck
pnpm --filter @paperclipai/server typecheck
# both exit 0
```

Manual: trigger a workspace incoherence event and confirm the evidence
object carries `ancestryVerdict` and `plainLanguageReason`; confirm the
fingerprint string stays `workspace_incoherence:v1:sha256:...`.

## Risks

**Low risk.** Purely additive. Fingerprint v1 payload is unchanged. The
new flag has no runtime effect in this PR. `git merge-base
--is-ancestor` exits non-zero for both "not an ancestor" and "command
error"; both are handled and collapsed to typed values with a prose
reason.

## Model Used

Provider: Anthropic, model: Claude Sonnet 4.6 (`claude-sonnet-4-6`),
200k context, tool use enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] 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
- [ ] 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>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 16:29:01 -07:00
Evyatar Bluzer c5d73844a5 fix(a11y): add tooltips and aria attributes to agent view toggle (#1937)
## Problem

On the Agents page, there are two small icon buttons for switching
between list view and org chart view. But these buttons had:
- No title attribute, so hovering show nothing
- No aria-label, so screen readers just say "button"
- No aria-pressed, so no way to know which view is active
- No role="group" on the container

I was confused the first time I see these buttons because one is a list
icon and the other is a git-branch icon, and without hovering or
clicking I had no idea what they do. Specially the git-branch icon - is
it for branches? Repos? No, it's for org chart view.

## What I changed

- Added `title` to each button: "List view" and "Org chart view"
- Added `aria-label` matching the title for screen readers
- Added `aria-pressed` to indicate which view is currently selected
- Added `role="group"` with `aria-label="View mode"` on the container
div

## How to test

1. Go to Agents page (must have more than 1 agent for toggle to appear)
2. Hover over the list icon - should see "List view" tooltip
3. Hover over the branch icon - should see "Org chart view" tooltip
4. Use screen reader - should announce "List view, pressed" or "Org
chart view, not pressed"

1 file, 7 lines added.
2026-07-06 16:03:10 -07:00
DottaandPaperclip 903886bc79 [codex] Add starred resource sidebar controls (#9085)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board UI is the main daily navigation surface for agents,
projects, and their related resources.
> - Operators need a lightweight way to keep frequently used agents and
projects close without changing company-wide ordering or ownership.
> - Resource memberships already model per-user relationships to
projects and agents, so they are the right place to store user-specific
starred state.
> - This pull request extends that membership contract with a starred
timestamp and exposes star controls in list/detail views.
> - The sidebar then uses those starred memberships to show compact,
user-specific shortcuts.
> - The benefit is faster navigation without introducing a separate
favorites system or leaking preferences across users.

## Linked Issues or Issue Description

No public GitHub issue exists.

Feature request:

## Problem or motivation

Users cannot pin frequently used agents or projects into the main
sidebar. Returning to important resources requires scanning full
project/agent lists or navigating through detail pages, which adds
friction to repeated daily workflows.

## Proposed solution

Store a per-user `starred_at` timestamp on agent and project
memberships, expose API actions to set or clear that state, add star
toggle controls to list/detail pages, and render starred projects and
agents as compact sidebar shortcuts.

## Alternatives considered

A separate favorites table would work, but it would duplicate membership
scoping and require another resource relationship model. Keeping starred
state on memberships preserves existing company/user boundaries and
avoids a second source of truth.

## Roadmap alignment

Checked `ROADMAP.md`; no overlapping planned core work for starred
resource/sidebar navigation was found.

## Additional context

The affected subsystems are `packages/db`, `packages/shared`, `server/`,
and `ui/`. The migration is idempotent with `IF NOT EXISTS` guards so
environments that saw an earlier local migration name can still apply
the final ordered migration safely.

## What Changed

- Added idempotent migration `0133_resource_membership_stars` for
`starred_at` columns and lookup indexes on agent/project memberships.
- Extended shared resource membership types and validators with starred
metadata and actions.
- Updated server resource membership services/routes to read and mutate
starred resource state.
- Added reusable star toggle UI and resource membership hook support for
starred state.
- Added starred projects and agents sidebar rendering, plus star
controls on list and detail pages.
- Added focused shared, server, and UI coverage for starred membership
behavior and sidebar rendering.

## Verification

- Rebased and force-with-lease pushed current PR head
`a086fc965391c9e50a51b5b83b5b44a797b2a6f4` onto current
`paperclipai/paperclip:master`; `gh pr view` reports `MERGEABLE` with no
merge conflicts. GitHub checks are green for this fresh head.
- `pnpm exec vitest run packages/shared/src/resource-memberships.test.ts
server/src/__tests__/resource-memberships-routes.test.ts
server/src/__tests__/workspace-runtime.test.ts
ui/src/components/Sidebar.test.tsx
ui/src/components/SidebarAgents.test.tsx
ui/src/components/SidebarStarredProjects.test.tsx
ui/src/components/StarToggle.test.tsx
ui/src/pages/InstanceExperimentalSettings.test.tsx` passed after the
rebase: 8 files, 143 tests.
- Greptile re-review is 5/5; the remaining screenshot thread was
resolved as non-blocking because this task explicitly requested no
screenshots/images in the PR.
- `pnpm exec vitest run
ui/src/components/SidebarStarredProjects.test.tsx` passed after the
mobile pending-spinner fix.
- `pnpm exec vitest run packages/shared/src/resource-memberships.test.ts
server/src/__tests__/resource-memberships-routes.test.ts
ui/src/components/Sidebar.test.tsx
ui/src/components/SidebarAgents.test.tsx
ui/src/components/SidebarStarredProjects.test.tsx
ui/src/components/StarToggle.test.tsx
ui/src/pages/InstanceExperimentalSettings.test.tsx` passed: 7 files, 68
tests.
- `pnpm --filter @paperclipai/db typecheck && pnpm --filter
@paperclipai/shared typecheck && pnpm --filter @paperclipai/server
typecheck && pnpm --filter @paperclipai/ui typecheck` passed
db/shared/server, then failed in pre-existing UI code outside this PR:
`src/pages/CompanyEnvironments.tsx` missing `@xterm/*` type declarations
and `previous` possibly null.
- Checked that the PR diff does not include `pnpm-lock.yaml` or
`.github/workflows` changes.
- Checked `ROADMAP.md` and found no overlapping planned core work for
starred resource/sidebar navigation.
- Searched existing GitHub PRs for duplicate starred-resource/sidebar
work and found none.

## Risks

- Migration touches membership tables. The SQL uses `IF NOT EXISTS` for
columns and indexes so environments that saw an earlier local migration
name can still apply this safely.
- Sidebar ordering and visibility changes could affect users who rely on
the previous flat sidebar layout.
- Starred state is per-user membership metadata; code paths must
continue preserving company/user scoping around memberships.

> 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, tool-enabled coding agent with shell/GitHub access.
Context window not disclosed 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-06 14:09:11 -05:00
DottaandPaperclip 518fc71cec [codex] Add work timeline page (#8938)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board UI is where operators inspect company activity, agent
work, and issue progress.
> - Existing board views show individual issue and run details, but they
do not give operators a compact time-based picture of work across
agents.
> - A work timeline helps operators scan when agents worked, how
handoffs happened, and where overlapping work occurred.
> - This pull request adds a company-scoped Work Timeline page backed by
the existing API surface and renders the timeline as a custom SVG
Gantt-style view.
> - The benefit is faster operator understanding of multi-agent
execution without opening each issue thread individually.

## Linked Issues or Issue Description

No public GitHub issue exists for this change.

Subsystem affected:
- ui/ — React + Vite board UI

Problem or motivation:
- Operators can inspect individual issues and runs, but there is no
compact time-based view of company work across agents.
- This makes it harder to scan overlaps, handoffs, retries, and activity
windows without opening many issue threads.

Proposed solution:
- Add a company-scoped Work Timeline page in the board UI.
- Render agent and system run spans as a custom SVG Gantt-style chart
with packed overlap lanes.
- Show issue color identity, kickoff attribution, hover-revealed
delegation connectors, retry styling, zoom controls, a sticky actor
gutter, and a minimap brush.
- Keep human activity lightweight by showing human kickoff chips without
plotting standalone human event rows.

Alternatives considered:
- Add the same information to existing issue-list or run-list views.
That would preserve simpler UI, but it would not show temporal overlap
or handoff paths clearly.
- Build this as a plugin-only surface. That keeps core smaller, but the
board already has the company-scoped route, navigation, and API client
patterns needed for this operator workflow.

Roadmap alignment:
- `ROADMAP.md` does not list an existing duplicate work-timeline
milestone. This supports the broader operator visibility direction
around artifacts, enforced outcomes, and higher-autonomy execution.

Additional context:
- Storybook includes `Pages/Work Timeline` stories for hour/day zoom and
a human-activity sample so reviewers can inspect the component without a
live backend.

## What Changed

- Added the Work Timeline page, route, sidebar entry, API client, query
key, and company-prefixed route helper coverage.
- Added a pure timeline layout transform for row packing, issue colors,
kickoff attribution, connector calculation, tick selection, and duration
formatting.
- Added the custom SVG timeline chart with sticky actor gutter,
hover-revealed connectors, zoom controls, minimap brushing,
visible-range feedback, and issue navigation.
- Added Storybook coverage plus sample fixtures for the work timeline.
- Added and corrected focused UI tests covering layout, chart behavior,
routing, sidebar behavior, and collapsed-sidebar expectations.
- Addressed Greptile feedback for kickoff fallback ordering, minimap
range math, document drag listener cleanup, and stable default `now`
handling.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/lib/timeline/layout.test.ts
src/components/timeline/WorkTimelineChart.test.tsx
src/pages/Timeline.test.tsx src/lib/company-routes.test.ts
src/components/Sidebar.test.tsx
src/components/RequestCollapsedSidebar.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- `git merge-tree $(git merge-base HEAD origin/master) HEAD
origin/master | rg -n "<<<<<<<|changed in both|CONFLICT"` returned no
conflicts.
- Attempted Storybook screenshot capture with Playwright; Storybook ran
locally, but Chromium could not launch in this container because native
browser libraries such as `libatk-1.0.so.0` are unavailable and `npx
playwright install-deps chromium` requires interactive sudo.

## Risks

- Medium UI risk: this adds a substantial visual surface with custom SVG
interaction logic, so browser-level review is still useful for
responsive behavior and usability.
- Low backend risk: this PR only adds a UI client/page around the
existing timeline API contract and does not change database schema or
server routes.

> 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, with repository file access, shell
command execution, GitHub connector access, and focused test execution.
Exact context-window details 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-06 07:57:23 -05:00
ad961227f5 feat(secrets): add user-specific runtime secrets (#8825)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent runs often need provider credentials, API tokens, and other
environment-bound secrets.
> - Company-level secrets work for shared credentials, but they do not
model values that should differ by human operator.
> - Without a user-scoped model, a run can dispatch without knowing
whether the responsible human has supplied the needed value.
> - Paperclip also needs run attribution to make those user-scoped
runtime checks deterministic and auditable.
> - This pull request adds user-specific secret definitions, per-user
values, environment bindings, responsible-user attribution, and runtime
resolution gates.
> - The benefit is that teams can define the secret once, let each user
provide their own value, and block runs before dispatch when required
user secrets or active definitions are unavailable.

## Linked Issues or Issue Description

Refs #224
Refs #6057

This PR implements user-specific secret support as a core
secret-management capability rather than a one-off adapter setting. It
is related to existing public work on company secrets UI and runtime
secret refs, but is distinct because the value is owned by the
responsible user and resolved at run dispatch time.

Related PR search before opening found existing secrets work such as
#1550, #8256, #8614, #8634, and #8647; none of those add the full
user-secret definition/value/runtime gate covered here.

## What Changed

- Added user-secret definitions and per-user "My secrets" values,
keeping stored values out of access metadata.
- Added `user_secret_ref` environment bindings and UI affordances to
pick them alongside existing secret refs.
- Added responsible-user runtime resolution so user-secret refs resolve
against the human responsible for the run.
- Added pre-dispatch missing-secret gates so runs fail before adapter
dispatch when required user values are absent or definitions are
inactive.
- Added low-trust allowlist hardening for user-secret runtime access.
- Added issue, routine, run, and agent API key responsible-user
attribution and fail-closed dispatch behavior when attribution cannot be
resolved.
- Added denial-copy mapping so responsible-user authorization failures
surface as actionable run outcomes instead of opaque setup failures.
- Added OpenAPI documentation for the user-secret routes.
- Rebases cleanly on current `master`; migrations were renumbered
incrementally as `0128_user_specific_secrets`,
`0129_agent_api_key_responsible_user`, and
`0130_run_responsible_user_invariant` after upstream `0126`/`0127`
migrations.
- Removed previously committed local design screenshots so the PR
contains code/docs/tests only.

## Verification

- PASS: PR head `2527febd106bcf3ca264ca0da7fca491084192d6` is based on
`paperclipai/paperclip:master`.
- PASS: `git diff --check`
- PASS: `git diff --name-only public/master...HEAD | rg
'^(pnpm-lock\\.yaml|\\.github/workflows/|screenshots/)' || true`
produced no files.
- PASS: migration journal audit confirmed unique indexes through `130`
with tail entries `0126_issue_comment_derived_attribution`,
`0127_environment_custom_images_instance_scoped`,
`0128_user_specific_secrets`, `0129_agent_api_key_responsible_user`, and
`0130_run_responsible_user_invariant`.
- PASS: `pnpm --filter @paperclipai/ui typecheck`
- PASS: `pnpm --filter @paperclipai/server typecheck`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-responsible-user-invariant.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-active-run-output-watchdog.test.ts
src/__tests__/heartbeat-stale-queue-invalidation.test.ts
src/__tests__/heartbeat-workspace-finalize-branch.test.ts
src/__tests__/issue-monitor-scheduler.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-comment-wake-batching.test.ts
src/__tests__/heartbeat-retry-scheduling.test.ts
src/__tests__/heartbeat-accepted-plan-workspace-refresh.test.ts
src/__tests__/heartbeat-plugin-environment.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/low-trust-red-team-routes.test.ts`
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/secrets-service.test.ts` (55 tests)
- PASS: `pnpm vitest run server/src/__tests__/secrets-routes.test.ts
server/src/__tests__/secrets-service.test.ts` (89 tests after final
Greptile cleanup fixes)
- PASS: `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/heartbeat-issue-liveness-escalation.test.ts` (17 tests
after the final rebase CI fix)
- PASS: focused server Vitest batches covering heartbeat recovery,
project env, plugin env, routines, low-trust, pipelines, monitors,
watchdog, and stale queue paths.
- PASS: GitHub checks are green on
`2527febd106bcf3ca264ca0da7fca491084192d6`, including Typecheck +
Release Registry, Build, General tests, serialized server suites, e2e,
Canary Dry Run, verify, security checks, and Greptile Review.
- PASS: Greptile Review completed successfully on
`2527febd106bcf3ca264ca0da7fca491084192d6` with Confidence Score 5/5,
and GraphQL review-thread audit returned zero unresolved non-outdated
threads.

## Risks

- Runtime behavior now depends on a run having a correct responsible
user; missing or incorrect responsibility assignment can block runs
before adapter dispatch.
- `user_secret_ref` bindings intentionally expose metadata without
values, but UI/API callers may need to handle the new binding kind
explicitly.
- External secret providers and IAM policies are not automatically
provisioned by this PR; operators still need to configure provider-side
access for non-local vaults.
- The PR is broad across db/shared/server/UI/runtime paths, so release
validation should include both API and UI secret workflows before merge.
- The migration renumbering is intentionally incremental after upstream
migrations; the branch migrations use guarded
column/table/index/constraint creation so users who tested the older
draft numbering should not hit duplicate DDL for the existing objects.

> 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 (`gpt-5`), Codex local adapter
with shell/tool use and code execution. Context window and internal
reasoning mode are 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>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 05:58:20 -05:00
Devin FoleyandPaperclip 85e36aaefb Show heartbeat progress in run logs (#8965)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The agent detail page is where operators inspect heartbeat runs and
watch live execution output.
> - Heartbeat runs can publish progress events while longer operations
are happening.
> - The live log viewer already appended streamed log and structured run
events, but it ignored progress events for the same run.
> - That made useful progress text invisible in the run log until
another event type arrived or the operator inspected other surfaces.
> - This pull request renders run progress events as system log lines in
the live agent run viewer.
> - The benefit is clearer live feedback during long-running heartbeat
operations without changing the backend event contract.

## Linked Issues or Issue Description

No public GitHub issue exists, so this PR describes the issue inline
following the bug report template.

### What happened

The agent detail run log subscribed to company live events and handled
`heartbeat.run.log` plus structured `heartbeat.run.event` payloads, but
it ignored `heartbeat.run.progress` events for the active run.

### Expected behavior

When a heartbeat run emits a progress message, the active run log should
show that message immediately as operator-visible system output.

### Steps to reproduce

1. Open an agent detail page for a live heartbeat run.
2. Trigger a run operation that emits `heartbeat.run.progress` events
with a `message` and optional `phase`.
3. Watch the live log viewer.

Before this change, the progress event was ignored by the log viewer.
After this change, it appears as a system log line, prefixed by
`[phase]` when a phase is present.

### Paperclip version / deployment mode

Current `master`; local development and normal board UI deployments.

### Related work search

Searched public GitHub issues and PRs in `paperclipai/paperclip` for
`heartbeat.run.progress AgentDetail` and `run progress log viewer`; no
duplicate issue or PR was found.

## What Changed

- Added live handling for `heartbeat.run.progress` events in
`AgentDetail`'s run `LogViewer`.
- Render progress messages as `system` log lines for the matching run.
- Include the optional progress phase in the displayed line as `[phase]
message`.
- Prefer the event's `updatedAt` timestamp when provided, falling back
to the live event timestamp.
- Added a replay key for progress log lines so WebSocket reconnect
replay does not duplicate the same rendered progress line.
- Added focused formatter/key tests covering phased progress, unphased
progress, empty messages, and replay-key output.

### Visual output example

The rendered log text is covered by the new formatter test:

```text
[workspace] Syncing issue history
Preparing workspace
```

No layout or styling changes are included; this PR only makes existing
log-line UI receive one more live event type.

## Verification

- `pnpm install --frozen-lockfile` — completed; emitted non-fatal
bin-link warnings for the unbuilt plugin SDK dev CLI.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- `pnpm --filter @paperclipai/ui exec vitest run
src/pages/AgentDetail.progress.test.ts
src/context/LiveUpdatesProvider.test.ts` — passed, 2 files / 26 tests.
- `git diff --check` — passed.
- Local sensitive-content scan over the PR diff using patterns for API
keys, tokens, secrets, passwords, auth headers, private keys,
localhost/private paths, internal ticket ids, agent links, and tailnet
markers — no findings.

## Risks

Low risk. This is a UI-only live-event handling change for an existing
event type. The replay guard is intentionally scoped to progress lines
and uses the rendered timestamp, stream, and chunk as the key, so
repeated progress events with distinct timestamps or messages still
appear.

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

## Model Used

OpenAI Codex, GPT-5 coding agent with repository tool use, shell
execution, GitHub CLI access, and local test execution. Context window
size was 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-04 06:33:49 -07:00
Devin FoleyandPaperclip bcac517f3b Add browser SSH terminal for custom image setup (#8911)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Environment sandboxes already support custom image creation and
refresh through a temporary SSH setup session.
> - The existing workflow makes operators copy an SSH command into an
external terminal before they can install packages or make image
changes.
> - That extra context switch is slower, easier to get wrong, and less
integrated with the setup session Paperclip already tracks.
> - This pull request adds an embedded browser SSH terminal for custom
image setup, so operators can start working in the target sandbox
directly from the environment configuration flow.
> - The implementation uses short-lived websocket attachment tokens,
session-lifetime SSH host-key pinning, and server-managed terminal
cleanup so the feature fits the existing setup-session boundary.
> - The benefit is a smoother custom image creation and refresh
experience without asking users to leave Paperclip for routine sandbox
setup work.

## Linked Issues or Issue Description

No public GitHub issue exists.

### Subsystem affected

Cross-cutting: `server/` custom image setup APIs and websocket handling,
`ui/` environment configuration UI, and shared custom image contracts.

### Problem or motivation

Custom image creation and refresh require an operator to open a separate
SSH client, paste the command shown by Paperclip, perform setup work,
then return to the browser to finish the image flow. This is functional
but awkward for a setup process that already starts and tracks a
temporary sandbox session.

### Proposed solution

Embed an SSH terminal in the custom image setup UI. When a setup session
exposes an SSH payload, Paperclip should open a browser terminal backed
by a server-side websocket session, let the operator run setup commands
in-place, and then close the terminal when setup is finished, cancelled,
expired, or disconnected.

### Alternatives considered

- Keep the existing copy/paste SSH command workflow. This remains a
fallback, but it does not streamline the common path.
- Put SSH credentials directly into websocket URLs. This was avoided so
terminal authentication can happen in an explicit first websocket auth
frame rather than in logged URLs.
- Trust the SSH host blindly for every reconnect. This PR instead pins
the observed host-key fingerprint for the setup-session lifetime.

### Roadmap alignment

This fits the roadmap theme of making agent workspaces usable in more
remote and sandboxed environments while preserving Paperclip's
control-plane model.

### Additional context

Public GitHub search did not find a duplicate issue or PR for `custom
image terminal ssh` in `paperclipai/paperclip`.

## What Changed

- Added server-side terminal session tracking for custom image setup
sessions, including connect-token issuance, websocket attachment,
expiry, resize, input, and shutdown handling.
- Added an embedded browser terminal to the custom image creation and
refresh flow when a setup session provides SSH connection details.
- Moved terminal token authentication out of the websocket URL and into
the first websocket JSON auth frame.
- Added SSH host-key SHA-256 pinning for each terminal session and
documented the provider convention for username-embedded SSH
credentials.
- Updated the custom image environment API and UI so the setup terminal
can open, reconnect, show status, authenticate, resize, and remain
active for the setup-session lifetime once attached.
- Kept custom image setup routes company-scoped and closed active
terminal sessions on setup finish/cancel.
- Added focused unit/integration/UI coverage for token expiry,
setup-session expiry, websocket close paths, host-key pinning, and
terminal session lifecycle behavior.
- Removed the generated lockfile delta from the PR; CI owns temporary
lockfile regeneration for manifest-changing PRs.

## Verification

- `pnpm exec vitest run
server/src/__tests__/server-startup-feedback-export.test.ts
server/src/__tests__/environment-custom-image-terminal-ws.test.ts
server/src/services/environment-custom-image-terminal-sessions.test.ts
server/src/__tests__/environment-custom-image-routes.test.ts
packages/shared/src/environment-custom-images.test.ts
ui/src/pages/CompanyEnvironments.test.tsx`
  - 6 test files passed
  - 58 tests passed
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm --filter @paperclipai/server build`
- `pnpm --filter @paperclipai/ui build`
- `pnpm run typecheck:build-gaps`
- `git diff --check`
- Local sensitive-content scan over the PR diff using patterns for API
keys, private keys, private hostnames, local paths, token fields, and
credential-like strings.
- Findings were limited to removed URL-token code and synthetic test
placeholders such as `ssh-token-secret` and
`terminal-token-terminal-token-123456`.
- No real credentials, private hostnames, local filesystem paths, or
instance-local links were found.
- Remote PR checks were green after the implementation commit, including
Build, Typecheck + Release Registry, General tests, serialized server
suites, e2e, verify, Socket, Snyk, Superagent, and Greptile 5/5.
- Post-merge PR hardening on July 3, 2026: merged `origin/master` at
`47448721e` into the branch, resolved the `CompanyEnvironments.tsx`
import conflict, reran focused tests, server/UI typechecks, server/UI
builds, `pnpm run typecheck:build-gaps`, and `git diff --check`, scanned
the final diff for sensitive content, pushed `4b43558cc`, and confirmed
all remote checks plus Greptile 5/5 were green.
- PR metadata correction on July 3, 2026: changed the title/body framing
from bug-fix language to feature-request language. No source files
changed for this metadata-only update.

## Risks

- Moderate surface area because this adds websocket routing,
setup-session runtime state, package dependencies, and a new custom
image UI path.
- New websocket attachments still require valid short-lived tokens;
established terminal sessions remain bounded by setup-session expiry,
explicit finish/cancel, client close, or server shutdown.
- The terminal-session store is in-memory, so active terminal websocket
tokens and host-key pins do not survive server restarts.
- SSH host-key verification uses session-lifetime TOFU pinning because
the current provider payload does not expose a trusted host-key
fingerprint.
- The external SSH command remains important as a fallback if a browser,
proxy, or network environment cannot sustain the websocket terminal.

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

## Model Used

OpenAI Codex, GPT-5 coding agent with shell/tool execution. Context
window size was 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-03 16:44:21 -07:00
b5c914126e Redesign environment variables editor (#8930)
## Thinking Path

> - Paperclip is the open source control plane people use to manage AI
agents for work.
> - Environment variables and secrets sit in the configuration surfaces
that let agents, projects, routines, and company environments run with
the right runtime inputs.
> - The previous editor was a single legacy component with cramped row
behavior, weak secret conversion affordances, and duplicated handling
across several call sites.
> - Operators need a clearer editor that handles text values, secret
references, draft rows, and sensitive-value warnings consistently
wherever environment variables are configured.
> - This pull request replaces the legacy editor with a reusable
environment variables editor and migrates the existing configuration
surfaces to it.
> - The benefit is a more reliable editing workflow with targeted test
coverage around row state, dotenv parsing, secret selection, and
affected page integrations.

## Linked Issues or Issue Description

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

### Subsystem affected

ui/ — React + Vite board UI

### Problem or motivation

Environment variables are edited in several Paperclip configuration
surfaces, including agent config, project properties, stage secrets,
routine sections, company environments, and company settings. The legacy
editor made common operator work difficult: rows could feel cramped,
secret conversion was inconsistent, draft rows and imported dotenv data
were easy to mishandle, and sensitive-value warnings did not have a
consistent place in the workflow.

### Proposed solution

Introduce a reusable environment variables editor component that
consistently supports text values, secret references, draft rows, dotenv
import parsing, sensitive-value hints, secret picking, secret creation,
and conversion to stored secrets. Migrate the existing
environment-variable call sites to the shared editor so behavior and
tests live in one component family.

### Alternatives considered

Keeping the existing `EnvVarEditor` and patching individual call sites
would preserve duplication and leave each surface responsible for its
own row and secret handling. This PR instead centralizes the behavior so
future fixes cover all migrated surfaces.

### Roadmap alignment

Checked `ROADMAP.md`; this does not duplicate a named roadmap item. It
supports the existing local-first and deployment-oriented product
direction by improving the UI where operators configure runtime
environment values.

### Additional context

The PR includes targeted tests for the editor model, dotenv parsing,
sensitive-value detection, component behavior, affected page
integrations, and Greptile review regressions around external saves and
bulk import immutability.

## What Changed

- Replaced the legacy `EnvVarEditor` with a reusable
`environment-variables-editor` component family.
- Added editor model helpers for draft rows, dotenv parsing,
sensitive-value detection, secret picking, secret creation, and
conversion to secret references.
- Migrated agent config, project properties, stage secrets, routine
editable sections, company environments, company settings, design guide
examples, and Storybook stories to the new editor.
- Added targeted tests for the editor model, parsing, sensitive-value
detection, component behavior, and affected company environment/settings
integrations.
- Fixed the company settings test harness to use the repo’s
`flushSync`-based React test helper pattern under the current React
build.
- Addressed Greptile feedback by flushing pending editor drafts before
enclosing form submits or external save-button clicks, cloning
bulk-import rows before mutation, and deferring the overflow
store-as-secret popover open path.

## Verification

- `pnpm exec vitest run
ui/src/components/environment-variables-editor/EnvironmentVariablesEditor.test.tsx
ui/src/pages/CompanyEnvironments.test.tsx
ui/src/components/AgentConfigForm.render.test.tsx` — passed, 3 files /
40 tests.
- Earlier focused Vitest coverage for model, dotenv parsing, sensitive
detection, company environments, and company settings passed, 6 files /
78 tests.
- `pnpm --filter @paperclipai/ui typecheck` — passed.
- GitHub PR checks on head `0aa49c6f8afed1f62d9e26da07fc466fbf299850` —
passed; CI checks green, security review neutral, Greptile check
success.
- Greptile review — 5/5 confidence on head
`0aa49c6f8afed1f62d9e26da07fc466fbf299850`; 0 unresolved review threads.

## Risks

- Medium UI risk: several environment-variable entry surfaces now share
the new editor, so regressions could affect multiple configuration
workflows at once.
- Secret conversion, draft-row behavior, external save flushing, and
bulk import behavior are covered by targeted tests, but reviewer
attention should still focus on manual editing flows, focus retention,
and save/cancel affordances.
- No database or API contract changes.

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

## Model Used

- OpenAI Codex, GPT-5-based coding agent with tool use and local command
execution; medium reasoning mode. Exact context-window metadata is 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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-03 11:41:45 -05:00
Devin FoleyandPaperclip c48feee190 Improve live agent feedback during sandboxed runs (#8915)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - A core part of that experience is watching active agent runs without
dropping into raw logs first
> - Local and sandbox-backed adapters already record useful run output,
progress, and tool activity
> - But active issue threads could sit visually stale while the agent
was syncing workspaces, tailing sandbox output, or emitting incremental
tool-call updates
> - Operators need timely, human-readable progress while preserving the
raw transcript underneath
> - This pull request streams sandbox run-log progress into runtime
status, keeps visible issue threads refreshed, and folds repeated ACPX
tool updates into stable transcript cards
> - The benefit is that long-running agent work becomes easier to
supervise without changing the task/comment control-plane model

## Linked Issues or Issue Description

No public GitHub issue exists for this exact change.

Problem/motivation:

- During long-running sandboxed agent work, the issue UI can appear idle
even though the agent is actively syncing, running tools, or producing
incremental output.
- Operators need realtime feedback at the issue-thread layer, not only
after opening raw logs or waiting for the final heartbeat result.
- Related public context: #1808 previously added live-run status dots to
Projects; #4362 touches heartbeat wakeup behavior but is not a duplicate
of this runtime/UI feedback change.

## What Changed

- Added sandbox run-log streaming support and defaulted sandbox-capable
local adapters into the richer live-feedback path.
- Surfaced environment/sandbox sync progress through heartbeat runtime
status with bounded, redacted snippets.
- Added live issue-thread cache patching so visible active runs update
as progress events arrive.
- Folded repeated ACPX `tool_call` updates into one transcript card
instead of stacking duplicate cards.
- Updated adapter docs and added focused regression coverage for sandbox
log streaming, runtime status, ACPX parsing, live updates, transcript
rendering, and issue chat messages.

## Verification

- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/context/LiveUpdatesProvider.test.ts`
- `pnpm exec vitest run
server/src/services/heartbeat-run-runtime-status.test.ts
server/src/__tests__/heartbeat-runtime-state.test.ts
ui/src/context/LiveUpdatesProvider.test.ts`
- `pnpm exec vitest run
packages/adapter-utils/src/execution-target-sandbox.test.ts
packages/adapter-utils/src/sandbox-managed-runtime.test.ts
server/src/services/heartbeat-run-runtime-status.test.ts
server/src/__tests__/agent-live-run-routes.test.ts
server/src/__tests__/heartbeat-runtime-state.test.ts
packages/adapters/acpx-local/src/ui/parse-stdout.test.ts
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/transcript/RunTranscriptView.test.tsx
ui/src/lib/issue-chat-messages.test.ts
ui/src/components/IssueChatThread.test.tsx`
- GitHub PR workflow on head `8397953e7b41ccd42e5d9457ee7e4dfb996e4ec5`:
`verify`, build, typecheck/release-registry, e2e, general shards,
serialized server shards, and canary dry run passed.
- Greptile Review on head `8397953e7b41ccd42e5d9457ee7e4dfb996e4ec5`:
Confidence Score 5/5, no unresolved review threads.

## Risks

- Live issue-thread cache patching could miss an edge case for a route
shape not covered by tests.
- Surfacing active-run snippets needs continued care around redaction;
this PR keeps snippets bounded and adds redaction-focused coverage.
- More frequent active-run UI refreshes could expose performance issues
on very large issue threads, though updates are scoped to visible
run/query caches.

## Model Used

OpenAI GPT-5 via Codex, operating as a tool-enabled coding agent with
shell, git, and repository-editing capabilities. Context window size is
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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-02 22:21:56 -07:00
Devin FoleyandPaperclip bf982c8c83 Normalize adapter display labels (#8913)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Adapter names are part of the board-facing agent setup and
management experience.
> - The product now treats adapters as harnesses, while execution
environments are modeled separately.
> - Several built-in adapter labels still carried legacy local wording
from the older harness-by-environment model.
> - That wording makes the UI noisier and implies a distinction users no
longer need to reason about.
> - This pull request normalizes adapter display labels while keeping
persisted adapter type identifiers unchanged.
> - The benefit is clearer adapter selection and management copy without
a database migration.

## Linked Issues or Issue Description

No public GitHub issue was found for this exact cleanup.

Related public PRs:

- Supersedes #8910, an earlier branch for the same cleanup that did not
include the later docs/gateway/Cursor alignment.
- Refs #8819, which is related display-registry work for external
multi-segment adapter labels, but not a duplicate of this built-in label
cleanup.

Feature request details:

- Subsystem affected: Cross-cutting (`ui/`, `packages/adapters`, and
docs).
- Problem or motivation: user-facing adapter names include legacy local
qualifiers even though adapters map to harnesses and environments are
first-class elsewhere.
- Proposed solution: remove the legacy local wording from built-in
display labels, keep machine-readable adapter type ids unchanged, and
keep gateway disambiguation where it is useful.
- Alternatives considered: changing persisted adapter type ids was ruled
out because it would create migration and compatibility risk; one-off UI
replacements were ruled out because the display registry is already the
correct central label boundary.
- Roadmap alignment: this is small adapter UX polish, not a new
roadmap-level core feature.

## What Changed

- Updated the adapter display registry so known adapter labels are final
and no built-in local adapter renders a legacy local suffix.
- Preserved clean derived labels for unknown plugin local types while
keeping gateway disambiguation for unknown gateway types.
- Updated `AdapterManager` to prefer registry labels when the server
reports raw adapter type ids for built-ins.
- Removed legacy local wording from built-in adapter metadata labels in
UI and adapter packages.
- Aligned Cursor adapter metadata with the central display registry
label.
- Updated adapter docs and Storybook fixtures to match the new display
names.
- Added focused registry coverage for built-in labels and unknown plugin
suffix behavior.

## Verification

- `pnpm check:tokens`
- `git diff --check origin/master...fix/adapter-display-labels`
- Patch-addition scan for added secrets, private paths, and internal
links: no matches.
- GitHub duplicate search for open adapter-label/local-suffix issues and
PRs; #8910 was identified as the older superseded public PR.
- `pnpm exec vitest run
ui/src/adapters/adapter-display-registry.test.ts`
- `pnpm --filter @paperclipai/ui typecheck`
- Stale-label scan found no remaining user-facing display-label
suffixes; remaining local wording is operational/test terminology such
as adapter ids, docs about running locally, and test descriptions.

## Risks

Low risk. The change is display-label and documentation focused, and
adapter type ids remain unchanged. The main risk is ambiguous gateway
naming, mitigated by keeping explicit gateway labels where variants need
disambiguation.

## Model Used

OpenAI GPT-5 via Codex, tool-enabled coding agent in a local repository
workspace. Context window size is not exposed by 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-02 21:32:50 -07:00
DottaandPaperclip ec92728536 [codex] remove Work Timeline page from navigation (#8882)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The app shell exposes user-visible product surfaces through routes
and the left navigation
> - The Work Timeline frontend landed on `master` in related PR #8880
before the product surface was ready for general users
> - The backend aggregation endpoint and shared DTOs can remain
available for continued iteration without exposing the page in the main
app
> - This pull request removes the visible `/timeline` route, sidebar
entry, page implementation, chart component, and Storybook fixtures
> - The benefit is that users no longer see an unfinished Work Timeline
page on `master`, while future work can continue from a preserved
branch/workspace

## Linked Issues or Issue Description

No public GitHub issue exists for this rollback request.

Bug-style description:

- **What happened:** A Work Timeline page was exposed in the app
navigation before the surface was ready for users.
- **Expected behavior:** Unready product work should not be visible from
the default app shell on `master`.
- **Steps to reproduce:** Open the app on current `master`; the sidebar
includes a `Timeline` item that routes to `/timeline`.
- **Paperclip version/commit:**
`60f7fb422394c94618b8eef27ae032702004f544`.
- **Deployment mode:** Local app / standard Paperclip app shell.
- **Related public PR:** #8880.

## What Changed

- Removed the `/timeline` route and `Timeline` page import from the app
route table.
- Removed the `Timeline` sidebar item and unused `GanttChartSquare` icon
import.
- Deleted the frontend Work Timeline API wrapper, chart component,
layout helper, page, Storybook story, and sample fixtures.
- Removed the now-unused `queryKeys.workTimeline` entry.
- Left the backend timeline endpoint and shared DTOs intact so the data
contract can continue to be developed off the preserved work.

## Verification

- `pnpm --filter @paperclipai/ui typecheck`
- Searched the frontend for stale `workTimeline`, `WorkTimeline`,
`/timeline` route/sidebar, and `GanttChartSquare` references after
deletion.

## Risks

- Low runtime risk: this removes an app route and navigation entry for
an unfinished surface.
- Deep links to `/timeline` will now fall through to the app's existing
not-found behavior.
- The backend endpoint remains available; if the intent was to remove
the API too, that should be handled in a separate, explicit PR.

## Model Used

OpenAI Codex coding agent, GPT-5-based model, with shell/tool use for
repository inspection, code editing, git, and GitHub CLI 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
- [ ] 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-02 14:52:09 -05:00
60f7fb4223 PAP-12424 Work Timeline — Phase C: frontend Gantt page (Direction C) (#8880)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Operators need to *see* how work actually flowed across their agents
over time — who was invoked, what they worked on, and how work was
delegated between them
> - The dashboard shows point-in-time state but nothing reconstructs the
temporal, cross-actor picture of heartbeat runs and delegations
> - A read-only company work-timeline endpoint was landed first (server
aggregation over runs/issues/activity); it had no frontend
> - This pull request adds the Gantt-style **Work Timeline** page that
renders that endpoint, plus the small additive server contract change it
needs (shared DTOs + a task title on each span)
> - The benefit is a single dense view — actor rows, concurrency lanes,
delegation connectors, zoom and a mini-map — that makes agent activity
legible without an N+1 fetch storm from the client

## Linked Issues or Issue Description

No public GitHub issue. Problem, in-PR:

- **Gap:** the company work-timeline aggregation endpoint has no UI.
There is no way to visually inspect how heartbeat runs unfolded over
time or how work was delegated between agents.
- **Solution:** a dashboard-adjacent Gantt-style page at
`/:companyPrefix/timeline`, linked from the sidebar's "Work" section,
rendering runs as bars on per-actor rows with delegation connectors,
kickoff chips, zoom, a lens filter, and a mini-map.
- Built with React + custom inline SVG (no chart dependency; consistent
with the existing Tailwind/Radix stack).

## What Changed

- **Frontend Gantt page** (`ui/src/pages/Timeline.tsx`,
`ui/src/components/timeline/WorkTimelineChart.tsx`): actor rows
(agents/system only — humans never get a row), overlapping runs packed
into concurrency sub-lanes, bars = heartbeat runs with a left colour tab
for issue identity, truncated task title + timing/status on hover,
click-through to the task.
- **Human activity markers & human rows** for kickoff/delegation
involving people, without giving humans their own run lane.
- **Kickoff avatar chips** at each bar's leading edge; straight
agent→agent delegation connectors (dashed for
retries/changes-requested); in-progress runs extend to a dashed "now"
line and fade out.
- **Zoom** (hour/day/week, auto-fit), full-window **mini-map** with a
draggable brush, **lens filter** (Everyone / per-user, server-side), and
colour **by task / by status**.
- **Pure layout/transform module** (`ui/src/lib/timeline/layout.ts`) —
packing, kickoff derivation, connector resolution, scales — unit-tested
in isolation.
- **Server contract (additive):** moved the `WorkTimeline*` DTOs into
`@paperclipai/shared` so the aggregation service and the UI consume one
contract; added `issueTitle` to each span so the tooltip shows the task
title with no N+1 client fetch.
- Sidebar link, query keys, API client (`ui/src/api/workTimeline.ts`),
and a Storybook story with fixtures.

## Verification

- `pnpm --filter @paperclipai/shared build` ✅
- `pnpm --filter @paperclipai/server typecheck` ✅ · `pnpm --filter
@paperclipai/ui typecheck` ✅
- `pnpm --filter @paperclipai/ui exec vitest run
src/lib/timeline/layout.test.ts
src/components/timeline/WorkTimelineChart.test.tsx` ✅ (15/15)
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/work-timeline-service.test.ts` ✅ (5/5) — the DTO move +
`issueTitle` are additive; existing service tests use `objectContaining`
and still pass.
- Rendered `WorkTimelineChart` headless against a real slice of company
activity via a Storybook story; manual browser QA of the live page
passed on the feature branch.

## Risks

- **Low risk.** The change is UI-only plus an additive server DTO
refactor (types relocated to `@paperclipai/shared`, one new optional
field). No schema/migration changes, no change to endpoint behaviour
beyond the extra `issueTitle` field. The page is behind its own route
and does not alter existing views.

## Model Used

- Claude, Opus 4.8 (`claude-opus-4-8`), via Claude Code with extended
thinking and tool use.

## Checklist

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

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 12:54:16 -05:00
Dotta 2f94a66ba1 Show live descendant status in inbox rows (#8876)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The inbox is where operators quickly scan which issues are active,
blocked, or waiting for attention
> - A blocked parent can still have active descendant work, but the
inbox previously depended on only loaded rows to infer that state
> - That made collapsed or partially loaded issue trees look more stuck
than they really were
> - This pull request carries live descendant summary data through the
issue list API and inbox UI
> - The benefit is a more accurate blocked-inbox signal, so operators
can distinguish truly stalled work from blocked parents that still have
live child activity

## Linked Issues or Issue Description

No public GitHub issue was found for this exact inbox descendant-status
polish.

Feature request fields:

**Subsystem affected**
Cross-cutting: `server/`, `packages/shared`, plugin/MCP API surfaces,
and `ui/` inbox rendering.

**Problem or motivation**
Inbox rows need to show when blocked or collapsed parents still have
live descendant work, even when the live child row is not loaded in the
current client tree. Without a server-provided descendant summary, a
parent can look stalled even though active work continues below it.

**Proposed solution**
Expose an optional live descendant count on issue list results, request
it from inbox views, and use it to render covered blocked status and
live-below indicators. Keep the field opt-in so other issue list callers
keep their existing payload shape and query cost.

**Alternatives considered**
Relying only on client-loaded subtree state was ruled out because it
misses collapsed or unloaded descendants. Always returning the count was
also avoided because most list callers do not need this extra summary.

**Roadmap alignment**
This is scoped operator-visibility polish for the existing inbox. It
does not duplicate a named `ROADMAP.md` milestone.

**Additional context**
The recursive summary query is guarded against parent cycles, and the UI
still falls back to loaded subtree live counts when server summary data
is absent or stale.

## What Changed

- Added optional `includeLiveDescendantSummary` support to issue list
contracts, SDK surfaces, MCP tools, routes, services, and tests.
- Added `liveDescendantCount` to issue list results when requested.
- Updated inbox and blocked-inbox queries to request live descendant
summaries.
- Updated inbox row status rendering so blocked parents with live
descendants show covered blocker treatment without duplicating the
live-below chip.
- Hardened live descendant summary traversal against parent cycles and
preserved the loaded-subtree fallback path for blocked inbox rows.
- Added focused tests for the API parameter, service behavior, helper
logic, cycle handling, and inbox UI query/rendering behavior.

## Verification

- `pnpm exec vitest run
server/src/__tests__/issue-list-assignee-filter-routes.test.ts
ui/src/lib/inbox-live-descendants.test.ts
ui/src/components/IssueColumns.test.tsx
ui/src/components/BlockedInboxView.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- Rebased cleanly onto current upstream `master` before pushing.
- Confirmed the branch diff does not include `pnpm-lock.yaml` or
`.github/workflows/*` changes.

## Risks

Low to moderate risk. The new descendant count is opt-in on list
requests, but it adds query work when the inbox asks for it. The
recursive traversal now tracks visited ancestors to avoid cycle
failures. The UI uses the server count as a supplement to existing
loaded-tree state, so stale or absent counts fall back to the prior
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, GPT-5 coding agent, tool-enabled with local shell and git
access. Reasoning mode and context window are managed by the
Paperclip/Codex 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-02 10:22:33 -05:00
Devin FoleyandPaperclip b4815bf964 Scope environment custom images to instance environments (#8850)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Environments are now managed as instance-level runtime resources
rather than per-company rows
> - The custom environment image setup tables were introduced with their
own `company_id` columns and route query parameters
> - That split made one saved environment image state depend on an extra
company context even though the environment itself is the durable owner
> - It also made saved-environment probes harder because applying the
active custom image template could require a company context when no
secret-backed config needed one
> - This pull request scopes custom image templates and setup sessions
directly to the saved environment
> - The benefit is that reusable environment images follow the same
instance-scoped model as environments while secret resolution still uses
company context only when secrets require it

## Linked Issues or Issue Description

No matching public GitHub issue was found.

Bug report:

### What happened?

saved environment custom-image routes and persistence required a
`companyId` even though environments are instance-scoped, and saved
sandbox probes did not opt into active custom-image template application
unless a company context was present.

### Expected behavior

custom-image templates and setup sessions should be owned by the saved
environment, and saved sandbox probes should apply the active template
while still requiring a company context only for secret-backed runtime
config.

### Steps to reproduce

1. Configure an instance-scoped sandbox environment with custom-image
setup support.
2. Start or inspect a custom-image session or template for that saved
environment.
3. Probe the saved environment without a custom-image-specific
`companyId` query parameter.

### Paperclip version or commit

current `master` after the environment custom-image template migration.

### Deployment mode

Local dev (pnpm dev) or authenticated local Paperclip instance.

### Installation method

Built from source (pnpm dev / pnpm build).

### Agent adapter(s) involved

Not adapter-specific (core bug).

### Database mode

Embedded PGlite/Postgres dev database.

### Access context

Board human operator.

### Privacy checklist

No logs, secrets, tokens, private URLs, or local machine paths are
included.

Duplicate search performed:

- `gh search prs "environment custom image companyId
repo:paperclipai/paperclip" --state open --limit 20`
- `gh search prs "custom image environment scoped
repo:paperclipai/paperclip" --state open --limit 20`
- `gh search issues "environment custom image
repo:paperclipai/paperclip" --state open --limit 20`

The returned results were unrelated adapter, Docker, auth, or
stale-workspace items.

## What Changed

- Removed redundant `company_id` columns from environment custom-image
templates and setup sessions.
- Added migration `0127_environment_custom_images_instance_scoped` to
collapse duplicate active rows per environment before dropping the old
company-scoped indexes/columns.
- Updated custom-image services, route handlers, shared validators, and
UI API/query keys to use environment-scoped custom-image state.
- Kept runtime secret resolution company-aware only when secret refs or
bindings require a company context.
- Made saved sandbox environment probes opt into active custom-image
template application.
- Updated DB, shared, server, and UI tests for the new
environment-scoped contract.

## Verification

- `pnpm --filter @paperclipai/db run check:migrations`
- `pnpm exec vitest run
packages/db/src/environment-custom-images-schema.test.ts
packages/shared/src/environment-custom-images.test.ts
server/src/__tests__/environment-custom-image-routes.test.ts
server/src/__tests__/environment-custom-images-service.test.ts
server/src/__tests__/environment-routes.test.ts
ui/src/pages/CompanyEnvironments.test.tsx`
- `pnpm -r typecheck`
- `pnpm test:run` before rebasing onto latest `master`; after the rebase
only the migration number changed, and the migration check plus focused
suite, typecheck, and build were rerun.
- `pnpm build`

## Risks

- Migration safety: the migration supersedes duplicate active templates
per environment and fails duplicate active setup sessions before adding
environment-only unique indexes. Operators with duplicate historical
active rows should review which active template is kept.
- Behavior shift: plugin custom-image setup calls now receive
`companyId: "instance"` when no secret binding determines a concrete
company context.
- Secret-backed configs still require an explicit or uniquely inferable
company context; environments with secret bindings spread across
multiple companies continue to fail fast.

> 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 via the `codex_local` adapter, GPT-5-based coding model
with tool-enabled repository inspection, editing, testing, git, and
GitHub CLI access. Exact context-window metadata was not exposed by the
runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have 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-01 23:57:31 -07:00
Evyatar Bluzer be8ae528c4 fix(a11y): add aria-pressed to date preset and day-of-week toggle buttons (#1913)
## Thinking Path

> - Paperclip orchestrates ai-agents for zero-human companies
> - But humans want to watch the agents and oversee their work
> - Human users interact with the dashboard UI to monitor costs,
schedules, and agent behavior
> - The UI has toggle button groups where you click one option and other
become unselected (like date range presets, day-of-week selectors)
> - Visually the active button look different (filled vs outlined), but
screen reader users hear no difference - all buttons sound same
> - The `aria-pressed` attribute is what screen readers need to announce
which toggle is active and which is not
> - I searched entire UI codebase for `aria-pressed` and found zero
usage anywhere
> - This pull request adds `aria-pressed={isActive}` to two toggle
button groups: date range presets in Costs page and day-of-week selector
in ScheduleEditor
> - Now screen reader users can tell which button is currently selected
without relying on visual styling only

## Problem

The app has button groups that work like toggles - you click one button
to select it and the others become unselected. Visually this work fine
because the active button change to a different variant (filled vs
outlined). But for screen reader users, ALL buttons sound exactly the
same - just "button, 7 days", "button, 30 days", etc with no way to tell
which one is currently active.

I searched the entire UI codebase for `aria-pressed` and found zero
results. This attribute is what screen readers need to announce "7 days,
pressed" vs "30 days, not pressed" for toggle button groups.

## What I changed

Added `aria-pressed={isActive}` to two toggle button groups:

1. **Costs.tsx** - Date range preset buttons (7d, 30d, 90d, Custom).
Screen reader now announce which date range is selected.

2. **ScheduleEditor.tsx** - Day of week selector (Mon, Tue, Wed...).
Screen reader now announce which day is selected for weekly schedule.

## How to test

1. Go to Costs page, use VoiceOver (Cmd+F5 on Mac)
2. Tab through the date preset buttons
3. Active button should announce "pressed", others "not pressed"
4. Same for ScheduleEditor - create/edit trigger with weekly preset, tab
through day buttons

2 files, 2 lines added.
2026-07-01 15:14:57 -05:00
a8f0ebaa80 Refresh run config before reusing workspaces (#8797)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent runs are assembled by the heartbeat service from agent config,
project workspaces, environment config, secret bindings, skills, and
runtime session state.
> - The heartbeat service intentionally reuses adapter sessions,
execution workspaces, and sandbox leases when that preserves useful
state.
> - Reuse becomes incorrect when the effective next-run config changes
after a saved session, workspace, or lease was created.
> - Stale reuse can make a later run appear pinned to old agent,
environment, secret, instruction, or workspace settings.
> - This pull request records non-sensitive fingerprints for the
effective session, workspace, and lease config at run boundaries.
> - When those fingerprints drift, Paperclip refreshes persisted runtime
config or starts fresh execution instead of reusing stale state.
> - The benefit is predictable next-run config freshness without storing
raw secret values, full env maps, provider credentials, or private path
details.

## Linked Issues or Issue Description

- Refs #8058
- Related PRs checked during dedup search: #4968, #4155, #84, #8480.
These cover nearby workspace/session routing or model-config freshness
areas, but do not duplicate this effective run config fingerprinting
path.

## What Changed

- Added effective run config fingerprinting for session, workspace, and
lease reuse decisions, with canonicalization that ignores generated
runtime noise and redacts sensitive values.
- Updated heartbeat reuse logic to compare stored and next-run
fingerprints, reset stale saved sessions, refresh persisted workspace
config snapshots, replace stale reused workspaces when required, and
avoid stale sandbox lease reuse.
- Included plain environment value drift via value hashes, without
storing the raw env values.
- Root-bound instruction content hashing so legacy direct absolute
instruction paths are represented but not read for config fingerprints.
- Batched secret/version metadata lookups for environment lease
fingerprinting.
- Added workspace operation/run result freshness metadata so operators
can inspect non-sensitive decision categories.
- Surfaced config freshness labels and next-run copy in the UI and docs.
- Added focused coverage for fingerprint redaction, session reset
decisions, workspace refresh/replace behavior, environment lease drift,
and persisted workspace restoration.

## Verification

- `git diff --check`
- Sensitive-data scan before push:
- `git diff --unified=0 origin/master...HEAD | rg -n --pcre2
"(AWS_ACCESS_KEY_ID|AWS_SECRET_ACCESS_KEY|ghp_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|sk-[A-Za-z0-9]{20,}|-----BEGIN
(RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----|AKIA[0-9A-Z]{16})"`
- `git diff --unified=0 origin/master...HEAD | rg -n --pcre2
"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"`
- `pnpm exec vitest run
server/src/__tests__/effective-run-config-fingerprints.test.ts
server/src/__tests__/heartbeat-workspace-session.test.ts
server/src/__tests__/environment-runtime.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm -r typecheck`
- `pnpm --filter @paperclipai/db clean`
- `pnpm test:run`
- `pnpm build`
- UI screenshots from Cutter:
-
https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-01.png
-
https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-02.png
-
https://artifacts.cutter.sh/8797/run-2f4827c-2026-06-30T18-57-25/preview/change-03.png

## Risks

- Medium: overly broad fingerprints could start fresh sessions,
workspaces, or sandbox leases more often than necessary.
- Medium: missing a config category would allow stale reuse to persist
for that category.
- Medium: legacy direct absolute instruction paths are no longer
content-hashed unless they are paired with an absolute managed
instructions root.
- Low data risk: fingerprint metadata stores hashes and category names,
not raw secrets, raw env values, provider credentials, or private path
details.

> 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 CLI / Codex coding agent, tool-enabled with
shell, Git, GitHub CLI, local test execution, and code editing. The
exact deployed model variant and context window are not exposed by 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>
Co-authored-by: Cody <cody@paperclip.ing>
2026-06-30 14:50:25 -07:00
Devin FoleyandPaperclip 8d9f9fd240 Add reusable sandbox custom images (#8794)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A growing part of that work runs in sandboxed environments rather
than on the operator's local machine.
> - Today sandbox providers can start fresh workspaces and run probes,
but they do not have a shared contract for capturing and reusing
prepared sandbox state.
> - Operators need a way to set up tools, credentials, and project
dependencies once, then reuse that prepared image for later agent runs.
> - This pull request adds reusable sandbox custom images across the
provider contract, server runtime, and board UI.
> - It also keeps probes and sandbox copy flows aligned with
pre-authenticated/custom-image environments.
> - The benefit is faster, more reliable sandbox runs without repeatedly
rebuilding the same environment setup.

## Linked Issues or Issue Description

No public GitHub issue was found for this change. Inline feature request
follows.

### Problem or motivation

Sandboxed agents need reusable prepared runtime state so repeated runs
do not require manual setup every time. Operators often need system
packages, CLIs, SDKs, dependency caches, credentials, and project
tooling available before an agent can work productively.

### Proposed solution

Add a provider-level custom-image capability, server-side setup/capture
lifecycle, Daytona/fake provider support, and board UI controls for
creating, testing, selecting, and deleting custom images.

### Alternatives considered

Leaving this as provider-specific setup outside Paperclip would keep the
control plane blind to image state and would not give agents consistent
environment metadata. Re-running setup commands for every lease is
simpler, but slower and less reliable for interactive or credentialed
setup.

### Roadmap alignment

Checked `ROADMAP.md`; this aligns with the Cloud / Sandbox agents
roadmap area and does not duplicate any related public issue or PR found
by search.

Additional context:
- Subsystem affected: cross-cutting (`packages/db`, `packages/shared`,
`packages/plugins`, `server`, `ui`).
- Duplicate search: searched GitHub for `sandbox custom image` and
`sandbox template environment`; no related public issues or PRs were
found.

## What Changed

- Added custom-image shared types, validators, constants, API paths, and
database schema/migration.
- Added server services/routes for custom-image templates and setup
sessions, including runtime cleanup and provider metadata handling.
- Extended plugin/sandbox provider capabilities for interactive setup,
template capture, and template deletion.
- Implemented custom-image support in the fake sandbox provider and
Daytona provider.
- Updated environment runtime/config handling so active custom images
flow into leases, probes, and agent execution.
- Added board UI controls and API client support for custom-image setup,
capture, selection, status, and error states.
- Hardened sandbox copy/probe behavior for insecure clipboard contexts
and pre-authenticated sandbox images.
- Added targeted coverage across shared validators, DB schema, server
routes/services, provider plugins, adapter probes, and UI flows.

## Verification

- `pnpm install --frozen-lockfile --ignore-scripts`
- `pnpm vitest run
packages/adapters/claude-local/src/server/test.probe.test.ts
packages/adapters/claude-local/src/server/test.ts
packages/adapters/codex-local/src/server/test.remote.test.ts
packages/adapters/codex-local/src/server/test.ts`
- `pnpm --filter @paperclipai/adapter-claude-local typecheck`
- `pnpm --filter @paperclipai/adapter-codex-local typecheck`
- `pnpm vitest run
packages/db/src/environment-custom-images-schema.test.ts
packages/shared/src/environment-custom-images.test.ts
packages/shared/src/validators/plugin.test.ts
server/src/__tests__/environment-custom-images-service.test.ts
server/src/__tests__/workspace-runtime.test.ts
packages/plugins/sandbox-providers/daytona/src/plugin.test.ts
ui/src/pages/CompanyEnvironments.test.tsx
ui/src/pages/CompanySettings.test.tsx`
- `pnpm -r typecheck`
- `pnpm build`
- `rm -rf packages/db/dist && pnpm test:run`
- Public-safety scan of the final diff found no internal Paperclip issue
links, private instance URLs, or real secret patterns.

## Risks

- Adds a database migration and new environment runtime tables, so
migration ordering and rollback need care.
- Provider implementations may differ in how reliably they can
capture/delete images; unsupported providers surface capability-gated UI
states.
- Custom-image state can contain operator-prepared tooling and
credentials inside the provider image, so providers must enforce their
own access controls and cleanup semantics.
- Broad surface area across shared contracts, server runtime, plugins,
adapters, and UI means CI and Greptile review should be watched closely.

> 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 (`gpt-5`) via Codex CLI with tool use and code execution.
Assisted with branch cleanup, conflict resolution, local verification,
and PR preparation. Earlier branch implementation work was assisted by
Paperclip-managed Claude/Codex agents.

## 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-06-30 09:57:49 -07:00
Dotta b4fccaa8c4 [codex] Unify issue media attachment gallery (#8785)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Issue detail pages and run output cards both render user-facing
attachment previews
> - Media attachments were handled through separate gallery entry
points, so attachments from issue comments and issue output did not
share one consistent viewing path
> - A shared gallery path makes image browsing more predictable across
the issue surface
> - This pull request unifies the issue media attachment gallery
behavior across attachments, output cards, and issue detail rendering
> - The benefit is a more consistent image preview experience with
focused regression coverage around the affected UI paths

## Linked Issues or Issue Description

Refs #8788

This PR fixes inconsistent issue media preview behavior across
attachment and output surfaces.

## What Changed

- Unified issue media attachment gallery behavior across issue
attachments, issue output, output primary cards, and issue detail
rendering.
- Added image gallery modal coverage and regression tests for
attachments, output image handling, keyboard navigation, and issue
detail interactions.
- Preserved the primary video output Open action while still allowing
gallery browsing when a gallery handler is available.
- Updated issue attachment and issue output helper logic to preserve
shared image gallery metadata.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/ImageGalleryModal.test.tsx
src/components/issue-output/IssueOutputSection.test.tsx
src/components/IssueAttachmentsSection.test.tsx
src/pages/IssueDetail.test.tsx`
- Result: 4 files passed, 47 tests passed.

## Risks

Low to medium risk. The change is UI-scoped but touches shared issue
attachment/output rendering paths, so regressions would most likely
appear as image/video preview ordering, missing gallery entries, or
incorrect non-image attachment 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, GPT-5 coding agent session with shell and git/GitHub CLI
tool use. Exact serving revision 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
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-06-30 07:53:40 -07:00
DottaandPaperclip 3e31bf09bc [codex] Add pipeline automation title templates (#8787)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Pipeline automations let operators standardize repeated issue and
workflow actions.
> - Pipeline-created issues currently need a way to derive useful titles
from routine variables.
> - Without a configurable title template, automated pipeline output is
harder to scan and distinguish.
> - This pull request adds a title-template field through shared
contracts, server persistence, API routes, and the pipeline settings UI.
> - The benefit is clearer issue titles for pipeline-created work while
preserving the existing pipeline behavior when no template is
configured.

## Linked Issues or Issue Description

Refs #8790

This PR adds configurable generated-issue title templates for pipeline
automations.

## What Changed

- Added `issueTitleTemplate` to the shared pipeline automation contract
and field constants.
- Persisted and returned the title template through pipeline service and
route code.
- Applied title-template rendering when pipeline automations create
issue work.
- Added pipeline settings UI controls for editing the title template and
reusing routine variables.
- Moved title-token cursor restoration out of the React state updater
and into a layout effect.
- Added server and UI coverage for storing, returning, and rendering
pipeline title templates.

## Verification

- `NODE_ENV=test pnpm run preflight:workspace-links && NODE_ENV=test
pnpm exec vitest run server/src/__tests__/pipelines-service.test.ts
server/src/__tests__/pipelines-routes.test.ts
ui/src/pages/PipelineSettings.test.ts`
- Result before review follow-up: 3 files passed, 58 tests passed.
- `pnpm --filter @paperclipai/ui exec vitest run
src/pages/PipelineSettings.test.ts`
- Result after review follow-up: 1 file passed, 7 tests passed.
- Branch was merged with current `paperclipai:master` at `f019f54bb3`
before opening this PR.
- Searched existing PRs for the same head branch and for pipeline
title-template duplicates; no matching existing PR was found.
- Note: GitHub could not open a PR directly from `cryppadotta/paperclip`
because that repository is not a fork of `paperclipai/paperclip`. The
same updated branch SHA was pushed to `paperclipai/paperclip` so this PR
can compare normally against `master`.

## Risks

Low to moderate risk. The change touches pipeline automation persistence
and generated issue creation, so regressions would most likely appear as
missing or incorrectly rendered generated issue titles. Existing
behavior should remain unchanged when `issueTitleTemplate` is unset.

## Model Used

OpenAI Codex, GPT-5-based coding agent, tool-enabled execution in a
Paperclip heartbeat, with repository inspection, Git, GitHub CLI, and
local 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-06-30 07:52:40 -07:00
DottaandClaude Opus 4.8 f3f50e2ecd [codex] Preselect vault when importing secrets (#8614)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operator secrets and provider vaults let a company connect external
secret stores without copying every value manually.
> - The existing AWS Secrets Manager import dialog already supports
importing remote secrets from any eligible vault.
> - From the Provider vaults tab, operators can see a specific vault
row, but there was no row-level import action that preserved that vault
context.
> - That meant importing from a specific vault required opening the
generic import dialog and reselecting the intended provider config.
> - This pull request adds a row-level refresh/import action that opens
the import dialog with the selected vault preselected.
> - The benefit is a tighter, less error-prone flow when a company has
multiple AWS provider vaults configured.

## Linked Issues or Issue Description

No public issue exists for this small UI follow-up.

Problem description:
- Users with multiple AWS Secrets Manager provider vaults need to
refresh/import secrets from the vault they are currently looking at.
- The existing import dialog defaulted to the configured default vault
or first eligible vault, even when the operator initiated the flow from
a specific provider-vault row.
- This creates extra selection work and makes it easier to import from
the wrong vault.

Related public PRs: Refs #5429, #8586.

## What Changed

- Added a Provider vaults row action for AWS Secrets Manager configs to
refresh/import existing remote secrets.
- Threaded an optional initial provider config id into
`ImportFromVaultDialog` so the selected vault is preselected when
eligible.
- Reset the initial vault selection when the dialog closes or routes to
vault management.
- Added render coverage proving the row action opens the import dialog
and previews against the selected vault id.

## Verification

- `pnpm exec vitest run ui/src/pages/Secrets.render.test.tsx` passed: 1
file, 9 tests.
- `pnpm --filter @paperclipai/ui typecheck` passed.

## Risks

Low risk. This is UI-only behavior scoped to AWS Secrets Manager
provider-vault rows and the existing import dialog. The main risk is
that future provider types may need their own row-level import labels or
eligibility rules instead of sharing this AWS-specific action.

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

## Model Used

OpenAI GPT-5 Codex via Paperclip/Codex local agent, with repository file
access, shell command execution, GitHub CLI, and TypeScript/Vitest
verification. Exact context-window metadata was not surfaced 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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:44:52 -05:00
Devin FoleyandPaperclip 500a75f7ce Show agent environment metadata (#8671)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Agents page is where operators scan the current agent roster,
runtime status, model, adapter, and last heartbeat.
> - Environment selection now affects where agents execute, but the
roster did not expose each agent's effective execution environment.
> - Operators need that context when multiple environments are
configured, especially when sandbox-backed environments use different
providers.
> - This pull request adds environment/provider metadata to the Agents
page while keeping it hidden when the column would not add useful
information.
> - The benefit is better operational visibility without adding noise
for single-environment or environment-disabled instances.

## Linked Issues or Issue Description

No matching public GitHub issue was found after searching for related
Agents environment-column issues and PRs.

## Problem or motivation

Operators use the Agents page to scan active agents, but when multiple
execution environments are configured there was no row-level indication
of which environment each agent uses. That makes it harder to
distinguish host-local agents from sandbox-backed agents and to see the
sandbox provider at a glance.

## Proposed solution

Show each agent's effective environment in the Agents page metadata when
environments are enabled and multiple environments are configured.
Resolve the value from the agent override, instance default, or local
fallback, and include sandbox provider display names when available.

## Alternatives considered

Always showing the column would add noise for single-environment
instances. Adding filters and grouping was also considered, but this PR
keeps the scope to read-only metadata until the product has more usage
data.

## Roadmap alignment

This is a small UI visibility improvement related to the roadmap's
cloud/sandbox agents direction, without adding a new core workflow or
adapter capability.

## Additional context

The column is hidden when the experimental environments setting is
disabled or when only one environment is configured.

## What Changed

- Added environment metadata loading to the Agents page, including
environment list, capabilities, and instance settings.
- Resolved each agent's effective environment from the agent override,
instance default, or local fallback.
- Rendered environment name and sandbox provider detail in list and org
views when environments are enabled and multiple environments are
configured.
- Hid the environment column when environments are disabled or only one
environment is configured.
- Added focused UI tests for display, fallback, loading, hidden-column,
disabled-feature, and no filter/grouping behavior.
- Addressed Greptile review feedback by preserving custom local
environment names, reserving the column while environment data loads,
and separating the capabilities query key.

## Verification

- `pnpm install --frozen-lockfile`
- `pnpm --filter @paperclipai/ui exec vitest run
src/pages/Agents.test.tsx` — 11 tests passed
- `pnpm --filter @paperclipai/ui build`
- Local PR-diff scan for secrets/private references before push
- GitHub PR workflow passed on head `bb770acc3`
- Commitperclip review check passed
- Greptile Review passed with confidence score 5/5 and no inline review
comments

## Risks

Low risk. The change is limited to the Agents page, query keys, and
tests. The main behavioral risk is extra metadata query traffic on the
Agents page when environments are enabled; those queries are skipped
when the experimental environments flag is disabled.

## Model Used

OpenAI Codex, GPT-5 coding agent with shell/tool use and code 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: Paperclip <noreply@paperclip.ing>
2026-06-26 15:31:42 -07:00
Devin Foley 765a75207a Add experimental server info debug view (#8676)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The dev/server UI exposes a `/api/health` endpoint and a lower-left
account drawer, but nothing surfaces *which* build the running instance
is on or when it last restarted
> - When iterating on a local dev instance it is hard to tell whether
the server you're looking at has actually restarted onto your latest
commit, or how stale the running process is
> - Developers need a lightweight, opt-in way to confirm the running
instance's identity without digging through logs or shelling into the
host
> - This pull request adds an experimental "Server Info Debug View"
setting that surfaces the running instance's last-restart time and
current commit as read-only rows in the account drawer
> - The benefit is a quick, in-UI sanity check of what the live server
is actually running, behind an experimental flag so it ships zero cost
to users who don't opt in

## Linked Issues or Issue Description

No public GitHub issue exists. Describing the underlying request inline
following the feature request template:

**Problem or motivation:**

When working against a local Paperclip dev instance there is no in-UI
way to confirm what the running server is — its current commit or when
it last restarted. You have to check logs or the host shell to know
whether the process picked up your latest build.

**Proposed solution:**

An opt-in experimental setting ("Server Info Debug View") that, once
enabled, renders a small read-only "Server" section at the bottom of the
lower-left account drawer showing **Last restarted** (the server process
start time) and **Running commit** (the current git HEAD short SHA +
subject).

**Alternatives considered:**

A separate top-right pill/overlay (like the work-life-balance plugin).
The account drawer was chosen to reuse existing menu-row styling and
avoid adding new always-present chrome.

**Roadmap alignment:**

Small, self-contained developer-experience aid gated behind an
experimental flag; does not overlap planned core roadmap work.

## What Changed

- Added `server/src/server-info.ts`: captures a `serverInfo` snapshot
once at boot — process start time and current git commit (SHA +
subject). Git is read via `execFileSync` with SHA validation and a
timeout.
- `/api/health` exposes the `serverInfo` snapshot, but only on
full-details health responses (board/agent in authenticated mode, or
local-trusted dev).
- Gated the UI surface behind a new `enableServerInfoDebugView`
experimental setting, wired through the shared instance type, validator,
settings normalizer, and OpenAPI schema.
- UI: added `SidebarServerInfo` rendering the read-only rows in the
account drawer (`BreadcrumbBar` / `SidebarAccountMenu`), plus the
experimental settings toggle and a typed `health` API client.
- Moved `ServerGitInfo` / `ServerInfoSnapshot` into
`@paperclipai/shared` so the server and UI share one definition instead
of duplicating it.
- Added unit tests for the server-info snapshot, health route exposure,
validator/normalizer, settings routes, the experimental settings page,
and the sidebar component.

## Verification

- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/health.test.ts src/__tests__/server-info.test.ts
src/__tests__/instance-settings-service.test.ts
src/__tests__/instance-settings-routes.test.ts` — 32 passed
- `pnpm --filter @paperclipai/ui exec vitest run
src/components/SidebarServerInfo.test.tsx
src/pages/InstanceExperimentalSettings.test.tsx` — 9 passed
- `tsc --noEmit` on both `@paperclipai/server` and `@paperclipai/ui` —
clean
- Manual: enable **Settings → Experimental → Server Info Debug View**,
refresh the UI, open the lower-left account drawer — a "Server" section
shows Last restarted and Running commit.

## Risks

- Low risk. The UI surface is fully opt-in via an experimental flag and
defaults off.
- The `serverInfo` field on `/api/health` is access-controlled to
full-details responses only (board/agent in authenticated mode, or
local-trusted dev) — never anonymous authenticated callers — so the git
SHA is not broadly exposed.
- The only new server work is a one-time git read at boot, guarded with
SHA validation and a timeout; failures degrade gracefully (the git block
reports `available: false` rather than throwing).

## Model Used

Claude — `claude-opus-4` (Anthropic), extended thinking with tool use,
via Claude Code.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no
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-06-26 14:47:01 -07:00
DottaandPaperclip 574543d7d3 Sort workspace routines by name (#8666)
Reviewed by CTO for PAP-12039. Client-side ordering change only, with focused helper coverage; CI, security scans, and Greptile are green.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-26 13:46:14 -05:00
DottaandPaperclip 43b005b704 Add pipeline workflow primitives and operator UI (#7903)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The pipeline subsystem models repeatable work as items moving
through stages, with agent automation, review gates, blockers, drift
notices, and linked work.
> - Operators need this to be usable as one coherent workflow surface,
not just as backend primitives or disconnected route experiments.
> - The branch now carries the pipeline data model, service/routes,
CLI/tutorial path, aggregation feeds, operator UI, stage automation
controls, liveness/retry handling, and follow-up polish that make the
primitive reviewable end to end.
> - This pull request is the single review target for that pipeline
workflow primitive stack.
> - The benefit is that reviewers can evaluate the full operator
experience and server contract together against `master`.

## Linked Issues or Issue Description

No public GitHub issue exists for this work. The underlying feature
request is described inline.

### Problem or motivation

Paperclip needs a first-class way to model multi-stage agent/company
workflows where upstream items can spawn downstream work, request
review, carry fields across pipelines, surface drift, retry automation,
and show operators where work is blocked or active. Without a unified
pipeline primitive, these workflows spread across ad hoc issues,
routines, and comments, making the state hard to inspect or operate.

### Proposed solution

Add the pipeline workflow primitive stack: database schema and
migrations, shared validators/types, server services and REST routes,
aggregation and liveness helpers, CLI/tutorial smoke support, and the
React operator UI for pipeline lists, boards, item detail,
review/learnings views, settings, stage automation, secrets, carry-over
fields, and retry/recovery flows.

### Alternatives considered

- Keep workflows as loosely linked issues and routines: rejected because
operators need a single board/detail/settings surface for repeated
workflow patterns.
- Ship backend primitives first and defer UI: rejected for this branch
because the operator experience is the main way to validate the
primitive.
- Add a narrower one-off content workflow: rejected because the same
primitives are useful across future company processes.

## What Changed

- Added and evolved pipeline schema, migrations, shared contracts,
server services, REST routes, route tests, and CLI/tutorial smoke
support.
- Added pipeline aggregation, health/liveness, drift acknowledgment,
blocker/carry-over, automation retry, stage automation environment, and
permission recovery behavior.
- Added the operator UI for pipeline index/board/item
detail/settings/review/learnings flows, including stage secrets,
automation controls, markdown/item descriptions, linked issue assets,
liveness banners, and source automation metadata.
- Refactored issue document frame rendering through the shared
`DocumentFrameHeader` component to keep document controls consistent
with the pipeline document surfaces.
- Kept this PR as the single base-branch review target for the current
pipeline branch.

## Verification

Current branch refresh:

- `pnpm vitest run server/src/__tests__/pipelines-service.test.ts` — 31
passed
- `pnpm vitest run server/src/__tests__/pipelines-routes.test.ts` — 19
passed
- `pnpm --filter ./server typecheck` — passed
- `pnpm --filter ./ui typecheck` — passed
- Verified Pipelines remains gated by `enablePipelines === true`:
sidebar item is hidden unless the flag is enabled, direct pipeline
routes redirect to `/dashboard` when disabled, and the Experimental
settings UI still has no Pipelines toggle.
- GitHub status checks on `df071c710646de625131064c3fb6588b5e97964a` —
all complete with no failing conclusions, including Actions, Socket,
Superagent/Security, and Greptile Review
- Greptile summary on `df071c710646de625131064c3fb6588b5e97964a` —
Confidence Score 5/5
- GitHub review-thread sweep — 0 unresolved Greptile threads

Previously recorded during branch development:

- Server pipeline service/route and aggregation tests
- Shared validator tests
- UI pipeline page/settings/item-detail/learnings/liveness tests
- Pipeline tutorial smoke path

## Risks

- High review surface: this is a large feature branch spanning database,
shared contracts, server behavior, CLI/docs, and UI.
- Migration ordering and schema compatibility need reviewer attention
because this branch has been kept current across multiple `master`
syncs.
- GitHub still reports merge state `BLOCKED` because the PR is awaiting
normal human review/branch-protection completion; all current status
checks are green.
- Branch-name checklist exception: this PR uses the pre-existing
requested branch name, which predates the current public-branch naming
rule. The PR title/body avoid internal issue references.

> 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 repository tool use,
shell execution, git/GitHub CLI operations, and local verification
commands. Earlier commits in this branch were assisted by Paperclip
agents and other AI coding agents as recorded in commit authorship.

## 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-06-26 12:02:44 -05:00
DottaandPaperclip c79d347abe Update company creation copy (#8653)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The onboarding and company switcher UI are the first places users
create or select an organization
> - Some of that surface still used older team/workspace wording even
though the product model is company-centric
> - Mixed wording makes the setup path feel inconsistent and can make
users wonder whether they are creating a team, workspace, or company
> - This pull request updates the affected UI copy to consistently say
company
> - The benefit is a clearer first-run and navigation experience without
changing behavior

## Linked Issues or Issue Description

No public issue exists for this small UI polish change.

### Problem or motivation

The company creation and switcher surfaces used mixed
team/workspace/company wording for the same concept, which makes the
setup path feel inconsistent.

### Proposed solution

Update the visible copy, accessibility label, inline comment, e2e
expectations, and matching test expectations to use company-centric
language consistently.

### Alternatives considered

Leave the existing wording alone, but that preserves inconsistent
terminology in a high-traffic setup path.

### Roadmap alignment

This is focused UI polish and does not overlap with a roadmap-level core
feature.

### Additional context

The create action keeps its trailing ellipsis because it opens the
onboarding wizard rather than completing immediately.

## What Changed

- Updated front door and onboarding wizard labels from team-oriented
copy to company-oriented copy.
- Updated the sidebar company menu from workspace/team wording to
company wording, including the trigger accessibility label and empty
fallback text.
- Kept the sidebar create action ellipsis for the dialog/wizard
affordance.
- Updated component and Playwright test expectations for the new copy.

## Verification

- `pnpm exec vitest run ui/src/components/SidebarCompanyMenu.test.tsx`
- Attempted `npx playwright test --config tests/e2e/playwright.config.ts
tests/e2e/onboarding.spec.ts tests/e2e/nux-phase4-screenshots.spec.ts
tests/e2e/planning-mode-visual-verification.spec.ts
tests/e2e/conference-room-typing-intro.spec.ts`; local browser launch is
blocked by missing host Chromium dependencies (`libatk1.0-0t64`,
`libatspi2.0-0t64`, `libxcomposite1`, `libxdamage1`, `libxfixes3`,
`libxrandr2`, `libgbm1`, `libasound2t64`).
- Screenshots intentionally omitted because this is a copy-only change
and no design screenshots are needed for review.

## Risks

Low risk. This is copy-only UI polish plus matching test updates; no
data model, API, migration, workflow, lockfile, or behavior changes are
included.

## Model Used

OpenAI GPT-5 Codex (`gpt-5`) via the Paperclip Codex agent, with
tool-assisted repository inspection, GitHub CLI usage, 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-26 12:01:02 -05:00
DottaandPaperclip 8e21e31a1a Fix UI detail regressions (#8613)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board UI needs to render issue details, comments, properties,
and rich external object labels clearly during normal operator
workflows.
> - Three small UI regressions made those workflows harder to scan: rich
object URLs could show weak labels, interrupting comments could briefly
flash in the wrong state, and watchdog labels could overflow the
properties panel.
> - These are related quality fixes in the same UI surface, with focused
regression coverage for each behavior.
> - This pull request groups the fixes so they go through normal review
instead of bypassing CI.
> - The benefit is a quieter, more predictable issue detail experience
for board operators.

## Linked Issues or Issue Description

No public GitHub issue was found for these regressions after searching
related PRs and issues.

### Pre-submission checklist

- Existing open and closed GitHub issues and PRs were searched for
duplicates.
- The fixes are based on current `master` behavior.
- The regressions originate in Paperclip board UI code, not an adapter,
API provider, or local configuration.

### What happened?

In the board UI, three issue-detail regressions made normal review
workflows harder to scan:

- URL-rich external objects could fall back to a weak generic label
instead of showing a useful URL label.
- An interrupting issue comment could briefly flash through the wrong
state while issue run data refreshed.
- Long watchdog property instructions could truncate or overflow instead
of wrapping inside the properties panel.

### Expected behavior

- URL-rich external objects should surface a clear URL label.
- Interrupting comments should stay visually stable while live run state
refreshes.
- Long watchdog property values should wrap within the available
properties panel width.

### Steps to reproduce

1. Open an issue detail view that includes URL-rich external object
metadata, an interrupting run/comment state, or long watchdog
instructions.
2. Observe the rendered issue detail thread and properties panel.
3. Compare the rendered label, comment state, and watchdog row wrapping
against the expected stable/readable behavior above.

### Paperclip version or commit

Current `master`, fixed by this PR branch at
`1c763001c9a16fa6cf3faad6f58a83c4b202c928`.

### Deployment mode

Local dev (`pnpm dev`) / board UI.

### Installation method

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

### Agent adapter(s) involved

Not adapter-specific (core board UI bug).

### Database mode

Not database-related.

### Access context

Board operator UI.

### Relevant logs or output

Not applicable.

### Relevant config

Not applicable.

### Additional context

The PR includes focused regression tests for all three behaviors.
Browser-visible before/after evidence for the watchdog wrapping change
was posted in
https://github.com/paperclipai/paperclip/pull/8613#issuecomment-4794863305.

### Privacy checklist

- All pasted output was reviewed for sensitive data; this PR body
contains no private config, logs, or internal instance links.

## What Changed

- Prefer direct URLs as rich object labels when rendering external
object metadata.
- Keep interrupting issue comments from flashing through the wrong
thread state while issue chat data is refreshing.
- Allow watchdog property labels to wrap cleanly inside the issue
properties panel.
- Added focused regression coverage for the external object helper,
issue detail interrupt behavior, and watchdog property wrapping.

## Verification

- `pnpm exec vitest run ui/src/lib/external-objects.test.ts
ui/src/lib/issue-chat-messages.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/pages/IssueDetail.test.tsx`

## Risks

Low risk. The changes are scoped to UI rendering/state handling and add
regression coverage for the touched behavior. No database, API,
workflow, lockfile, or migration changes are included.

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

## Model Used

OpenAI Codex using GPT-5 (`gpt-5`) with repository shell/tool access.
The changes were prepared by an AI coding agent with local command
execution for git inspection and focused Vitest verification.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-25 21:55:03 -05:00
DottaandPaperclip 569b7affc4 [codex] Add bounded workspace overview (#8627)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The execution workspace subsystem powers project and workspace views
by listing runtime state, branch metadata, issue links, and status
summaries.
> - The existing workspace views relied on broad list data that can grow
expensive as a company accumulates many workspaces and linked issues.
> - That makes the Workspaces page and project workspace cards slower
than necessary because the UI does not always need the full workspace
detail payload up front.
> - This pull request adds a bounded overview contract for workspace
listings and moves the relevant UI surfaces to that cheaper path.
> - The benefit is faster workspace loading while preserving detail
fetches for pages that actually need full workspace data.

## Linked Issues or Issue Description

No public GitHub issue exists for this change. Inline bug report follows
the repository bug template.

### What happened?

Workspace index-style screens can load too much execution workspace
detail before the user asks for it. Several UI surfaces used fuller
workspace data paths for summary displays, which can make workspace
loading slower as workspace history grows.

### Expected behavior

Overview screens should request a bounded summary payload, while detail
screens should keep using the full workspace detail endpoint.

### Steps to reproduce

1. Run Paperclip from source with enough execution workspace history to
make workspace lists non-trivial.
2. Open the Workspaces page or a project workspace summary card.
3. Observe that summary UI needs only bounded workspace metadata but can
depend on broader workspace payloads.

### Paperclip version or commit

`master` at the time this branch was prepared.

### Deployment mode

Local dev (`pnpm dev`)

## What Changed

- Added shared types, validators, and path constants for bounded
execution workspace overviews.
- Added server service and route support for overview queries with
bounded linked issue/runtime metadata.
- Updated workspace overview UI API calls, query keys, breadcrumbs,
quicklooks, close dialogs, project summaries, and detail links to
consume the cheaper overview shape where appropriate.
- Added regression coverage for the new server route/service behavior
and the UI overview consumers.
- Registered the new workspace overview route in the generated OpenAPI
spec.
- Kept overview totals aligned with the project join and preserved
project slug links in workspace headers.

## Verification

- `pnpm exec vitest run
server/src/__tests__/execution-workspaces-service.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts
ui/src/api/execution-workspaces.test.ts
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/pages/Workspaces.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck && pnpm --filter @paperclipai/ui
typecheck`
- `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts
server/src/__tests__/execution-workspaces-service.test.ts`
- `pnpm test:run:serialized -- --shard-index 1 --shard-count 4`

## Risks

Low to medium risk. The change introduces a new overview contract across
shared/server/ui layers, so the main risk is a mismatch between summary
and detail payload expectations. The added route/service/UI tests cover
the intended split, and full detail pages continue using the detail
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-based coding agent with repository tool use and
local command execution. Exact served model identifier and context
window were 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-06-25 21:38:14 -05:00
DottaandPaperclip 841742fc1a [codex] Graduate experimental conference room defaults (#8628)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The board UI has been graduating experimental conference-room task
experiences into the default issue and onboarding flows
> - Several task UI improvements were still coupled to the Conference
Room Chat experimental flag even though they are useful outside chat
itself
> - That coupling meant disabling chat also reverted unrelated defaults
such as work-mode labels, task status colors, team creation copy, and
the graduated issue thread
> - This pull request keeps chat-specific gating scoped to chat while
making the graduated task UI the default experience
> - The benefit is that operators can use the newer task workflows
without needing to enable the separate chat experiment

## Linked Issues or Issue Description

No public GitHub issue exists for this exact change.

### Problem or motivation

The Conference Room Chat experimental flag was controlling unrelated
task UI defaults, which made non-chat workflows regress when chat was
disabled.

### Proposed solution

Remove that flag from task-thread, work-mode, onboarding, status, and
team-creation presentation paths while leaving chat-specific behavior
separately gated.

### Alternatives considered

Keeping the flag as a broad umbrella until chat graduates would avoid a
behavior change, but it keeps unrelated UI improvements hidden behind
the wrong capability switch.

### Roadmap alignment

Checked `ROADMAP.md`; this is focused graduation/polish for existing UI
surfaces rather than a new roadmap-level core feature.

Related search:

- Searched open PRs and issues for `conference room chat experimental
flag`: no matches.
- Searched open PRs and issues for `graduated issue thread`: no matches.

## What Changed

- Removes Conference Room Chat flag branching from task-thread
rendering, work-mode labels, task status colors, and team creation copy.
- Makes the onboarding completion path create/reuse an onboarding
project, create the first assigned task, and send the user to the
dashboard instead of chat.
- Deletes the legacy onboarding wizard and classic task-thread files now
that the graduated flow is the default.
- Updates focused UI tests and affected E2E specs for the default task
experience.
- Adds a user-visible onboarding error if restored state is missing the
company or agent required for launch.

## Verification

- `pnpm run preflight:workspace-links && pnpm exec vitest run
ui/src/components/NewIssueDialog.test.tsx
ui/src/components/OnboardingWizardVariant.test.tsx
ui/src/components/RunChatSurface.test.tsx
ui/src/components/SidebarCompanyMenu.test.tsx
ui/src/components/StatusBadge.test.tsx ui/src/lib/agent-order.test.ts
ui/src/lib/onboarding-launch.test.ts ui/src/lib/work-mode-meta.test.ts
ui/src/pages/IssueDetail.test.tsx`
- `pnpm --filter @paperclipai/ui typecheck`
- `npx playwright test --config tests/e2e/playwright.config.ts --list
tests/e2e/conference-room-typing-intro.spec.ts
tests/e2e/planning-mode-visual-verification.spec.ts`
- Attempted targeted Playwright execution locally, but this host is
missing Chromium system libraries (`libatk1.0-0t64`, `libatspi2.0-0t64`,
`libxcomposite1`, `libxdamage1`, `libxfixes3`, `libxrandr2`, `libgbm1`,
`libasound2t64`). CI runs the specs in the proper Actions environment.

## Risks

- Medium UI behavior risk: this intentionally changes the default
experience for users who have not enabled Conference Room Chat.
- Medium onboarding risk: completion now creates/reuses a project and
creates the first task instead of only navigating.
- Low migration risk: no database schema or migration changes are
included.
- The PR avoids `pnpm-lock.yaml` and `.github/workflows` changes.

## Model Used

OpenAI Codex, GPT-5-class coding model, tool-enabled local repository
workflow with shell, git, and test execution.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-25 11:52:36 -05:00
DottaandPaperclip b4a7efa8d2 Add skill category editing in settings (#8615)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Skills can be installed, inspected, filtered, and grouped inside
company settings
> - Skill category metadata already exists in the data model and list
filters, but users could not edit categories after a skill was created
or imported
> - That made category filters and counts drift from the way operators
actually want to organize their skills
> - This pull request adds category editing to the existing skill
settings dialog and sends those edits through the existing
company-scoped skill update API
> - The server mutation now includes category information in the
activity log so settings changes are auditable
> - The benefit is that operators can keep installed skills organized
without reinstalling or recreating them

## Linked Issues or Issue Description

No duplicate or closely related public GitHub issues or PRs were found
for `skill categories settings`.

Feature request fields:

**Subsystem affected**

Cross-cutting: `server/` REST API routes/services and `ui/` React board
settings.

**Problem or motivation**

Company operators can create or import skills with categories, and
Paperclip already exposes category filters and category counts. After
installation, though, operators could not edit a skill's categories from
the skill detail settings screen. That made it difficult to keep skills
grouped correctly as workflows evolved.

**Proposed solution**

Add category editing to the existing skill settings dialog. The category
field accepts comma-separated values, normalizes them into slugs,
deduplicates repeated categories, allows clearing all categories, and
saves categories together with the existing sharing setting through the
company-scoped skill update API.

**Alternatives considered**

One alternative was to keep categories editable only during
create/import flows, but that forces users to recreate or reinstall
skills just to adjust grouping metadata. Another was a separate
categories-only action, but batching settings into one explicit Save
action keeps the dialog predictable.

**Roadmap alignment**

This supports the completed Skills Manager roadmap area by making
installed skills easier to organize and maintain inside company
settings.

**Additional context**

The server already persisted skill categories and supported category
list filters/counts. This PR wires the existing metadata into the
settings editing path and adds focused route, service, and UI tests.

## What Changed

- Added category editing to the skill detail settings dialog, including
comma-separated input, normalized deduplication, reset, dirty-state
handling, and save feedback.
- Updated the skill settings mutation path to save categories and
sharing scope together, then refresh detail/list cache entries.
- Included updated categories in `company.skill_updated` activity
details.
- Added server route/service coverage for category updates,
normalization, filtering, counts, clearing, and activity logging.
- Added UI coverage for saving category edits, clearing categories,
reordered no-op category sets, saving sharing changes together, and
preserving draft input after a failed save.
- Updated the Storybook skill detail harness for the renamed settings
callback props.

## Verification

- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/company-skills-routes.test.ts
server/src/__tests__/company-skills-service.test.ts
ui/src/pages/CompanySkills.test.tsx`
- Latest-head GitHub checks are green for typecheck, build, e2e, general
tests, serialized server suites, policy, commitperclip review, Socket
Security, Snyk status, and Canary Dry Run.
- Greptile Review succeeded on the latest head with zero unresolved
review threads.

## Risks

Low risk. The change uses the existing company skill update API and
category normalization path. The main behavioral change is that the
settings dialog now batches sharing and category edits behind an
explicit Save button instead of saving sharing immediately on select
change.

> 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 tool-enabled repository
inspection, shell execution, git, and GitHub CLI 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-25 10:03:41 -05:00
DottaandPaperclip ed65d08d57 [codex] Gate skill mutations with skills:create permission (#8616)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents and board users operate inside a company-scoped control plane
where permissions decide which mutating actions they can perform
> - Company skills are part of the reusable agent-company setup surface,
but skill mutation had been coupled to broader agent-creation authority
> - That coupling meant importing or managing skills required a
permission that also implies hiring power, which is broader than the
operation needs
> - Paperclip already has a grant-based permission vocabulary, so skill
mutation should be authorized through a dedicated `skills:create`
capability while preserving existing default behavior for trusted agents
> - This pull request adds the skill creation permission contract,
enforces it on company skill mutations, exposes it in agent permission
management, and documents the changed CLI/API expectations
> - The benefit is a narrower, auditable permission path for skill
import/create/update/delete flows without forcing agents to receive
broader agent-creation authority

## Linked Issues or Issue Description

No public issue is linked.

Problem: company skill mutation APIs were effectively tied to broader
agent creation authority. This PR splits skill mutation authorization
onto the public `skills:create` permission while keeping existing
default skill creation behavior for agents unless explicitly disabled.

Related public PR found during duplicate search: #5330. That PR uses an
older `canManageSkills` shape; this PR implements the `skills:create`
grant path instead.

## What Changed

- Added `skills:create` to shared permission constants and agent
permission types/validators as `canCreateSkills`.
- Backfilled default human/member role grants for `skills:create`.
- Updated company skill mutation routes to require board/user or agent
access to `skills:create`, while preserving legacy/default agent
behavior through `canCreateSkills` unless explicitly disabled.
- Updated agent permission update handling, UI permission controls,
duplicate-agent payloads, plugin SDK fixtures, and agent detail API
surfaces for `canCreateSkills`.
- Added regression coverage for skill route authorization, permission
schema/default behavior, invite grants, omitted permission updates, and
duplicate-agent payloads.
- Updated CLI and Paperclip skill documentation for the new skill
creation permission.

## Verification

- `pnpm exec vitest run
server/src/__tests__/agent-permissions-service.test.ts
server/src/__tests__/agent-permissions-routes.test.ts
server/src/__tests__/company-skills-routes.test.ts
server/src/__tests__/invite-join-grants.test.ts
ui/src/lib/duplicate-agent-payload.test.ts` — 5 files, 90 tests passed.
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck && pnpm --filter @paperclipai/ui
typecheck` — passed.
- `pnpm test:run ...changed files...` was attempted first, but the
stable wrapper rejects explicit file arguments; direct Vitest was used
for the same targeted files.

## Risks

- Moderate authorization risk: this changes the gate for company skill
mutations, so the tests cover board grant checks, agent explicit grant
checks, legacy default allowance, and explicit denial.
- Migration/backfill risk is low: the migration only grants
`skills:create` to existing human roles that already need broad
management capability.
- UI/API compatibility risk is low: `canCreateSkills` remains default-on
for full agent permissions, and the update validator preserves omitted
values so unrelated permission edits do not re-enable disabled skill
creation.

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

## Model Used

OpenAI Codex, GPT-5 coding agent with terminal/tool use enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (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-06-25 09:49:10 -05:00
bac15ebd09 feat: task status icons & colors (#8580)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work, and task status is one of the most-scanned signals across its
whole UI.
> - The Tasks UI shows status through small coloured ring icons and
chips spread across the list, kanban, task detail, the properties
flyout, inline `@`-mentions and the breadcrumb.
> - Those ring glyphs lean heavily on colour to distinguish states,
which is hard to read for colour-blind users, and the status hues were
hard-coded in component classes rather than a single source.
> - We want color-blind-safe, distinct *shapes* per status plus a single
`--status-*` colour-token system the chips and icons share.
> - This pull request adds a unified `StatusGlyph` (one shape per
status) and the `--status-*` colour-token system, and adopts them across
every task-status surface so the new glyphs + colours render by default.
> - The benefit is a more accessible, consistent status language with
one source of truth for status hues.

## Linked Issues or Issue Description

This is a **feature** (no public issue filed). Following the feature
issue template:

- **Problem / motivation:** Task status is communicated mostly by colour
(ring fills/borders), which is hard to distinguish for colour-blind
users, and the status hues are duplicated across component classes with
no single source of truth. Several community PRs have nibbled at parts
of this (see related PRs below).
- **Proposed solution:** A single `StatusGlyph` component with a
distinct *shape* per status (not just colour), backed by a `--status-*`
CSS-variable colour system (base hues + AA-tuned icon hues +
`.status-chip` / `.status-fill` color-mix helpers), adopted across all
task-status surfaces.
- **Alternatives considered:** Recolouring the existing rings in place
(rejected — still colour-only, no shape differentiation).
- **Roadmap alignment:** Additive UI only; no overlap with planned core
work.

Related community PRs (partial / different approaches to the same area —
not duplicates):

- Refs #3806 — Show issue ref and status icon in breadcrumbs and
properties
- Refs #1760 — Improve design of cancelled task status icon
- Refs #1856 — a11y title/aria-label on status and priority icons

## What Changed

- **Colour token system:** `--status-agent-*` / `--status-task-*` base
hues, AA-tuned `--status-task-icon-*` hues (light + dark), and
`.status-chip` / `.status-fill` color-mix helpers in `index.css`;
matching status→CSS-var maps in `status-colors.ts`.
- **`StatusGlyph`** — one `viewBox="0 0 24 24"` glyph per status with
distinct, color-blind-safe shapes (dashed ring, open ring, half-fill,
ring+dot, disc+check, ring+bar, ring+slash, and `in_queue` = the blocked
shape recoloured blue). Sizes `sm`/`md`/`lg`.
- **Adoption (renders by default)** across `StatusIcon`, `StatusBadge`
(agent + issue chips), `MarkdownBody` inline mentions, `IssueRow`,
`IssuesList`, `IssueProperties`, `BreadcrumbBar` + `BreadcrumbContext`,
and the task-detail header/breadcrumb.
- **Tests** for `StatusGlyph`, `StatusIcon`, `StatusBadge`, `IssueRow`,
`IssuesList`, `MarkdownBody` lock the rendered behaviour.

Scope notes: no experimental flag and no Theme Editor surfaces. The
generic `StatusBadge` (runs/goals/approvals) is unchanged.
Project-status recolour is deferred (no in-scope consumer).

## Verification

- `pnpm --filter @paperclipai/shared build` — green (tsc).
- `pnpm --filter @paperclipai/ui build` — green (tsc + vite).
- Targeted unit tests green: `StatusGlyph`, `StatusIcon`, `StatusBadge`,
`IssueRow`, `IssuesList`, `MarkdownBody`, plus consumer suites that
render these (`IssueProperties`, `IssueDetail`, `Search`,
`IssueChatThread`, `IssueFiltersPopover`, `InterruptHandoffViews`) — all
passing.
- Remaining: interactive light + dark visual confirmation across list /
kanban / detail / properties / inline mentions / breadcrumb. The glyph
shapes + AA-tuned hues were previously QA'd on the originating feature
branch.

## Risks

Low risk. Additive UI: a new component + CSS tokens, adopted at existing
status call sites. The generic `StatusBadge` and all non-status UI are
untouched; no schema/migration changes. Behaviour is exercised by unit +
consumer test suites.

## Model Used

Claude Opus 4.8 (`claude-opus-4-8`), extended thinking, with tool use /
code execution (file edits, local builds + vitest).

## Checklist

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-24 16:42:27 -05:00
DottaandPaperclip f88ac9d078 [codex] Fix local skill, secrets, and file viewer regressions (#8586)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents rely on local skills, provider-backed secrets, and workspace
file previews during normal execution.
> - Local skill imports need bounded reference-file inventory so direct
skill discovery stays accurate without accidentally walking too much of
the filesystem.
> - Secrets provider setup needs actionable AWS discovery errors so
operators can recover from IAM/config problems without losing manual
form input.
> - The issue detail file viewer should reopen cleanly after the first
close so users can keep inspecting files during task review.
> - This pull request collects the small fixes and regression tests for
those related operator workflows.
> - The benefit is more predictable local skill imports, clearer secrets
setup failure states, and a less brittle file preview interaction.

## Linked Issues or Issue Description

- No public GitHub issue was found for this extracted local work.
- Related prior sync context: #8536.
- Problem: local skill reference discovery, AWS provider-vault discovery
errors, and issue file preview reopening each had narrow workflow
regressions that made operator recovery harder.
- Expected behavior: skill imports inventory reference files within
bounded local skill directories, AWS discovery failures present safe
actionable guidance while preserving manual values, and closing the
first file preview does not prevent opening another preview.
- Reproduction scope: import a local skill with referenced files,
attempt AWS Secrets Manager discovery with insufficient IAM/list
permissions, and open/close/reopen file previews from an issue detail
page.
- Duplicate search: searched GitHub PRs/issues for `skill inventory
secrets file viewer` and `skill inventory secrets AWS file viewer`; no
matching public duplicate was found.

## What Changed

- Bounded direct local skill file inventory discovery and added
regression coverage for reference file imports.
- Preserved and surfaced safe, actionable AWS Secrets Manager
discovery/import errors in server responses and the secrets UI.
- Kept AWS provider-vault manual form values intact when discovery fails
or returns no candidates.
- Fixed issue file viewer state so closing the first preview still
allows later file previews to open.
- Updated the secrets render test harness to avoid the missing
`React.act` export in the current React package set.

## Verification

- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/secrets-routes.test.ts
server/src/__tests__/secrets-service.test.ts
ui/src/context/FileViewerContext.test.ts
ui/src/pages/Secrets.render.test.tsx`
- Result: 5 test files passed, 116 tests passed.
- Install note: the isolated worktree needed `NODE_ENV=development pnpm
install --frozen-lockfile --prod=false --force` before local
verification because it initially had no dev dependencies installed.

## Risks

- Low-to-medium risk: this touches skill import inventory,
secrets-provider error handling, and file-viewer UI state, but each
change is covered by focused regression tests.
- No migrations.
- No dependency or lockfile changes.
- CI is rerunning on the latest head after review fixes; Greptile is 5/5
with no unresolved Greptile threads.

> 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, GPT-5-family model as provided in the
Paperclip run environment, 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-06-24 09:17:51 -05:00
DottaandPaperclip e68188c438 fix: upstream deployed document-comment, routine-annotation, workspace & board-polling fixes (#8536)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - This change touches several already-shipped subsystems —
document-comment annotations, the selected-agent Conference Room chat
surface, routine description annotations, workspace-operation tracking,
and the board polling/inbox UI
> - A batch of incremental fixes and two small backend additions had
accumulated on a local mainline and were deployed to a live instance,
but never landed upstream — so each `origin/master` sync kept
re-diverging
> - Leaving them un-upstreamed means the same delta has to be re-merged
on every sync and risks being lost or silently reverted
> - This pull request rebases that delta cleanly on top of current
`origin/master` (preserving recent upstream work such as reusable
sandbox leases and the relation-list collapse controls) and brings it up
for review
> - The benefit is that mainline and the deployed instance converge, and
these fixes/additions get normal review + CI + Greptile coverage

## Linked Issues or Issue Description

No single GitHub issue tracks this; it is a bundle of bug fixes and two
small feature additions. Following the issue-template fields:

**Bug fixes (what was wrong → what this does):**
- Document comments rendered out of document order, didn't live-update
across clients, swallowed save failures, and lost the markdown text
selection on re-render. Now: doc-order sort, live updates, surfaced
save-failure state, stable selection across re-renders.
- The board polling hot path returned oversized payloads on every poll.
Now: an opt-in `summary` projection trims the heartbeat-run list
payload.
- Assorted UI fixes: sidebar nav peek/streamlining edge cases, markdown
file-viewer re-mount/line-height issues on iOS Safari, inbox badge/skill
deep-link tab selection, and `⌘.` work-mode cycling on iOS.

**Feature additions:**
- `workspace_operations.issue_id` — associate a workspace operation with
the issue that triggered it (new migration `0106`, schema, service,
shared type).
- Routine **description annotations** — comment threads on a routine's
description document, mirroring issue document annotations (new
migration `0107`, `routine_documents` schema, routes/service,
editable-sections UI).
- Selected-agent **Conference Room chat** surface wiring and live
issue-thread updates.

**Related PR:** #8229 (`feat(control-plane): add annotation and
workspace controls`, draft) covers overlapping
annotation/workspace-control territory — flagging it so a reviewer can
reconcile the two rather than double-merging.

## What Changed

- `feat(workspace)`: `workspace_operations.issue_id` migration +
schema/service/type; issue workspace property controls reconciled with
upstream's evolved "Service" row.
- `feat(routines)`: routine description annotations —
`routine_documents` schema, migration `0107`, routes/service,
`editable-sections` UI.
- `fix(document-comments)`: doc-order sort, live updates, save-failure
surfacing, stable markdown selection (+ storybook story, rerender test).
- `feat(chat)`: selected-agent Conference Room chat surface and live
issue-thread updates (`LiveUpdatesProvider`, `issue-chat-messages`,
interactions service).
- `perf(board)`: opt-in `summary` projection for the board
polling/heartbeat-run list payload, plus assorted sidebar / file-viewer
/ inbox / IssueProperties UI fixes.

Organized into 5 logical commits. Migrations are numbered incrementally
after upstream's latest (`0105`) — `0106` then `0107`, no journal
collision.

## Verification

- Built by 3-way merging the deployed delta onto current
`origin/master`; the only merge conflict (`IssueProperties.test.tsx`,
two adjacent test blocks) was resolved in favor of upstream's evolved
"green service link above the workspace row" layout, which matches the
merged component's rendered output.
- Confirmed recent upstream work is preserved post-merge: reusable
sandbox lease teardown (`#8513`), the IssueProperties relation-list
collapse controls, and the sidebar streamlined-nav default.
- Confirmed the net diff vs `origin/master` is exactly the intended
feature delta (65 files) and that overlapping server files (`issues.ts`,
`agents.ts`, `heartbeat.ts`) only add feature code without disturbing
upstream logic.
- This delta is already running on a live deployed instance.
- Full typecheck/test suite + Greptile to run in CI (see checklist).

## Risks

- Two new migrations (`0106`, `0107`). Both are additive (new table /
new nullable column) and ordered after upstream's `0105`; no data
backfill, low risk. If another migration-bearing PR merges first,
renumber before merge.
- Largest blast radius is in the merged overlapping UI/service files;
covered by the existing test suites for those files plus CI.
- Overlaps thematically with draft PR #8229 — reviewers should reconcile
rather than merge both blindly.

## Model Used

Claude Opus 4.8 (`claude-opus-4-8`), extended thinking, with tool use
(git, shell). Agentic coding workflow.

## Checklist

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