flexdesk 0.16.1 → 0.17.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 (262) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/LICENSE +0 -0
  3. package/README.md +2435 -42
  4. package/THIRD_PARTY_LICENSES.md +0 -0
  5. package/canvas.js +18 -0
  6. package/charts.js +21 -0
  7. package/core.js +14 -0
  8. package/css/base.css +1834 -75
  9. package/css/flexdesk.css +3165 -159
  10. package/css/overrides.css +16 -0
  11. package/css/reset.css +0 -0
  12. package/css/tokens.css +0 -0
  13. package/dist/canvas.js +6 -239
  14. package/dist/canvas.js.map +3 -3
  15. package/dist/charts.js +707 -18
  16. package/dist/charts.js.map +4 -4
  17. package/dist/chunk-3PHCPZHT.js +0 -0
  18. package/dist/chunk-3PHCPZHT.js.map +0 -0
  19. package/dist/chunk-4A7SJC3T.js +503 -0
  20. package/dist/chunk-4A7SJC3T.js.map +7 -0
  21. package/dist/{chunk-6JSOVNID.js → chunk-CVMCZZX2.js} +635 -10
  22. package/dist/chunk-CVMCZZX2.js.map +7 -0
  23. package/dist/chunk-D3COLZZ2.js +1311 -0
  24. package/dist/chunk-D3COLZZ2.js.map +7 -0
  25. package/dist/chunk-FOOS3T5L.js +0 -0
  26. package/dist/chunk-FOOS3T5L.js.map +0 -0
  27. package/dist/{chunk-SN4LSOAR.js → chunk-GOQLR5WR.js} +452 -2
  28. package/dist/chunk-GOQLR5WR.js.map +7 -0
  29. package/dist/{chunk-FL5KFNQH.js → chunk-HNU6MM2B.js} +52 -17
  30. package/dist/chunk-HNU6MM2B.js.map +7 -0
  31. package/dist/chunk-HYJYYEPK.js +375 -0
  32. package/dist/chunk-HYJYYEPK.js.map +7 -0
  33. package/dist/chunk-JKZLNKG6.js +2041 -0
  34. package/dist/chunk-JKZLNKG6.js.map +7 -0
  35. package/dist/chunk-JYWURG5T.js +0 -0
  36. package/dist/chunk-JYWURG5T.js.map +0 -0
  37. package/dist/{chunk-FBGP5KN5.js → chunk-LWV23YVE.js} +5073 -532
  38. package/dist/chunk-LWV23YVE.js.map +7 -0
  39. package/dist/chunk-N7HC3ADV.js +30 -0
  40. package/dist/chunk-N7HC3ADV.js.map +7 -0
  41. package/dist/{chunk-RQM5Z2MU.js → chunk-RMTRWWEO.js} +633 -311
  42. package/dist/chunk-RMTRWWEO.js.map +7 -0
  43. package/dist/{chunk-NLTOY57M.js → chunk-UURZ37SD.js} +28 -48
  44. package/dist/chunk-UURZ37SD.js.map +7 -0
  45. package/dist/{chunk-B5Q53LAJ.js → chunk-UWO43BZU.js} +2 -2
  46. package/dist/chunk-UWO43BZU.js.map +7 -0
  47. package/dist/chunk-WVFGV5FT.js +0 -0
  48. package/dist/chunk-WVFGV5FT.js.map +0 -0
  49. package/dist/core.js +170 -118
  50. package/dist/core.js.map +2 -2
  51. package/dist/editor.js +156 -70
  52. package/dist/editor.js.map +2 -2
  53. package/dist/flexdesk.css +3165 -159
  54. package/dist/flow.js +2789 -306
  55. package/dist/flow.js.map +4 -4
  56. package/dist/host.js +109 -3
  57. package/dist/host.js.map +3 -3
  58. package/dist/reset.css +0 -0
  59. package/dist/tile_registry-6WZPTUZV.js +0 -0
  60. package/dist/tile_registry-6WZPTUZV.js.map +0 -0
  61. package/dist/tiles.js +657 -234
  62. package/dist/tiles.js.map +4 -4
  63. package/dist/tokens.css +0 -0
  64. package/dist/widgets.js +3290 -2124
  65. package/dist/widgets.js.map +4 -4
  66. package/dist/wm.js +1227 -347
  67. package/dist/wm.js.map +4 -4
  68. package/editor.js +20 -0
  69. package/flow.js +21 -0
  70. package/host.js +14 -0
  71. package/package.json +12 -1
  72. package/src/canvas/canvas_adapter.js +5 -0
  73. package/src/canvas/edge_router.js +0 -0
  74. package/src/canvas/graph/connector_router.js +0 -0
  75. package/src/canvas/graph/history_service.js +0 -0
  76. package/src/canvas/graph/node_platform.js +0 -0
  77. package/src/canvas/index.js +1 -0
  78. package/src/canvas/layered_layout.js +244 -0
  79. package/src/charts/chart_types.js +0 -0
  80. package/src/charts/data_series_plot_window.js +0 -0
  81. package/src/charts/downsample.js +2 -2
  82. package/src/charts/plot_config.js +53 -29
  83. package/src/charts/plot_config_editor.js +627 -0
  84. package/src/charts/plot_grid.js +449 -0
  85. package/src/charts/plot_popout_window.js +103 -317
  86. package/src/charts/plotly_wrapper.js +22 -2
  87. package/src/charts/series_transforms.js +206 -0
  88. package/src/core/event_bus.js +0 -0
  89. package/src/core/logging.js +1 -1
  90. package/src/core/settings.js +105 -19
  91. package/src/core/state_guard.js +93 -51
  92. package/src/core/state_guard_config.js +85 -74
  93. package/src/core/state_machine.js +0 -0
  94. package/src/editor/editor_pane.js +3 -3
  95. package/src/editor/monaco_editor_factory.js +124 -60
  96. package/src/editor/monaco_loader.js +103 -28
  97. package/src/editor/notebook_search.js +0 -0
  98. package/src/editor/notebook_tab_bar.js +38 -52
  99. package/src/editor/notebook_undo_manager.js +0 -0
  100. package/src/editor/split_pane_container.js +6 -3
  101. package/src/flow/canvas_editor/connections.js +90 -0
  102. package/src/flow/canvas_editor/editor.js +2351 -153
  103. package/src/flow/canvas_editor/index.js +2 -1
  104. package/src/flow/canvas_editor/layout.js +119 -12
  105. package/src/flow/canvas_editor/strings.js +80 -0
  106. package/src/flow/kit/always_before.js +0 -0
  107. package/src/flow/kit/catalogue.js +97 -3
  108. package/src/flow/kit/chip_input.js +0 -0
  109. package/src/flow/kit/dom.js +0 -0
  110. package/src/flow/kit/findings.js +0 -0
  111. package/src/flow/kit/history.js +0 -0
  112. package/src/flow/kit/index.js +3 -3
  113. package/src/flow/kit/keys.js +7 -1
  114. package/src/flow/kit/logic_graph.js +97 -15
  115. package/src/flow/kit/references.js +0 -0
  116. package/src/flow/kit/settings_panel.js +0 -0
  117. package/src/flow/kit/settings_schema.js +2 -1
  118. package/src/flow/kit/step_picker.js +0 -0
  119. package/src/flow/kit/strings.js +3 -1
  120. package/src/flow/kit/value_picker.js +0 -0
  121. package/src/flow/kit/widgets.js +86 -109
  122. package/src/flow/lanes/editor.js +136 -14
  123. package/src/flow/lanes/index.js +3 -1
  124. package/src/flow/lanes/layout.js +0 -0
  125. package/src/flow/lanes/pipeline.js +44 -2
  126. package/src/flow/lanes/preview.js +0 -0
  127. package/src/flow/lanes/strings.js +1 -0
  128. package/src/flow/outline/editor.js +0 -0
  129. package/src/flow/outline/index.js +0 -0
  130. package/src/flow/outline/mapping.js +0 -0
  131. package/src/flow/outline/menu.js +0 -0
  132. package/src/flow/outline/operations.js +0 -0
  133. package/src/flow/outline/recognise.js +0 -0
  134. package/src/flow/outline/strings.js +0 -0
  135. package/src/help/help_modal.js +168 -42
  136. package/src/help/help_registry.js +12 -1
  137. package/src/host/external_links.js +0 -0
  138. package/src/host/file_picker.js +117 -0
  139. package/src/host/host.js +10 -2
  140. package/src/host/photino_host.js +9 -0
  141. package/src/host/photino_host.md +21 -3
  142. package/src/host/pywebview_host.js +10 -0
  143. package/src/tiles/chart_tiles.js +53 -245
  144. package/src/tiles/config_schema.js +8 -0
  145. package/src/tiles/figure_tile.js +322 -0
  146. package/src/tiles/layout_persistence.js +3 -3
  147. package/src/tiles/list_tiles.js +7 -7
  148. package/src/tiles/scope_picker.js +0 -0
  149. package/src/tiles/tile_base.js +1 -1
  150. package/src/tiles/tile_config_form.js +442 -0
  151. package/src/tiles/tile_grid.js +2 -0
  152. package/src/tiles/tile_registry.js +0 -0
  153. package/src/tiling/bottom_panel_tabs.js +67 -99
  154. package/src/tiling/command_palette.js +64 -19
  155. package/src/tiling/content_registry.js +4 -1
  156. package/src/tiling/desktops.js +11 -1
  157. package/src/tiling/entity_sources.js +0 -0
  158. package/src/tiling/keymap.js +403 -128
  159. package/src/tiling/kind_taxonomy.js +78 -0
  160. package/src/tiling/landing_table.js +0 -0
  161. package/src/tiling/loading_overlay.js +0 -0
  162. package/src/tiling/nav_panel.js +59 -10
  163. package/src/tiling/page_factory.js +5 -5
  164. package/src/tiling/panel_availability.js +49 -0
  165. package/src/tiling/panel_keys.js +0 -0
  166. package/src/tiling/shell.js +114 -12
  167. package/src/tiling/tab_strip.js +0 -0
  168. package/src/tiling/tile_breadcrumb.js +0 -0
  169. package/src/tiling/tile_renderer.js +105 -9
  170. package/src/tiling/tile_tab_menu.js +0 -0
  171. package/src/tiling/tile_tree.js +0 -0
  172. package/src/tiling/wm.js +562 -30
  173. package/src/tiling/zoom.js +0 -0
  174. package/src/ui/base/component_base.js +0 -0
  175. package/src/ui/base/controller_base.js +0 -0
  176. package/src/ui/base/page_base.js +0 -0
  177. package/src/ui/components/about_dialog.js +0 -0
  178. package/src/ui/components/action_dropdown.js +30 -2
  179. package/src/ui/components/alert_log.js +0 -0
  180. package/src/ui/components/alerts_pane.js +0 -0
  181. package/src/ui/components/attribute_list_editor.js +0 -0
  182. package/src/ui/components/autocomplete_field.js +0 -0
  183. package/src/ui/components/cell_editor_host.js +293 -0
  184. package/src/ui/components/cell_editors.js +480 -0
  185. package/src/ui/components/cell_grid.js +761 -0
  186. package/src/ui/components/cell_paste.js +243 -0
  187. package/src/ui/components/cell_selection.js +220 -0
  188. package/src/ui/components/choice_controls.js +351 -0
  189. package/src/ui/components/color_field.js +211 -0
  190. package/src/ui/components/color_list_field.js +210 -0
  191. package/src/ui/components/column_fit.js +0 -0
  192. package/src/ui/components/column_groups.js +314 -0
  193. package/src/ui/components/column_order.js +142 -0
  194. package/src/ui/components/computing_status_window.js +98 -25
  195. package/src/ui/components/confirm_dialog.js +81 -38
  196. package/src/ui/components/context_menu.js +2 -2
  197. package/src/ui/components/conversation_view.js +440 -0
  198. package/src/ui/components/crosstab.js +289 -0
  199. package/src/ui/components/data_table.js +696 -71
  200. package/src/ui/components/detail_header.js +22 -11
  201. package/src/ui/components/document_outline.js +397 -0
  202. package/src/ui/components/drag_reorder.js +0 -0
  203. package/src/ui/components/fact_table.js +0 -0
  204. package/src/ui/components/fill_handle.js +322 -0
  205. package/src/ui/components/gallery_picker.js +19 -8
  206. package/src/ui/components/header_actions.js +55 -0
  207. package/src/ui/components/inline_renamer.js +0 -0
  208. package/src/ui/components/job_progress.js +51 -0
  209. package/src/ui/components/managed_window.js +27 -4
  210. package/src/ui/components/menu_bar.js +745 -0
  211. package/src/ui/components/modal.js +449 -75
  212. package/src/ui/components/notification_history.js +3 -3
  213. package/src/ui/components/progress.js +483 -0
  214. package/src/ui/components/record_list.js +0 -0
  215. package/src/ui/components/row_activation.js +0 -0
  216. package/src/ui/components/section_stack.js +298 -0
  217. package/src/ui/components/series.js +173 -0
  218. package/src/ui/components/settings_view.js +634 -0
  219. package/src/ui/components/slide_out_panel.js +43 -6
  220. package/src/ui/components/slider_field.js +275 -18
  221. package/src/ui/components/sortable_list.js +0 -0
  222. package/src/ui/components/staged_edits.js +361 -0
  223. package/src/ui/components/staged_history.js +172 -0
  224. package/src/ui/components/table_filter_chips.js +0 -0
  225. package/src/ui/components/table_state_store.js +0 -0
  226. package/src/ui/components/table_structure.js +182 -0
  227. package/src/ui/components/table_values.js +0 -0
  228. package/src/ui/components/tabs.js +497 -0
  229. package/src/ui/components/tag_input.js +215 -0
  230. package/src/ui/components/toast.js +25 -8
  231. package/src/ui/components/toggle_field.js +175 -0
  232. package/src/ui/components/tree_view.js +55 -34
  233. package/src/ui/components/tsv.js +74 -0
  234. package/src/ui/components/window_taskbar.js +0 -0
  235. package/src/ui/components/wizard.js +563 -0
  236. package/src/ui/controllers/window_chrome_controller.js +2 -2
  237. package/src/ui/notification_center.js +375 -119
  238. package/src/ui/utils/auto_scrollbars.js +0 -0
  239. package/src/ui/utils/markdown.js +709 -0
  240. package/src/ui/utils/native_context_menu.js +0 -0
  241. package/src/ui/utils/overlay_scrollbar.js +16 -12
  242. package/src/ui/utils/raf_resize_observer.js +0 -0
  243. package/src/ui/utils/scroll_lock.js +0 -0
  244. package/src/ui/utils/strip_scroll.js +55 -0
  245. package/src/ui/utils/tooltip_service.js +0 -8
  246. package/tiles.js +27 -0
  247. package/widgets.js +69 -0
  248. package/wm.js +28 -0
  249. package/dist/chunk-6JSOVNID.js.map +0 -7
  250. package/dist/chunk-B5Q53LAJ.js.map +0 -7
  251. package/dist/chunk-FBGP5KN5.js.map +0 -7
  252. package/dist/chunk-FL5KFNQH.js.map +0 -7
  253. package/dist/chunk-NLTOY57M.js.map +0 -7
  254. package/dist/chunk-NNFTETK3.js +0 -633
  255. package/dist/chunk-NNFTETK3.js.map +0 -7
  256. package/dist/chunk-O5OHMWBB.js +0 -284
  257. package/dist/chunk-O5OHMWBB.js.map +0 -7
  258. package/dist/chunk-RQM5Z2MU.js.map +0 -7
  259. package/dist/chunk-SN4LSOAR.js.map +0 -7
  260. package/dist/chunk-W6FBJLPW.js +0 -367
  261. package/dist/chunk-W6FBJLPW.js.map +0 -7
  262. package/src/ui/controllers/panel_state_machine.js +0 -634
