Problem
Third-party plugins (dynamic groups with DynamicGroupPrefix like G:plugin.id) cannot be dragged or reordered when using the V2 bar layout. In V1 mode, drag-and-drop works natively because LayoutModel was designed with DynamicGroupPrefix support from the start.
Root cause
The Omarchy state service validates V2 layouts and strips non-G1-G18 IDs when processing the config. Even though dynamic groups are persisted to bar.shibumi.v2Layout on disk, the state service's config binding normalizes them away. This creates a disconnect:
stateService.setV2Layout() persists dynamic groups to disk ✓
stateService.config.v2Layout strips them during processing ✗
v2Slots binding never sees dynamic groups ✗
What I tried
- Extending
V2LayoutModel.js with dynamic group support (DynamicGroupPrefix, isDynamicGroupId, addDynamicGroup, reconcilePluginGroups) — works at the model level but the state service still strips them on read
- Using
mutateShellConfig to bypass the state service — created a separate bar.v2Layout key that the state service doesn't read
- Writing to
bar.shibumi.v2Layout via mutateShellConfig — broke normal V2 operations (add/remove slots) because the state service processes the config asynchronously
Architecture gap
V1 LayoutModel has built-in support for dynamic groups (DynamicGroupPrefix), and stateService.setLayout preserves them. V2 was designed as a fixed 18-group grid with no extension mechanism.
Suggested solutions
- State service: Stop stripping dynamic group IDs from V2 layouts during config processing
- V2LayoutModel: Add native dynamic group support that the state service recognizes
- BarSection drag: Add drag-and-drop support to the BarSection component (where unassigned plugins render) as an alternative to putting them in V2 slots
Related
PR #28 fixes the V1 reconciliation bug that prevented third-party plugins from being enabled/disabled in V2 mode.
Problem
Third-party plugins (dynamic groups with
DynamicGroupPrefixlikeG:plugin.id) cannot be dragged or reordered when using the V2 bar layout. In V1 mode, drag-and-drop works natively becauseLayoutModelwas designed withDynamicGroupPrefixsupport from the start.Root cause
The Omarchy state service validates V2 layouts and strips non-
G1-G18IDs when processing the config. Even though dynamic groups are persisted tobar.shibumi.v2Layouton disk, the state service's config binding normalizes them away. This creates a disconnect:stateService.setV2Layout()persists dynamic groups to disk ✓stateService.config.v2Layoutstrips them during processing ✗v2Slotsbinding never sees dynamic groups ✗What I tried
V2LayoutModel.jswith dynamic group support (DynamicGroupPrefix,isDynamicGroupId,addDynamicGroup,reconcilePluginGroups) — works at the model level but the state service still strips them on readmutateShellConfigto bypass the state service — created a separatebar.v2Layoutkey that the state service doesn't readbar.shibumi.v2LayoutviamutateShellConfig— broke normal V2 operations (add/remove slots) because the state service processes the config asynchronouslyArchitecture gap
V1
LayoutModelhas built-in support for dynamic groups (DynamicGroupPrefix), andstateService.setLayoutpreserves them. V2 was designed as a fixed 18-group grid with no extension mechanism.Suggested solutions
Related
PR #28 fixes the V1 reconciliation bug that prevented third-party plugins from being enabled/disabled in V2 mode.