Relax the dashboard route from canSeeAdmin (strict platform admin)
to canSeeOrgAdmin so the access seam can widen the audience past
the platform admin — by default platform admin, plus whatever an
access extension chooses to admit. The dashboard endpoint takes
care of scoping the response per caller.
Also move Dashboard under the canSeeOrgAdmin bullet in the
access.ts predicate notes.
The "chore: hide cluster detail" change had commented out both the
cluster-detail route and the cluster name link in the list. The
detail page component still ships in the OSS tree, so reach is
restored but the link is plugin-gated rather than unconditional:
plain OSS renders the name as a span; with a registered
`clusterDetail.linkableName` flag the name turns into a
`Typography.Link` that fires the parent's existing `onCellClick`
(which navigates to the detail route).
Detail tabs adjustments for the in-cluster context:
- Drop the Deployments tab (deployments are managed from the
top-level Models page; the detail view is scoped to a single
cluster's hardware).
- `WorkerList` and `GPUList` accept an optional `clusterId`. When
set, the list pins `cluster_id` in its query and hides the
cluster-filter dropdown so the user can't scope away from the
cluster they're inside.
`clusterDetail.extraTabs(clusterId, intl)` exposes a plugin slot
that appends additional tab items — used by the enterprise plugin
to inject per-cluster Access / Quotas surfaces. No-op without a
plugin.
Four purely-additive seams that let build-time tooling extend host
behaviour without forking files:
* `src/access.extensions.ts` — identity `applyAccessExtensions`
(mirrors `config/routes.extensions.ts`). `src/access.ts` runs the
resolved predicate object through it. Adds two new predicates,
`canSeeOrgAdmin` and `canManageCurrentOrg`, alongside the existing
`canSeeAdmin`. Resources, Models children, Cluster Management, and
Resources/Backends are retagged from `canSeeAdmin` to
`canSeeOrgAdmin`. Users and Dashboard stay strict.
* `src/request.extensions.ts` — identity-empty
`extraRequestInterceptors`. `src/request-config.tsx` spreads it
into the existing `requestInterceptors` list so extensions can
inject context-aware headers without forking the request config.
* Users page action column — renders
`getGPUStackPlugin()?.components?.UserRowActions` next to the
existing DropdownButtons inside a Space when a plugin component
is registered. If absent, the cell renders exactly as before.
* `src/components/plugin-extra-fields.tsx` — generic component-slot
helper. Renders `pluginManager.components.<name>` if registered,
forwarding a `context` payload. Used by create/edit forms to let
plugins inject extra `Form.Item` fields. Mounted in the relevant
create forms — API Keys, Cloud Credentials, Clusters, Model
Routes, Model Providers, and Inference Backends — under the slot
name `CreateOrgScopeField`. Resources whose org is implicit from a
parent (Models / Workers / Benchmarks / Worker Pools / Model Files
inherit from the chosen Cluster) deliberately don't mount the slot.