Skip to content
This repository was archived by the owner on Feb 28, 2026. It is now read-only.

Commit ba95cc4

Browse files
committed
Update docs
1 parent 5a920fe commit ba95cc4

File tree

11 files changed

+80
-74
lines changed

11 files changed

+80
-74
lines changed

.github/copilot-instructions.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pnpm storybook # run Storybook
9090
- Snapshot tests: **basic rendering only**. Start names with `(Snapshot)`.
9191
- Extract DOM querying into wrappers; assertions stay in tests.
9292
- Coverage: enabled across packages with V8-based coverage and CI reporting.
93+
- Use the test runner tool instead of running tests in the terminal manually.
9394

9495
### Design & UX Philosophy
9596

@@ -109,4 +110,5 @@ pnpm storybook # run Storybook
109110
- Treat this as **production code from day one**. No shortcuts, no placeholders.
110111
- Prioritize long-term maintainability.
111112
- Work with me iteratively: pause, summarize, ask.
112-
- Above all: **be reliable, disciplined, and clear.**
113+
- Above all: **be reliable, disciplined, and clear.**
114+
- Use Serena tools wherever possible for searches, lookups, replacements, and file operations.

packages/docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [Plugin system](plugins/plugin-system.md)
77
* [Settings](plugins/settings.md)
88
* [Queue](plugins/queue.md)
9+
* [Providers](plugins/providers.md)
910

1011
## Theming
1112

packages/docs/plugins/providers.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
description: Extend Nuclear with custom metadata providers through the Providers API.
3+
---
4+
5+
# Providers
6+
7+
## Providers API for Plugins
8+
9+
The Providers API allows plugins to register custom providers that supply metadata for tracks, albums, and artists. This enables Nuclear to integrate with any music service or database.
10+
11+
{% hint style="info" %}
12+
Access providers via `NuclearAPI.Providers.*` in your plugin's lifecycle hooks. Only metadata providers are supported.
13+
{% endhint %}
14+
15+
---
16+
17+
## Core concepts
18+
19+
### What are providers?
20+
21+
Providers are modules that fulfill specific data requests from Nuclear. When the app needs information (like album art, track metadata, or artist details), it queries the selected provider.
22+
23+
### Provider types
24+
25+
**Metadata Providers** (current)
26+
- Supply information about tracks, albums, and artists
27+
- Examples: MusicBrainz, Last.fm, Discogs
28+
- Used for search, library management, and display

packages/docs/themes/themes-advanced.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ Here's the basic structure to get you started:
4141

4242
**Typography**
4343
- font-family (example: "'Inter', system-ui, -apple-system, sans-serif")
44-
- font-weight-normal, font-weight-bold
44+
- font-family-heading
45+
- font-weight-normal, font-weight-bold, font-weight-extra-bold
4546

4647
**Shape & visual effects**
47-
- radius, radius-sm, radius-lg
48+
- radius-sm, radius-md, radius-lg
4849
- shadow-color, shadow-x, shadow-y, shadow-blur
4950

5051
## A few helpful notes
@@ -90,11 +91,13 @@ Here's a complete template with Nuclear's default values that you can copy and c
9091
"shadow-blur": "0px",
9192

9293
"font-family": "'DM Sans', system-ui, -apple-system, sans-serif",
94+
"font-family-heading": "'Bricolage Grotesque', 'DM Sans', system-ui, sans-serif",
9395
"font-weight-normal": "400",
9496
"font-weight-bold": "700",
97+
"font-weight-extra-bold": "800",
9598

