Asana and Linear were pinned to customer-owned OAuth clients on the strength of an Aug-26 research snapshot, so both asked for a client ID and secret from a developer console before the first sign-in. Re-probed both servers on 2026-09-28: each advertises a registration endpoint and issues a client on request, and Linear also advertises client-ID metadata documents. The snapshot was simply out of date. So stop treating the catalog as the last word. A curated OAuth method still earns a dynamic registration when the provider's own metadata advertises one; ownershipModes stays as the manual fallback. A stale entry now costs a console detour at worst instead of silently outranking what the server just said about itself. Asana's registration is localhost-only — it refuses a hosted redirect URI — so its catalog text says that rather than promising one click everywhere. Linear accepts both. When the client-ID fields are genuinely required, the screen now says whose limitation it is, so the extra work reads as the exception it is rather than as that connector's normal path. Also fixes a tsc error from the previous commit: renderDefaults is an optional prop, not a nullable one. Tests: AppsConnect 165/165, connections 38/38, shared 24/24. The customer-owned-client case moved to Box, which is still genuinely pinned; Asana gained a test asserting it now reaches the handoff with no form in between. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@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.