@mohsinonxrm/pptb-commandbar-studio 0.5.2 → 0.6.1

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