@@ -65,7 +65,10 @@
65
65
  * groupLabel the group's header, when the group is not a taxonomy kind
66
66
  * kindLabel the word drawn on the right, when the taxonomy's is wrong
67
67
  * boost added to the match score (an embedder's "recently opened")
68
- * modes which of 'split' / 'window' the row offers (key hints)
68
+ * modes which of 'split' / 'window' the row offers (key hints). For
69
+ * a row whose kind is single (KindDef `single`) both are copy
70
+ * verbs: the hints are drawn greyed with the taxonomy's reason,
71
+ * and Ctrl/Shift+Enter on the row does nothing.
69
72
  * drillLabel the Tab hint ("search rows"); Tab is offered only with it
70
73
  * shortcut a key binding drawn on the right
71
74
  * verb the Enter hint ('open' by default, 'run' for a command)
@@ -79,16 +82,33 @@
79
82
  */
80
83
 
81
84
  import { HelpModal } from '../help/help_modal.js';
85
+ import { KEYBOARD_SHORTCUTS_TOPIC_ID, KEYMAP_SHORTCUTS, keyboardShortcutsTopic } from './keymap.js';
82
86
 
83
87
  const ROOT_ID = 'twm-cmdpal';
84
88
 
85
- // Non-entity commands surfaced in the palette's search results. They
86
- // carry an `action` so `commit()` runs them instead of opening a tile.
87
- const STATIC_COMMANDS = [
88
- { kind: 'command', id: 'shortcuts', label: 'Keyboard shortcuts',
89
- hint: 'Show all key bindings (?)', icon: 'keyboard', shortcut: '?', verb: 'run',
90
- action: () => HelpModal.open('keyboard-shortcuts') },
91
- ];
89
+ /** The words a shortcuts table uses for the help action — the default `?` row's. */
90
+ const HELP_ACTION = KEYMAP_SHORTCUTS.find((r) => r.keys === '?').action;
91
+
92
+ /**
93
+ * Non-entity commands surfaced in the palette's search results. They carry an
94
+ * `action` so `commit()` runs them instead of opening a tile. `shortcuts` is
95
+ * the table the *Keyboard shortcuts* command shows — the shell passes the one
96
+ * its keymap's bindings produced (`keymapShortcuts`). The command's hint names
97
+ * the keys that open help in that table: `?` by default, `F9` when an embedder
98
+ * moved help there, none when no key opens it.
99
+ */
100
+ function _staticCommands(shortcuts) {
101
+ const helpKeys = shortcuts.filter((r) => r.action === HELP_ACTION).map((r) => r.keys).join(' / ');
102
+ return [
103
+ { kind: 'command', id: 'shortcuts', label: 'Keyboard shortcuts',
104
+ hint: helpKeys ? `Show all key bindings (${helpKeys})` : 'Show all key bindings',
105
+ icon: 'keyboard', ...(helpKeys ? { shortcut: helpKeys } : {}), verb: 'run',
106
+ // The application's help may define the topic; when it does not, the
107
+ // window manager's own bindings are shown rather than an error.
108
+ action: () => HelpModal.open(KEYBOARD_SHORTCUTS_TOPIC_ID,
109
+ { fallback: keyboardShortcutsTopic(shortcuts) }) },
110
+ ];
111
+ }
92
112
 
93
113
  const DEFAULT_GROUP_CAP = 4;
94
114
  const DEFAULT_COMMAND_MIN_CHARS = 2;
@@ -104,7 +124,9 @@ const MAX_ROWS = 200;
104
124
  * gesture. See `commit` for what it is for; omitted, the
105
125
  * palette behaves as it always has.
106
126
  * @param chrome, layout, groupCap, empty, emptyLabel, commands,
107
- * commandMinChars, drill, cache, tips, footerNote — C39, above. */
127
+ * commandMinChars, drill, cache, tips, footerNote — C39, above.
128
+ * @param shortcuts the rows the built-in *Keyboard shortcuts* command lists
129
+ * (`{keys, action}`); `KEYMAP_SHORTCUTS` when omitted. */
108
130
  export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder = 'Search…',
109
131
  onPick = null,
110
132
  chrome = {}, layout = 'flat',
@@ -113,7 +135,8 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
113
135
  commands = null,
114
136
  commandMinChars = DEFAULT_COMMAND_MIN_CHARS,
115
137
  drill = null, cache = false,
116
- tips = null, footerNote = '' }) {
138
+ tips = null, footerNote = '',
139
+ shortcuts = KEYMAP_SHORTCUTS }) {
117
140
  if (!taxonomy) throw new Error('createCommandPalette: a taxonomy is required');
118
141
  if (!catalog) throw new Error('createCommandPalette: an entity catalog is required');
119
142
  const grouped = layout === 'grouped';
@@ -122,6 +145,9 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
122
145
  let cached = null; // C39 `cache`: the last loaded catalogue
123
146
  let onClose = null;
124
147
 
148
+ /** A row whose kind exists once (KindDef `single`): no split, no window. */
149
+ const isSingle = (row) => !!row && taxonomy.isSingle(row.kind);
150
+
125
151
  const isOpen = () => !!overlay;
126
152
  const close = () => {
127
153
  if (!overlay) return;
@@ -132,6 +158,7 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
132
158
  };
133
159
  const toggle = () => { isOpen() ? close() : open(); };
134
160
  const invalidate = () => { cached = null; };
161
+ const staticCommands = _staticCommands(shortcuts);
135
162
 
136
163
  const open = async () => {
137
164
  if (overlay) return;
@@ -152,11 +179,22 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
152
179
  const chips = overlay.querySelectorAll('[data-shortcut]');
153
180
  const toggles = overlay.querySelectorAll('[data-toggle]');
154
181
 
155
- // Reflect current panel state in toggle buttons.
156
- for (const btn of toggles) {
182
+ // Reflect current panel state in toggle buttons. A panel the primary
183
+ // content withholds is a chip that says why and does nothing.
184
+ const syncToggle = (btn) => {
157
185
  const which = btn.dataset.toggle;
186
+ const { available, reason } = wm.getPanelAvailability(which);
158
187
  btn.classList.toggle('twm-chip--on', wm.isPanelOpen(which));
159
- }
188
+ if (available) {
189
+ btn.removeAttribute('aria-disabled');
190
+ btn.removeAttribute('title');
191
+ } else {
192
+ btn.setAttribute('aria-disabled', 'true');
193
+ if (reason) btn.setAttribute('title', reason);
194
+ else btn.removeAttribute('title');
195
+ }
196
+ };
197
+ toggles.forEach(syncToggle);
160
198
 
161
199
  chips.forEach((btn) => btn.addEventListener('click', () => {
162
200
  const kind = btn.dataset.shortcut;
@@ -164,9 +202,8 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
164
202
  close();
165
203
  }));
166
204
  toggles.forEach((btn) => btn.addEventListener('click', () => {
167
- const which = btn.dataset.toggle;
168
- wm.togglePanel(which);
169
- btn.classList.toggle('twm-chip--on', wm.isPanelOpen(which));
205
+ wm.togglePanel(btn.dataset.toggle);
206
+ syncToggle(btn);
170
207
  }));
171
208
 
172
209
  // Scoped-search state. Typing `<prefix>:` converts the prefix
@@ -296,8 +333,13 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
296
333
  const modes = Array.isArray(r.modes) ? r.modes : [];
297
334
  const acts = [`<span><kbd>Enter</kbd> ${_esc(verb)}</span>`];
298
335
  if (r.drillLabel && drill) acts.push(`<span><kbd>Tab</kbd> ${_esc(r.drillLabel)}</span>`);
299
- if (modes.includes('split')) acts.push('<span><kbd>Ctrl Enter</kbd> split</span>');
300
- if (modes.includes('window')) acts.push('<span><kbd>Shift Enter</kbd> window</span>');
336
+ // A single kind has no copies: its split and window hints are
337
+ // drawn refused, with the reason, rather than offered.
338
+ const refused = isSingle(r)
339
+ ? ` class="twm-cmdpal__act--disabled" aria-disabled="true" title="${_esc(taxonomy.singleReason(r.kind))}"`
340
+ : '';
341
+ if (modes.includes('split')) acts.push(`<span${refused}><kbd>Ctrl Enter</kbd> split</span>`);
342
+ if (modes.includes('window')) acts.push(`<span${refused}><kbd>Shift Enter</kbd> window</span>`);
301
343
  const side = r.shortcut
302
344
  ? `<kbd class="twm-cmdpal__shortcut">${_esc(r.shortcut)}</kbd>`
303
345
  : `<span class="twm-cmdpal__kind">${_esc(kindLabel(r))}</span>`;
@@ -411,6 +453,9 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
411
453
  const picked = filtered[i];
412
454
  if (!picked) return;
413
455
  if (picked.more) { showAll(picked.more); return; }
456
+ // Split and window open a COPY; a single kind refuses both, and the
457
+ // palette stays open on the row whose hints say why.
458
+ if (mode !== 'open' && isSingle(picked)) return;
414
459
  const pick = _public(picked);
415
460
  const how = { mode, scope: scope?.id ?? null };
416
461
  close();
@@ -668,7 +713,7 @@ export function createCommandPalette({ wm, api, taxonomy, catalog, placeholder =
668
713
  try { extra = (commands() || []).map((c) => ({ kind: 'command', ...c })); }
669
714
  catch (err) { console.warn('[cmdpal] commands() threw', err); }
670
715
  }
671
- return [...STATIC_COMMANDS, ...extra];
716
+ return [...staticCommands, ...extra];
672
717
  };
673
718
  // Objects before commands in the grouped layout, so that a tie that
674
719
  // survives every rule goes to the object (first seen wins).
@@ -12,7 +12,10 @@
12
12
  * `ctx` is the shell's ctx plus, per leaf, `leafId` and `setTitle(text)` —
13
13
  * rename the pane's chrome title from inside the content, at mount or any
14
14
  * time after; it survives repaints, and `setTitle(null)` gives the title back
15
- * to the tree (tile_renderer.js, C41).
15
+ * to the tree (tile_renderer.js, C41) — and `setChromeActions(specs)`, which
16
+ * replaces the pane's content buttons the same way: at mount (winning over a
17
+ * returned `chromeActions`) or any time after, surviving repaints, `null` or
18
+ * `[]` clearing them (tile_renderer.js, C42).
16
19
  *
17
20
  * ── ONE REGISTRY PER SHELL ────────────────────────────────────────────
18
21
  * This module used to hold a module-level `Map` plus a `register(kind, fn)`
@@ -4,7 +4,8 @@
4
4
  * Where that key actually lands is the embedder's business (see the host's
5
5
  * `resolvePath`); this module only names it.
