mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-21 16:27:18 +02:00
6cfdcbb659ba82da5aeccbdc14c3eb092766c6bf
24
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
582911ba74 |
fix(access): give Operators default company editing permissions (#15377)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Human company members receive permission grants from their role preset. > - Human invitations use the Operator role by default. > - The old Operator preset only granted task assignment, so ordinary members could not edit agents or manage connections. > - This pull request gives Operators company editing and audit access while keeping join approval and member-permission management separate. > - Members can configure their agents and accounts without an Owner role. ## Linked Issues or Issue Description **What existing behavior does this improve?** The default permission grants for human Operators and the invitation role description. **Subsystem affected** server/ permission presets and invitation authorization, plus ui/ invitation and tool access gates. **Current behavior** Operators receive only `tasks:assign` as an explicit default grant. Agent configuration and managed account setup fail their permission checks. **Proposed behavior** Operators receive agent creation/configuration, skills, environments, invitations, task assignment, pipelines, connections, tool management/use, and audit grants. The preset excludes `joins:approve` and `users:manage_permissions`. Operators can invite Operators and Viewers. Inviting a role with either excluded power requires that power, so invitations cannot bypass the restriction. **Reason and benefit** Ordinary company members can edit company work and connect accounts through the existing routes. **Breaking changes** The Operator preset grants more permissions. The existing startup and Cloud sign-in seeding paths can insert these missing grants for existing Operators. They retain custom grant scopes. Explicit invitation grants still take precedence. Inviting Admins now requires join approval; inviting Owners also requires member-permission management. This PR adds no migration or new backfill path. Related: #5945 describes missing role grants in another membership entry point. This PR changes the preset and does not change that endpoint. ## What Changed - Expanded the Operator preset to 14 company editing, invitation, tool, and audit grants. - Kept join approval and member-permission management out of the preset. - Required those powers when an invitation's selected human role includes them, preventing Operators from delegating the excluded powers through Owner/Admin invitations. - Updated the invitation role copy and the product specifications. - Allowed active Operators (including legacy Member roles) through the invite shortcut and advanced tool/profile UI gates. Kept inactive memberships, Viewers, and other companies excluded; API grants remain authoritative. - Added tests for the default Operator grants, both excluded actions, agent editing, company boundaries, and invitation role authorization. - Simplified adapter-route test imports so authorization errors and the error handler use one module graph; retained the upstream mock-initialization fix. - Kept Owner/Admin/Viewer presets and explicit invitation grants unchanged. Added no EE code or database migration. ## Verification - Permission and invitation tests: 38 passed across access service, invitation defaults, and invitation creation routes. - UI access tests: 61 passed across invitation shortcuts, Operator tool/profile access, and invitation UI. - Adapter route tests: 15 passed after resolving the upstream test setup conflict. - `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates`: passed on the final branch. - The initial local `pnpm test:run` general-server batch reported three tool-access failures and eight upload-helper timeouts. Both complete affected suites passed in isolation on the final branch: 403 tests. The initial full local run was not green. - Both complete tool-access and adapter route suites also passed on an untouched snapshot of base `88ff98b83`: 387 tests. The earlier tool failures did not reproduce there. - [All CI gates passed](https://github.com/paperclipai/paperclip/actions/runs/37527422346) for `068be153b9c2a064f2aaccc0627fdf458e73747e`, including the previously failing serialized adapter lane, general tests, E2E, typecheck, build, Runner checks, and canary dry run. - Greptile scored that exact commit 5/5. Superagent passed. Both invitation review threads are resolved. ## Risks - Operators gain broad company editing and invitation access by design. - Existing default seeding can add the new missing grants during startup or Cloud sign-in. It does not replace existing scopes. - Company boundaries and the two excluded permission checks still apply. - An Admin without member-permission management can no longer invite an Owner. Operators retain invitation access for Operator/Viewer roles and agent-only invites. - This PR changes company permissions. Cloud workspace invitation rules remain separate. ## Model Used OpenAI Codex, GPT-6. The exact deployment model ID and context window were not exposed in this session. Used repository inspection, code editing, shell execution, and test 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 a merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d6fa1fd1ef |
feat(ui): streamline account menu profile access and add Invite shortcut (#14480)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Humans work in teams, so Paperclip has a multi-user system with logins, profiles, and a company sidebar. > - The account menu in the lower-left corner of the sidebar is the main entry point for a user's own settings. > - The account menu spent half of its rows on "View profile" and "Edit profile". Users open these rows rarely. > - The account menu had no fast path to invite a new member. The invite flow is different on a self-hosted instance and on Paperclip Cloud. > - This pull request removes the two profile rows, makes the header a link to the profile, adds an "Edit profile" button on the profile page, and adds an "Invite" row. > - The benefit is a shorter account menu that keeps profile access and gives users with the invite permission a one-click path to invite people. ## Linked Issues or Issue Description No public GitHub issue exists for this change. The description below follows the enhancement template. Refs #14060. That earlier pull request holds the first two commits and the first Greptile review. It closed when the branch got a new name to remove an internal ticket id. All Greptile findings from both reviews are fixed in this branch. **What existing behavior does this improve?** The account menu in the sidebar (`SidebarAccountMenu` and its `.production` variant) and the user profile page at `/u/:userSlug`. **Subsystem affected** ui/ — React + Vite board UI **Current behavior** The account menu shows the user's picture and name at the top. Below them, the menu shows "View profile" and "Edit profile" rows, then the other rows. The header is not a link. The menu has no row to invite people. On a self-hosted instance, the user must open Company settings, then Members, then the Invites tab. On Paperclip Cloud, the user must open the Members page and use the Cloud People link there. **Proposed behavior** The account menu does not show "View profile" or "Edit profile". The picture and name at the top of the menu are a link to the user's own profile page. The profile page shows an "Edit profile" button when the viewer looks at their own profile. The account menu shows an "Invite" row with the same `UserPlus` icon as the company menu. On a self-hosted instance, the row opens the Members page on the Invites tab, and shows only to boards that hold the `users:invite` grant (company owners and admins, instance admins, and local boards). On Paperclip Cloud, the row opens the People settings for the current stack, and shows only to the owner or admin of the stack, the same rule the Members page uses. **Reason and benefit** Users open their profile rarely, but the two rows took half of the menu. Inviting people is a common task, but it needed three clicks and a different path on Cloud. The new menu is shorter, keeps profile access in one tap on the header, and gives one "Invite" entry point on both hosting modes to the users who can invite. **Breaking changes** None. Routes, API responses, and settings keys do not change. The profile page and the invite pages keep their current URLs. ## What Changed - `SidebarAccountMenu.tsx` and `SidebarAccountMenu.production.tsx`: remove the "View profile" and "Edit profile" rows. Make the picture and name header a link to the user's profile. Add the "Invite" row after "Settings" in the streamlined menu and first in the production menu. - Header structure: `master` added a staging commit SHA link under the email in the same header. The profile link is now a stretched overlay behind the header content, so the SHA anchor sits beside the email and the header has no nested anchors. - `ui/src/lib/userProfileLinks.ts` (new): build the profile path from the user id first. The profile endpoint treats the id as the one unique slug, so two members with the same display name get different links. Name and email are a fallback only when the session has no id. - `ui/src/hooks/useCloudInviteUrl.ts` (new): read the Cloud stack portfolio and return the People settings URL only when the current stack role is owner or admin. This is the same rule as the Members page. - `ui/src/hooks/useCompanyInviteAccess.ts` (new): read the current board access snapshot and report whether the board may invite people to the selected company on a self-hosted instance. Local boards and instance admins pass. Other boards need an active owner or admin membership, the roles that carry `users:invite`. This follows the same client-side gate pattern as `ToolsAdminGate` and the run ledger. The server stays authoritative. - Invite row visibility: the row is hidden when the operator hides `company.members` or `company.invites`, and until the health check resolves. On self-hosted instances, the row is hidden until the board access snapshot loads and when the board cannot invite. On Cloud, the row is hidden when no People URL can be built. The in-app Invites tab is never a fallback on Cloud, because it drives a different flow. - `ui/src/pages/UserProfile.tsx`: add an "Edit profile" button that links to `/company/settings/instance/profile`. The button shows only on the viewer's own profile and follows the `instance.profile` hidden-settings gate. - Tests: extend `SidebarAccountMenu.test.tsx`; add `userProfileLinks.test.ts`, `UserProfile.test.tsx`, and `useCompanyInviteAccess.test.ts`. - No documentation references the removed menu rows, so no docs change is needed. ## Verification Run the focused tests from the `ui/` directory: ```bash pnpm vitest run src/components/SidebarAccountMenu.test.tsx src/hooks/useCompanyInviteAccess.test.ts src/lib/userProfileLinks.test.ts src/pages/UserProfile.test.tsx ``` - 52 tests pass in these four files. They cover the header link by user id, the removed rows, the header overlay with no nested anchors, the self-hosted invite target, the self-hosted permission gate (owner, admin, instance admin, and local board see the row; an operator does not, on both menu variants), the Cloud invite target with no `target="_blank"`, the menu order, the hidden-settings gate on both variants, the Cloud role gate (a plain member sees no row), the no-fallback rule when Cloud stack metadata is missing, the staging commit SHA link from `master`, and the own-profile-only "Edit profile" button. - `tsc -b` in `ui/` reports no errors in the changed files. The only errors are pre-existing `@paperclipai/plugin-sdk/ui` resolution errors in `PluginOrganizationSwitcher.tsx` from an unbuilt workspace package. Manual steps: 1. Sign in and open the account menu in the lower-left corner. Confirm the menu has no "View profile" or "Edit profile" rows. 2. Click your picture or name at the top of the menu. Confirm your profile page opens and shows an "Edit profile" button. 3. Open another user's profile. Confirm the page shows no "Edit profile" button. 4. On a self-hosted instance, as a company owner or admin, click "Invite". Confirm the Members page opens on the Invites tab. As an operator or viewer, confirm the menu shows no "Invite" row. 5. On Paperclip Cloud, as a stack owner or admin, click "Invite". Confirm the Cloud People settings page opens in the same tab. As a plain member, confirm the menu shows no "Invite" row. ## Risks - Low risk. The change is limited to the UI and touches ten files. - Users who know the "View profile" and "Edit profile" rows must learn the new header link. The header has hover and focus styles to show that it is a link. - On self-hosted instances, the "Invite" row depends on the board access snapshot from `/cli-auth/me`, which other gates in the UI already use. A member with a custom `users:invite` grant but an operator or viewer role does not see the row. That member can still use the Members page. The row is a shortcut, not the only path. - On Paperclip Cloud, the "Invite" row depends on the stack portfolio query. When that query fails or the role is unknown, the menu hides the row instead of sending the user to the wrong flow. - Both menu variants change together, so a behavior difference between them is not expected. ## Model Used - Provider: Anthropic. Model: Claude Fable 5.1 (`claude-fable-5-1`). - Run through Claude Code on the Claude Agent SDK inside a Paperclip `claude_local` agent, with extended thinking and tool use (file edits, shell, tests, GitHub API). - The model wrote the code, the tests, and this description. A human reviewed the pull request and requested the review fixes. ## 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 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Bender (Fable) <bender@paperclip.local> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com> |
||
|
|
270afd2fb8 |
feat(ui): show running commit in staging account menu (#14410)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The account menu shows the signed-in user's identity. > - Staging users need to know which server commit is running after a deploy. > - The health endpoint already returns that commit, but the menu does not show it. > - This pull request adds the short commit below the email on staging hosts. > - Users can open the menu to check a deploy without opening deployment tools. ## Linked Issues or Issue Description **What existing behavior does this improve?** The account menu on staging instances. **Current behavior** The menu shows the user's name and email. It does not show the running server commit. **Proposed behavior** On `*.staging.paperclip.app`, show `SHA 8751e2d` below the email. Use the current `/api/health` commit. Show the full SHA on hover and link to the commit on GitHub. Refresh the health query when the menu opens. Hide the label on other hosts and when commit metadata is unavailable. **Reason and benefit** A user can confirm which commit a staging instance runs after an automatic deploy. **Breaking changes** None. The server already returns the commit field. Refs #14060 for related account-menu work. This change adds deployment information only. ## What Changed - Add the existing health response commit field to the UI type. - Share the staging host check and a separate health query across both account-menu variants. A menu refresh failure leaves the access gate health state unchanged. - Show a short SHA below the email. Link to the full commit on GitHub and include the full SHA in its accessible name and hover title. - Document the staging label and cover staging hosts, other hosts, missing metadata, refresh on reopen, and request failure isolation. ## Verification - `pnpm exec vitest run ui/src/components/SidebarAccountMenu.test.tsx` — 24 tests passed. - `pnpm check:token-gates` — passed. - `pnpm -r typecheck` — passed. - `pnpm build` — passed. The UI build and typecheck also passed again after review fixes. - Full test matrix — passed on the latest commit in [CI](https://github.com/paperclipai/paperclip/actions/runs/36447810742). The local `pnpm test:run` was stopped before completion after CI finished the same suites. The focused local tests, full local typecheck, and full local build passed. - Browser shard 6 passed on one rerun. Its first attempt lost part of the draft text in the existing attachment-receipt reload test. No code changed for the rerun. - Rendered the real account menu in a local browser fixture with a staging hostname condition and mocked health response. Confirmed the SHA fits below the email in the dark menu. - Greptile review — 5/5, all review threads resolved. - Manual check after deployment: open the menu on a staging host and compare the SHA with `/api/health`. Open the menu again after a deploy to refresh it. Confirm the label is absent on production and localhost. ## Risks - Low risk. Each menu opening on staging can make one additional health request. - The host check applies to `*.staging.paperclip.app`. Other staging domains will need an explicit update. - The label identifies the running server commit. It can briefly show cached data while the request completes. ## Model Used OpenAI Codex, GPT-6. The exact model variant and context window are not exposed in this session. Used code execution, repository inspection, and browser inspection. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #123` / `Refs #123` 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> |
||
|
|
fe38085174 |
fix(ui): hide profile feedback flag on Cloud (#13292)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The sidebar provides account controls and a feedback link. > - Cloud now has Plain chat through the snippet support in #13168. > - The feedback flag creates a second feedback route on Cloud. > - This PR uses the existing Cloud metadata to hide the flag. > - Self-hosted users keep the existing feedback link. ## Linked Issues or Issue Description Refs #13168 and #10850. Related: #12778 proposes a separate native feedback relay; this PR only hides the existing flag on Cloud. **What happened?** Cloud users see both Plain chat and the profile feedback flag, which opens the external feedback form. **Expected behavior** Cloud users use Plain chat. Self-hosted users keep the profile feedback flag. **Steps to reproduce** Open a Cloud instance with Plain enabled and expand the sidebar. Both feedback controls are visible. ## What Changed - Use `useCloudInstance()` in both account-menu variants. - Render the feedback flag only when the sidebar is expanded and the instance is not Cloud. - Extend existing tests for Cloud and authenticated self-hosted behavior. ## Verification - Account-menu tests: 6 passed (`cd ui && pnpm exec vitest run src/components/SidebarAccountMenu.test.tsx`). - `pnpm check:token-gates`: passed. - `pnpm --filter @paperclipai/ui typecheck`: passed. - Full typecheck: failed in unchanged `plugin-workspace-diff` code (`editStateKey` required by `UseFileDiffInstanceProps`). - UI build: blocked by four missing exports in the installed `assistant-cloud` dependency, including `createRunReport`. - Repository build: failed on the same unchanged workspace-diff plugin types. - Full test suite: started, then stopped after broader validation hit dependency failures. Only the six targeted account-menu tests are claimed as passed. - Fresh installation used `--no-frozen-lockfile --lockfile=false` because the base lockfile and server manifest differ. No dependency or lockfile changes are included. - After deployment, check that Cloud has no profile feedback flag and self-hosted still links to `https://paperclip.ing/feedback`. ## Risks Low risk. The hook reads the existing health query cache and adds no request. CloudAccessGate loads health before the main UI mounts. The flag is hidden on all Cloud instances, so operators must keep Plain configured. No backend, settings, or Plain integration changes. ## Model Used OpenAI GPT-6 Codex, with code inspection and command execution. The exact model ID and context-window size are 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 - [ ] 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 |
||
|
|
5b56d430e9 |
feat(ui): refine core navigation and task detail (#12854)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The main navigation and task detail view are core operator surfaces. > - Several controls used different hover states, popover layouts, and spacing rules. > - Recent task actions also needed a compact menu and correct inbox archive behavior. > - These differences made the interface feel inconsistent and caused some content to look crowded or clipped. > - This pull request aligns these surfaces with the Paperclip design tokens and current interaction patterns. > - The benefit is a simpler and more consistent operator experience in light and dark modes. ## Linked Issues or Issue Description **What happened?** Profile and organization popovers used inconsistent layouts. Navigation controls used different hover and selected backgrounds. Task warnings and the composer could crowd nearby content. Archiving a recent task could also remove it from more than the inbox. **Expected behavior** Popover menus should use the same compact visual language. Navigation controls should share readable hover and selected tokens. Task detail content should keep consistent spacing. Archiving should hide a task from the inbox while keeping it in the task list. **Steps to reproduce** 1. Open the main sidebar in light or dark mode. 2. Open the profile and organization menus. 3. Hover navigation items, the organization trigger, the profile trigger, and the feedback flag. 4. Open a task with a warning banner and a long thread. 5. Use the recent task overflow menu and archive a task. **Paperclip version or commit** Reproduced on `master` before this branch. **Deployment mode** Local dev (`pnpm dev`). ## What Changed - Rebuilt the profile and organization popovers with compact token-based layouts. - Matched organization popover width and alignment to the profile popover. - Unified sidebar hover and selected states in light and dark modes. - Added a recent task overflow menu with rename, archive, and pause or restart actions. - Kept archived tasks in the task list while removing them from the inbox. - Improved warning banner and composer spacing in task detail views. - Added and updated focused UI tests for the changed behavior. ## Verification - `pnpm check:token-gates` passed. - `pnpm --filter @paperclipai/ui typecheck` passed. - The seven affected UI test files passed with 216 tests. - `pnpm --filter @paperclipai/ui build` passed. - GitHub CI passed the full build, typecheck and release registry, general test, serialized server, canary dry-run, and end-to-end matrices. - Greptile reviewed commit `6e296be85` at 5/5 with no outstanding actionable findings. ## Risks - Risk is limited to sidebar presentation, recent task actions, and task detail layout. - The recent task archive action now follows inbox-only archive semantics. - No database schema or public API contract changed. > I checked [`ROADMAP.md`](ROADMAP.md). This pull request does not duplicate planned core work. ## Model Used - OpenAI Codex, GPT-5.6. The model used high reasoning, tool use, and code execution. The context window size was not exposed. ## 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: Scott Tong <scott@scottsmbpm5max.lan> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
c38b59484c |
fix(ui): remove the Account badge and version line from the account menu (#12818)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The web UI has a sidebar account menu that opens from the user's name in the lower left > - The menu header shows an "Account"/"Local" badge and a "Paperclip <sha>" (or "Paperclip v<version>") build line next to the user's identity > - These labels add noise to the header and repeat information that is available elsewhere: the email line already shows the sign-in state, and the opt-in "Server" debug section in the same menu shows the running commit > - This pull request removes the badge and the build line so the header shows only the user's name and email > - The benefit is a cleaner account menu that shows only identity information ## Linked Issues or Issue Description No existing issue. Related: #9637 (closed) added the source-sha rendering that this PR removes from the menu header. Description follows the enhancement template: **What existing behavior does this improve?** The sidebar account menu popover. Its header shows the user's name, an "Account" or "Local" badge, the email, and a build identifier line ("Paperclip <short sha>" with branch/commit links for source builds, or "Paperclip v<version>" for release builds). **Current behavior** The popover header mixes identity information with deployment and build metadata. The badge and the version line take space and do not help daily use. **Proposed behavior** The popover header shows only the user's name and email. Build information stays available in the "Server" section at the bottom of the same menu when the server-info debug view is enabled in experimental instance settings. **Reason and benefit** Less visual noise in a menu that users open often. No information is lost: sign-in state is clear from the email line, and the running commit remains visible through the server-info debug view. **Breaking changes** None. The `SidebarAccountMenu` components no longer accept the `serverGit` and `version` props; both call sites in the two `Layout` variants are updated in this PR. ## What Changed - `ui/src/components/SidebarAccountMenu.tsx` and `SidebarAccountMenu.production.tsx`: remove the "Account"/"Local" badge and the full version block (source-build branch/commit links and the release-version fallback); drop the now-unused `serverGit`/`version` props, the sha-parsing helper, and the `Badge` import - `ui/src/components/Layout.tsx` and `Layout.production.tsx`: stop passing the removed props at all four call sites - `ui/src/components/SidebarAccountMenu.test.tsx`: delete the source-build sha test; the sign-out test now pins that the popover contains neither "Account" nor "Paperclip v" - `ui/storybook/stories/navigation-layout.stories.tsx`: stop passing the removed `version` prop in the account-menu story ## Verification - `pnpm vitest run ui/src/components/SidebarAccountMenu.test.tsx ui/src/components/Layout.test.tsx` — 36 tests pass - `tsc --noEmit` for the `ui` package passes - Manual: open the app, click your name in the lower left. The popover header shows only name and email. ## Risks - Low risk. UI-only removal with no data or API changes. - Users who relied on the header sha to identify a source build must enable the experimental server-info debug view to see the running commit in the same menu. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - Claude (Anthropic), Claude Fable 5, model ID `claude-fable-5`, extended thinking enabled, via Claude Code CLI with tool use (file edit, shell, test runner) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
871f7d1124 |
fix(ui): polish core navigation and task layout (#12793)
<!-- Write all pull request text in Simplified Technical English (ASD-STE100): short sentences, one instruction per sentence, simple approved vocabulary, and the active voice. --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Operators use the main navigation, contextual navigation, and task chat throughout the product. > - The recent core UI refactor left uneven spacing and inconsistent navigation styles. > - The Apps label also did not match the Connectors product language. > - The account area did not provide a clear direct path for feedback. > - This pull request aligns these related core UI surfaces and preserves their existing behavior. > - The benefit is a more consistent interface with clearer navigation and balanced task-chat layout. ## Linked Issues or Issue Description **What existing behavior does this improve?** This improves the core sidebar, Settings navigation, Connectors catalog, task-chat layout, and account controls. **Subsystem affected** `ui/` — React and Vite board UI. **Current behavior** The task chat had uneven edge treatment. Settings used a separate contextual-navigation style. Apps used inconsistent product labels. The account footer did not expose a direct feedback control. **Proposed behavior** The task chat keeps balanced content padding while its scrollbar sits at the properties boundary. Settings replaces the primary sidebar with a matching navigation surface and a Back to app link. Apps uses Connectors and Browse labels. The account footer provides a dedicated feedback icon with a tooltip. **Reason and benefit** These changes make related navigation and layout patterns predictable. They reduce duplicate labels and improve access to feedback. **Breaking changes** None. Routes, APIs, and stored data do not change. ## What Changed - Balanced the task-chat content gutter and moved its scrollbar to the properties-panel boundary. - Reworked Settings navigation to replace the main sidebar and use the shared primary-sidebar style. - Added a Back to app navigation item to Settings. - Renamed Apps to Connectors in the main navigation and added the `Unplug` icon. - Renamed the Connectors contextual item to Browse. - Added the Connectors top-level header and aligned the search field with the connector cards. - Added account-footer hover states and a direct feedback flag with a Share feedback tooltip. - Removed the duplicate Feedback item from the account popover. - Added regression coverage for each changed UI surface. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/components/AppsSidebar.test.tsx src/components/CompanySettingsSidebar.test.tsx src/components/Layout.test.tsx src/components/Sidebar.test.tsx src/components/SidebarAccountMenu.test.tsx src/components/task-chat/TaskMessageScroller.test.tsx src/pages/apps/Browse.test.tsx` — 90 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm --filter @paperclipai/ui build` — passed. - `pnpm check:token-gates` — passed. - `git diff --check origin/master...HEAD` — passed. - `env PAPERCLIP_PLAYWRIGHT_CHANNEL=chrome PAPERCLIP_E2E_PORT=3201 pnpm exec playwright test --config tests/e2e/playwright.config.ts tests/e2e/apps-dark-mode-shots.spec.ts tests/e2e/sidebar-takeover.spec.ts` — 10 tests passed. - The full workspace typecheck and build reached the Rust runner and stopped because `cargo` is not installed on this machine. - The full test suite exposed unrelated server and workspace-runtime failures and was stopped after the affected suites completed. No changed UI test failed. - Manually verified the changed Settings, Connectors, task-chat, and account-menu surfaces in the running app. ## Risks - Low risk. The change affects layout and navigation presentation only. - The Settings sidebar now replaces the main sidebar by design. Users must use Back to app to return to the application navigation. - The task scrollbar offset depends on the existing responsive page gutters. Regression tests cover both narrow and desktop spacing. > 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.6-sol`, extended reasoning with tool use and code execution. The host does not expose the 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 - [ ] 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: Scott Tong <scott@scottsmbpm5max.lan> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
597fd63b61 | feat(ui): add streamlined navigation foundation (#12746) | ||
|
|
f258b34bbd |
fix(ui): unify cloud-managed sign-out (#10994)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip can run as a self-hosted app or as a Cloud-managed tenant. > - These modes need different sign-out sequences because Cloud owns three sessions. > - Several visible controls implemented sign-out separately and could choose different paths. > - This pull request adds one Cloud-aware sign-out action and moves every visible control to it. > - The benefit is one safe sign-out path in Cloud and unchanged local sign-out in self-hosted deployments. ## Linked Issues or Issue Description Refs #2073. That older PR adds a separate company-settings sign-out surface. This change centralizes the existing account, company, and instance-settings surfaces and preserves the self-hosted behavior described there. **What happened?** Visible sign-out controls used separate implementations. A Cloud-managed control could call the app-local sign-out endpoint and open the local auth page. That path did not enter the Cloud-owned logout sequence for the tenant, Cloud, and identity sessions. **Expected behavior** Every visible sign-out control must use one action. Cloud-managed instances must navigate the top-level window to the same-origin `/cloud/logout` route without a local sign-out call first. Authenticated self-hosted instances must keep the local sign-out API and cache invalidation behavior. **Steps to reproduce** 1. Open a Cloud-managed tenant. 2. Use the account menu, company menu, or instance-settings sign-out control. 3. Observe that independently implemented controls can enter different sign-out paths. **Paperclip version or commit** The problem reproduces at `656ecfa585b31938e2685ffab3db22e794474803`. **Deployment mode** Cloud-managed tenant built from source. The regression tests also cover authenticated self-hosted mode. ## What Changed - Added `useSignOut` as the shared Cloud-aware sign-out action. - Navigated Cloud-managed sessions to `/cloud/logout` exactly once without calling local auth first. - Preserved local API sign-out and cache invalidation for authenticated self-hosted sessions. - Migrated the account menu, company menu, and instance general settings to the shared action. - Added focused tests for mode selection, menu closure, pending state, failure state, and settings behavior. ## Verification - `pnpm exec vitest run ui/src/hooks/useSignOut.test.tsx ui/src/components/SidebarAccountMenu.test.tsx ui/src/components/SidebarCompanyMenu.test.tsx ui/src/pages/InstanceGeneralSettings.test.tsx` — 26 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — passed. - `git diff --check origin/master..HEAD` — passed. ## Risks - Low risk. The change centralizes existing behavior and adds no schema, API, telemetry, or style-token changes. - Cloud mode depends on the existing health decision. Tests pin both mode branches. - The change does not alter Fetch Metadata, CSRF, cookie, prefetch, or return-URL protections owned by the Cloud logout route. > 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. The runtime does not expose a more specific model ID or context-window size. The agent used high-reasoning mode, shell tools, and API 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 - [ ] 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> |
||
|
|
ac3b2e1d7a |
fix(ui): use cloud logout for managed sign-out (#10937)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip supports self-hosted and Cloud-managed authenticated deployments > - A Cloud-managed tenant uses the Cloud harness to own the full browser session > - The account menu treated every authenticated deployment as Cloud and called the local sign-out API first > - This pull request uses the existing Cloud health metadata as the mode gate > - Cloud-managed sign-out now starts the harness logout round trip with a top-level navigation > - Self-hosted authenticated sign-out keeps the existing local API flow > - The benefit is a complete Cloud logout without changing self-hosted behavior ## Linked Issues or Issue Description Related prior work: Refs #10802. **What happened?** The account menu called the app-local sign-out endpoint before it moved an authenticated browser to the Cloud logout route. It also used authenticated deployment mode as the Cloud test. This test included self-hosted authenticated instances. **Expected behavior** A Cloud-managed tenant must navigate the top-level browser directly to `/cloud/logout`. A self-hosted authenticated instance must keep the app-local sign-out flow. **Steps to reproduce** 1. Open a Cloud-managed tenant. 2. Open the account menu. 3. Select **Sign out**. 4. Observe that the browser returns through the tenant auth route instead of completing the Cloud logout round trip. **Paperclip version or commit** Reproduced on `master` after `76f442040c`. **Deployment mode** Paperclip Cloud-managed authenticated deployment. ## What Changed - Read the existing Cloud instance metadata in the account menu. - Navigate directly to `/cloud/logout` for Cloud-managed instances without calling the local sign-out API. - Keep the local sign-out API and cache refresh for self-hosted authenticated instances. - Add regression coverage for both sides of the mode gate. ## Verification - `pnpm exec vitest run ui/src/components/SidebarAccountMenu.test.tsx` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` ## Risks - Low risk. The change is limited to the account-menu action. - The Cloud branch depends on the existing `health.cloud` metadata that already gates other Cloud UI behavior. - The self-hosted regression test verifies that authenticated mode alone does not select the Cloud route. > 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 based on GPT-5. The runtime provided agentic reasoning, repository tools, shell execution, and test execution. The exact internal model ID and context window are not exposed to the agent. ## 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> |
||
|
|
76f442040c |
fix(ui): follow managed sign-out redirects
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
6f204605ad |
fix(ui): show source SHA for unreleased builds (#9508)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI-agent companies > - Operators need to identify the exact build running from the persistent account menu > - Formal releases already have a concise public version, but source builds include a long derived version string > - The derived version identifies a commit but does not expose the source branch or a direct path to inspect the code > - Server Git metadata is auth-sensitive, so the UI must also refresh it when the current session changes > - This pull request shows linked branch and commit metadata for source builds while preserving `v<version>` for formal releases > - The benefit is faster build diagnosis with correct metadata across sign-in and sign-out transitions ## Linked Issues or Issue Description ### Pre-submission checklist - [x] I searched existing open and closed issues and found no duplicate implementing this exact account-menu behavior. - [x] The behavior reproduces on `master`. - [x] The behavior originates in Paperclip's core UI, not an adapter, provider, or local configuration. ### What happened? Source builds displayed the full derived version, such as `2026.626.0+58.git.518fc71ce`, without linking the operator to the corresponding source branch or commit. ### Expected behavior Source builds should show the concise branch and short commit SHA with links to GitHub, while formal releases should continue showing their public version. Auth transitions should refresh the health metadata that supplies those Git details. ### Steps to reproduce 1. Run Paperclip from a commit after a release tag. 2. Open the account menu. 3. Inspect the build label beneath the user identity. 4. Sign in or out and reopen the menu. ### Paperclip version or commit Any source build whose server version uses the `<version>+<count>.git.<sha>[.dirty]` format. ### Deployment mode Local dev (`pnpm dev`) or authenticated deployments. ### Installation method Built from source. ## What Changed - Detect source-derived version strings and render the source branch plus seven-character commit SHA in `SidebarAccountMenu`. - Link source branches and commits to the canonical `paperclipai/paperclip` GitHub repository. - Extend server Git metadata with the full SHA and expose it through health/OpenAPI contracts. - Refresh auth-sensitive health metadata after sign-in and every sign-out entry point. - Preserve the existing `v<version>` label for formal releases and add focused regression coverage. ## Verification - `pnpm --filter @paperclipai/ui exec vitest run src/pages/Auth.test.tsx src/components/SidebarAccountMenu.test.tsx src/components/SidebarServerInfo.test.tsx` - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/health.test.ts src/__tests__/server-info.test.ts` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm check:token-gates` - `git diff --check public/master...HEAD` ## Risks - Low risk: formal release rendering retains the existing fallback behavior when the source-version pattern does not match. - Source links assume the build came from the canonical public repository; fork-only branches or commits may not resolve there. - Health metadata is invalidated after auth transitions, adding one bounded refetch so the displayed Git details match the new session. > 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.4 with medium reasoning, repository/tool access, shell execution, and code editing; context-window size was not exposed by the runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [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> |
||
|
|
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> |
||
|
|
765a75207a |
Add experimental server info debug view (#8676)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The dev/server UI exposes a `/api/health` endpoint and a lower-left
account drawer, but nothing surfaces *which* build the running instance
is on or when it last restarted
> - When iterating on a local dev instance it is hard to tell whether
the server you're looking at has actually restarted onto your latest
commit, or how stale the running process is
> - Developers need a lightweight, opt-in way to confirm the running
instance's identity without digging through logs or shelling into the
host
> - This pull request adds an experimental "Server Info Debug View"
setting that surfaces the running instance's last-restart time and
current commit as read-only rows in the account drawer
> - The benefit is a quick, in-UI sanity check of what the live server
is actually running, behind an experimental flag so it ships zero cost
to users who don't opt in
## Linked Issues or Issue Description
No public GitHub issue exists. Describing the underlying request inline
following the feature request template:
**Problem or motivation:**
When working against a local Paperclip dev instance there is no in-UI
way to confirm what the running server is — its current commit or when
it last restarted. You have to check logs or the host shell to know
whether the process picked up your latest build.
**Proposed solution:**
An opt-in experimental setting ("Server Info Debug View") that, once
enabled, renders a small read-only "Server" section at the bottom of the
lower-left account drawer showing **Last restarted** (the server process
start time) and **Running commit** (the current git HEAD short SHA +
subject).
**Alternatives considered:**
A separate top-right pill/overlay (like the work-life-balance plugin).
The account drawer was chosen to reuse existing menu-row styling and
avoid adding new always-present chrome.
**Roadmap alignment:**
Small, self-contained developer-experience aid gated behind an
experimental flag; does not overlap planned core roadmap work.
## What Changed
- Added `server/src/server-info.ts`: captures a `serverInfo` snapshot
once at boot — process start time and current git commit (SHA +
subject). Git is read via `execFileSync` with SHA validation and a
timeout.
- `/api/health` exposes the `serverInfo` snapshot, but only on
full-details health responses (board/agent in authenticated mode, or
local-trusted dev).
- Gated the UI surface behind a new `enableServerInfoDebugView`
experimental setting, wired through the shared instance type, validator,
settings normalizer, and OpenAPI schema.
- UI: added `SidebarServerInfo` rendering the read-only rows in the
account drawer (`BreadcrumbBar` / `SidebarAccountMenu`), plus the
experimental settings toggle and a typed `health` API client.
- Moved `ServerGitInfo` / `ServerInfoSnapshot` into
`@paperclipai/shared` so the server and UI share one definition instead
of duplicating it.
- Added unit tests for the server-info snapshot, health route exposure,
validator/normalizer, settings routes, the experimental settings page,
and the sidebar component.
## Verification
- `pnpm --filter @paperclipai/server exec vitest run
src/__tests__/health.test.ts src/__tests__/server-info.test.ts
src/__tests__/instance-settings-service.test.ts
src/__tests__/instance-settings-routes.test.ts` — 32 passed
- `pnpm --filter @paperclipai/ui exec vitest run
src/components/SidebarServerInfo.test.tsx
src/pages/InstanceExperimentalSettings.test.tsx` — 9 passed
- `tsc --noEmit` on both `@paperclipai/server` and `@paperclipai/ui` —
clean
- Manual: enable **Settings → Experimental → Server Info Debug View**,
refresh the UI, open the lower-left account drawer — a "Server" section
shows Last restarted and Running commit.
## Risks
- Low risk. The UI surface is fully opt-in via an experimental flag and
defaults off.
- The `serverInfo` field on `/api/health` is access-controlled to
full-details responses only (board/agent in authenticated mode, or
local-trusted dev) — never anonymous authenticated callers — so the git
SHA is not broadly exposed.
- The only new server work is a one-time git read at boot, guarded with
SHA validation and a timeout; failures degrade gracefully (the git block
reports `available: false` rather than throwing).
## Model Used
Claude — `claude-opus-4` (Anthropic), extended thinking with tool use,
via Claude Code.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no
instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
|
||
|
|
8ddd735a7a |
feat(ui): theme toggle on unauthenticated auth page (supersedes part of #3732) (#5874)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Operators sign in via the `/auth` page, which renders before any session exists > - The signed-in app has a theme toggle inside `SidebarAccountMenu`, but the signed-out `/auth` page has none — first-time visitors are stuck in whichever theme was hardcoded at boot > - Master's existing toggle was inline inside `SidebarAccountMenu.tsx` as a `MenuAction` row, not exported as a reusable widget; round-1 of this PR added a standalone `ThemeToggle` but punted on unifying the two surfaces > - This pull request makes `ThemeToggle` the canonical theme widget (one source of truth for label, icon, and toggle behaviour), used both as a compact icon button on `/auth` and as a full-width menu row in `SidebarAccountMenu` > - The benefit is a working pre-auth theme switch and zero risk of the two call sites drifting out of sync as the theme model evolves ## Linked Issues or Issue Description No existing issue covers this directly — problem described in-PR (feature-gap shape): - The signed-in app has a theme toggle inside `SidebarAccountMenu`, but the signed-out `/auth` page has none — first-time visitors are stuck in whichever theme was hardcoded at boot. - The existing toggle lived inline in `SidebarAccountMenu.tsx` as a `MenuAction` row, not exported as a reusable widget, so the two surfaces could drift apart as the theme model evolves. - This PR supersedes part of PR #3732 (the auth-page toggle slice); no standalone issue was filed for it. Duplicate-PR search: related open theme PRs #2769 and #4666 add in-app three-state system-theme toggles — different surface from this PR (unauthenticated auth page); sibling PR in this series: #5873. ## What Changed - **`ui/src/components/ThemeToggle.tsx`** — accepts `variant: "icon" | "menu-action"` (default `"icon"`) and an `onAfterToggle` callback. Both variants share `useTheme` and the same label/icon derivation. The `menu-action` variant matches the existing `MenuAction` row styling. - **`ui/src/components/SidebarAccountMenu.tsx`** — drops its inline `useTheme()` + `MenuAction`-for-the-theme-row in favor of `<ThemeToggle variant="menu-action" onAfterToggle={() => setOpen(false)} />`. Sun/Moon icon imports and theme state move with it. - **`ui/src/pages/Auth.tsx`** — unchanged from round 0; renders `<ThemeToggle />` at top-right of the `/auth` page (already using the default `icon` variant). - **`ui/src/components/ThemeToggle.test.tsx`** (new) — covers both variants, the `onAfterToggle` callback, and the label/icon flip across themes. - **`ui/src/components/SidebarAccountMenu.test.tsx`** — unchanged; its `ThemeContext` mock still works because `ThemeToggle` uses the same hook. ## Verification - `pnpm --filter @paperclipai/ui run typecheck` — clean. - `npx vitest run src/components/ThemeToggle.test.tsx src/components/SidebarAccountMenu.test.tsx` — 5 passed (4 new + 1 existing). - Manual: launched `pnpm dev` for the UI, mocked `/api/auth/get-session` 401, navigated to `/auth` — toggle is visible top-right, click flips light/dark. Screenshots committed. ## Risks Low. The change is structural — both call sites render the same widget that already worked on each surface independently. `SidebarAccountMenu`'s popover behaviour is preserved via `onAfterToggle`, and `ThemeContext` is untouched. ## Model Used Claude Opus 4.7 (1M context), extended thinking mode. ## Checklist - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] Thinking path traces from project context to this change - [x] Model used specified - [x] Checked ROADMAP.md — not in conflict with planned core work - [x] Tests run locally and pass - [x] Added tests for the new ThemeToggle component (both variants) - [x] UI change — before/after screenshots in `docs/pr-screenshots/pr-5874/` - [x] No documentation updates required (purely internal refactor + new component) - [x] Documented risks above - [x] Will address all Greptile and reviewer comments before merge Supersedes part of #3732. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Devin Foley <devin@paperclip.ing> |
||
|
|
e3aada1df2 |
feat(ui): add Feedback item to the account flyout menu (PAP-107) (#7854)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The web UI has a bottom-left account flyout menu where users reach profile, docs, and the light/dark toggle > - There was no in-product way for users to send feedback or report issues — they had to find an external channel > - We want a low-friction, always-visible entry point for feedback, and a clean URL we can re-point later without shipping app changes > - This pull request adds a **Feedback** item (Megaphone icon) to the account flyout, between Documentation and the theme toggle, that opens `https://paperclip.ing/feedback` in a new tab > - `paperclip.ing/feedback` is a stable indirection (added to the marketing site) that currently 302-redirects to a Google Form, so the destination can be swapped for a richer solution later with no app release > - The benefit is a one-click feedback path for users and a future-proof link the team controls ## Linked Issues or Issue Description No public GitHub issue exists (tracked internally as Paperclip PAP-107). Describing the underlying request inline as a feature, per CONTRIBUTING.md path (B): ### Problem or motivation Users have no in-app affordance to give feedback or report issues; that friction loses signal we'd otherwise act on. ### Proposed solution Add a Feedback item to the account flyout (Megaphone icon, between Documentation and the theme toggle) that opens a stable `paperclip.ing/feedback` URL in a new tab. That URL redirects to a Google Form for now, keeping the client decoupled from the destination. ### Alternatives considered Linking the Google Form directly from the app — rejected because it bakes a throwaway URL into the client; the `/feedback` indirection keeps the link clean and swappable. ### Roadmap alignment Small, self-contained UX addition; no overlap with planned core work (checked ROADMAP.md). The `/feedback` redirect lives in the separate `paperclip-website` repo (Astro site on Cloudflare Pages), commit `f65b566`. No duplicate/related PRs found in this repo (searched feedback/flyout/menu). ## What Changed - `ui/src/components/SidebarAccountMenu.tsx`: import `Megaphone` from `lucide-react`; add `FEEDBACK_URL = "https://paperclip.ing/feedback"` const next to `DOCS_URL`; insert a `Feedback` `MenuAction` between Documentation and the theme toggle using the `external` prop so it opens in a new tab (`target="_blank"`, `rel="noreferrer"`) and closes the popover on click. - `ui/src/components/SidebarAccountMenu.test.tsx`: assert the Feedback item renders with the correct `href`, opens in a new tab, and is ordered after Documentation and before the theme toggle. - (Separate repo, for context) `paperclip-website` `public/_redirects`: `/feedback` → 302 → the feedback Google Form. ## Verification - **Unit tests:** `SidebarAccountMenu` tests pass (item renders, correct `href`, `target="_blank"`, ordering). Run: `cd ui && npm test -- SidebarAccountMenu`. - **Manual / canary:** The board previewed the canary build of the menu item and accepted it. Clicking **Feedback** opens a new tab to `paperclip.ing/feedback`. - **Redirect:** After the Cloudflare Pages deploy propagates, `curl -sI https://paperclip.ing/feedback` returns the Google Form in the `Location` header. _Screenshots:_ UI change was validated via the accepted canary preview; the item reuses the existing `MenuAction` styling, so it visually matches the Documentation/theme rows. ## Risks - **Low risk.** Additive, self-contained UI change with no new state or API calls. The only external dependency is the `paperclip.ing/feedback` redirect (separate repo, already deployed); if it were missing the link would 404, but it is in place. No migrations, no breaking changes. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. ## Model Used - **Claude (Anthropic).** PR authoring/orchestration: **claude-opus-4-8** (extended thinking + tool use). The implementation commit `b454a12d` was produced with assistance from **claude-sonnet-4-6**. All changes reviewed before pushing. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
50bff3b274 |
feat(ui): add collapsible sidebar rail and takeover panes (#7824)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents, work, and company context. > - The board UI sidebar is the main way operators keep orientation across companies, projects, agents, issues, and settings. > - The existing fixed expanded sidebar competes with route-specific navigation, especially company settings and plugin routes that bring their own contextual sidebar. > - A collapsible primary rail preserves global navigation while giving contextual pages more horizontal room. > - This pull request adds a persisted collapsed rail, hover/focus peek, keyboard toggle, and a secondary sidebar takeover model for settings and plugin `routeSidebar` surfaces. > - The benefit is a denser board shell that keeps the app rail available without replacing it when a route needs its own navigation. ## Linked Issues or Issue Description Paperclip issue: PAP-10638 Create collapsible sidebar branch. Related GitHub PR found during duplicate search: #3838 (`feat/collapsible-sidebar`) covers a similar sidebar area but is a different head branch and implementation. This PR intentionally packages the work from `PAP-10638-collapsable-sidebar` into one reviewable branch. Problem description: The board shell needs a first-class collapsed sidebar mode. Contextual surfaces such as company settings and plugin route sidebars should not replace the global app sidebar; they should collapse the app sidebar to a rail and render their contextual navigation beside it. ## What Changed - Added desktop collapsed/sidebar-peek state to `SidebarContext`, including persisted user pins, route collapse requests, and forced collapse for secondary-sidebar routes. - Replaced the old resizable sidebar pane with `SidebarShell`, which supports a fixed 64px rail, persisted expanded width, keyboard/pointer resizing, and hover/focus peek overlay behavior. - Updated `Sidebar`, sidebar nav items, project/agent sections, badges, and account/company menu presentation for expanded, collapsed, and peeking states. - Added `RequestCollapsedSidebar` and `SecondarySidebar` so routes and plugin `routeSidebar` slots can request contextual sidebar layouts without replacing the primary app sidebar. - Wired company settings and plugin route sidebars into the secondary-pane takeover model. - Added focused Vitest coverage for sidebar state precedence, shell sizing, nav item rail rendering, keyboard shortcuts, layout takeover behavior, and route collapse requests. - Updated plugin authoring docs/spec references for route sidebar behavior. ## Verification Targeted local verification passed: ```sh NODE_ENV=test pnpm run preflight:workspace-links && NODE_ENV=test pnpm exec vitest run ui/src/context/SidebarContext.test.tsx ui/src/components/SidebarShell.test.tsx ui/src/components/Sidebar.test.tsx ui/src/components/Layout.test.tsx ui/src/components/RequestCollapsedSidebar.test.tsx ui/src/components/SidebarNavItem.test.tsx ui/src/components/SidebarAgents.test.tsx ui/src/components/SidebarProjects.test.tsx ui/src/components/KeyboardShortcutsCheatsheet.test.tsx ui/src/hooks/useKeyboardShortcuts.test.tsx ``` Result: 10 test files passed, 88 tests passed. Additional follow-up verification passed after review fixes: ```sh NODE_ENV=test pnpm run preflight:workspace-links && NODE_ENV=test pnpm exec vitest run ui/src/components/Layout.test.tsx ui/src/context/SidebarContext.test.tsx && pnpm --filter /ui typecheck ``` Result: 2 test files passed, 28 tests passed, and UI typecheck passed. Latest PR-head remote checks: Paperclip PR workflow, Snyk, Socket, and Greptile are green; commitperclip `review` is cancelled in its security-gate step after filing a non-blocking neutral `security-review` check. Notes: - A direct run without `NODE_ENV=test` loads React's production build in this workspace, where `act` is unavailable; the command above matches the repo stable runner's test environment. - I did not run Playwright/browser e2e or full workspace build/typecheck in this PR-creation heartbeat. - QA screenshots are attached in https://github.com/paperclipai/paperclip/pull/7824#issuecomment-4661968387 for expanded, collapsed rail, hover peek, and settings secondary-sidebar states. ## Risks - Medium UI layout risk: this changes the board shell and primary sidebar composition across many routes. - Local storage migration risk is low: new collapsed state uses a new key and existing width storage remains scoped to the sidebar width. - Plugin route risk: plugin `routeSidebar` slots now render as secondary panes on desktop, so plugin authors should confirm their route sidebar content fits a 240px contextual pane. - Mobile risk appears low because mobile keeps the drawer model and gates collapsed/peek behavior to desktop. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex coding agent based on GPT-5, with local shell/git/GitHub CLI tool use. Exact service-side model identifier and context window were not exposed in this runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
76c88e5855 |
[codex] Move instance settings under company settings (#7680)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Operators manage both company-scoped configuration and instance-level runtime/admin settings from the board UI > - Instance settings previously lived as their own top-level sidebar area, separate from the company settings context operators already use > - That split made settings navigation feel heavier and made instance configuration less discoverable from the settings tab > - This pull request moves instance settings under company settings while preserving the existing instance settings routes and plugin/admin surfaces > - The benefit is a smaller primary sidebar and a more coherent settings hierarchy for operators ## Linked Issues or Issue Description - Refs #338 - Internal: PAP-10491, PAP-10538 ## What Changed - Moved instance settings navigation under the company settings area. - Added route helpers and sidebar entries for nested instance settings paths. - Updated plugin/admin settings routes to use the company settings instance scope. - Preserved legacy instance-settings bookmarks through compatibility redirects that keep the active company prefix. - Updated focused UI and plugin tests for the new navigation shape. - Stabilized the process-loss retry test that was failing the serialized server shard in CI. - Rebased the branch onto current `paperclipai/paperclip` `master` and pushed the current head. ## Verification - `pnpm exec vitest run ui/src/components/CompanySettingsSidebar.test.tsx ui/src/components/access/CompanySettingsNav.test.tsx ui/src/lib/instance-settings.test.ts ui/src/components/InstanceSidebar.test.tsx ui/src/components/Layout.test.tsx ui/src/components/SidebarAccountMenu.test.tsx ui/src/pages/PluginPage.test.tsx ui/src/plugins/bridge.test.ts packages/shared/src/validators/plugin.test.ts` - `pnpm exec vitest run ui/src/lib/instance-settings.test.ts ui/src/components/CompanySettingsSidebar.test.tsx ui/src/components/access/CompanySettingsNav.test.tsx ui/src/components/Layout.test.tsx ui/src/plugins/bridge.test.ts` - `pnpm exec vitest run server/src/__tests__/heartbeat-process-recovery.test.ts -t "queues exactly one retry when the recorded local pid is dead"` - `pnpm test:run:serialized -- --shard-index 0 --shard-count 4` - GitHub PR checks are green on head `fe7b0955169dcae55cbe10889c1876a70ab0b80c`, including `verify`, `General tests (server)`, all serialized server shards, build, e2e, policy, security checks, and Greptile. - Confirmed the PR diff does not include `pnpm-lock.yaml` or `.github/workflows` changes. ## Risks - Medium UI/navigation risk: instance settings links are intentionally moving under company settings, so stale external bookmarks to legacy paths rely on the compatibility routing in this branch. - Low test-only risk from the CI stabilization commit: it makes the recovery assertion select the actual retry run by `retryOfRunId` instead of whichever non-original run appears first. - No database migrations. - No dependency lockfile or workflow changes. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex coding agent based on GPT-5, with shell/tool execution in a local repository worktree. Exact context window was not exposed by the runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d734bd43d1 |
[codex] Roll up May 17 branch changes (#6210)
## Thinking Path > - Paperclip is the control plane for autonomous AI companies, so agent work needs visible ownership, recovery, and operator controls. > - This local branch had accumulated several related control-plane reliability and operator-experience fixes across recovery actions, watchdog folding, model-profile defaults, mentions, markdown editing, plugin launchers, and small UI polish. > - The branch needed to be converted into a PR against the current `origin/master` without losing dirty work or including lockfile/workflow churn. > - The safest standalone shape is a single rollup PR because the recovery/server/UI files overlap heavily across the local commits and splitting would create avoidable conflicts. > - This pull request replays the local branch onto latest `origin/master`, preserves the uncommitted work as logical commits, and adds a Zod 4 validator compatibility fix found during verification. > - The benefit is that the May 17 local branch can be reviewed and merged as one coherent, conflict-free branch under the 100-file Greptile limit. ## What Changed - Rebased the local May 17 branch work onto current `origin/master` in a dedicated worktree. - Preserved and committed previously dirty changes for recovery retry handling, plugin/sidebar launcher polish, and `.herenow` ignores. - Added recovery-action behavior for returning source issues to `todo` when retrying source-scoped recovery. - Included the existing local recovery/liveness/watchdog fold, Codex cheap-profile, markdown/mention, duplicate-agent, and UI polish commits from the branch. - Normalized shared validator `z.record(...)` schemas to explicit string-key records for Zod 4 compatibility. - Confirmed the PR has no `pnpm-lock.yaml` or `.github/workflows/*` changes and stays below the 100-file Greptile limit. ## Verification - `pnpm install --frozen-lockfile --ignore-scripts` - `npm run install` in `node_modules/.pnpm/sqlite3@5.1.7/node_modules/sqlite3` to build the local native sqlite3 binding after installing with scripts disabled - `pnpm exec vitest run packages/shared/src/validators/issue.test.ts packages/shared/src/project-mentions.test.ts packages/adapter-utils/src/server-utils.test.ts server/src/__tests__/heartbeat-model-profile.test.ts server/src/__tests__/issue-recovery-actions.test.ts server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts server/src/__tests__/heartbeat-active-run-output-watchdog.test.ts server/src/__tests__/plugin-local-folders.test.ts ui/src/components/IssueRecoveryActionCard.test.tsx ui/src/components/Sidebar.test.tsx ui/src/components/SidebarAccountMenu.test.tsx ui/src/components/IssueProperties.test.tsx ui/src/components/MarkdownEditor.test.tsx ui/src/components/MarkdownBody.test.tsx ui/src/lib/duplicate-agent-payload.test.ts ui/src/pages/Routines.test.tsx` - First pass: 13 files passed with 201 passing tests; 3 server files failed before sqlite3 native binding was built. - After rebuilding sqlite3: `server/src/__tests__/heartbeat-model-profile.test.ts`, `server/src/__tests__/issue-recovery-actions.test.ts`, and `server/src/__tests__/heartbeat-active-run-output-watchdog.test.ts` passed/loaded; embedded Postgres tests were skipped by the local host guard. - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/adapter-utils typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` ## Risks - Medium risk: this is a broad rollup PR across recovery semantics, server tests, shared validators, and UI surfaces. - Some embedded Postgres tests skipped locally due the host guard, so CI should provide the stronger database-backed signal. - UI changes were covered by component tests, but no browser screenshot was captured in this PR creation pass. - This branch may overlap with existing recovery/liveness PR work; merge this PR independently or restack/close overlapping branches rather than merging duplicate implementations 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 — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5-based coding agent, tool-enabled local repository and GitHub workflow, medium reasoning effort. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
4103978578 |
Polish operator sidebar and issue property controls (#5355)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Operators use the board sidebar and issue properties panel to move between companies and understand task metadata > - Small UI regressions in these controls make repeated board operation slower and less predictable > - The local branch already contained targeted fixes for company ordering, issue date display, and sidebar rail sizing > - This pull request isolates those operator UI quality-of-life fixes into a standalone branch against `origin/master` > - The benefit is a focused, reviewable PR that can merge independently of the issue-thread activity work ## What Changed - Shows issue property timestamps with time, not just dates. - Adds edit-mode support for ordering companies in the sidebar company menu. - Fixes a workspace switcher rail regression and keeps the account menu aligned with the rail width. - Includes focused component coverage for the touched controls. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run ui/src/components/IssueProperties.test.tsx ui/src/components/SidebarCompanyMenu.test.tsx ui/src/components/Layout.test.tsx ui/src/components/SidebarAccountMenu.test.tsx` — 4 files passed, 29 tests passed. - `pnpm --filter /ui typecheck` - PR checks on `a4030f7a` are green: policy, verify, serialized server suites 1/4-4/4, e2e, Canary Dry Run, Greptile Review, and Snyk. - Captured a local Storybook screenshot of `Product/Navigation & Layout` after the sidebar polish: `/tmp/pap-3659-screenshots/navigation-layout-after.png`. - Confirmed the PR changes 8 files and does not include `pnpm-lock.yaml` or `.github/workflows/*`. ## Risks - Low to moderate UI risk: this touches shared sidebar components and issue metadata rendering. - The company ordering behavior depends on existing query/cache behavior, so stale cache bugs would show up as ordering inconsistencies. - No database, API, workflow, or lockfile changes are included. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5 coding agent, shell/tool-use enabled, used to split the existing branch, verify the isolated PR branch, and create this PR. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2de893f624 |
[codex] add comprehensive UI Storybook coverage (#4132)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - The board UI is the main operator surface, so its component and workflow coverage needs to stay reviewable as the product grows. > - This branch adds Storybook as a dedicated UI reference surface for core Paperclip screens and interaction patterns. > - That work spans Storybook infrastructure, app-level provider wiring, and a large fixture set that can render real control-plane states without a live backend. > - The branch also expands coverage across agents, budgets, issues, chat, dialogs, navigation, projects, and data visualization so future UI changes have a concrete visual baseline. > - This pull request packages that Storybook work on top of the latest `master`, excludes the lockfile from the final diff per repo policy, and fixes one fixture contract drift caught during verification. > - The benefit is a single reviewable PR that adds broad UI documentation and regression-surfacing coverage without losing the existing branch work. ## What Changed - Added Storybook 10 wiring for the UI package, including root scripts, UI package scripts, Storybook config, preview wrappers, Tailwind entrypoints, and setup docs. - Added a large fixture-backed data source for Storybook so complex board states can render without a live server. - Added story suites covering foundations, status language, control-plane surfaces, overview, UX labs, agent management, budget and finance, forms and editors, issue management, navigation and layout, chat and comments, data visualization, dialogs and modals, and projects/goals/workspaces. - Adjusted several UI components for Storybook parity so dialogs, menus, keyboard shortcuts, budget markers, markdown editing, and related surfaces render correctly in isolation. - Rebasing work for PR assembly: replayed the branch onto current `master`, removed `pnpm-lock.yaml` from the final PR diff, and aligned the dashboard fixture with the current `DashboardSummary.runActivity` API contract. ## Verification - `pnpm --filter @paperclipai/ui typecheck` - `pnpm --filter @paperclipai/ui build-storybook` - Manual diff audit after rebase: verified the PR no longer includes `pnpm-lock.yaml` and now cleanly targets current `master`. - Before/after UI note: before this branch there was no dedicated Storybook surface for these Paperclip views; after this branch the local Storybook build includes the new overview and domain story suites in `ui/storybook-static`. ## Risks - Large static fixture files can drift from shared types as dashboard and UI contracts evolve; this PR already needed one fixture correction for `runActivity`. - Storybook bundle output includes some large chunks, so future growth may need chunking work if build performance becomes an issue. - Several component tweaks were made for isolated rendering parity, so reviewers should spot-check key board surfaces against the live app behavior. ## Model Used - OpenAI Codex, GPT-5-based coding agent in the Paperclip harness; exact serving model ID is not exposed in-runtime to the agent. - Tool-assisted workflow with terminal execution, git operations, local typecheck/build verification, and GitHub CLI PR creation. - Context window/reasoning mode not surfaced by the 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
d8b63a18e7 |
[codex] Add access cleanup and user profile page (#4088)
## Thinking Path > - Paperclip is moving from a solo local operator model toward teams supervising AI-agent companies. > - Human access management and human-visible profile surfaces are part of that multiple-user path. > - The branch included related access cleanup, archived-member removal, permission protection, and a user profile page. > - These changes share company membership, user attribution, and access-service behavior. > - This pull request groups those human access/profile changes into one standalone branch. > - The benefit is safer member removal behavior and a first profile surface for user work, activity, and cost attribution. ## What Changed - Added archived company member removal support across shared contracts, server routes/services, and UI. - Protected company member removal with stricter permission checks and tests. - Added company user profile API, shared types, route wiring, client API, route, and UI page. - Simplified the user profile page visual design to a neutral typography-led layout. ## Verification - `pnpm install --frozen-lockfile` - `pnpm exec vitest run server/src/__tests__/access-service.test.ts server/src/__tests__/user-profile-routes.test.ts ui/src/pages/CompanyAccess.test.tsx --hookTimeout=30000` - `pnpm exec vitest run server/src/__tests__/user-profile-routes.test.ts --testTimeout=30000 --hookTimeout=30000` after an initial local embedded-Postgres hook timeout in the combined run. - Split integration check: merged after runtime/governance and dev-infra/backups with no merge conflicts. - Confirmed this branch does not include `pnpm-lock.yaml`. ## Risks - Medium risk: changes member removal permissions and adds a new user profile route with cross-table stats. - The profile page is a new UI surface and may need visual follow-up in browser QA. - No database migrations are included. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic code-editing/runtime with local shell and GitHub CLI access; exact context window and reasoning mode are 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b9a80dcf22 |
feat: implement multi-user access and invite flows (#3784)
## Thinking Path > - Paperclip is the control plane for autonomous AI companies. > - V1 needs to stay local-first while also supporting shared, authenticated deployments. > - Human operators need real identities, company membership, invite flows, profile surfaces, and company-scoped access controls. > - Agents and operators also need the existing issue, inbox, workspace, approval, and plugin flows to keep working under those authenticated boundaries. > - This branch accumulated the multi-user implementation, follow-up QA fixes, workspace/runtime refinements, invite UX improvements, release-branch conflict resolution, and review hardening. > - This pull request consolidates that branch onto the current `master` branch as a single reviewable PR. > - The benefit is a complete multi-user implementation path with tests and docs carried forward without dropping existing branch work. ## What Changed - Added authenticated human-user access surfaces: auth/session routes, company user directory, profile settings, company access/member management, join requests, and invite management. - Added invite creation, invite landing, onboarding, logo/branding, invite grants, deduped join requests, and authenticated multi-user E2E coverage. - Tightened company-scoped and instance-admin authorization across board, plugin, adapter, access, issue, and workspace routes. - Added profile-image URL validation hardening, avatar preservation on name-only profile updates, and join-request uniqueness migration cleanup for pending human requests. - Added an atomic member role/status/grants update path so Company Access saves no longer leave partially updated permissions. - Improved issue chat, inbox, assignee identity rendering, sidebar/account/company navigation, workspace routing, and execution workspace reuse behavior for multi-user operation. - Added and updated server/UI tests covering auth, invites, membership, issue workspace inheritance, plugin authz, inbox/chat behavior, and multi-user flows. - Merged current `public-gh/master` into this branch, resolved all conflicts, and verified no `pnpm-lock.yaml` change is included in this PR diff. ## Verification - `pnpm exec vitest run server/src/__tests__/issues-service.test.ts ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx` - `pnpm run preflight:workspace-links && pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts` - `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts server/src/__tests__/workspace-runtime-service-authz.test.ts server/src/__tests__/access-validators.test.ts` - `pnpm exec vitest run server/src/__tests__/authz-company-access.test.ts server/src/__tests__/routines-routes.test.ts server/src/__tests__/sidebar-preferences-routes.test.ts server/src/__tests__/approval-routes-idempotency.test.ts server/src/__tests__/openclaw-invite-prompt-route.test.ts server/src/__tests__/agent-cross-tenant-authz-routes.test.ts server/src/__tests__/routines-e2e.test.ts` - `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts ui/src/pages/CompanyAccess.test.tsx` - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/db typecheck && pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm db:generate` - `npx playwright test --config tests/e2e/playwright.config.ts --list` - Confirmed branch has no uncommitted changes and is `0` commits behind `public-gh/master` before PR creation. - Confirmed no `pnpm-lock.yaml` change is staged or present in the PR diff. ## Risks - High review surface area: this PR contains the accumulated multi-user branch plus follow-up fixes, so reviewers should focus especially on company-boundary enforcement and authenticated-vs-local deployment behavior. - UI behavior changed across invites, inbox, issue chat, access settings, and sidebar navigation; no browser screenshots are included in this branch-consolidation PR. - Plugin install, upgrade, and lifecycle/config mutations now require instance-admin access, which is intentional but may change expectations for non-admin board users. - A join-request dedupe migration rejects duplicate pending human requests before creating unique indexes; deployments with unusual historical duplicates should review the migration behavior. - Company member role/status/grant saves now use a new combined endpoint; older separate endpoints remain for compatibility. - Full production build was not run locally in this heartbeat; CI should cover the full matrix. ## Model Used - OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use environment. Exact deployed model identifier 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge Note on screenshots: this is a branch-consolidation PR for an already-developed multi-user branch, and no browser screenshots were captured during this heartbeat. --------- Co-authored-by: dotta <dotta@example.com> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |