feat(plugins): add theme contributions
Adds plugin-contributed light and dark app themes, including persistence, host-aware coalescing, fallback behavior, documentation, examples, and browser/iOS QA.
This commit is contained in:
@@ -13,6 +13,7 @@ Local plugins are directory sources installed into one Paseo daemon. A plugin ca
|
||||
- React Native surfaces and sidebar items to Paseo clients;
|
||||
- workspace and agent panels opened as workspace tabs;
|
||||
- global, workspace, and agent actions in the Command Center;
|
||||
- dark themes in Settings → Appearance;
|
||||
- schema-validated RPC handlers running beside the daemon;
|
||||
- normal Paseo operations through the TypeScript SDK;
|
||||
- searchable external resources in the message composer.
|
||||
@@ -150,13 +151,16 @@ Plugin UI runs on desktop, browser, iOS, and Android, across every Paseo theme.
|
||||
|
||||
Recreate styles when `theme` or `layout.compact` changes.
|
||||
|
||||
| Key | Required for | Use it for |
|
||||
| ------------------------------ | -------------------------- | ----------------------------------- |
|
||||
| `theme.colors.foreground` | Every primary `Text` | Titles and body copy |
|
||||
| `theme.colors.foregroundMuted` | Secondary `Text` | Labels and supporting copy |
|
||||
| `theme.colors.surface0` | Root view | Panel background |
|
||||
| `layout.compact` | Padding and stacking | `true` on mobile and narrow windows |
|
||||
| `layout.platform` | Platform-specific behavior | `ios`, `android`, or `web` |
|
||||
| Key | Required for | Use it for |
|
||||
| ------------------------------- | -------------------------- | ----------------------------------- |
|
||||
| `theme.colors.foreground` | Every primary `Text` | Titles and body copy |
|
||||
| `theme.colors.foregroundMuted` | Secondary `Text` | Labels and supporting copy |
|
||||
| `theme.colors.surface0` | Root view | Panel background |
|
||||
| `theme.colors.accent` | Primary action fills | Buttons and selected states |
|
||||
| `theme.colors.accentForeground` | Text on an accent fill | Button labels |
|
||||
| `theme.colors.statusDanger` | Failure copy | Error messages and destructive text |
|
||||
| `layout.compact` | Padding and stacking | `true` on mobile and narrow windows |
|
||||
| `layout.platform` | Platform-specific behavior | `ios`, `android`, or `web` |
|
||||
|
||||
Do not hardcode `#000`, `#fff`, or React Native's default text color. Primary copy uses `foreground`. Labels use `foregroundMuted`. Tighten padding when `layout.compact` is true.
|
||||
|
||||
@@ -164,6 +168,60 @@ Workspace and agent panels receive the same `theme` and `layout` fields.
|
||||
|
||||
Client code can import `react`, `react-native`, `@tanstack/react-query`, `zod`, `@getpaseo/plugin`, and `@getpaseo/plugin/server`. Install them locally for typechecking; Paseo provides the client runtime instances.
|
||||
|
||||
## Contribute a theme
|
||||
|
||||
`addTheme` adds a light or dark theme to Settings → Appearance, listed under the built-ins by its `name`. A
|
||||
theme is data, so it needs no client file:
|
||||
|
||||
```ts
|
||||
import type { PluginContext } from "@getpaseo/plugin";
|
||||
|
||||
export default function contribute(plugin: PluginContext) {
|
||||
plugin.addTheme({
|
||||
id: "mocha",
|
||||
name: "Catppuccin Mocha",
|
||||
appearance: "dark",
|
||||
colors: {
|
||||
background: "#1e1e2e",
|
||||
foreground: "#cdd6f4",
|
||||
raised: "#313244",
|
||||
control: "#45475a",
|
||||
border: "#45475a",
|
||||
accent: "#cba6f7",
|
||||
mutedForeground: "#a6adc8",
|
||||
ring: "#6c7086",
|
||||
},
|
||||
});
|
||||
return () => {};
|
||||
}
|
||||
```
|
||||
|
||||
Every color is a hex string; anything else fails to load. Paseo expands the palette into the full
|
||||
token set the built-in dark themes use, so a contributed theme covers panels, menus, diffs, status
|
||||
colors, and the terminal without listing them.
|
||||
|
||||
| Color | Becomes |
|
||||
| ----------------- | ----------------------------------------------------------------- |
|
||||
| `background` | App, workspace, and terminal background |
|
||||
| `foreground` | Primary text, terminal foreground and cursor |
|
||||
| `raised` | Cards, popovers, and hovered rows |
|
||||
| `control` | Inputs, secondary fills, and the light-theme sidebar |
|
||||
| `border` | Borders and the highest raised-surface tint |
|
||||
| `accent` | Buttons, selection, and focus. Optional; `foreground` if omitted. |
|
||||
| `mutedForeground` | Secondary text |
|
||||
| `ring` | Focus rings, scrollbars, and terminal bright black |
|
||||
|
||||
`appearance` is `"light"` or `"dark"`. Paseo uses it to select the matching surface, status,
|
||||
diff, syntax, terminal, and shadow derivation.
|
||||
|
||||
Only one contributed theme is active at a time. Selecting one persists the choice; if the plugin is
|
||||
later disabled or removed, Paseo falls back to the default theme rather than leaving the app
|
||||
unpainted.
|
||||
|
||||
Themes need a host that supports them. A daemon released before `addTheme` compiles the call into
|
||||
the plugin's backend bundle, where it does not exist, and the plugin fails to start with
|
||||
`plugin.addTheme is not a function`. Update the host.
|
||||
|
||||
## Workspace panels
|
||||
|
||||
Register one panel for workspace or agent context:
|
||||
|
||||
Reference in New Issue
Block a user