6
6
  *
7
- * Each desktop = { id, label, tree (TileTree), windows ([]), panels }.
7
+ * Each desktop = { id, label, tree (TileTree), windows ([]), panels,
8
+ * panelShares }.
8
9
  * Switching desktops swaps the active tree under the renderer.
9
10
  */
10
11
 
@@ -47,6 +48,11 @@ function _makeDesktop(label, seed, panelDefaults = DEFAULT_PANEL_STATE) {
47
48
  // when it asked for nothing. Names are assigned by wm._canonicalize via
48
49
  // PANEL_TITLES.
49
50
  panels: { ...panelDefaults },
51
+ // Each panel's last share of the WM area along its axis, recorded by
52
+ // the WM when a splitter drag ends (and, for a panel not yet
53
+ // measured, when it rebuilds the panels). A side with none opens at
54
+ // the default ratio.
55
+ panelShares: {},
50
56
  // C40. Both unset is a desktop exactly as it always was.
51
57
  group: null,
52
58
  fixed: false,
@@ -159,6 +165,9 @@ export class DesktopManager {
159
165
  id: d.id, label: d.label,
160
166
  tree: d.tree.serialize(),
161
167
  panels: { ...d.panels },
168
+ // Written only when a panel has been measured, like the C40
169
+ // keys below.
170
+ ...(Object.keys(d.panelShares).length ? { panelShares: { ...d.panelShares } } : {}),
162
171
  // C40. Written only when set, so a blob without them is
163
172
  // byte-for-byte the blob it always was.
164
173
  ...(d.group ? { group: d.group } : {}),
@@ -182,6 +191,7 @@ export class DesktopManager {
182
191
  // this merge order avoids. The default only fills a key the stored
183
192
  // blob predates.
184
193
  panels: { ...m.panelDefaults, ...(raw.panels || {}) },
194
+ panelShares: { ...(raw.panelShares || {}) },
185
195
  group: raw.group || null,
186
196
  fixed: !!raw.fixed,
187
197
  }));
File without changes