Commit Graph
2 Commits
Author SHA1 Message Date
Devin FoleyandPaperclip e4237c45f3 fix(ui): prevent organization title flicker during plugin loading (#13854)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The sidebar identifies the current organization.
> - An optional plugin can replace this navigation surface.
> - The built-in title appears before discovery and module loading
finish.
> - This pull request reserves the trigger until its owner is known.
> - The organization name appears once, while failures retain built-in
navigation.

## Linked Issues or Issue Description

Refs #13832. Searched related pull requests and issues; no duplicate fix
found.

**What happened?**
The organization switcher renders a provisional built-in title before an
installed replacement loads. Unrelated plugin imports can also affect
its loading state.

**Expected behavior**
Reserve the trigger with a neutral placeholder, then show the resolved
navigation surface. Keep the built-in menu on failed or absent
contributions.

**Steps to reproduce**
Install an organization-switcher contribution. Delay session, company,
contribution, and module responses. Reload the page and watch the
trigger through each stage.

## What Changed

- Reserve the trigger through account, company selection, slot
discovery, and module loading.
- Distinguish failed session lookup from pending lookup so errors retain
usable navigation.
- Load and await only contributions matching the requested slots.
Observe completion of imports started by another consumer.
- Document loading behavior and add regression coverage for loading,
failures, unrelated modules, and identity transitions.

## Verification

- `pnpm -r typecheck` passed, including Rust checks.
- `pnpm build` passed.
- All 629 UI test files passed: 6,593 tests. The 42 focused
UI/API/plugin tests also passed.
- `pnpm check:token-gates` and `git diff --check` passed.
- `pnpm test:run` was also attempted. The broad local server run was
stopped after recording skill-cache/channel fixture failures outside
this diff (for example, runtime skill source status `missing` instead of
`available`). The original cause is not established. All latest-head
Linux CI gates pass; the complete UI suite and affected local checks
pass.
- Desktop (1440px) and mobile (390px) Chromium checks passed with real
host components, dynamic module loading, and the built Account bundle.
Delayed fixture responses produced exactly two title states: empty
placeholder, then the resolved name. A slow refresh preserved the title
and trigger dimensions; absent/failed plugin fallback and Escape
dismissal passed, with zero uncaught browser errors. This is browser
component integration, not a live signed-in tenant test.

## Risks

A cold load displays a neutral placeholder until discovery completes.
Absent, ambiguous, failed, and invalid contributions still use the
built-in menu. No migrations or authorization changes. Scoped module
loading changes when an unrelated contribution is imported; each surface
loads its own matching modules.

## Model Used

OpenAI Codex, GPT-6, with reasoning, code execution, and browser
verification. The exact deployment ID and context window 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
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-22 20:33:29 -07:00
Devin FoleyandPaperclip 7badae6981 feat(plugins): add an optional organization switcher slot (#13832)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Plugins can add UI surfaces to the board.
> - Organization navigation is still fixed in the host sidebar.
> - A distribution needs a supported way to supply its own organization
menu.
> - This pull request adds one optional React slot with host-owned
navigation controls.
> - The built-in menu stays available when the optional contribution
cannot render.

## Linked Issues or Issue Description

**Subsystem affected**

Plugin SDK, server capability validation, and sidebar UI.

**Problem or motivation**

An installed plugin cannot replace the organization switcher without
editing the host menu. Existing sidebar and overlay slots do not provide
this replacement surface.

**Proposed solution**

Add an `organizationSwitcher` slot that requires `ui.sidebar.register`.
Pass display state, an icon renderer, and navigation/logout callbacks.
Keep the built-in menu for absent, ambiguous, missing, failed, or
unsupported contributions.

**Roadmap alignment**

This keeps distribution UI in plugins and adds a small host contract. It
does not add an account system or change company authorization. The
maintainer requested this extension.

Related prior menu changes: #12788, #10917, and #10850. No duplicate
replacement-slot PR was found.

## What Changed

- Add the slot to shared validation, SDK types, and server capability
checks.
- Wrap both sidebar menu variants with the optional replacement.
- Resolve selection against the current account query before mounting,
and reset replacement state on account or company changes.
- Add host-specific component props and a fallback to `PluginSlotMount`.
- Document the React-only contract and its trust boundary.
- Report runtime-supervisor fixture startup details when CI readiness
fails.

## Verification

- `pnpm -r typecheck` and `pnpm build` passed.
- `pnpm check:token-gates` passed.
- `pnpm exec vitest run --project @paperclipai/ui`: 6,580 tests passed.
- Targeted manifest, replacement, and built-in menu tests: 26 passed,
including the incoming-account selection regression.
- Installed a local test contribution into an isolated server. CLI
inspection reported `ready`. Browser checks covered the loaded
production UI, keyboard dismissal, current-organization selection, and
an expired remote session. Remote account responses were fixtures.
- `pnpm test:run` was attempted. Its first server phase passed 8,323
tests but failed in 36 files due to embedded PostgreSQL startup and
filesystem permission errors on this Mac. Later phases did not run. The
current Linux CI run is green: 54 checks passed and two were skipped,
including build, typecheck, and browser gates. See
https://github.com/paperclipai/paperclip/actions/runs/35796722770.
- The earlier runtime-supervisor readiness failure did not reproduce
locally. The complete affected shard passed locally: 58 files and 843
tests. The six supervisor tests also passed on Node 24.21.0 with CI
flags. Added fixture startup diagnostics for the selected Node
executable and listener port. The affected Linux shard then passed all
843 tests. The original root cause remains unconfirmed; no production
runtime behavior or timeout was changed.

## Risks

- Plugin UI remains trusted same-origin code. Display props do not
authorize account requests.
- A replacement can change navigation behavior. The host retains the
built-in menu when discovery or rendering fails and keeps logout/session
cleanup host-owned.
- No database migration. Existing menus and portfolio behavior remain
available.
- Local full-suite verification is limited by the environment failures
listed above.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository inspection, code
execution, and browser testing. The runtime does not expose a more
specific model ID or context-window size.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-22 16:39:11 -07:00