Extensible optionsSource registry for configuration UI #328

Closed
opened 2026-06-05 22:24:31 +00:00 by steve · 0 comments
Owner

Make configuration-schema optionsSource dynamically extensible so the settings UI resolves option lists without hardcoded switches such as workspace.editorViews.

Problem

The workspace settings renderer hardcodes optionsSource === "workspace.editorViews" in configuration.ts. Plugins cannot register their own option sources for declarative settings.

Goal

  • Core services register built-in option sources (starting with workspace.editorViews).
  • Plugins register option sources during onload via Plugin.registerConfigurationOptionSource.
  • Object-map and object-array settings resolve options through App.configurationOptionSources.
  • Unknown sources degrade gracefully; invalidation refreshes mounted controls.

Scope

  • ConfigurationOptionSourceRegistry in API package
  • App wiring + built-in workspace.editorViews source
  • Plugin registration API with lifecycle cleanup
  • Workspace renderer migration (object-map, object-array)
  • Component label polish for unknown values
  • Spec update

Non-goals

  • optionsSourceParams schema field
  • Top-level string dropdown/combobox (follow-up)
  • Registry-level caching

Acceptance Criteria

  • workspace.editorViews registered on App at boot; invalidates on EditorViewRegistry changes
  • No hardcoded optionsSource switch in workspace configuration renderer
  • Editor Associations resolves options via registry (no schema change)
  • Object-array columns with optionsSource resolve via registry
  • Plugins can registerConfigurationOptionSource("ruleIds", …)plugin-id.ruleIds; unload removes it
  • Unknown sources degrade gracefully; current values preserved when allowUnknownOptions: true
  • Mounted controls refresh options on source invalidation
  • Tests: registry, plugin lifecycle, workspace resolver
  • Spec updated

Implementation Notes

See attached implementation plan. Phases: registry module → App wiring → plugin API → workspace renderer → component polish → spec.

Suggested Files or Specs To Inspect

  • packages/api/src/lib/configuration-option-source-registry.ts (new)
  • packages/api/src/lib/context.svelte.ts
  • packages/api/src/lib/plugin.ts
  • packages/workspace/src/lib/components/configuration/configuration.ts
  • spec/src/30-cross-package-contracts/configuration-and-settings.md

Validation Commands

pnpm --filter @lapis-notes/api check:all
turbo run check:all --filter=@lapis-notes/workspace...
pnpm test:smoke
pnpm check:all
  • #321 object-array control (uses optionsSource columns)

Follow-up Tasks

  • Top-level string + optionsSource dropdown/combobox
  • optionsSourceParams for parameterized sources

Implementation Summary

Added ConfigurationOptionSourceRegistry on App with built-in workspace.editorViews source, Plugin.registerConfigurationOptionSource lifecycle API, registry-backed resolve/bind helpers for object-map and object-array settings, and (custom) unknown-value labels. Validated with api/workspace unit tests and pnpm test:smoke.

Make configuration-schema `optionsSource` dynamically extensible so the settings UI resolves option lists without hardcoded switches such as `workspace.editorViews`. ## Problem The workspace settings renderer hardcodes `optionsSource === "workspace.editorViews"` in `configuration.ts`. Plugins cannot register their own option sources for declarative settings. ## Goal - Core services register built-in option sources (starting with `workspace.editorViews`). - Plugins register option sources during `onload` via `Plugin.registerConfigurationOptionSource`. - Object-map and object-array settings resolve options through `App.configurationOptionSources`. - Unknown sources degrade gracefully; invalidation refreshes mounted controls. ## Scope - `ConfigurationOptionSourceRegistry` in API package - App wiring + built-in `workspace.editorViews` source - Plugin registration API with lifecycle cleanup - Workspace renderer migration (object-map, object-array) - Component label polish for unknown values - Spec update ## Non-goals - `optionsSourceParams` schema field - Top-level string dropdown/combobox (follow-up) - Registry-level caching ## Acceptance Criteria - [ ] `workspace.editorViews` registered on `App` at boot; invalidates on `EditorViewRegistry` changes - [ ] No hardcoded `optionsSource` switch in workspace configuration renderer - [ ] Editor Associations resolves options via registry (no schema change) - [ ] Object-array columns with `optionsSource` resolve via registry - [ ] Plugins can `registerConfigurationOptionSource("ruleIds", …)` → `plugin-id.ruleIds`; unload removes it - [ ] Unknown sources degrade gracefully; current values preserved when `allowUnknownOptions: true` - [ ] Mounted controls refresh options on source invalidation - [ ] Tests: registry, plugin lifecycle, workspace resolver - [ ] Spec updated ## Implementation Notes See attached implementation plan. Phases: registry module → App wiring → plugin API → workspace renderer → component polish → spec. ## Suggested Files or Specs To Inspect - `packages/api/src/lib/configuration-option-source-registry.ts` (new) - `packages/api/src/lib/context.svelte.ts` - `packages/api/src/lib/plugin.ts` - `packages/workspace/src/lib/components/configuration/configuration.ts` - `spec/src/30-cross-package-contracts/configuration-and-settings.md` ## Validation Commands ```bash pnpm --filter @lapis-notes/api check:all turbo run check:all --filter=@lapis-notes/workspace... pnpm test:smoke pnpm check:all ``` ## Related Issues - #321 object-array control (uses optionsSource columns) ## Follow-up Tasks - Top-level string + optionsSource dropdown/combobox - `optionsSourceParams` for parameterized sources ## Implementation Summary Added ConfigurationOptionSourceRegistry on App with built-in workspace.editorViews source, Plugin.registerConfigurationOptionSource lifecycle API, registry-backed resolve/bind helpers for object-map and object-array settings, and (custom) unknown-value labels. Validated with api/workspace unit tests and pnpm test:smoke. <!-- backlog:task_id=TASK-PLUGIN-073 source_spec=spec/src/30-cross-package-contracts/configuration-and-settings.md -->
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lapis-notes/lapis#328
No description provided.