96-
"radius": "8px",
9799
"radius-sm": "4px",
100+
"radius-md": "8px",
98101
"radius-lg": "12px"
99102
},
100103
"dark": {

packages/player/src/integration-tests/settings.test.tsx

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,15 @@ describe('Settings integration', () => {
4343
);
4444
const api = new NuclearAPI({ settingsHost: pluginHost });
4545

46-
await api.Settings.register(
47-
[
48-
{
49-
id: 'example.enabled',
50-
category: 'Example',
51-
title: 'Enabled',
52-
kind: 'boolean',
53-
default: true,
54-
},
55-
],
46+
await api.Settings.register([
5647
{
57-
type: 'plugin',
58-
pluginId: 'itest',
59-
pluginName: 'Integration Test Plugin',
48+
id: 'example.enabled',
49+
category: 'Example',
50+
title: 'Enabled',
51+
kind: 'boolean',
52+
default: true,
6053
},
61-
);
54+
]);
6255

6356
const definitions = useSettingsStore.getState().definitions;
6457
expect(definitions['plugin.itest.example.enabled']).toBeTruthy();
@@ -74,18 +67,15 @@ describe('Settings integration', () => {
7467
);
7568
const api = new NuclearAPI({ settingsHost: pluginHost });
7669

77-
await api.Settings.register(
78-
[
79-
{
80-
id: 'example.enabled',
81-
category: 'Example',
82-
title: 'Enabled',
83-
kind: 'boolean',
84-
default: false,
85-
},
86-
],
87-
{ type: 'plugin', pluginId: 'itest' },
88-
);
70+
await api.Settings.register([
71+
{
72+
id: 'example.enabled',
73+
category: 'Example',
74+
title: 'Enabled',
75+
kind: 'boolean',
76+
default: false,
77+
},
78+
]);
8979

9080
const initial = await api.Settings.get<boolean>('example.enabled');
9181
expect(initial).toBe(false);

packages/player/src/services/settingsHost.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@ export const createPluginSettingsHost = (
2020
): SettingsHost => {
2121
const pluginSource: SettingSource = { type: 'plugin', pluginId, pluginName };
2222
return {
23-
register: async (
24-
definitions: SettingDefinition[],
25-
_source: SettingSource,
26-
) => {
27-
void _source;
23+
register: async (definitions: SettingDefinition[]) => {
2824
const registeredIds = useSettingsStore
2925
.getState()
3026
.register(definitions, pluginSource);
@@ -64,7 +60,7 @@ export const createPluginSettingsHost = (
6460
export const createCoreSettingsHost = (): SettingsHost => {
6561
const coreSource: SettingSource = { type: 'core' };
6662
return {
67-
register: async (definitions) => {
63+
register: async (definitions: SettingDefinition[]) => {
6864
const registeredIds = useSettingsStore
6965
.getState()
7066
.register(definitions, coreSource);

packages/player/src/stores/settingsStore.test.ts

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -78,31 +78,25 @@ describe('useSettingsStore', () => {
7878
const hostA = createPluginSettingsHost('p1', 'Plugin One');
7979
const hostB = createPluginSettingsHost('p2', 'Plugin Two');
8080

81-
await hostA.register(
82-
[
83-
{
84-
id: 'feature.enabled',
85-
title: 'Enabled',
86-
category: 'Example',
87-
kind: 'boolean',
88-
default: false,
89-
},
90-
],
91-
{ type: 'plugin', pluginId: 'p1' },
92-
);
81+
await hostA.register([
82+
{
83+
id: 'feature.enabled',
84+
title: 'Enabled',
85+
category: 'Example',
86+
kind: 'boolean',
87+
default: false,
88+
},
89+
]);
9390

94-
await hostB.register(
95-
[
96-
{
97-
id: 'feature.enabled',
98-
title: 'Enabled',
99-
category: 'Example',
100-
kind: 'boolean',
101-
default: true,
102-
},
103-
],
104-
{ type: 'plugin', pluginId: 'p2' },
105-
);
91+
await hostB.register([
92+
{
93+
id: 'feature.enabled',
94+
title: 'Enabled',
95+
category: 'Example',
96+
kind: 'boolean',
97+
default: true,
98+
},
99+
]);
106100

107101
expect(
108102
useSettingsStore.getState().definitions['plugin.p1.feature.enabled'],

packages/plugin-sdk/src/api/settings.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ describe('Settings (SDK)', () => {
1919
},
2020
];
2121

22-
const res = await api.Settings.register(definitions, {
23-
type: 'plugin',
24-
pluginId: 'p1',
25-
});
22+
const res = await api.Settings.register(definitions);
2623
expect(res.registered).toContain('plugin.p1.feature.enabled');
2724

2825
const initial = await api.Settings.get<boolean>('feature.enabled');
@@ -50,7 +47,7 @@ describe('Settings (SDK)', () => {
5047
expect(() => api.Settings.set('x', 'y')).toThrow(
5148
'Settings host not available',
5249
);
53-
expect(() => api.Settings.register([], { type: 'core' })).toThrow(
50+
expect(() => api.Settings.register([])).toThrow(
5451
'Settings host not available',
5552
);
5653
expect(() => api.Settings.subscribe('x', () => {})).toThrow(

packages/plugin-sdk/src/api/settings.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type {
22
SettingDefinition,
33
SettingsHost,
4-
SettingSource,
54
SettingValue,
65
} from '../types/settings';
76

@@ -20,8 +19,8 @@ export class Settings {
2019
return fn(host);
2120
}
2221

23-
register(defs: SettingDefinition[], source: SettingSource) {
24-
return this.#withHost((h) => h.register(defs, source));
22+
register(defs: SettingDefinition[]) {
23+
return this.#withHost((h) => h.register(defs));
2524
}
2625

2726
get<T extends SettingValue = SettingValue>(id: string) {

packages/plugin-sdk/src/test/utils/inMemorySettingsHost.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ export class InMemorySettingsHost implements SettingsHost {
2525
return `core.${id}`;
2626
}
2727

28-
async register(definitions: SettingDefinition[], _source: SettingSource) {
29-
void _source;
28+
async register(definitions: SettingDefinition[]) {
3029
const registered: string[] = [];
3130
for (const definition of definitions) {
3231
const fullyQualifiedId = this.fullyQualified(definition.id);

0 commit comments

Comments
 (0)