## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - A user creates an agent in the New Agent flow and connects a model provider in the model step. > - When a saved subscription exists, the step shows it as the selected default and labels the primary button "Use saved subscription". > - The button stays disabled until the user clicks the provider tile, which adds no auth step on this path. > - This extra click is a papercut: the visible choice looks ready but does not work. > - This pull request lets a selected saved subscription enable the button without the tile click. > - The benefit is one less confusing step, with no change to new sign-ins or API keys. ## Linked Issues or Issue Description No public issue exists. The description follows the bug template. **What happened** In New Agent > Connect model, choose a provider that has a saved subscription (for example OpenAI with a saved default). The saved subscription shows as selected and the primary button reads "Use saved subscription". The button stays disabled until you click the provider tile. **Expected behavior** The button is enabled when a saved subscription is selected. A click on it reuses that subscription. **Steps to reproduce** 1. Have a saved OpenAI subscription. 2. Open New Agent and go to the model connection step for a Codex agent. 3. Do not click the OpenAI Subscription tile. 4. See that "Use saved subscription" is disabled. **Paperclip version or commit** master at `4abff286c`. ## What Changed - `AgentProviderConnection.tsx`: the `!opened` gate on the footer primary button no longer applies when `method === "subscription"` and a saved subscription is selected. All other disabled conditions stay (pending auth, loading saved keys, login readiness, API key input). - `connect()` never reads `opened`, so no auth step is skipped. New sign-ins and API keys still require the user to open the provider tile. - `AgentProviderConnection.test.tsx`: a regression test that renders the initial state (tile not opened, saved subscription selected) and expects the button to be enabled and to connect with the saved subscription. A guard test checks that a new sign-in still requires opening the tile. ## Verification - `cd ui && npx vitest run src/components/new-agent src/components/ai-connections --no-file-parallelism`: 6 files, 64/64 tests pass. - The new regression test fails on master and passes with this change. - `pnpm --filter @paperclipai/ui typecheck`: 0 errors. - `node scripts/check-token-gates.mjs`: all gates clean. - Component QA in Storybook (real component, provider verification simulated): before, the button is disabled and skipped by Tab until the tile click. After, a direct click and Tab+Enter both connect, with exactly one verification callback. Selecting a new subscription still requires opening the tile. - Full-app before/after QA with a disposable empty backend and a simulated provider response: same result. - Not tested: a live OpenAI sign-in. Repo-wide `pnpm -r typecheck`, `pnpm test:run` and `pnpm build` are left to CI. Manual check: open New Agent with a saved subscription, go to the model step, and click "Use saved subscription" without clicking the tile. ## Risks - Low risk. The change is one condition in one component. - If a future change makes `connect()` depend on the tile being opened for saved subscriptions, this path would skip that work. The comment at the condition records why the gate is skipped. - Open PR #14698 edits nearby lines in the same component. A small merge conflict is possible. ## Model Used - Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, via Claude Code with tool use (shell, file edit, browser automation). Extended reasoning on. ## 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: scotttong <squadbot000@users.noreply.github.com> Co-authored-by: Paperclip <noreply@paperclip.ing>
@paperclipai/ui
Published static assets for the Paperclip board UI.
What gets published
The npm package contains the production build under dist/. It does not ship the UI source tree or workspace-only dependencies.
Storybook
Storybook config, stories, and fixtures live under ui/storybook/.
pnpm --filter @paperclipai/ui storybook
pnpm --filter @paperclipai/ui build-storybook
Typical use
Install the package, then serve or copy the built files from node_modules/@paperclipai/ui/dist.
Editor dependency identity
Keep the root and workspace overrides for @codemirror/state,
@codemirror/view, and @lezer/common aligned. CodeMirror requires shared
extension identity, while Lezer parsers and syntax highlighters require shared
NodeProp IDs. Multiple Lezer copies can crash code-block highlighting with
tags is not iterable. src/lib/codemirror-single-instance.test.ts checks the
installed dependency graph and highlights sample code through the editor's real
language dependencies. GitHub Actions owns regeneration of pnpm-lock.yaml.