mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-11 14:10:50 +02:00
codex/plugin-task-execution
2085
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9a1d4b7983 |
fix(ui): use prose editor for markdown agent instructions (#9332)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agent setup depends on instruction files that are readable and editable from the board UI > - The instructions tab already receives server-side metadata describing whether each file is Markdown > - The UI was deciding Markdown editor usage primarily from the file extension, which makes extensionless Markdown instruction files feel like raw code > - This pull request makes the instructions editor trust server Markdown metadata for existing files and keep extension fallback only for new unsaved files > - The benefit is that AGENTS-style prose instructions render and edit like prose while explicitly non-Markdown files still use the raw textarea ## Linked Issues or Issue Description - Refs #8201 - Refs #5652 - Refs #3427 - Refs #2068 - Related PRs: #2468, #2620 ## What Changed - Use server `markdown` metadata from instruction file details/summaries to choose the prose Markdown editor for existing instruction files. - Keep extension-based Markdown detection only for pending new files before server metadata exists. - Remove the monospace content styling from the Markdown editor path so prose instructions read like normal text. - Add focused tests for extensionless Markdown files, new `.md` files, and `.md` files explicitly marked non-Markdown by the server. ## Verification - `pnpm check:token-gates` - `pnpm exec vitest run ui/src/pages/AgentDetail.instructions.test.tsx` - `pnpm --filter @paperclipai/ui typecheck` ## Risks - Low risk. The editor selection now depends on server metadata for existing files, so incorrect server metadata would choose the wrong editor. The fallback still preserves extension-based behavior for newly created unsaved files. > 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, tool-enabled terminal workflow. Context window details 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> |
||
|
|
606aa4f266 |
feat(search): filters, sorting, operators & command-palette parity (#9327)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Company search is the primary way operators find issues, comments, documents, artifacts, agents, and projects across a busy company > - Search previously supported only a bare text query: no way to narrow by status/assignee/project/label/date, no sort control, no typed operators, and weak relevance/snippets meant hunting through noise > - As companies accumulate tens of thousands of items, unfiltered single-sort search stops scaling for day-to-day operator workflows > - This pull request adds a full filtering model (filter bar, chips, mobile sheet, URL state), sort modes, typed query operators (`status:`, `assignee:`, `type:`, …) with command-palette parity, relevance/snippet/deep-link improvements, zero-results recovery, and the supporting shared validators, backend service work, and DB indexes > - The benefit is that operators can go from a vague query to the exact item in a couple of keystrokes, on desktop and mobile, with shareable filtered-search URLs ## Linked Issues or Issue Description No existing public GitHub issue; describing the underlying feature request inline (per feature_request template): - **Problem:** Company search accepted only a plain text query. Users could not filter results by status, assignee, project, label, or recency; could not change result ordering; and got no guidance when filters emptied the result set. - **Desired solution:** Structured search filters (UI controls + typed query operators + URL parameters), selectable sort modes, better relevance and snippets with exact deep links, and parity between the search page and the command palette. - **Alternatives considered:** Client-side filtering of unfiltered results (does not scale past the fetch limit); a separate "advanced search" page (splits the surface and duplicates state handling). Related (not duplicate) PRs found while searching: #4848 (issue search query planning), #8235 (search rate limiting). ## What Changed - **Shared contract:** new search filter/sort/count/zero-results types and validators in `packages/shared` (`validators/search.ts`, types index). - **Backend:** `server/src/services/company-search.ts` supports issue filters, sort modes, per-filter option counts, snippets, artifact visibility, and zero-results loosen suggestions; single-statement match replaces per-scope scans and predicates are trigram-index compatible (~3.7s → ~350ms on a live 14.8k-hit corpus). - **DB:** migration `0142_company_search_sort_indexes.sql` adds the supporting indexes. - **Search page (`ui/src/pages/Search.tsx`):** filter bar, removable chips, mobile filter sheet with result-count preview, sort menu, URL round-tripping, zero-results recovery UI. - **Query operators (`ui/src/lib/search-query-parser.ts`):** typed operators parsed into filters, operator autocomplete, filter pills. - **Command palette:** operator-aware parsing and full-search handoff. - **Stale-operator fix (latest commit):** typed operator filters are no longer folded into persistent URL-filter state, so deleting a token (e.g. removing `status:blocked` from the input) actually removes the filter from subsequent requests; filter-control edits materialize control state and strip typed tokens so a removed chip cannot resurrect from the input. ## Verification - `cd ui && npx vitest run src/pages/Search.test.tsx` — 19 tests including two new red→green regressions for the stale-operator paths (both fail on the previous commit, pass now). - `cd ui && npx vitest run src/components/CommandPalette.test.tsx` and `cd server && npx vitest run src/services/company-search-service.test.ts` — operator parity and backend filter/sort/count coverage. - `cd ui && npx tsc --noEmit` — clean. - Manual: open `/search`, type `auth status:blocked`, confirm the status filter applies; delete `status:blocked`, confirm results are unfiltered again; drive the same filters from the filter bar/chips/mobile sheet and confirm the URL round-trips (reload/back/forward preserves state). - Full end-to-end QA pass (9/9 acceptance checks) against the wireframes on desktop (1280px) and mobile (390px) with a live API and browser automation. ## Risks - Additive migration (indexes only, no data rewrites) — safe to roll forward; index creation cost is paid once at migrate time. - Search request shape gains optional parameters only; old clients keep working. - Behavioral shift: filter-control edits now strip typed operator tokens from the query text (their values persist as filter state) — deliberate, so removed filters stay removed. - Ranking changes alter result ordering for existing queries; covered by service tests and the QA pass. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - Claude Fable 5 (`claude-fable-5`, Anthropic, extended thinking + tool use) — stale-operator-filter fix, regression tests, PR preparation. - GPT-5 Codex (`codex_local` adapter) and Claude Opus 4.6 (`claude-opus-4-6`) — earlier implementation phases (backend contract, filter UI, operators, ranking) under agent orchestration. ## 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 — pre-existing branch name retained to avoid closing/reopening the PR - [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 (no user-facing docs affected) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green (pending re-run on latest commit) - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (pending re-review of the stale-filter fix) - [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> |
||
|
|
f3ca4d24bc |
fix: repair dirty/foreign-branch execution worktrees (#9297)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Execution workspaces are the bridge between Paperclip's control plane and a local agent's checked-out repository state. > - When a workspace is restored after a failed or interrupted run, the recorded branch can disagree with the branch currently checked out on disk. > - A clean branch mismatch can be reconciled safely, but a dirty mismatch needs a lossless path that does not discard uncommitted agent work. > - This pull request adds a quarantine-and-restore path that saves dirty work to a rescue branch, restores the recorded branch, and exposes the repair from the board UI and run page. > - The benefit is that operators can recover wedged execution workspaces without losing work or moving another live branch unexpectedly. ## Linked Issues or Issue Description No public GitHub issue exists for this workspace-recovery failure, so this PR includes the bug report inline. **What happened** A git worktree-backed execution workspace could become wedged when Paperclip expected one branch but found a different checked-out branch with dirty tracked or untracked files. The existing safe repair path refused the restore, leaving the source task blocked with no lossless one-click recovery path. **Expected behavior** Paperclip should preserve dirty work before restoring the recorded workspace branch. If another live workspace claims the checked-out branch, or an attached runtime service is active, the repair should refuse with clear operator-facing evidence instead of risking work loss or file contention. **Steps to reproduce** Create a git worktree execution workspace whose persisted branch name differs from the checked-out branch, add dirty tracked or untracked files in that worktree, then trigger workspace validation or use the branch reconcile endpoint. Before this change, the dirty mismatch remained blocked because Paperclip had no quarantine restore mode. **Paperclip version or commit** Observed on the pre-fix workspace-recovery implementation. Verified on this PR head after rebasing onto current `master`. **Deployment mode** Local trusted development/worktree deployments using git worktree execution workspaces and optional workspace runtime services. ## What Changed - Added dirty-worktree quarantine repair that creates a rescue branch, commits dirty tracked and untracked files there, restores the recorded branch, writes audit comments/activity, and preserves the live foreign branch ref. - Added `quarantine_restore` branch reconcile API support, recovery-action resolution, source-task wake behavior, execution-review preservation, claimant refusal, runtime-service refusal, and coverage for the non-transactional git ordering. - Added board UI controls for the repair action in the recovery card plus a compact failed-run workspace recovery surface that uses the same reconcile handlers. - Hardened Greptile follow-up cases by best-effort restoring the recorded branch after a mid-sequence rescue commit failure and by refusing quarantine restore while attached runtime services are active. ## Verification - `pnpm exec vitest run server/src/__tests__/execution-workspaces-service.test.ts -t "quarantine_restore"` - `pnpm exec vitest run server/src/__tests__/workspace-runtime.test.ts -t "workspace dirty quarantine branch repair"` - `pnpm exec vitest run server/src/__tests__/heartbeat-workspace-finalize-branch.test.ts -t "repairs clean unrecorded branch drift|adopts unrecorded forward branch drift"` - `pnpm exec vitest run server/src/__tests__/workspace-runtime-routes-authz.test.ts` - `pnpm --filter @paperclipai/server typecheck` - Earlier PR verification covered the route, service, heartbeat, UI component, and run-page recovery surfaces; Cutter posted public preview screenshots for the repair popover and run-page panel at https://github.com/paperclipai/paperclip/pull/9297#issuecomment-4926934211. - GitHub PR checks are green on `dcac76b05f4cf6e1ee16544c2831d83c7857e475`. - Greptile is 5/5 with zero annotations and no unresolved review threads on `dcac76b05f4cf6e1ee16544c2831d83c7857e475`. ## Risks - Moderate risk because the change intentionally runs git commands against local worktrees; the implementation refuses dirty repair when another claimant or active runtime service is detected and records rescue refs for auditability. - Compatibility / release-note callout for self-hosted operators: existing instances that left `enableWorkspaceBranchReconcileForward` unset now get automatic forward branch reconciliation during heartbeat workspace recovery. Operators who want the previous advisory-only behavior can set `experimental.enableWorkspaceBranchReconcileForward` to `false`; dirty quarantine repair can likewise be disabled with `experimental.enableWorkspaceDirtyQuarantineRepair: false`. - If the git rescue succeeds but a later database write fails, the worktree may already be restored while the recovery action remains open; this ordering is documented in code because git side effects cannot participate in the database transaction. - UI risk is limited to the workspace recovery surfaces and covered by component tests plus the existing Cutter visual preview. ## Model Used OpenAI Codex coding agent based on GPT-5, with repository tool use, shell execution, and local test execution. Earlier preserved commits on this branch also show Claude Code / Claude Opus 4.8 assistance in their commit metadata. ## 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] Branch naming exception documented: this PR preserves the existing worktree branch requested for publication while keeping the PR title and body public-facing - [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> |
||
|
|
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> |
||
|
|
9acce52aa5 |
[codex] Polish operator UI work state details (#9320)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators use the issue list, blocked-work notices, pipeline body documents, and issue documents to understand what agents are doing > - Some of those surfaces had low-information details: live-work blockers were visually easy to miss, revision history showed generic actor labels, and selected active subtasks carried an extra accent border > - These details matter because Paperclip's default UI should make agent state and work history legible without requiring users to inspect raw logs > - This pull request groups a small set of related operator UI polish changes for those work-state and document-history surfaces > - The benefit is clearer review context for blocked work, better attribution in document revision history, and cleaner active-subtask row styling ## Linked Issues or Issue Description No public GitHub issue found during dedup search. ### Bug Report **Pre-submission checklist** - Searched existing open PRs/issues for `document revision authors` and `blocked notice live work`; no duplicates found. - Reproduced against the current `master` base for this PR. - Confirmed this is core board UI behavior, not adapter/provider/local configuration. **What happened?** Blocked live-work notices, document revision history, pipeline body document revision history, and active subtask rows exposed technically correct but low-signal UI details. Revision menus could show generic `Board`/`Agent` labels instead of the specific author, and selected active subtasks had an extra accent border. **Expected behavior** Operators should see clear blocked-live-work copy, recognizable revision authors using available agent/user profile data, and visually consistent selected task rows. **Steps to reproduce** 1. Open an issue with a live-work blocker and inspect the blocked notice. 2. Open an issue document revision menu with agent/user-authored revisions. 3. Open a pipeline item body document revision menu with agent/user-authored revisions. 4. Inspect a selected active subtask row in the issue list. **Paperclip version or commit** `8b6a06ee2` (`origin/master` at branch creation). **Deployment mode** Local dev / self-hosted board UI. **Installation method** Built from source. **Agent adapter(s) involved** Not adapter-specific (core board UI). **Database mode** Not database-related. **Access context** Board operator UI. **Relevant logs or output** Not applicable. **Relevant config** Not applicable. **Additional context** This PR is a small polish/fix contribution. `ROADMAP.md` allows tightly scoped bugs and polish without roadmap-level coordination. **Privacy checklist** Reviewed the PR body for private instance references and omitted internal ticket links. ## What Changed - Polished the live-work blocked notice copy and tests so operators get a clearer explanation of what is blocking progress. - Show issue document revision authors with agent/user names and avatar treatment instead of generic actor labels. - Show pipeline body document revision authors with the same available agent/user profile data. - Removed the extra left accent border from selected active subtask rows. - Stabilized the document revision test helper for React runtimes where `act` is not exported as a function. ## Verification - `git diff --check origin/master..HEAD` - `git diff --name-only origin/master..HEAD -- .github/workflows pnpm-lock.yaml` produced no output. - `pnpm check:token-gates` passed: all color literal, arbitrary bracket value, and raw font-size gates clean. - `pnpm exec vitest run ui/src/components/IssueBlockedNotice.test.tsx ui/src/components/IssueDocumentsSection.test.tsx ui/src/components/IssueRow.test.tsx` passed: 3 test files, 32 tests. - `pnpm --filter @paperclipai/ui typecheck` passed. - Remote PR checks passed on head `3e18fe3f`: 22 complete, 0 pending, 0 failing. - Greptile completed at 5/5 with no blocking issues after addressing the pipeline revision author feedback. ## Risks Low risk. The change is limited to board UI rendering and component tests. The main risk is a subtle visual regression in issue/document surfaces that are not covered by screenshots; the affected component tests cover the intended copy, attribution, and row-style behavior. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex coding agent, GPT-5 model family, tool-enabled CLI session. Exact runtime context window is not exposed by this execution environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have 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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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.   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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |
||
|
|
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> |
||
|
|
5d0de3499d |
[codex] Fix collapsed starred project indentation (#9215)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board sidebar is a high-frequency navigation surface for companies, projects, and work queues. > - Starred projects render as child rows under Projects in the expanded sidebar. > - The collapsed rail should align every nav icon in the same rail column. > - The starred-project child indent was still applied in the collapsed rail, which pushed the project glyph out of alignment. > - This pull request keeps the expanded hierarchy indent while removing it only for the collapsed rail. > - The benefit is a cleaner collapsed sidebar without changing expanded sidebar hierarchy. ## Linked Issues or Issue Description No public GitHub issue exists. ## What happened? In the collapsed sidebar rail, starred project rows kept the expanded child indentation. That pushed the project glyph out of alignment with the rest of the collapsed sidebar icons. ## Expected behavior Collapsed starred project icons should align with the other sidebar rail icons while the expanded sidebar should keep the child-row indentation under Projects. ## Steps to reproduce 1. Open Paperclip with at least one starred project. 2. Collapse the sidebar into rail mode. 3. Compare the starred project glyph position with the other collapsed sidebar glyphs. ## Paperclip version or commit Reproduced on the PR base before this branch; fixed on commit |
||
|
|
555391fed7 |
fix: run restart recovery, workspace self-heal, quota-aware retries, failed-run metrics (#9183)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run in heartbeat runs orchestrated by the server; run
lifecycle, retry scheduling, and the dashboard's run-activity metrics
are the subsystems involved
> - A spike in "failed" tasks traced to three causes: server restarts
killing in-flight runs and mislabeling them as failures, deterministic
workspace-validation loops when a worktree's branch diverged, and
provider quota/usage-limit errors being classified as generic transient
failures (putting agents into error state and polluting metrics)
> - Killed-then-recovered runs and quota waits are not product failures,
so both the runtime behavior and the reporting needed to distinguish
them
> - This pull request drains runs gracefully on shutdown with idempotent
restart retries, self-heals workspace branch mismatches, adds a
quota-aware failure class with reset-time retry, separates recovered
restart kills from true failures on the dashboard, and documents restart
hygiene for operators
> - The benefit is fewer spurious failures, automatic recovery instead
of manual repair, and dashboard metrics that reflect real failure rates
## Linked Issues or Issue Description
No public GitHub issue exists; describing the bug inline per the
bug-report template:
**What happened?**
In-flight heartbeat runs are marked `failed` when the server restarts,
even though a retry later succeeds. Worktrees whose checked-out branch
diverges from the issue branch fail workspace validation on every
subsequent run with no recovery path. Provider quota/usage-limit
responses are treated as generic transient upstream errors, putting
agents into an error state and retrying before the quota window resets.
The dashboard counts all of these as true failures, inflating failure
metrics.
**Expected behavior**
Graceful shutdown should interrupt (not fail) running runs and chain
exactly one recovery retry. Workspace validation should repair
recoverable branch mismatches automatically. Quota errors should get
their own error class with the retry scheduled at the provider reset
time and the agent left idle. The dashboard should report recovered
restart kills separately from true failures.
**Steps to reproduce**
1. Start a heartbeat run, then restart the server (SIGTERM) while it is
in flight — the run lands as `failed` with a process-loss error code
even when its retry succeeds
2. Check out an issue whose worktree branch has diverged (e.g. after a
force-moved branch) — every subsequent run fails
`workspace_validation_failed` deterministically
3. Drive an agent into a provider usage-limit window — the run fails as
a generic transient upstream error and the agent enters an error state
instead of idling until the reset time
**Paperclip version or commit**
master (base
|
||
|
|
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> |
||
|
|
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 |
||
|
|
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> |
||
|
|
329b229591 |
Fix annotation selection in routine editor (#9182)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The issue and routine editor surfaces share document annotation behavior for commentable text. > - The annotation layer currently observes document selections inside its container and converts those selections into pending comment anchors. > - Routine editor fields can live inside that same annotated document container while still needing normal native text selection behavior. > - When a user selects text inside an editable routine field, the annotation layer should leave that selection alone instead of preparing a comment. > - This pull request teaches the annotation layer to ignore selections touching editable controls and covers that case with focused component tests. > - The benefit is that routine editing remains editable text UX, while document annotation selection continues to work for normal read-only document text. ## Linked Issues or Issue Description No public GitHub issue exists for this bug. Inline bug report follows. ### Pre-submission checklist - [x] I have searched existing open and closed issues and this is not a duplicate. - [x] I am on current `master` for this PR branch. - [x] I have confirmed the error originates in Paperclip itself, not in an agent adapter, API provider, or local configuration. ### What happened? Selecting text inside an editable routine field could be interpreted as a document annotation selection. That meant the annotation layer could prepare a pending comment anchor or show annotation affordances while the user was just selecting text to edit routine content. ### Expected behavior Editable controls should keep native text selection behavior. Selecting text inside `input`, `textarea`, `select`, or contenteditable routine editor regions should not build a document annotation anchor or show the document annotation toolbar. ### Steps to reproduce 1. Render document annotation behavior around a document/editor container that also contains an editable routine text region. 2. Select text inside the editable region. 3. Observe that the document annotation layer treats the selection as commentable text instead of ignoring it. ### Paperclip version or commit Reproduced and fixed against `master` at `5356b7d73`, with PR head `4f53f83f1`. ### Deployment mode Local dev / component test environment. ### Installation method Built from source. ### Agent adapter(s) involved Not adapter-specific; core UI behavior. ### Database mode Not database-related. ### Access context Board / human operator UI behavior. ### Relevant logs or output No runtime logs. Regression coverage is in `ui/src/components/DocumentAnnotationLayer.test.tsx`. ### Relevant config Not applicable. ### Additional context Root cause: `DocumentAnnotationLayer` filtered selections by container membership, but did not exclude editable controls or all valid contenteditable hosts before building a pending annotation anchor. ### Privacy checklist - [x] I have reviewed all pasted output for PII and redacted where necessary. ## What Changed - Added an editable-selection guard in `DocumentAnnotationLayer` that ignores selections touching `input`, `textarea`, `select`, or contenteditable elements. - Covered both `contenteditable="true"` and bare/empty `contenteditable` hosts so routine editor selections do not build annotation anchors. - Added focused regression tests proving editable selections do not call the annotation anchor helpers or show the annotation toolbar. ## Verification - `pnpm vitest run ui/src/components/DocumentAnnotationLayer.test.tsx` - `git diff --check` - GitHub PR checks are green for head `4f53f83f1`, including policy, review, typecheck/release registry, build, general tests, serialized suites, e2e, canary dry run, security checks, and Greptile. ## Risks Low risk. The change only narrows annotation capture when a selection touches an editable element inside the annotation container. Normal read-only document annotation selections still use the existing anchor-building path. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex coding agent based on GPT-5, with shell, Git, Vitest, and GitHub connector/CLI tool use. The exact hosted runtime model identifier is not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2ef70c3673 | build(deps): upgrade lexical family to 0.46.0 and pin via overrides (fixes dual-version getType crash) (#9180) | ||
|
|
6d103b8358 |
fix: system-authored comments display as 'You' instead of 'Paperclip' (#6330)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - The issue chat thread renders comments from agents, users, and the system itself > - When Paperclip's internal recovery system posts a comment (e.g., stranded issue recovery), it creates a comment with `author_type: "system"`, no agent ID, and no user ID > - The UI function `authorNameForComment` falls back to `"You"` when both author IDs are null > - This PR returns `"Paperclip"` instead for system notices > - The benefit: system comments are clearly attributed to Paperclip, not the logged-in viewer ## What Changed - `ui/src/lib/issue-chat-messages.ts`: In `authorNameForComment`, the null-userId fallback now checks `options?.isSystemNotice` and returns `"Paperclip"` instead of `"You"` for system-authored comments. One-line change. ## Verification - 82/82 existing tests pass (issue-chat-messages 20, IssueChatThreadSystemNotice 11, IssueChatThread 51) - Manual repro: view any issue with a system-authored comment (stranded issue recovery moves issue to blocked). Before: author "You". After: author "Paperclip". ## Risks Low risk. One-line change. Only affects system-authored comments with no user/agent ID. The `isSystemNotice` flag is already computed upstream (`comment.authorType === "system"`) and passed into this function. ## Model Used zai/glm-5.1 (200K context). Investigation and code tracing assisted by the model. ## Checklist - [x] Thinking path included - [x] Model specified - [x] Checked ROADMAP.md — bug fix, not a feature - [x] Tests pass locally (82/82) - [x] Risks documented - [x] Will address all reviewer comments |
||
|
|
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> |
||
|
|
5356b7d737 |
build(deps): bump @tanstack/react-query from 5.90.21 to 5.101.2 (#9067)
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.90.21 to 5.101.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/TanStack/query/releases">@tanstack/react-query's releases</a>.</em></p> <blockquote> <h2><code>@tanstack/react-query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.2</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/TanStack/query/commit/f5bf180d933d8b8d9d9e7b845e55b26a3a413b07"><code>f5bf180</code></a>, <a href="https://github.com/TanStack/query/commit/25cdd975fed4703d2ca5b600ca5ccd2b600b3dd8"><code>25cdd97</code></a>, <a href="https://github.com/TanStack/query/commit/ecd89c8faf7acc226f00633ea3a761d3ab842c1d"><code>ecd89c8</code></a>, <a href="https://github.com/TanStack/query/commit/01c763444e3cf3dfa9744f13911aa1533cac3c29"><code>01c7634</code></a>, <a href="https://github.com/TanStack/query/commit/49012dbd5192dfe483d3b108b72ffaa7f2849e0f"><code>49012db</code></a>]: <ul> <li><code>@tanstack/query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.2</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.2</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-next-experimental</code><a href="https://github.com/5"><code>@5</code></a>.101.2</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.2</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-persist-client</code><a href="https://github.com/5"><code>@5</code></a>.101.2</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-persist-client-core</code><a href="https://github.com/5"><code>@5</code></a>.101.2</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.2</li> </ul> </li> </ul> <h2><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.2</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.101.2</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.1</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-devtools</code><a href="https://github.com/5"><code>@5</code></a>.101.1</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.1</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-next-experimental</code><a href="https://github.com/5"><code>@5</code></a>.101.1</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.1</li> </ul> </li> </ul> <h2><code>@tanstack/react-query-persist-client</code><a href="https://github.com/5"><code>@5</code></a>.101.1</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-persist-client-core</code><a href="https://github.com/5"><code>@5</code></a>.101.1</li> <li><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.1</li> </ul> </li> </ul> <h2><code>@tanstack/react-query</code><a href="https://github.com/5"><code>@5</code></a>.101.1</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/TanStack/query/commit/9eff92ed86e284ec0125b3a3539d028688235bd1"><code>9eff92e</code></a>]:</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md">@tanstack/react-query's changelog</a>.</em></p> <blockquote> <h2>5.101.2</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.101.2</li> </ul> </li> </ul> <h2>5.101.1</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/TanStack/query/commit/9eff92ed86e284ec0125b3a3539d028688235bd1"><code>9eff92e</code></a>]: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.101.1</li> </ul> </li> </ul> <h2>5.101.0</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.101.0</li> </ul> </li> </ul> <h2>5.100.14</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix(react-query): do not go into optimistic fetching state when not subscribed (<a href="https://redirect.github.com/TanStack/query/pull/10759">#10759</a>)</p> </li> <li> <p>Updated dependencies []:</p> <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.100.14</li> </ul> </li> </ul> <h2>5.100.13</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies [<a href="https://github.com/TanStack/query/commit/d423168f6261a5cb3d353e53b27c8150cc271151"><code>d423168</code></a>]: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.100.13</li> </ul> </li> </ul> <h2>5.100.12</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.100.12</li> </ul> </li> </ul> <h2>5.100.11</h2> <h3>Patch Changes</h3> <ul> <li>Updated dependencies []: <ul> <li><code>@tanstack/query-core</code><a href="https://github.com/5"><code>@5</code></a>.100.11</li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/TanStack/query/commit/610e8d1684614f63e13f5829ad4bc375782ff06d"><code>610e8d1</code></a> ci: Version Packages (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10996">#10996</a>)</li> <li><a href="https://github.com/TanStack/query/commit/1f84256a2e5967882f65fd2b26e6b67b33a7fdd9"><code>1f84256</code></a> docs: document the <code>select</code> typing caveat for parallel-queries hooks (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10984">#10984</a>)</li> <li><a href="https://github.com/TanStack/query/commit/b80929716f9ae36104245da9d99e8af3550e6f58"><code>b809297</code></a> ci: Version Packages (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10977">#10977</a>)</li> <li><a href="https://github.com/TanStack/query/commit/ccc843ea44220ba4fb931fd3a0fe06f9e0f9ec74"><code>ccc843e</code></a> test({react,preact}-query/useQueries): move type-only tests to 'useQueries.te...</li> <li><a href="https://github.com/TanStack/query/commit/415461346f319db94c47c9ff1dc47a1b845b6709"><code>4154613</code></a> test({react,preact}-query/useMutation): split 'should handle conditional logi...</li> <li><a href="https://github.com/TanStack/query/commit/8bb5fdea3e78c20d7d25c8017a0a2f23c6508996"><code>8bb5fde</code></a> test({react,preact}-query/useMutation): split 'should pass meta to mutation' ...</li> <li><a href="https://github.com/TanStack/query/commit/87426a301609fa56ac595a8d26b846e0ef1ee788"><code>87426a3</code></a> test(react-query): replace deprecated 'toBeCalledTimes' with 'toHaveBeenCalle...</li> <li><a href="https://github.com/TanStack/query/commit/feb1efd804c1262106f72c8adc1d82a8ce9cfbb0"><code>feb1efd</code></a> test(*): move 'vi.useRealTimers' to the end of 'afterEach' so cleanup runs un...</li> <li><a href="https://github.com/TanStack/query/commit/f3d8d2abbf15bf81ff7575d3be9845d7b402f25a"><code>f3d8d2a</code></a> ci: Version Packages (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10774">#10774</a>)</li> <li><a href="https://github.com/TanStack/query/commit/532bb298fba15e945e69c6ee4edc0c759ff21324"><code>532bb29</code></a> fix(tests): disable local coverage instrumentation (<a href="https://github.com/TanStack/query/tree/HEAD/packages/react-query/issues/10776">#10776</a>)</li> <li>Additional commits viewable in <a href="https://github.com/TanStack/query/commits/@tanstack/react-query@5.101.2/packages/react-query">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
faaa9b22e5 |
build(deps-dev): bump storybook from 10.4.2 to 10.4.6 (#9063)
Bumps [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core) from 10.4.2 to 10.4.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/releases">storybook's releases</a>.</em></p> <blockquote> <h2>v10.4.6</h2> <h2>10.4.6</h2> <ul> <li>CSF: Allow partial globals overrides in story and meta annotations - <a href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>, thanks <a href="https://github.com/TheSeydiCharyyev"><code>@TheSeydiCharyyev</code></a>!</li> <li>Dependencies: Upgrade esbuild - <a href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>, thanks <a href="https://github.com/Kakadus"><code>@Kakadus</code></a>!</li> </ul> <h2>v10.4.5</h2> <h2>10.4.5</h2> <ul> <li>Core: Rework AI checklist feature gate - <a href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>Preview: Stop mixed CSF3+4 stories getting core annotations injected twice - <a href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>, thanks <a href="https://github.com/JReinhold"><code>@JReinhold</code></a>!</li> </ul> <h2>v10.4.4</h2> <h2>10.4.4</h2> <ul> <li>Telemetry: Add timeout to event-log POST to prevent build hang - <a href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>, thanks <a href="https://github.com/badams"><code>@badams</code></a>!</li> </ul> <h2>v10.4.3</h2> <h2>10.4.3</h2> <ul> <li>Addon Docs: Fix Primary and Controls blocks not rendering in custom MDX pages - <a href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>, thanks <a href="https://github.com/NYCU-Chung"><code>@NYCU-Chung</code></a>!</li> <li>Core: Respect !dev tag on MDX docs in sidebar - <a href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>, thanks <a href="https://github.com/JReinhold"><code>@JReinhold</code></a>!</li> <li>React: Add support for resolving subcomponents attached as properties of a parent component - <a href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>, thanks <a href="https://github.com/yatishgoel"><code>@yatishgoel</code></a>!</li> <li>UI: Prevent docs page scroll reset on HMR re-render - <a href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>, thanks <a href="https://github.com/LongTangGithub"><code>@LongTangGithub</code></a>!</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md">storybook's changelog</a>.</em></p> <blockquote> <h2>10.4.6</h2> <ul> <li>CSF: Allow partial globals overrides in story and meta annotations - <a href="https://redirect.github.com/storybookjs/storybook/pull/34985">#34985</a>, thanks <a href="https://github.com/TheSeydiCharyyev"><code>@TheSeydiCharyyev</code></a>!</li> <li>Dependencies: Upgrade esbuild - <a href="https://redirect.github.com/storybookjs/storybook/pull/35157">#35157</a>, thanks <a href="https://github.com/Kakadus"><code>@Kakadus</code></a>!</li> </ul> <h2>10.4.5</h2> <ul> <li>Core: Rework AI checklist feature gate - <a href="https://redirect.github.com/storybookjs/storybook/pull/35053">#35053</a>, thanks <a href="https://github.com/Sidnioulz"><code>@Sidnioulz</code></a>!</li> <li>Preview: Stop mixed CSF3+4 stories getting core annotations injected twice - <a href="https://redirect.github.com/storybookjs/storybook/pull/35094">#35094</a>, thanks <a href="https://github.com/JReinhold"><code>@JReinhold</code></a>!</li> </ul> <h2>10.4.4</h2> <ul> <li>Telemetry: Add timeout to event-log POST to prevent build hang - <a href="https://redirect.github.com/storybookjs/storybook/pull/35085">#35085</a>, thanks <a href="https://github.com/badams"><code>@badams</code></a>!</li> </ul> <h2>10.4.3</h2> <ul> <li>Addon Docs: Fix Primary and Controls blocks not rendering in custom MDX pages - <a href="https://redirect.github.com/storybookjs/storybook/pull/34496">#34496</a>, thanks <a href="https://github.com/NYCU-Chung"><code>@NYCU-Chung</code></a>!</li> <li>Core: Respect !dev tag on MDX docs in sidebar - <a href="https://redirect.github.com/storybookjs/storybook/pull/35031">#35031</a>, thanks <a href="https://github.com/JReinhold"><code>@JReinhold</code></a>!</li> <li>React: Add support for resolving subcomponents attached as properties of a parent component - <a href="https://redirect.github.com/storybookjs/storybook/pull/34967">#34967</a>, thanks <a href="https://github.com/yatishgoel"><code>@yatishgoel</code></a>!</li> <li>UI: Prevent docs page scroll reset on HMR re-render - <a href="https://redirect.github.com/storybookjs/storybook/pull/35021">#35021</a>, thanks <a href="https://github.com/LongTangGithub"><code>@LongTangGithub</code></a>!</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/storybookjs/storybook/commit/5496a4270da7f3a8e0203185792685cba671fdc5"><code>5496a42</code></a> Bump version from "10.4.5" to "10.4.6" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/a80a5afdddc48e741edffabcfe5f7be4a559023e"><code>a80a5af</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34985">#34985</a> from TheSeydiCharyyev/fix/issue-34951-partial-globals</li> <li><a href="https://github.com/storybookjs/storybook/commit/5b929cadfbef571342b48b2039b31cddfd0ef894"><code>5b929ca</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35157">#35157</a> from Kakadus/update-esbuild</li> <li><a href="https://github.com/storybookjs/storybook/commit/48e7b20074222ed926d14fb6c678c2edfc86ee7b"><code>48e7b20</code></a> Bump version from "10.4.4" to "10.4.5" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/730f744aa65abdb73479ee119c5356070c624040"><code>730f744</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35094">#35094</a> from storybookjs/jeppe-cursor/a236965c</li> <li><a href="https://github.com/storybookjs/storybook/commit/dc88f70020c22a690f5dbb3e60c230fffece1a61"><code>dc88f70</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35053">#35053</a> from storybookjs/sidnioulz/double-gate-ai-optin</li> <li><a href="https://github.com/storybookjs/storybook/commit/5adebe753f29d414d1e214e935c94d6e5451861f"><code>5adebe7</code></a> Bump version from "10.4.3" to "10.4.4" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/ce1491d9e4c6d2b42864028fdf57801b855fc573"><code>ce1491d</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/35085">#35085</a> from badams/fix/telemetry-fetch-timeout</li> <li><a href="https://github.com/storybookjs/storybook/commit/624e6187fd462e56719cbd80c1b4bfb67b68fc89"><code>624e618</code></a> Bump version from "10.4.2" to "10.4.3" [skip ci]</li> <li><a href="https://github.com/storybookjs/storybook/commit/c89882282295be3bc05b3a366916c53d7a499841"><code>c898822</code></a> Merge pull request <a href="https://github.com/storybookjs/storybook/tree/HEAD/code/core/issues/34496">#34496</a> from NYCU-Chung/fix/docs-blocks-custom-mdx</li> <li>Additional commits viewable in <a href="https://github.com/storybookjs/storybook/commits/v10.4.6/code/core">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
f10464fee4 |
build(deps): bump @radix-ui/react-slot from 1.2.4 to 1.3.0 (#9066)
Bumps [@radix-ui/react-slot](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slot) from 1.2.4 to 1.3.0. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/radix-ui/primitives/blob/main/packages/react/slot/CHANGELOG.md">@radix-ui/react-slot's changelog</a>.</em></p> <blockquote> <h2>1.3.0</h2> <h3>Added generic type arguments for <code>SlotProps</code> and <code>createSlot</code></h3> <p><code>SlotProps</code> and <code>createSlot</code> now accept generic type arguments to specify the type of element a slot should render, as well as its props.</p> <pre lang="tsx"><code>const Slot = createSlot<HTMLButtonElement, MyCustomButtonProps>('Slot'); </code></pre> <h2>1.2.5</h2> <ul> <li>Fixed infinite re-render loop in React 19 caused by <code>Slot</code> creating a new ref callback on every render</li> <li>Added support for nested <code>Slottable</code> via a render prop, so a slotted element can be wrapped while still merging Slot props and refs onto it</li> <li>Added repository.directory to all package.json files</li> <li>Improved error messages for invalid slot children</li> <li>Updated dependencies: <code>@radix-ui/react-compose-refs@1.1.3</code></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slot">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for <code>@radix-ui/react-slot</code> since your current version.</p> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
59092e85d5 |
[codex] Fix work timeline actor avatars (#9152)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The work timeline UI visualizes agent and human activity across kickoff chips and the Gantt chart. > - The timeline actor chips were falling back to generic initials or blank circular avatars instead of using the richer identity data already available elsewhere in the app. > - Agent rows should match the sidebar identity treatment, and human entries should use the user's configured avatar image when one exists. > - This pull request teaches the timeline avatar renderer to prefer configured agent icons and human avatar URLs, while preserving initials as a fallback. > - The benefit is a more recognizable work timeline that matches the rest of the Paperclip UI. ## Linked Issues or Issue Description No public GitHub issue exists for this UI bug. The underlying issue: work timeline actor avatars did not consistently use the available actor identity assets. Agents appeared as generic white-circle initials instead of their configured sidebar icons, and human kickoff entries appeared as initials even when the user had an avatar image. Related prior timeline work: #8875 and #8880. No open duplicate PR was found for this avatar correction. ## What Changed - Updated the work timeline actor avatar renderer to show configured agent icons for agent rows and chips. - Updated human kickoff avatar rendering to prefer the user avatar image and fall back to initials only when no image is available. - Added regression coverage for agent sidebar-style icons and human avatar images in `WorkTimelineChart`. ## Verification - `pnpm exec vitest run ui/src/components/timeline/WorkTimelineChart.test.tsx` - `pnpm --filter @paperclipai/ui typecheck` - `git diff --check origin/master...HEAD` ## Risks Low risk. The change is scoped to work timeline avatar presentation and preserves the existing initials fallback when configured icons or avatar images are unavailable. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, GPT-5-class coding agent in local tool-use mode with shell, git, test execution, and GitHub connector access. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
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. |
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |
||
|
|
bded6ac5c7 |
[codex] Polish operator issue workflow UI (#9091)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board UI is where operators create issues, inspect issue-thread decisions, write markdown, and move between issue workflow surfaces. > - A broad recovered branch mixed these operator workflow polish fixes with unrelated backend, pipeline, plugin, eval, and work-product changes. > - Reviewers need the operator UI workflow fixes in a small PR that can be understood without pulling in the rest of that recovery branch. > - This pull request extracts only the issue workflow UI slice: interaction cards, markdown editing fallback behavior, create-issue work mode shortcuts, file-viewer URL handling, and issue navigation scroll behavior. > - The benefit is a lower-risk review path for operator workflow fixes while keeping unrelated execution-workspace and server work out of this PR. ## Linked Issues or Issue Description - Refs #8866, the closed broad source PR that this focused slice was extracted from. - Related: #8228 is an open UI polish PR, but its file list does not overlap this branch. - Related: #4090 is older merged operator workflow polish context. No public GitHub issue exists for this exact extracted slice. The problem is that several small operator issue-workflow fixes were bundled inside a broad recovery branch, making them hard to review and ship independently. ## What Changed - Removed interaction continuation wake-policy labels from issue-thread interaction card headers and updated the card test/story copy accordingly. - Added a markdown editor error boundary so rich editor render crashes fall back to a raw textarea instead of breaking the compose surface. - Made the create-issue work-mode shortcut accept ctrl-period and iOS hardware-keyboard command-period-as-Escape behavior without dismissing the dialog. - Fixed file-viewer URL navigation to compare against the live browser search string when router state is stale. - Restored scroll reset when navigating from an issue detail route back to the issue index, while preserving browser-history restoration behavior. ## Screenshots Before removing the continuation wake-policy badge from interaction card headers:  After removing the wake-policy badge:  ## Verification - `pnpm exec vitest run ui/src/components/IssueThreadInteractionCard.test.tsx ui/src/components/MarkdownEditor.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/context/FileViewerContext.test.ts ui/src/lib/navigation-scroll.test.ts` — 5 files, 102 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `git diff --check` — passed. ## Risks Low risk. The PR is limited to UI workflow components/helpers and their tests. Main behavioral risks are keyboard shortcut edge cases across browsers and fallback editor rendering, both covered by focused tests. ## Model Used OpenAI Codex, GPT-5-based coding agent (`gpt-5` family; exact served variant and context window are not exposed in this runtime), with terminal, Git, GitHub, and test execution tools. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
dfc256a543 |
[codex] Add heartbeat policy eval coverage (#9087)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents for work. > - The relevant subsystem is the agent heartbeat policy surface: the Paperclip skill, default onboarding AGENTS.md, new-agent runtime defaults, and promptfoo eval coverage for agent behavior. > - A broad recovery PR collected several unrelated local-mainline changes, which made review too large and mixed policy/eval updates with server execution and UI work. > - This PR extracts only the heartbeat policy and prompt-eval slice so reviewers can assess the behavior contract independently. > - The eval additions cover scoped wake handling, idle no-op behavior, dependency-blocked comment triage, final disposition, budget hard stops, and Phase 5 memory/control-surface policy expectations. > - The benefit is a narrower review surface plus deterministic follow-up guidance for server/shared tests that should back these prompt-level checks. ## Linked Issues or Issue Description Refs #8866 No public issue was filed for this split. This is a focused extraction from the closed broad recovery PR so heartbeat policy and eval coverage can be reviewed separately from execution behavior, work-product feature work, plugin hardening, pipeline health, and unrelated UI polish. ## What Changed - Added promptfoo release-gate cases for scoped wake payload handling, idle exits, dependency-blocked comment triage, final disposition, and budget hard-stop behavior. - Added Phase 5 memory/control-surface prompt eval cases for provider binding precedence, provenance/audit fields, hook cost/trust handling, and auditable board command surfaces. - Documented how these prompt evals map to deterministic server/shared follow-up coverage. - Updated agent policy guidance so operator-facing engineering outputs such as PRs, branches, commits, previews, and runtime services get matching work products. - Defaulted new agent runtime config to skip timer heartbeats when there is no actionable work, with focused test coverage. ## Verification - `cd evals/promptfoo && npx promptfoo@latest validate -c promptfooconfig.yaml` passes. - `/srv/paperclip/home/paperclipai/paperclip/node_modules/.bin/vitest run ui/src/lib/new-agent-runtime-config.test.ts` passes in an isolated worktree after `pnpm install --ignore-scripts --frozen-lockfile` created workspace links. - A live promptfoo eval was not run because `OPENROUTER_API_KEY`, `OPENAI_API_KEY`, and `ANTHROPIC_API_KEY` were unset in the workspace. ## Risks Low-to-medium risk. The runtime default reduces timer-driven empty heartbeats for newly created agents, so the main behavioral risk is missing an edge case where timer wakes were expected despite no actionable work. The promptfoo additions are deterministic assertion coverage and documentation-only until a live eval is run with provider credentials. > 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-based Codex coding agent in the Paperclip local Codex adapter environment; exact hosted model ID and context window were not exposed to the agent runtime. Tool use included shell, git, promptfoo validation, Vitest, and the GitHub connector/CLI. ## 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> |
||
|
|
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> |
||
|
|
574b4e71db |
[codex] Bundle UI webfonts with the app (#9020)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The browser UI depends on the Inter font family for its intended visual baseline > - The app previously referenced remote Google Fonts stylesheets at runtime > - That meant self-hosted, offline, or privacy-sensitive deployments could lose the intended typography or depend on an external request > - This pull request bundles the required Inter variable font files with the UI and serves them from the app > - A normal UI test now covers the static assets and CSS wiring without adding a package script or build step > - The benefit is a more reliable, self-contained UI that does not rely on third-party webfont hosting ## Linked Issues or Issue Description No public GitHub issue was found for this exact gap. **Subsystem affected** ui/ — React + Vite board UI **Problem or motivation** Paperclip's UI should ship the webfont assets it references so production and self-hosted deployments render consistently without reaching out to Google Fonts at runtime. **Proposed solution** Bundle the Inter variable font files under the UI public assets, load them with local `@font-face` declarations, document the bundled assets, and cover the source assets/CSS wiring with a normal UI Vitest test. **Alternatives considered** Keeping the remote stylesheet dependency is simpler, but leaves deployments dependent on external font hosting. Using system fonts only would avoid the asset footprint, but changes the intended UI typography. **Roadmap alignment** This is a focused UI reliability/polish fix, not a roadmap-level core feature. **Additional context** Searched public GitHub issues and PRs for `webfonts repo:paperclipai/paperclip`; no duplicates or closely related open items were found. ## What Changed - Added bundled Inter variable font assets and their notice under `ui/public/fonts/`. - Replaced remote Google Fonts imports with local `@font-face` declarations using relative public-asset URLs that remain subpath-safe from built CSS. - Documented the local font asset expectation in development and UI spec docs. - Removed the follow-up font asset checker scripts and package/build wiring after review feedback clarified they are not required for building the UI. - Added `ui/src/lib/ui-font-assets.test.ts` to verify the shipped WOFF2 files, notice text, and CSS font references through the normal UI test suite. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/lib/ui-font-assets.test.ts --config vitest.config.ts` - Passed. - Confirms the bundled font files exist, are WOFF2 files, have notice coverage, and are referenced by `ui/src/index.css`. - `pnpm --filter @paperclipai/ui build` - Passed. - Confirmed the UI still builds after removing the checker from `ui/package.json`. - Confirmed `ui/dist/fonts/` contains `InterVariable.woff2`, `InterVariable-Italic.woff2`, and `NOTICE.md` after the build. - The UI build emitted existing warnings about `::highlight(...)`, a dynamic/static import overlap for `MarkdownEditor.tsx`, unresolved relative public font URLs left for runtime resolution, and large chunks, but completed successfully. ## Risks Low risk. This adds static font assets and swaps the font source from a remote stylesheet to same-origin files. The main tradeoff is a larger repository/UI asset footprint from the bundled `.woff2` files. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, GPT-5-based coding agent, tool-enabled terminal/GitHub workflow with reasoning support. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have 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> |
||
|
|
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> |
||
|
|
8a058f9d79 |
fix: deduplicate adapter-agnostic config keys (#9058)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - When you swap an agent's adapter (e.g. from one LLM provider to another), the server merges the incoming PATCH body with stored config — keys listed in \`ADAPTER_AGNOSTIC_KEYS\` are preserved regardless of which adapter is active > - That constant was defined independently in two places: \`server/src/agents.ts\` (used by the adapter-swap route) and \`ui/src/lib/agent-config-patch.ts\` (used by the UI patch builder) > - PR #8975 fixed the bug where \`paperclipSkillSync.desiredSkills\` was dropped on adapter swap by adding it to the server-side constant, but the UI-side copy was not updated in the same PR — creating ongoing drift risk > - This pull request hoists \`ADAPTER_AGNOSTIC_KEYS\` into \`packages/shared\` so both consumers import the same constant > - The benefit is a single source of truth: any future key addition is made in one place and both the server route and the UI patch builder pick it up automatically, with a drift guard to catch any accidental re-duplication ## Linked Issues or Issue Description Refs #8975 — follow-up deduplication: #8975 fixed the runtime bug but left the constant duplicated across server and UI. This PR closes that gap. ## What Changed - Added \`ADAPTER_AGNOSTIC_KEYS\` constant and \`AdapterAgnosticKey\` type to \`packages/shared/src/adapter-agnostic-keys.ts\` - Updated \`server/src/agents.ts\` to import the shared constant, removing the local copy - Updated \`ui/src/lib/agent-config-patch.ts\` to import the shared constant, removing the local copy - Added \`packages/shared/src/adapter-agnostic-keys.test.ts\`: drift guard asserting the expected key set and both consumer import sites ## Verification \`\`\`bash pnpm exec vitest run packages/shared/src/adapter-agnostic-keys.test.ts ui/src/lib/agent-config-patch.test.ts server/src/__tests__/agent-instructions-routes.test.ts pnpm --filter @paperclipai/shared typecheck pnpm --filter @paperclipai/server typecheck pnpm --filter @paperclipai/ui typecheck \`\`\` All 15 tests pass across the three files; all three packages typecheck clean. ## Risks Low risk — behavior-preserving refactor. The key set is unchanged; only the import source changes. The drift guard will fail loudly if someone accidentally re-introduces a local copy or modifies one without updating the other. > 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 - Provider: Anthropic - Model: Claude Sonnet 4.6 (\`claude-sonnet-4-6\`) - Context: standard context window, tool use enabled - Reasoning: standard mode (no extended thinking) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with \`Fixes: #\` / \`Closes #\` / \`Refs #\` OR (b) described the issue in-PR following the relevant issue template - [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 - [ ] 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> |
||
|
|
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> |
||
|
|
eb2cb916be |
fix(agents): preserve skill selection when switching adapter type (#8975)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Each agent runs on an adapter (`claude_local`, `codex_local`, …) and can be assigned company skills that are synced into its runtime > - An agent's desired-skill selection is persisted inside its single `adapterConfig` JSON blob under `paperclipSkillSync`, even though the selection is a company-level, adapter-agnostic choice > - When a user changes an agent's adapter type, both the server PATCH handler and the UI patch builder rebuild `adapterConfig` and carry over only a hardcoded allow-list of adapter-agnostic keys (`env`, `cwd`, instructions bundle, …) > - `paperclipSkillSync` was missing from both allow-lists, so switching adapters (e.g. claude_local → codex_local) silently wiped every assigned skill > - This pull request adds `paperclipSkillSync` to the adapter-agnostic preservation list on both layers and covers it with regression tests > - The benefit is that switching an agent's adapter no longer destroys its skill configuration — skills are preserved exactly like env/cwd/instructions already are ## Linked Issues or Issue Description Fixes #8974 ## What Changed - **Server (authoritative fix)** — `server/src/routes/agents.ts`: added `"paperclipSkillSync"` to the `ADAPTER_AGNOSTIC_KEYS` list in the `changingAdapterType` branch of `PATCH /agents/:id`. On an adapter-type change the handler now restores the skill-sync selection from the existing persisted config when the incoming config omits it — the same mechanism already used for `env`, `cwd`, and the instructions bundle. This protects every API/CLI client, not just the UI. - **UI (defense in depth)** — `ui/src/lib/agent-config-patch.ts`: added `"paperclipSkillSync"` to the client-side `ADAPTER_AGNOSTIC_KEYS` in `buildAgentUpdatePatch`, so the optimistic patch the client builds on an adapter switch stops stripping the key before it reaches the server. - **Tests** — added regression tests on both layers: - `server/src/__tests__/agent-instructions-routes.test.ts`: `PATCH`ing `adapterType` (claude_local → codex_local) with `replaceAdapterConfig: true` keeps `adapterConfig.paperclipSkillSync`. - `ui/src/lib/agent-config-patch.test.ts`: `buildAgentUpdatePatch` preserves `paperclipSkillSync` when the overlay changes the adapter type. ## Verification ``` # server (run from repo root) cd server && ../node_modules/.bin/vitest run \ src/__tests__/agent-instructions-routes.test.ts \ src/__tests__/agent-skills-routes.test.ts \ src/__tests__/agent-adapter-validation-routes.test.ts \ src/__tests__/agent-permissions-routes.test.ts # 83 passed ../node_modules/.bin/tsc --noEmit -p tsconfig.json # clean # ui cd ui && ./node_modules/.bin/vitest run src/lib/agent-config-patch.test.ts # 7 passed pnpm --filter @paperclipai/ui typecheck # clean ``` Both new tests fail without the corresponding source change (verified red → green). Manual: create an agent on `claude_local`, assign skills, switch it to `codex_local`, and confirm `GET /api/agents/:id/skills` still returns the desired skills. ## Risks Low risk. - The change only *adds* one key to an existing preservation allow-list; it does not alter how any other key is handled. Behavior for agents without a `paperclipSkillSync` block is unchanged (the key is simply absent and nothing is copied). - `paperclipSkillSync` is adapter-agnostic (company skill keys, not adapter-specific), so carrying it across an adapter switch is always safe — a target adapter that does not support skill sync just ignores it, and switching back restores the selection. - Same-adapter config edits already merged and preserved the key; this only closes the adapter-type-change gap, matching the existing env/cwd/instructions behavior. - Follow-up (not in this PR to keep it minimal): the server and client `ADAPTER_AGNOSTIC_KEYS` lists are maintained separately and already diverge (`instructionsFilePath` is client-only); a shared constant could prevent future drift. ## Model Used Claude Opus 4.8 (`claude-opus-4-8`, 1M-token context), extended thinking enabled, with tool use (file edit, shell, GitHub CLI) via Claude Code. A read-only sub-agent was used to trace the root cause across the server and UI layers. ## 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 (bug fix, not a feature) - [x] I have searched GitHub for duplicate or related PRs and linked them above (none found) - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (`fix/preserve-skills-on-adapter-type-switch`) 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 (N/A — internal config-preservation fix, no user-facing docs or API contract change) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green (pending CI on this PR) - [ ] 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 |
||
|
|
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> |
||
|
|
7bfaaadcb8 | Add dependency wake reconciliation backstop (#8943) | ||
|
|
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> |
||
|
|
47448721e1 |
[codex] Clean up issue properties pane (#8941)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The issue details sidebar is a high-traffic operator surface for scanning task state, ownership, policy, relationships, and external references. > - The previous properties pane mixed too much behavior in one large component and several rows could overflow or become hard to scan with long labels and relation lists. > - The UI needed a narrower, more reusable structure so compact property rows, relation pills, external URL rows, and picker triggers behave consistently. > - This pull request splits the properties pane into focused helper modules and tightens the pane's layout, truncation, popover, and overflow behavior. > - The benefit is a denser, more stable properties pane that stays usable when issues have long titles, many relationships, external URLs, or execution policy IDs. ## Linked Issues or Issue Description No public issue exists for this work. I searched GitHub issues and PRs for `IssueProperties properties pane`; there was no duplicate issue and the matching PRs were unrelated test stabilization or other work. ### Problem or motivation The board issue details properties pane is a frequent operator workflow surface, but it was implemented as one large component and several rows could become hard to scan with long labels, many relationships, external URLs, or execution policy IDs. ### Proposed solution Split the properties pane into focused modules, tighten compact row layout and truncation behavior, add bounded previews with explicit expansion controls for long relation and URL lists, and make execution policy ID generation work on insecure origins as well as normal browser origins. ### Alternatives considered A smaller patch inside the existing monolithic component would fix individual overflow symptoms, but it would keep related primitives, picker behavior, relation controls, and external URL rendering tangled in one file. The split keeps the behavior easier to test and review without changing public APIs. ### Roadmap alignment This is an incremental UI quality improvement to the existing board task details surface. I checked `ROADMAP.md` and did not find overlapping planned core feature work. ## What Changed - Split the issue properties pane into focused modules for helpers, primitives, relation controls, property pickers, and external object rows. - Cleaned up row spacing, truncation, picker trigger alignment, scroll behavior, status color coverage, and long-value titles. - Added bounded previews and expand/collapse controls for blocking, sub-task, related-task, and external URL lists. - Fixed execution policy ID generation so insecure origins fall back to a stable base URL instead of throwing. - Updated Storybook issue-management stories and expanded unit coverage for the new properties pane behavior. ## Verification - `git diff --check origin/master..HEAD` - `pnpm --filter @paperclipai/ui exec vitest run src/components/IssueProperties.test.tsx` — 38 tests passed ## Risks Low to moderate risk. The changes are UI-only, but they touch a frequently used task details surface. The main risk is a subtle layout regression in an untested viewport or issue shape; the branch adds targeted coverage for long relation and external URL lists. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI GPT-5 Codex coding agent with repository 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> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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 |