@mohsinonxrm/pptb-commandbar-studio 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +363 -99
  2. package/LICENSE +661 -661
  3. package/README.md +343 -316
  4. package/SECURITY.md +62 -0
  5. package/dist/assets/BulkPublishModal-DqX2QmUD.js +29 -0
  6. package/dist/assets/CommandEditorPanel-DidGBtFC.js +1 -0
  7. package/dist/assets/CommandPalette-AuDfsF8l.js +1 -0
  8. package/dist/assets/ConflictDrawer-DxQ_jd-x.js +1 -0
  9. package/dist/assets/CrmParameterEditor-BdmP65mF.js +1 -0
  10. package/dist/assets/DiffViewer-BZuqvP4f.js +7 -0
  11. package/dist/assets/HideInsteadOfDeleteModal-BYHCTZrG.js +1 -0
  12. package/dist/assets/IconPickerModal-Bw0C7KwV.js +1 -0
  13. package/dist/assets/ImportXmlModal-B8NgiUDZ.js +1 -0
  14. package/dist/assets/LocalizationEditor-tmniX5PC.js +1 -0
  15. package/dist/assets/MonacoEditor-Bbg9u2FW.js +2 -0
  16. package/dist/assets/NewButtonModal-BVvlbCv4.js +1 -0
  17. package/dist/assets/NewGroupModal-CgQy-uo4.js +1 -0
  18. package/dist/assets/NewTabModal-B_2-kwAx.js +1 -0
  19. package/dist/assets/RuleEditorPanel-BkNwBgaP.js +1 -0
  20. package/dist/assets/ScalingEditorPanel-ezMkzvG1.js +1 -0
  21. package/dist/assets/TabDisplayRulesPanel-trzExQ1T.js +1 -0
  22. package/dist/assets/UrlComposerModal-BlVXHKRM.js +1 -0
  23. package/dist/assets/WebResourceBrowser-DaPOZQ5X.js +1 -0
  24. package/dist/assets/XmlDrawer-BI6Wy6kL.js +2 -0
  25. package/dist/assets/crmParameters-rgfZhhzN.js +1 -0
  26. package/dist/assets/cssMode-DdC7kBk-.js +1 -0
  27. package/dist/assets/{dnd-DHB99ZH7.js → dnd-fsSwRnQv.js} +2 -2
  28. package/dist/assets/{editor.worker-CdQrwHl8.js → editor.worker-1APKdqmi.js} +2 -2
  29. package/dist/assets/fluent-icons-DxKNRZ1A.js +1 -0
  30. package/dist/assets/fluent-ui-D7EtYwEg.js +43 -0
  31. package/dist/assets/{freemarker2-B8bME0pA.js → freemarker2-DDn-Wpd6.js} +1 -1
  32. package/dist/assets/{handlebars-zIyCxTW6.js → handlebars-Ck_SjSJx.js} +1 -1
  33. package/dist/assets/{html-B5hFqu3X.js → html-BaJUqhKx.js} +1 -1
  34. package/dist/assets/htmlMode-CnYhJfhG.js +1 -0
  35. package/dist/assets/index-Bu7BlRFk.js +139 -0
  36. package/dist/assets/{javascript-BQGsYMat.js → javascript-2UlV1Qbm.js} +1 -1
  37. package/dist/assets/{jsonMode-CR0b-9Un.js → jsonMode-BmSpB9yr.js} +1 -1
  38. package/dist/assets/{liquid-DLq8jbP8.js → liquid-CE2reFvH.js} +1 -1
  39. package/dist/assets/{lspLanguageFeatures-C3buAG32.js → lspLanguageFeatures-BvbzEddk.js} +2 -2
  40. package/dist/assets/{mdx-5ni22WXY.js → mdx-BvcZv3tC.js} +1 -1
  41. package/dist/assets/{monaco-BLZnQb2P.js → monaco-Bx8A1Vm1.js} +4 -4
  42. package/dist/assets/monaco-Dprb6f6S.css +1 -0
  43. package/dist/assets/{python-F20Pd69B.js → python-MTPSN2vk.js} +1 -1
  44. package/dist/assets/{razor-3xmsG6cc.js → razor-Ccq_CgR8.js} +1 -1
  45. package/dist/assets/ruleKinds-B9hACGaq.js +1 -0
  46. package/dist/assets/{server.browser-DfdiBs1P.js → server.browser-C3R9jebn.js} +1 -1
  47. package/dist/assets/{tsMode-Cyusk9p4.js → tsMode-2cv3qhqp.js} +1 -1
  48. package/dist/assets/{typescript-BXT-ECX3.js → typescript-BD6t7JEG.js} +1 -1
  49. package/dist/assets/webResourceService-CvyHBu7T.js +1 -0
  50. package/dist/assets/{xml-Cwzeco8o.js → xml-DJGPA7j9.js} +1 -1
  51. package/dist/assets/xmlValidator-D7JG-eNC.js +3 -0
  52. package/dist/assets/{yaml-BHUePD-R.js → yaml-Cpl0dvFM.js} +1 -1
  53. package/dist/icons/icon.svg +16 -0
  54. package/dist/index.html +24 -18
  55. package/index.html +18 -12
  56. package/package.json +18 -32
  57. package/dist/assets/BulkPublishModal-DlglMah4.js +0 -29
  58. package/dist/assets/CommandEditorPanel-4pYnil3i.js +0 -1
  59. package/dist/assets/CommandPalette-iYxzI2G_.js +0 -1
  60. package/dist/assets/ConflictDrawer-DBPRRkoa.js +0 -1
  61. package/dist/assets/DiffViewer-DFBJPZKA.js +0 -7
  62. package/dist/assets/IconPickerModal-Bg0Zc8UZ.js +0 -1
  63. package/dist/assets/ImportXmlModal-BccMoaDv.js +0 -3
  64. package/dist/assets/LocalizationEditor-DVZy2uLy.js +0 -1
  65. package/dist/assets/MonacoEditor-DFYisBG6.js +0 -2
  66. package/dist/assets/NewButtonModal-D5Hz1yx4.js +0 -1
  67. package/dist/assets/NewGroupModal-BgTVG-VJ.js +0 -1
  68. package/dist/assets/NewTabModal-7-ZPcPi-.js +0 -1
  69. package/dist/assets/RuleEditorPanel-BwQzOQBe.js +0 -1
  70. package/dist/assets/ScalingEditorPanel-B221zNLL.js +0 -1
  71. package/dist/assets/TabDisplayRulesPanel-drKzEO_E.js +0 -1
  72. package/dist/assets/UrlComposerModal-Bnifp4oB.js +0 -1
  73. package/dist/assets/WebResourceBrowser-qtcNTNge.js +0 -1
  74. package/dist/assets/XmlDrawer-CN941TbU.js +0 -2
  75. package/dist/assets/cssMode-DFSY9yCW.js +0 -1
  76. package/dist/assets/fluent-icons-DiKr_qRE.js +0 -1
  77. package/dist/assets/fluent-ui-kUA2U4Gr.js +0 -43
  78. package/dist/assets/htmlMode-BmPxEBms.js +0 -1
  79. package/dist/assets/index-DjHxPFpB.js +0 -6
  80. package/dist/assets/monaco-Dvl_Svmm.css +0 -1
  81. package/dist/assets/webResourceService-Ck07E3GN.js +0 -1
  82. package/dist/assets/xmlGenerator-DEaVrfZJ.js +0 -130
  83. package/dist/stats.html +0 -4949
  84. package/npm-shrinkwrap.json +0 -13253
package/CHANGELOG.md CHANGED
@@ -1,99 +1,363 @@
1
- # Command Bar Studio — Changelog
2
-
3
- All notable changes to Command Bar Studio will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ---
9
-
10
- ## [0.5.0] - 2026-07-16
11
-
12
- ### 🎉 First Beta Release
13
-
14
- Command Bar Studio 0.5.0-beta — a fully featured visual designer for Dataverse
15
- classic ribbon / command bar customizations, running inside Power Platform ToolBox.
16
-
17
- #### ✨ Features
18
-
19
- - **Visual ribbon canvas** — Classic (tabbed groups + large icon tiles), Modern
20
- (flat command bar), and List (data grid) views for all 4 ribbon locations
21
- (HomepageGrid, SubGrid, Form, Application)
22
- - **Classic ribbon drag-and-drop** — Migrated from HTML5 native drag to **@dnd-kit**
23
- with a styled `DragOverlay` ghost tile (brand border, box-shadow, `grabbing` cursor).
24
- `DroppableSlot` zones between buttons show a 2 px animated drop-line indicator.
25
- `DroppableGroupContainer` highlights the target group. `PointerSensor` with 5 px
26
- activation constraint so ordinary clicks still select buttons. Keyboard sensor
27
- retained for accessibility.
28
- - **Properties pane** — Label/tooltip/icon/kind/sequence/templateAlias editing;
29
- locale chip row; command binding; display/enable rule pills; scaling summary;
30
- advanced section (form scope, OpenRecordItem override, client-type filter)
31
- - **Command editor** — JavaScript (library Browse… to Web Resource Browser), URL (PassParams,
32
- WinMode, named params), **Power Fx** (inline Monaco editor — syntax-highlighted,
33
- word wrap, no line numbers — with variable hints and async-rule note), Custom API;
34
- References tab with button breadcrumbs; Versions tab
35
- - **Rule editor** — All 30 `RuleStep` kinds from `RibbonTypes.xsd`; drag-to-reorder;
36
- OrRule nesting with nested “Add step”; InvertResult + Default toggles;
37
- plain-English `summarizeRule()` output
38
- - **Localization editor** — Multi-LCID label / tooltip title / tooltip body;
39
- 20 built-in LCIDs; line-break insertion (`​​`)
40
- - **Icon picker** — Fluent icons (auto-uploaded as SVG web resource), web resource
41
- browser, custom SVG upload
42
- - **Scaling editor** — MaxSize / Scale step sequence management per MS docs
43
- - **Tab display rules editor** — EntityRule (all 4 contexts) + PageRule
44
- - **Web Resource Browser** — Virtualized; upload; edit JS/CSS/XML in Monaco;
45
- callback registry so selection propagates back to caller (Image16/32, library field)
46
- - **URL Action Composer** — PassParams table, CrmParameter querystring keys, live preview
47
- - **XML Drawer** — Per-location RibbonDiffXml in Monaco; Format XML; CBS completions
48
- - **Diff / Compare Viewer** — Monaco `DiffEditor` baseline comparison
49
- - **Bulk Publish dialog** — Per-entity change counts; progress overlay; ribbonmetadatasettoprocess monitoring
50
- - **Solution Conflict Drawer** — `msdyn_componentlayer` provenance; managed-solution
51
- banner in properties pane auto-populated after ribbon load
52
- - **Command Palette** (Ctrl+K) — buttons, commands, rules, entities, actions
53
- - **Undo/Redo** — 80-entry history stack; `mutationsSincePublish` counter
54
- - **localStorage persistence** — Auto-save + restore banner on startup
55
-
56
- #### 🏗️ Architecture
57
-
58
- - **Delta-only `RibbonDiffXml`** — only changed elements emitted; system `Mscrm.*`
59
- commands/rules never re-emitted; OOB commands with JS actions (e.g.
60
- `Mscrm.OpenRecordItem`) correctly emitted as overrides
61
- - **Correct `behavior=2` (shell-only)** entity root component — does not drag in
62
- every attribute / form / view on import
63
- - **ImportJobId required** — supplied to every `deploySolution` call; 5-minute poll
64
- with progress beats
65
- - **Post-publish observability** — `ribbonmetadatasettoprocess` polling after
66
- `publishCustomizations()` surfaces silent ribbon-compile failures
67
- - **Parser: all 30 rule kinds** — `EntityPrivilegeRule`, `RecordPrivilegeRule`,
68
- `ShowOnGridRule`, `DeviceTypeRule`, `RelationshipTypeRule`, and 14 more;
69
- previously these were silently dropped, risking security-rule corruption on republish
70
- - **TabDisplayRules DOM scope** — read from document-level `RuleDefinitions > TabDisplayRules`,
71
- not from inside `<Tab>` elements (parser bug that caused tab rules to always appear empty)
72
- - **Group selector fixed** — `:scope > Groups > Group` (dropped rogue `, Group` clause
73
- that matched groups inside `CustomAction > CommandUIDefinition`, creating phantom groups)
74
- - **`getWebResourceContent` uses `api.retrieve`** instead of `queryData` with key
75
- predicate — correct single-record fetch that works reliably with PPTB's `dataverseAPI`
76
- - **Web resource browser callback registry** — module-level one-shot callback
77
- so Image16/32 and Command Editor library-field Browse selections propagate correctly
78
- (previously selecting a resource in the browser did nothing — the `onSelect` prop
79
- was never wired through the global Layout overlay)
80
- - **`@dnd-kit` DragOverlay** — ClassicRibbon button drag fully migrated from HTML5
81
- native drag to `@dnd-kit` (`useDraggable`, `useDroppable`, `DragOverlay`)
82
- - **`@pptb/types` 1.2.3** — latest Power Platform ToolBox host API types
83
-
84
- #### 🧪 Tests
85
-
86
- - **148 / 148 passing** across 8 Vitest suites
87
- - `all-rule-kinds.xml` fixture — covers every `RuleStep` kind in a round-trip
88
- parse → generate → re-parse test; regression guard for the 18 formerly-missing
89
- parser kinds, TabDisplayRules DOM scope, and group selector
90
-
91
- ---
92
-
93
- ## [0.1.0] - 2025-01-01
94
-
95
- ### Initial scaffold
96
-
97
- - Project initialization with Vite + React 18 + TypeScript 5 + Fluent UI v9
98
- - Shell layout, ribbon canvas stubs, Zustand stores, XML generator/parser scaffolding
99
-
1
+ # Command Bar Studio — Changelog
2
+
3
+ All notable changes to Command Bar Studio will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [Unreleased]
11
+
12
+ ## [0.6.0] - 2026-10-18
13
+
14
+ The v0.6.0 milestone: publishing that keeps what's already in your customizations and verifies
15
+ what it wrote, editing what isn't yours (Customise Command / Customise button), menus, new tabs
16
+ and groups, restoring unsaved changes, pre-publish validation, and Power Platform ToolBox 1.2.7,
17
+ in the desktop app and the VS Code extension. 0.5.x stays available for PPTB versions before
18
+ 1.2.7 (see `SECURITY.md`).
19
+
20
+ ### ⚠️ Requires Power Platform ToolBox 1.2.7
21
+
22
+ - **Power Platform ToolBox 1.2.7 ([#10](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/10)).**
23
+ - **Requires PPTB 1.2.7 or later** — `features` is now `{ "connections": 1, "minAPI": "1.2.7" }`
24
+ (the legacy `multiConnection` field is deprecated; older PPTB builds don't understand
25
+ `connections`, so they show the tool as incompatible).
26
+ - **`@pptb/types` ^1.2.7** (validator now in `@pptb/validate`); removed the last
27
+ `execute` type cast.
28
+ - **Theme** follows the host when PPTB raises `settings:updated`, not only when the
29
+ tool becomes visible again.
30
+
31
+ ### ✨ Added
32
+
33
+ - **Publishing keeps what's already there ([#11](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/11)).**
34
+ - Publish reads the solution's existing unmanaged ribbon layer and merges your changes into it
35
+ in one import, so customizations made elsewhere (for example with Ribbon Workbench) are kept.
36
+ Every publish is imported twice so Unified Interface picks it up, and the published layer is
37
+ read back and checked.
38
+ - Load: when the server returns an out-of-date copy of a command or rule right after a publish
39
+ (it can lag 10 minutes or more), the copy in your customizations is used ([#52](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/52)).
40
+ - **Flyout and split-button menus ([#27](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/27)).**
41
+ - Menus are modelled, parsed and published: add, edit, hide and delete menu items, create new
42
+ flyouts and split buttons with sections.
43
+ - Duplicating a flyout gives its items short ids of their own, and label ids stay within 128
44
+ characters: longer ones inside a menu made publishing fail after the import ([#86](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/86)).
45
+ Copies keep platform (`$Resources:`) texts instead of showing the resource key.
46
+ - **New tabs and groups ([#58](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/58), [#59](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/59)).**
47
+ - Buttons in a new group on an existing tab are written with the group; new tabs get a command
48
+ and a display rule, are rebuilt on reload, and can be renamed and deleted.
49
+ - Group scaling uses free sequences: colliding ones made Unified Interface drop every custom
50
+ control of the table. Layers written by earlier versions are repaired on the next publish.
51
+ - **Editing what isn't yours ([#25](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/25), [#26](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/26), [#31](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/31)).**
52
+ - **Customise Command** copies an out-of-the-box command into your customizations so it can be
53
+ changed; **Customise button** copies a button and hides the original.
54
+ - Moving a button that isn't yours moves your copy and hides the original, as one undo step.
55
+ - Edits to existing commands and rules are published.
56
+ - **Restoring unsaved changes ([#16](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/16)).**
57
+ - **Restore** now brings back everything that was going to be published: the canvas,
58
+ commands, rules, labels and translations, un-hides, and customised / uncustomised
59
+ commands. It goes on top of the ribbon as loaded now, so the restored changes publish
60
+ (before, they were taken as the loaded state and nothing could be published). Undo
61
+ takes the restore back as one step (the draft is kept).
62
+ - The offer is a dialog shown only once the table has finished loading, so a restore is no
63
+ longer overwritten by the load, and nothing can be edited until you choose **Restore**
64
+ or **Discard**. When the table's ribbon changed on the server since the draft was saved,
65
+ the dialog says so: review the publish plan before publishing.
66
+ - Drafts are kept per org, solution and table. Loading a table no longer deletes its
67
+ draft; a draft is removed after publishing everything, when undoing back to the loaded
68
+ ribbon, or with **Discard**. A publish that fails for the table keeps it (and the table
69
+ still counts as changed). Drafts saved by earlier versions, and drafts older than 30
70
+ days, are discarded at startup.
71
+ - Switching table or solution with unpublished changes asks first: **Keep as draft**
72
+ (offered again when you reopen the table in that solution), **Discard** or **Cancel**.
73
+ - A draft stores only what differs from the loaded ribbon (changed, added and removed tabs,
74
+ groups, buttons, commands, rules and labels), deflated: a few KB instead of over a million
75
+ characters per table, so drafts of several tables fit in `localStorage`. What the server
76
+ added since the draft was saved is kept on restore.
77
+ - When a draft can't be saved (browser storage full), a banner says so (and when the last
78
+ saved draft is from), and **Keep as draft** is disabled (and never switches) so the
79
+ changes aren't lost.
80
+ - **Pre-publish validation ([#35](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/35)).**
81
+ - The publish dialog checks the RibbonDiffXml each scope would import (your
82
+ existing unmanaged layer plus this session's changes) before **Publish** is
83
+ enabled. **Errors block the publish**: dropped Power Fx / Custom API actions,
84
+ flyout / split buttons without a menu, controls' commands or commands' rules
85
+ that are defined nowhere, scaling steps of a tab on the same Sequence (Unified
86
+ Interface then drops every custom control of the table) and duplicate control
87
+ ids. **Warnings don't**: rule kinds in the wrong kind of rule, `$LocLabels:`
88
+ references without a label in the customization, missing web resources or
89
+ ones outside the solution, scaling sizes that aren't a layout of the group's
90
+ template, and new ids without the publisher prefix. Problems only in what is
91
+ already published are warnings. A check that takes over 30 s is reported as
92
+ incomplete and doesn't hold Publish back; publishing re-runs the check and
93
+ imports nothing on an error.
94
+ - **Importing RibbonDiffXml ([#30](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/30)).**
95
+ - Import is lossless (labels in every language, rules, hides) and merges into the workspace as
96
+ one undo step; the result publishes.
97
+ - **Modern commands ([#32](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/32)).**
98
+ - Modern commands (`appaction`) are shown read-only next to the classic buttons, with an App
99
+ filter; classic buttons (and flyout menu items) a migrated modern command hides or replaces
100
+ are flagged.
101
+ - **Orphaned customizations ([#64](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/64)).**
102
+ - Customizations in your layer that the ribbon never shows (for example on the Charts tab, or in
103
+ a group that no longer exists) are listed with the reason and can be deleted. Right after a
104
+ publish, what it just wrote can't be deleted from there.
105
+ - **Power Platform ToolBox for VS Code ([#89](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/89)).**
106
+ - The tool now works in the Power Platform ToolBox VS Code extension (1.1.0): it loads instead
107
+ of showing a blank tab, reads table ribbons, and publishes. Before, its code files were
108
+ requested from the wrong address there.
109
+ - Loading, importing and publishing send the same Dataverse requests in the desktop app and in
110
+ VS Code, so the extension's different helpers don't change what is imported or published.
111
+
112
+ ### 🔧 Changed
113
+
114
+ - **Canvas opens on the main tab ([#64](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/64)).**
115
+ - Loading a table or switching location opens the table's **main tab** instead of the
116
+ first tab listed (on the Home Grid that was the Charts tab).
117
+ - The Charts / `AllEntities` tabs show a warning (in every view):
118
+ Unified Interface never shows their buttons, and they don't come back on reload.
119
+ - **Orphaned customizations:** buttons, menu items, groups and tabs your unmanaged
120
+ customizations add that the ribbon doesn't return anywhere (added to the Charts tab, to a
121
+ group or menu that no longer exists, at a misspelled Location, …) are listed in the
122
+ Properties pane with where they are and why they aren't shown; a canvas banner points
123
+ there. **Delete** removes one on the next publish, together with the command, rules and
124
+ labels nothing else uses (undoable until then). Other publishes keep them untouched.
125
+ - The pre-publish check warns when a publish adds something at such a Location.
126
+ - **Unsupported command actions ([#28](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/28)).**
127
+ - The command editor no longer offers **Power Fx** or **Custom API** actions:
128
+ classic ribbon commands can't run them (they exist only in modern commanding).
129
+ A command that still has one (from an older saved session) shows an error with
130
+ **Remove**, and publishing it is blocked with a message saying what to do.
131
+ - **No form-specific ribbon scope ([#14](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/14)).**
132
+ - Removed the **Specific form only** option (and its form picker) from the properties
133
+ pane. Form-specific ribbons aren't supported on Unified Interface and CBS never wrote
134
+ them; form command bar changes apply to every main form of the table, as the pane
135
+ now says.
136
+ - **Undo and redo ([#34](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/34)).**
137
+ - Undo / redo cover commands, rules and labels too, and typing is one step.
138
+ - **Deleting safely ([#17](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/17), [#18](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/18), [#75](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/75)).**
139
+ - Delete only removes your own buttons, groups and tabs; for anything else it offers Hide.
140
+ Keyboard shortcuts stay out of text fields and dialogs.
141
+ - Rename group, change template and confirmations are proper dialogs (`window.prompt` /
142
+ `confirm` don't work in Power Platform ToolBox); accessible names use readable titles.
143
+ - **Icons and web resources ([#19](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/19), [#51](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/51)).**
144
+ - **Web resources are added to the active solution** — icons, uploads from the web
145
+ resource browser and scripts saved from the command editor are added to the active
146
+ unmanaged solution (`AddSolutionComponent`), so the ribbon's dependency travels with
147
+ the solution. Saving a web resource without an unmanaged solution selected shows a
148
+ warning (it only lands in the Default solution); the icon picker requires one.
149
+ - **Fluent icons are published** — picking a Fluent icon uploads it as an SVG web
150
+ resource named `<prefix>_/icons/cbs/<icon>.svg` (`<icon>.filled.svg` for the filled
151
+ variant), reusing an existing one with that name, and the button's `ModernImage`
152
+ points at it. The web resource is published (retrying while another solution
153
+ operation runs) whenever it hasn't been published in this session yet, so an icon
154
+ whose first publish failed is published on the next pick.
155
+ The filled/regular switch is now honoured, also when the icon's name equals the
156
+ button's original `ModernImage`. If the upload fails the button is left
157
+ unchanged and the picker shows the error (previously the button kept a preview-only
158
+ icon that was never published). The properties pane shows the `ModernImage` that
159
+ Publish will write.
160
+
161
+ ### 🔧 Fixed
162
+
163
+ - **Publish gaps ([#46](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/46), [#47](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/47), [#48](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/48), [#49](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/49), [#50](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/50), [#52](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/52), [#26](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/26)).**
164
+ - **Hidden by customizations** — controls hidden by a `HideCustomAction` in the
165
+ table's (or application ribbon's) unmanaged layer are listed in the properties
166
+ pane, with **Unhide**; the hide is removed on the next publish.
167
+ - **Deleting your own tabs and groups** removes them from the unmanaged layer,
168
+ together with the buttons placed in them, their labels, scaling, tab display
169
+ rules and commands nothing else uses. Deleting tabs / groups from other
170
+ solutions is reported instead of silently ignored.
171
+ - **Translation-only edits** of labels your layer defines, and display-rule edits
172
+ of your own tabs, are published. Edits CBS can't write are reported.
173
+ - **Base language** — edited labels are written in the organisation's base
174
+ language; other languages are kept. Labels show in the base language.
175
+ - **Moving / re-ordering your own buttons** moves their CustomAction in place.
176
+ - **Busy environments** — publish waits for running solution operations and
177
+ retries imports / publishes that fail with `0x80071151`; after publishing it
178
+ verifies the published ribbon layer and explains Unified Interface caching.
179
+ - **Reload right after publish** fills in button commands missing from
180
+ `RetrieveEntityRibbon` from the unmanaged layer.
181
+ - **Record open override and properties-pane fixes ([#22](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/22)).**
182
+ - **Override default record open behavior** (`Mscrm.OpenRecordItem`, home grid and sub-grid)
183
+ now publishes, can be turned off, and survives a reload. Following Microsoft's recipe, turning
184
+ it on adds the `Mscrm.OpenRecordItem` command and an **Open record** button that uses it to the
185
+ location's command bar; turning it off removes only that button (your own buttons using the
186
+ command stay), and the command once no button uses it. Publishing is blocked while the
187
+ command's JavaScript action has no web resource or function, and the pre-publish check warns
188
+ when that button is hidden or the command gets display rules.
189
+ - The **Translations** chips list only the button's own labels (`Btn1` no longer shows `Btn10`'s).
190
+ - **Switching solution** clears the table list, the loaded table's ribbon, its pending edits and
191
+ undo history, and the selection (the restore banner still offers the auto-saved edits when the
192
+ table is opened again). Picking the solution that is already active keeps everything.
193
+ - Removing or re-ordering **rule steps** no longer moves a step's inputs to its neighbour, and an
194
+ undo / redo of the steps no longer leaves them on the wrong step.
195
+ - The **Command Editor** closes when the command it shows is undone away.
196
+ - **Icons on copies and picked web resources ([#60](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/60), [#61](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/61)).**
197
+ - A button **duplicated** or **copied from Solution Elements** keeps its icon (the loaded
198
+ ModernImage and image16/image32); a copy from Solution Elements also keeps its command
199
+ and tooltips. Label tokens of the original are still not reused.
200
+ - Picking an **existing web resource** in the icon picker adds it to the active unmanaged
201
+ solution, so a solution export carries the icon (with a warning when no unmanaged
202
+ solution is selected; an error when the typed name doesn't exist).
203
+ - Dropping onto a button in the modern command bar no longer applies the drop twice
204
+ (a Solution Elements copy was created twice and a drag-move ran twice, the second time
205
+ into the tab's first group).
206
+ - **Rules and actions round trip ([#29](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/29), [#42](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/42)).**
207
+ - Rules and actions are kept exactly as loaded (unknown kinds verbatim); generated XML is
208
+ schema-valid.
209
+ - ToggleButton, Label, DropDown, MRUSplitButton, Spinner and GalleryButton show on the canvas
210
+ (read-only), can be hidden and unhidden, and are never dropped. Tab and group `Description`s
211
+ round trip, and tabs inside customizations no longer appear as phantom tabs.
212
+ - **Startup and closing ([#10](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/10), [#89](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/89)).**
213
+ - Power Platform ToolBox asks before closing the tool while an import or publish runs.
214
+ - A start-up failure (or a host that doesn't answer) shows what went wrong and what to try,
215
+ instead of a blank tab. So does an error later on that the tool can't recover from.
216
+ - **Tool icon ([#54](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/54)).**
217
+ - The icon is now bundled at `dist/icons/icon.svg` (PPTB resolves `icon` relative to
218
+ `dist/`); `package.json` `icon` is `icons/icon.svg` and the repo-root `icons/` folder
219
+ is no longer shipped. Pre-release versions get a gold-cornered **Insider** variant.
220
+ - The `viewBox` is cropped to the hexagon so the icon fills PPTB's 20 px slot.
221
+ - **README images in PPTB ([#9](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/9)).**
222
+ - The badges are now SVGs committed under `assets/badges/` and referenced by
223
+ `raw.githubusercontent.com` URL. PPTB's main window only allows images from GitHub,
224
+ so the `img.shields.io` badges never loaded there.
225
+
226
+ ### 🏗️ Technical
227
+
228
+ - **Release process from FetchXML Studio.** `main` holds the stable release, betas are
229
+ tagged on `release/X.Y`, fixes merge forward, and the previous minor gets critical fixes
230
+ for 30 days (`RELEASING.md`, `SECURITY.md`, `CONTRIBUTING.md`, the PR template).
231
+ - `release.yml` chooses the npm tag from the version and the tagged branch: `-beta.N` /
232
+ `-rc.N` → `beta`, a stable tag on `main` → `latest`, on `support/X.Y` → `support-X.Y`.
233
+ Anything else fails before publishing.
234
+ - CI also runs on `release/**` and `support/**`, and fails on high or critical
235
+ `npm audit --omit=dev` findings.
236
+ - Dependabot proposes grouped weekly npm and GitHub Actions updates into `dev`, with a
237
+ 14-day cooldown.
238
+ - A README version badge, generated with `npm run version-badge`. `engines` asks for
239
+ Node 22 or later, and `@pptb/types` is pinned to 1.2.7.
240
+ - **Dev harness ([#24](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/24)).**
241
+ - **`npm run dev:harness`** runs the real UI in a normal browser against a live
242
+ Dataverse org (`CBS_HARNESS_ORG=https://<org>.crm.dynamics.com`). It uses a stub of the
243
+ PPTB host APIs that mirrors PPTB 1.2.7's request shaping, and a localhost-only Vite
244
+ proxy that attaches an Azure CLI token server-side. Dev-only, so it is not part of the
245
+ build or the npm package. See `CONTRIBUTING.md`.
246
+ - **Build, packaging & repo hygiene ([#20](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/20)).**
247
+ - **Lint fixed** — ESLint now uses a flat `eslint.config.js` with the
248
+ `typescript-eslint` package (previously `eslint.config.ts` imported a missing
249
+ dependency). `npm run lint` lints the whole repo with `--max-warnings 0`.
250
+ - **No more compiled config files in git** — `tsconfig.node.json` emits only
251
+ declarations into `node_modules/.tmp`; the stale `vite.config.js`,
252
+ `vitest.config.js` and their `.d.ts` files are removed
253
+ (Vite was loading `vite.config.js` ahead of `vite.config.ts`).
254
+ - **Committed lockfile** — `package-lock.json` is now tracked. The package no longer
255
+ ships `npm-shrinkwrap.json`.
256
+ - **Tool icon shipped** — added the tool icon (referenced by the manifest but missing
257
+ from 0.5.x packages; now bundled under `dist/`, see #54) and `SECURITY.md`.
258
+ - **GitHub templates** — bug and feature issue forms and a pull request template;
259
+ `.github/` is no longer git-ignored.
260
+ - **Prettier** — added `.prettierrc` (matching the existing tab/double-quote
261
+ style) plus `format` / `format:check` scripts. The codebase has not been
262
+ mass-reformatted yet.
263
+ - **CI/CD ([#21](https://github.com/mohsinonxrm/pptb-mxrm-commandbar-studio/issues/21)).**
264
+ - **CI** (`.github/workflows/ci.yml`) runs on every PR and on pushes to `dev` and
265
+ `main`: typecheck, lint, tests, `pptb-validate`, build, and a package contents/size
266
+ check.
267
+ - **Release** (`.github/workflows/release.yml`) runs when a `v*` tag is pushed. It
268
+ publishes to npm through trusted publishing (OIDC + provenance, no token; `--tag beta`
269
+ for pre-releases) and creates the GitHub Release. See `RELEASING.md`.
270
+ - **Simpler tooling** — removed husky + commitlint (git hooks), release-it, the old Dependabot
271
+ config (replaced, see above), coverage, the bundle analyzer and unused testing-library packages (12 dev dependencies
272
+ in total).
273
+
274
+ ## [0.5.0] - 2026-07-16
275
+
276
+ ### 🎉 First Beta Release
277
+
278
+ Command Bar Studio 0.5.0-beta — a fully featured visual designer for Dataverse
279
+ classic ribbon / command bar customizations, running inside Power Platform ToolBox.
280
+
281
+ #### ✨ Features
282
+
283
+ - **Visual ribbon canvas** — Classic (tabbed groups + large icon tiles), Modern
284
+ (flat command bar), and List (data grid) views for all 4 ribbon locations
285
+ (HomepageGrid, SubGrid, Form, Application)
286
+ - **Classic ribbon drag-and-drop** — Migrated from HTML5 native drag to **@dnd-kit**
287
+ with a styled `DragOverlay` ghost tile (brand border, box-shadow, `grabbing` cursor).
288
+ `DroppableSlot` zones between buttons show a 2 px animated drop-line indicator.
289
+ `DroppableGroupContainer` highlights the target group. `PointerSensor` with 5 px
290
+ activation constraint so ordinary clicks still select buttons. Keyboard sensor
291
+ retained for accessibility.
292
+ - **Properties pane** — Label/tooltip/icon/kind/sequence/templateAlias editing;
293
+ locale chip row; command binding; display/enable rule pills; scaling summary;
294
+ advanced section (form scope, OpenRecordItem override, client-type filter)
295
+ - **Command editor** — JavaScript (library Browse… to Web Resource Browser), URL (PassParams,
296
+ WinMode, named params), **Power Fx** (inline Monaco editor — syntax-highlighted,
297
+ word wrap, no line numbers — with variable hints and async-rule note), Custom API;
298
+ References tab with button breadcrumbs; Versions tab
299
+ - **Rule editor** — All 30 `RuleStep` kinds from `RibbonTypes.xsd`; drag-to-reorder;
300
+ OrRule nesting with nested “Add step”; InvertResult + Default toggles;
301
+ plain-English `summarizeRule()` output
302
+ - **Localization editor** — Multi-LCID label / tooltip title / tooltip body;
303
+ 20 built-in LCIDs; line-break insertion (`&#x200b;&#x200b;`)
304
+ - **Icon picker** — Fluent icons (auto-uploaded as SVG web resource), web resource
305
+ browser, custom SVG upload
306
+ - **Scaling editor** — MaxSize / Scale step sequence management per MS docs
307
+ - **Tab display rules editor** — EntityRule (all 4 contexts) + PageRule
308
+ - **Web Resource Browser** — Virtualized; upload; edit JS/CSS/XML in Monaco;
309
+ callback registry so selection propagates back to caller (Image16/32, library field)
310
+ - **URL Action Composer** — PassParams table, CrmParameter querystring keys, live preview
311
+ - **XML Drawer** — Per-location RibbonDiffXml in Monaco; Format XML; CBS completions
312
+ - **Diff / Compare Viewer** — Monaco `DiffEditor` baseline comparison
313
+ - **Bulk Publish dialog** — Per-entity change counts; progress overlay; ribbonmetadatasettoprocess monitoring
314
+ - **Solution Conflict Drawer** — `msdyn_componentlayer` provenance; managed-solution
315
+ banner in properties pane auto-populated after ribbon load
316
+ - **Command Palette** (Ctrl+K) — buttons, commands, rules, entities, actions
317
+ - **Undo/Redo** — 80-entry history stack; `mutationsSincePublish` counter
318
+ - **localStorage persistence** — Auto-save + restore banner on startup
319
+
320
+ #### 🏗️ Architecture
321
+
322
+ - **Delta-only `RibbonDiffXml`** — only changed elements emitted; system `Mscrm.*`
323
+ commands/rules never re-emitted; OOB commands with JS actions (e.g.
324
+ `Mscrm.OpenRecordItem`) correctly emitted as overrides
325
+ - **Correct `behavior=2` (shell-only)** entity root component — does not drag in
326
+ every attribute / form / view on import
327
+ - **ImportJobId required** — supplied to every `deploySolution` call; 5-minute poll
328
+ with progress beats
329
+ - **Post-publish observability** — `ribbonmetadatasettoprocess` polling after
330
+ `publishCustomizations()` surfaces silent ribbon-compile failures
331
+ - **Parser: all 30 rule kinds** — `EntityPrivilegeRule`, `RecordPrivilegeRule`,
332
+ `ShowOnGridRule`, `DeviceTypeRule`, `RelationshipTypeRule`, and 14 more;
333
+ previously these were silently dropped, risking security-rule corruption on republish
334
+ - **TabDisplayRules DOM scope** — read from document-level `RuleDefinitions > TabDisplayRules`,
335
+ not from inside `<Tab>` elements (parser bug that caused tab rules to always appear empty)
336
+ - **Group selector fixed** — `:scope > Groups > Group` (dropped rogue `, Group` clause
337
+ that matched groups inside `CustomAction > CommandUIDefinition`, creating phantom groups)
338
+ - **`getWebResourceContent` uses `api.retrieve`** instead of `queryData` with key
339
+ predicate — correct single-record fetch that works reliably with PPTB's `dataverseAPI`
340
+ - **Web resource browser callback registry** — module-level one-shot callback
341
+ so Image16/32 and Command Editor library-field Browse selections propagate correctly
342
+ (previously selecting a resource in the browser did nothing — the `onSelect` prop
343
+ was never wired through the global Layout overlay)
344
+ - **`@dnd-kit` DragOverlay** — ClassicRibbon button drag fully migrated from HTML5
345
+ native drag to `@dnd-kit` (`useDraggable`, `useDroppable`, `DragOverlay`)
346
+ - **`@pptb/types` 1.2.3** — latest Power Platform ToolBox host API types
347
+
348
+ #### 🧪 Tests
349
+
350
+ - **148 / 148 passing** across 8 Vitest suites
351
+ - `all-rule-kinds.xml` fixture — covers every `RuleStep` kind in a round-trip
352
+ parse → generate → re-parse test; regression guard for the 18 formerly-missing
353
+ parser kinds, TabDisplayRules DOM scope, and group selector
354
+
355
+ ---
356
+
357
+ ## [0.1.0] - 2025-01-01
358
+
359
+ ### Initial scaffold
360
+
361
+ - Project initialization with Vite + React 18 + TypeScript 5 + Fluent UI v9
362
+ - Shell layout, ribbon canvas stubs, Zustand stores, XML generator/parser scaffolding
363
+