@grifhinz/logics-manager 2.2.0 → 2.3.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 (43) hide show
  1. package/README.md +95 -1
  2. package/VERSION +1 -1
  3. package/clients/README.md +9 -0
  4. package/clients/shared-web/media/css/board.css +658 -0
  5. package/clients/shared-web/media/css/details.css +457 -0
  6. package/clients/shared-web/media/css/layout.css +123 -0
  7. package/clients/shared-web/media/css/toolbar.css +576 -0
  8. package/clients/shared-web/media/harnessApi.js +324 -0
  9. package/clients/shared-web/media/hostApi.js +213 -0
  10. package/clients/shared-web/media/hostApiContract.js +55 -0
  11. package/clients/shared-web/media/icon.png +0 -0
  12. package/clients/shared-web/media/layoutController.js +246 -0
  13. package/clients/shared-web/media/logics.svg +7 -0
  14. package/clients/shared-web/media/logicsModel.js +910 -0
  15. package/clients/shared-web/media/main.css +112 -0
  16. package/clients/shared-web/media/main.js +3 -0
  17. package/clients/shared-web/media/mainApp.js +1005 -0
  18. package/clients/shared-web/media/mainCore.js +604 -0
  19. package/clients/shared-web/media/mainInteractionHandlers.js +324 -0
  20. package/clients/shared-web/media/mainInteractions.js +378 -0
  21. package/clients/shared-web/media/renderBoard.js +3 -0
  22. package/clients/shared-web/media/renderBoardApp.js +1339 -0
  23. package/clients/shared-web/media/renderDetails.js +685 -0
  24. package/clients/shared-web/media/renderMarkdown.js +449 -0
  25. package/clients/shared-web/media/toolsPanelLayout.js +172 -0
  26. package/clients/shared-web/media/uiStatus.js +54 -0
  27. package/clients/shared-web/media/webviewChrome.js +405 -0
  28. package/clients/shared-web/media/webviewPersistence.js +116 -0
  29. package/clients/shared-web/media/webviewSelectors.js +491 -0
  30. package/clients/viewer/README.md +5 -0
  31. package/clients/viewer/browser-host.js +847 -0
  32. package/clients/viewer/index.html +237 -0
  33. package/clients/viewer/viewer.css +433 -0
  34. package/logics_manager/assist.py +9 -142
  35. package/logics_manager/assist_handoff.py +132 -0
  36. package/logics_manager/assist_surface.py +38 -0
  37. package/logics_manager/cli.py +78 -5
  38. package/logics_manager/flow.py +126 -24
  39. package/logics_manager/flow_evidence.py +63 -0
  40. package/logics_manager/update_check.py +138 -0
  41. package/logics_manager/viewer.py +533 -0
  42. package/package.json +12 -6
  43. package/pyproject.toml +1 -1
@@ -0,0 +1,604 @@
1
+ (() => {
2
+ function normalizeWorkspacePath(value) {
3
+ if (!value) {
4
+ return "";
5
+ }
6
+ const normalized = value.replace(/\\/g, "/").replace(/\/+$/, "");
7
+ return normalized.toLowerCase();
8
+ }
9
+
10
+ function areSameWorkspacePath(left, right) {
11
+ return normalizeWorkspacePath(left) === normalizeWorkspacePath(right);
12
+ }
13
+
14
+ window.createCdxLogicsMainCore = function createCdxLogicsMainCore(options) {
15
+ const {
16
+ state,
17
+ board,
18
+ mainPane,
19
+ layout,
20
+ splitter,
21
+ details,
22
+ detailsBody,
23
+ detailsToggle,
24
+ detailsTitle,
25
+ filterPanel,
26
+ toolsPanel,
27
+ filterToggle,
28
+ toolsToggle,
29
+ viewModeToggleButton,
30
+ projectGithubUrl,
31
+ stackedQuery,
32
+ compactListQuery,
33
+ hostApi,
34
+ layoutController,
35
+ boardRenderer,
36
+ detailsRenderer,
37
+ chrome,
38
+ applyToolsPanelOpen,
39
+ renderActivityPanel,
40
+ renderHelpBanner,
41
+ updateButtons,
42
+ updateViewModeToggle,
43
+ updateFilterState,
44
+ syncChromeInputs,
45
+ captureScrollState,
46
+ restoreScrollState,
47
+ schedulePersistState,
48
+ resetPersistedUiState,
49
+ persistState,
50
+ isListMode,
51
+ isVisible,
52
+ getVisibleStages,
53
+ groupByStage,
54
+ getListGroups,
55
+ getAttentionReasons,
56
+ getStageLabel,
57
+ isPrimaryFlowStage,
58
+ isRequestProcessed,
59
+ getSelectedItem,
60
+ buildContextPack,
61
+ buildDependencyMap,
62
+ findManagedItemByReference,
63
+ formatDate,
64
+ collectCompanionDocs,
65
+ collectSpecs,
66
+ collectPrimaryFlowItems,
67
+ getCanResetProjectRoot,
68
+ setCanResetProjectRoot,
69
+ getCanBootstrapLogics,
70
+ setCanBootstrapLogics,
71
+ setBootstrapLogicsTitle,
72
+ getCanLaunchCodex,
73
+ setCanLaunchCodex,
74
+ setLaunchCodexTitle,
75
+ getCanLaunchClaude,
76
+ setCanLaunchClaude,
77
+ setLaunchClaudeTitle,
78
+ getCanRepairLogicsKit,
79
+ setCanRepairLogicsKit,
80
+ setRepairLogicsKitTitle,
81
+ getCanPublishRelease,
82
+ setCanPublishRelease,
83
+ setPublishReleaseTitle,
84
+ getShouldRecommendCheckEnvironment,
85
+ setShouldRecommendCheckEnvironment
86
+ } = options;
87
+
88
+ const defaultCollapsedDetailSections = new Set([
89
+ "attentionExplain",
90
+ "contextPack",
91
+ "dependencyMap",
92
+ "companionDocs",
93
+ "indicators",
94
+ "specs",
95
+ "primaryFlow",
96
+ "references",
97
+ "usedBy"
98
+ ]);
99
+
100
+ function getSnapshot(scrollValues = { boardLeft: 0, boardTop: 0, detailsTop: 0 }) {
101
+ return {
102
+ workspaceRoot: state.activeWorkspaceRoot,
103
+ selectedId: state.selectedId,
104
+ hideCompleted: state.hideCompleted,
105
+ hideProcessedRequests: state.hideProcessedRequests,
106
+ hideSpec: state.hideSpec,
107
+ showCompanionDocs: state.showCompanionDocs,
108
+ hideEmptyColumns: state.hideEmptyColumns,
109
+ searchQuery: state.searchQuery,
110
+ groupMode: state.groupMode,
111
+ sortMode: state.sortMode,
112
+ secondaryToolbarOpen: state.secondaryToolbarOpen,
113
+ activityPanelOpen: state.activityPanelOpen,
114
+ attentionOnly: state.attentionOnly,
115
+ helpDismissed: state.helpDismissed,
116
+ collapsedListStages: Array.from(state.collapsedListStages),
117
+ detailsCollapsed: state.uiState.detailsCollapsed,
118
+ collapsedDetailSections: Array.from(state.collapsedDetailSections),
119
+ viewMode: state.uiState.viewMode,
120
+ splitRatio: state.uiState.splitRatio,
121
+ boardScrollLeft: scrollValues.boardLeft,
122
+ boardScrollTop: scrollValues.boardTop,
123
+ detailsScrollTop: scrollValues.detailsTop
124
+ };
125
+ }
126
+
127
+ function applyResetState({ defaultFilterState, uiDefaults }) {
128
+ state.hideCompleted = defaultFilterState.hideCompleted;
129
+ state.hideProcessedRequests = defaultFilterState.hideProcessedRequests;
130
+ state.hideSpec = defaultFilterState.hideSpec;
131
+ state.showCompanionDocs = defaultFilterState.showCompanionDocs;
132
+ state.hideEmptyColumns = defaultFilterState.hideEmptyColumns;
133
+ state.searchQuery = "";
134
+ state.groupMode = "stage";
135
+ state.sortMode = "updated-desc";
136
+ state.activityPanelOpen = false;
137
+ state.attentionOnly = false;
138
+ state.helpDismissed = false;
139
+ state.collapsedListStages = new Set();
140
+ state.collapsedDetailSections = new Set(defaultCollapsedDetailSections);
141
+ state.selectedId = null;
142
+ state.secondaryToolbarOpen = false;
143
+ state.toolsPanelOpen = false;
144
+ state.uiState.detailsCollapsed = uiDefaults.detailsCollapsed;
145
+ state.uiState.viewMode = uiDefaults.viewMode;
146
+ state.uiState.splitRatio = uiDefaults.splitRatio;
147
+ state.activeColumnMenu = null;
148
+ state.activeColumnMenuButton = null;
149
+ }
150
+
151
+ function applyPersistedState(nextState, nextScrollState) {
152
+ if (nextState && typeof nextState.hideCompleted === "boolean") {
153
+ state.hideCompleted = nextState.hideCompleted;
154
+ }
155
+ if (nextState && typeof nextState.hideProcessedRequests === "boolean") {
156
+ state.hideProcessedRequests = nextState.hideProcessedRequests;
157
+ } else if (nextState && typeof nextState.hideUsedRequests === "boolean") {
158
+ state.hideProcessedRequests = nextState.hideUsedRequests;
159
+ }
160
+ if (nextState && typeof nextState.hideSpec === "boolean") {
161
+ state.hideSpec = nextState.hideSpec;
162
+ }
163
+ if (nextState && typeof nextState.showCompanionDocs === "boolean") {
164
+ state.showCompanionDocs = nextState.showCompanionDocs;
165
+ }
166
+ if (nextState && typeof nextState.hideEmptyColumns === "boolean") {
167
+ state.hideEmptyColumns = nextState.hideEmptyColumns;
168
+ }
169
+ if (nextState && typeof nextState.searchQuery === "string") {
170
+ state.searchQuery = nextState.searchQuery;
171
+ }
172
+ if (nextState && typeof nextState.groupMode === "string") {
173
+ state.groupMode = nextState.groupMode;
174
+ }
175
+ if (nextState && typeof nextState.sortMode === "string") {
176
+ state.sortMode = nextState.sortMode;
177
+ }
178
+ if (nextState && typeof nextState.activityPanelOpen === "boolean") {
179
+ state.activityPanelOpen = nextState.activityPanelOpen;
180
+ }
181
+ if (nextState && typeof nextState.attentionOnly === "boolean") {
182
+ state.attentionOnly = nextState.attentionOnly;
183
+ }
184
+ if (nextState && typeof nextState.helpDismissed === "boolean") {
185
+ state.helpDismissed = nextState.helpDismissed;
186
+ }
187
+ if (nextState && typeof nextState.secondaryToolbarOpen === "boolean") {
188
+ state.secondaryToolbarOpen = nextState.secondaryToolbarOpen;
189
+ }
190
+ if (nextState && typeof nextState.detailsCollapsed === "boolean") {
191
+ state.uiState.detailsCollapsed = nextState.detailsCollapsed;
192
+ }
193
+ if (nextState && typeof nextState.viewMode === "string") {
194
+ state.uiState.viewMode = nextState.viewMode;
195
+ }
196
+ if (nextState && typeof nextState.splitRatio === "number") {
197
+ state.uiState.splitRatio = nextState.splitRatio;
198
+ }
199
+ if (nextState && Array.isArray(nextState.collapsedListStages)) {
200
+ state.collapsedListStages = new Set(nextState.collapsedListStages);
201
+ }
202
+ if (nextState && Array.isArray(nextState.collapsedDetailSections)) {
203
+ state.collapsedDetailSections = new Set(nextState.collapsedDetailSections);
204
+ }
205
+ if (nextState && typeof nextState.selectedId === "string") {
206
+ state.selectedId = nextState.selectedId;
207
+ }
208
+ if (nextScrollState && typeof nextScrollState.boardLeft === "number") {
209
+ state.scrollState.boardLeft = nextScrollState.boardLeft;
210
+ }
211
+ if (nextScrollState && typeof nextScrollState.boardTop === "number") {
212
+ state.scrollState.boardTop = nextScrollState.boardTop;
213
+ }
214
+ if (nextScrollState && typeof nextScrollState.detailsTop === "number") {
215
+ state.scrollState.detailsTop = nextScrollState.detailsTop;
216
+ }
217
+ }
218
+
219
+ function buildColumnMenu() {
220
+ const menu = document.createElement("div");
221
+ menu.className = "column__menu";
222
+ menu.setAttribute("role", "menu");
223
+ const options = [
224
+ { label: "Open", action: "open" },
225
+ { label: "Read", action: "read" },
226
+ { label: "Promote", action: "promote" }
227
+ ];
228
+ for (const option of options) {
229
+ const item = document.createElement("button");
230
+ item.type = "button";
231
+ item.className = "column__menu-item";
232
+ item.textContent = option.label;
233
+ item.setAttribute("role", "menuitem");
234
+ item.addEventListener("click", () => {
235
+ hostApi[option.action](state.selectedItem);
236
+ closeColumnMenu();
237
+ });
238
+ menu.appendChild(item);
239
+ }
240
+ return menu;
241
+ }
242
+
243
+ function closeColumnMenu() {
244
+ if (state.activeColumnMenu) {
245
+ state.activeColumnMenu.remove();
246
+ }
247
+ if (state.activeColumnMenuButton) {
248
+ state.activeColumnMenuButton.setAttribute("aria-expanded", "false");
249
+ }
250
+ state.activeColumnMenu = null;
251
+ state.activeColumnMenuButton = null;
252
+ }
253
+
254
+ function toggleColumnMenu(button) {
255
+ if (state.activeColumnMenuButton === button) {
256
+ closeColumnMenu();
257
+ return;
258
+ }
259
+ closeColumnMenu();
260
+ const menu = buildColumnMenu();
261
+ state.activeColumnMenu = menu;
262
+ state.activeColumnMenuButton = button;
263
+ button.setAttribute("aria-expanded", "true");
264
+ button.parentElement?.appendChild(menu);
265
+ }
266
+
267
+ function setState(nextItems, nextSelectedId) {
268
+ state.items = Array.isArray(nextItems) ? nextItems : [];
269
+ if (typeof nextSelectedId === "string") {
270
+ state.selectedId = nextSelectedId;
271
+ } else if (!state.items.find((item) => item.id === state.selectedId)) {
272
+ state.selectedId = null;
273
+ }
274
+ render();
275
+ }
276
+
277
+ function restoreDefaultFilters() {
278
+ state.hideCompleted = options.defaultFilterState.hideCompleted;
279
+ state.hideProcessedRequests = options.defaultFilterState.hideProcessedRequests;
280
+ state.hideSpec = options.defaultFilterState.hideSpec;
281
+ state.showCompanionDocs = options.defaultFilterState.showCompanionDocs;
282
+ state.hideEmptyColumns = options.defaultFilterState.hideEmptyColumns;
283
+ }
284
+
285
+ function setFilterPanelOpen(isOpen) {
286
+ state.secondaryToolbarOpen = isOpen;
287
+ if (filterPanel) {
288
+ filterPanel.hidden = !isOpen;
289
+ filterPanel.setAttribute("aria-hidden", String(!isOpen));
290
+ }
291
+ updateFilterState();
292
+ persistState();
293
+ }
294
+
295
+ function setToolsPanelOpen(viewName, isOpen) {
296
+ state.toolsPanelOpen = isOpen;
297
+ if (isOpen && typeof viewName === "string" && viewName) {
298
+ state.toolsPanelView = viewName;
299
+ }
300
+ if (typeof applyToolsPanelOpen === "function") {
301
+ applyToolsPanelOpen(viewName, isOpen);
302
+ }
303
+ if (toolsPanel) {
304
+ toolsPanel.hidden = !isOpen;
305
+ toolsPanel.setAttribute("aria-hidden", String(!isOpen));
306
+ }
307
+ }
308
+
309
+ function openSelectedItem(mode) {
310
+ if (!state.selectedId) {
311
+ return;
312
+ }
313
+ const item = state.items.find((entry) => entry.id === state.selectedId);
314
+ if (!item) {
315
+ return;
316
+ }
317
+ hostApi.openItem(item, mode);
318
+ }
319
+
320
+ async function handleChangeProjectRoot() {
321
+ await hostApi.changeProjectRoot();
322
+ }
323
+
324
+ function handleResetProjectRoot() {
325
+ hostApi.resetProjectRoot();
326
+ }
327
+
328
+ function handleBootstrapLogics() {
329
+ hostApi.bootstrapLogics();
330
+ }
331
+
332
+ function handleAbout() {
333
+ hostApi.about();
334
+ }
335
+
336
+ function renderBoardErrorState(message) {
337
+ if (!board) {
338
+ return;
339
+ }
340
+ board.replaceChildren();
341
+ const container = document.createElement("div");
342
+ container.className = "state-message";
343
+ container.textContent = String(message || "");
344
+ board.appendChild(container);
345
+ }
346
+
347
+ function render() {
348
+ if (layoutController && typeof layoutController.updateLayoutMode === "function") {
349
+ layoutController.updateLayoutMode();
350
+ }
351
+ if (
352
+ layoutController &&
353
+ typeof layoutController.isSplitInteractionDisabled === "function" &&
354
+ typeof layoutController.isDraggingSplit === "function" &&
355
+ layoutController.isSplitInteractionDisabled() &&
356
+ layoutController.isDraggingSplit()
357
+ ) {
358
+ if (typeof layoutController.resetDraggingState === "function") {
359
+ layoutController.resetDraggingState();
360
+ }
361
+ }
362
+ const selectedItem = state.items.find((item) => item.id === state.selectedId);
363
+ if (selectedItem && !isVisible(selectedItem) && !state.activityPanelOpen) {
364
+ state.selectedId = null;
365
+ }
366
+ if (details) {
367
+ details.classList.toggle("details--collapsed", state.uiState.detailsCollapsed);
368
+ }
369
+ if (detailsToggle) {
370
+ detailsToggle.setAttribute("aria-expanded", String(!state.uiState.detailsCollapsed));
371
+ detailsToggle.setAttribute("aria-label", state.uiState.detailsCollapsed ? "Expand details" : "Collapse details");
372
+ detailsToggle.title = state.uiState.detailsCollapsed ? "Expand details" : "Collapse details";
373
+ }
374
+ if (layoutController && typeof layoutController.updateSplitterA11y === "function") {
375
+ layoutController.updateSplitterA11y();
376
+ }
377
+ if (board) {
378
+ board.classList.toggle("board--list", isListMode());
379
+ board.hidden = state.activityPanelOpen;
380
+ }
381
+ if (mainPane) {
382
+ mainPane.classList.toggle("layout__main--activity", state.activityPanelOpen);
383
+ }
384
+ updateViewModeToggle();
385
+ boardRenderer.renderBoard();
386
+ detailsRenderer.renderDetails();
387
+ renderActivityPanel();
388
+ renderHelpBanner();
389
+ updateButtons();
390
+ updateFilterState();
391
+ syncChromeInputs();
392
+ restoreScrollState();
393
+ }
394
+
395
+ function handleHostMessage(event) {
396
+ const { type, payload, action } = event.data || {};
397
+ if (type === "trigger-tool-action" && typeof action === "string") {
398
+ const toolButton = document.querySelector(`[data-action="${action}"]`);
399
+ if (toolButton instanceof HTMLElement) {
400
+ toolButton.click();
401
+ }
402
+ return;
403
+ }
404
+ if (type === "data") {
405
+ if (payload && typeof payload.root === "string") {
406
+ state.activeWorkspaceRoot = payload.root;
407
+ if (options.harnessApi && typeof options.harnessApi.setCurrentRoot === "function") {
408
+ options.harnessApi.setCurrentRoot(payload.root);
409
+ }
410
+ if (state.persistedWorkspaceRoot && !areSameWorkspacePath(state.persistedWorkspaceRoot, payload.root)) {
411
+ resetPersistedUiState();
412
+ }
413
+ }
414
+ if (payload && typeof payload.canResetProjectRoot === "boolean") {
415
+ state.canResetProjectRoot = payload.canResetProjectRoot;
416
+ }
417
+ if (payload && typeof payload.canBootstrapLogics === "boolean") {
418
+ state.canBootstrapLogics = payload.canBootstrapLogics;
419
+ }
420
+ if (payload && typeof payload.bootstrapLogicsTitle === "string") {
421
+ state.bootstrapLogicsTitle = payload.bootstrapLogicsTitle;
422
+ }
423
+ if (payload && typeof payload.canLaunchCodex === "boolean") {
424
+ state.canLaunchCodex = payload.canLaunchCodex;
425
+ }
426
+ if (payload && typeof payload.launchCodexTitle === "string") {
427
+ state.launchCodexTitle = payload.launchCodexTitle;
428
+ }
429
+ if (payload && typeof payload.canLaunchClaude === "boolean") {
430
+ state.canLaunchClaude = payload.canLaunchClaude;
431
+ }
432
+ if (payload && typeof payload.launchClaudeTitle === "string") {
433
+ state.launchClaudeTitle = payload.launchClaudeTitle;
434
+ }
435
+ if (payload && typeof payload.canRepairLogicsKit === "boolean") {
436
+ state.canRepairLogicsKit = payload.canRepairLogicsKit;
437
+ }
438
+ if (payload && typeof payload.repairLogicsKitTitle === "string") {
439
+ state.repairLogicsKitTitle = payload.repairLogicsKitTitle;
440
+ }
441
+ if (payload && typeof payload.canPublishRelease === "boolean") {
442
+ state.canPublishRelease = payload.canPublishRelease;
443
+ }
444
+ if (payload && typeof payload.publishReleaseTitle === "string") {
445
+ state.publishReleaseTitle = payload.publishReleaseTitle;
446
+ }
447
+ if (payload && typeof payload.shouldRecommendCheckEnvironment === "boolean") {
448
+ state.shouldRecommendCheckEnvironment = payload.shouldRecommendCheckEnvironment;
449
+ }
450
+ state.changedPaths = Array.isArray(payload && payload.changedPaths) ? payload.changedPaths : [];
451
+ state.activeAgent = payload && payload.activeAgent ? payload.activeAgent : null;
452
+ if (payload && payload.error) {
453
+ renderBoardErrorState(payload.error);
454
+ detailsBody.innerHTML = "";
455
+ if (detailsTitle) {
456
+ detailsTitle.textContent = "Details";
457
+ }
458
+ state.selectedId = null;
459
+ updateButtons();
460
+ updateViewModeToggle();
461
+ return;
462
+ }
463
+ const nextItems = payload && payload.items ? payload.items : [];
464
+ const nextSelected = payload ? payload.selectedId : undefined;
465
+ setState(nextItems, nextSelected);
466
+ }
467
+ }
468
+
469
+ function handleDocumentClick(event) {
470
+ const clickTarget = event.target;
471
+ if (clickTarget instanceof Element && clickTarget.closest("[data-tools-panel-close]")) {
472
+ setToolsPanelOpen(undefined, false);
473
+ return;
474
+ }
475
+ if (state.toolsPanelOpen && toolsPanel) {
476
+ const toolbarButtons = [toolsToggle].filter(Boolean);
477
+ const clickedToolbarButton = toolbarButtons.some((button) => button && button.contains(clickTarget));
478
+ if (!toolsPanel.contains(clickTarget) && !clickedToolbarButton) {
479
+ setToolsPanelOpen(undefined, false);
480
+ }
481
+ }
482
+ if (!state.activeColumnMenu) {
483
+ return;
484
+ }
485
+ const menuTarget = event.target;
486
+ if (state.activeColumnMenu.contains(menuTarget)) {
487
+ return;
488
+ }
489
+ if (state.activeColumnMenuButton && state.activeColumnMenuButton.contains(menuTarget)) {
490
+ return;
491
+ }
492
+ closeColumnMenu();
493
+ }
494
+
495
+ function handleDocumentKeydown(event) {
496
+ if (event.key === "Escape" && state.secondaryToolbarOpen) {
497
+ setFilterPanelOpen(false);
498
+ }
499
+ if (event.key === "Escape" && state.toolsPanelOpen) {
500
+ setToolsPanelOpen(undefined, false);
501
+ }
502
+ if (event.key === "Escape" && state.activeColumnMenu) {
503
+ closeColumnMenu();
504
+ }
505
+ }
506
+
507
+ function handleSplitterKeydown(event) {
508
+ if (event.key === "ArrowUp") {
509
+ event.preventDefault();
510
+ if (layoutController && typeof layoutController.nudgeSplitFromKeyboard === "function") {
511
+ layoutController.nudgeSplitFromKeyboard(0.03);
512
+ }
513
+ render();
514
+ return;
515
+ }
516
+ if (event.key === "ArrowDown") {
517
+ event.preventDefault();
518
+ if (layoutController && typeof layoutController.nudgeSplitFromKeyboard === "function") {
519
+ layoutController.nudgeSplitFromKeyboard(-0.03);
520
+ }
521
+ render();
522
+ return;
523
+ }
524
+ if (event.key === "Home") {
525
+ event.preventDefault();
526
+ if (layoutController && typeof layoutController.persistAndApplySplitRatio === "function") {
527
+ layoutController.persistAndApplySplitRatio(0.9);
528
+ }
529
+ render();
530
+ return;
531
+ }
532
+ if (event.key === "End") {
533
+ event.preventDefault();
534
+ if (layoutController && typeof layoutController.persistAndApplySplitRatio === "function") {
535
+ layoutController.persistAndApplySplitRatio(0.1);
536
+ }
537
+ render();
538
+ }
539
+ }
540
+
541
+ function handleResponsiveLayoutChange() {
542
+ if (layoutController && typeof layoutController.updateLayoutMode === "function") {
543
+ layoutController.updateLayoutMode();
544
+ }
545
+ if (layoutController && typeof layoutController.updateSplitterA11y === "function") {
546
+ layoutController.updateSplitterA11y();
547
+ }
548
+ if (
549
+ layoutController &&
550
+ typeof layoutController.isStackedLayout === "function" &&
551
+ layoutController.isStackedLayout() &&
552
+ typeof layoutController.applySplitRatio === "function"
553
+ ) {
554
+ layoutController.applySplitRatio(state.uiState.splitRatio, false);
555
+ }
556
+ render();
557
+ }
558
+
559
+ function triggerPersistState() {
560
+ if (typeof options.persistState === "function") {
561
+ options.persistState();
562
+ }
563
+ }
564
+
565
+ function hydratePersistedState(previousState) {
566
+ if (typeof options.hydratePersistedState === "function") {
567
+ options.hydratePersistedState(previousState);
568
+ }
569
+ }
570
+
571
+ return {
572
+ getSnapshot,
573
+ applyResetState,
574
+ applyPersistedState,
575
+ normalizeWorkspacePath,
576
+ areSameWorkspacePath,
577
+ buildColumnMenu,
578
+ closeColumnMenu,
579
+ toggleColumnMenu,
580
+ setState,
581
+ render,
582
+ restoreDefaultFilters,
583
+ setFilterPanelOpen,
584
+ setToolsPanelOpen,
585
+ openSelectedItem,
586
+ handleChangeProjectRoot,
587
+ handleResetProjectRoot,
588
+ handleBootstrapLogics,
589
+ handleAbout,
590
+ handleHostMessage,
591
+ renderBoardErrorState,
592
+ handleDocumentClick,
593
+ handleDocumentKeydown,
594
+ handleSplitterKeydown,
595
+ handleResponsiveLayoutChange,
596
+ hydratePersistedState,
597
+ persistState: triggerPersistState,
598
+ captureScrollState,
599
+ restoreScrollState,
600
+ schedulePersistState,
601
+ resetPersistedUiState
602
+ };
603
+ };
604
+ })();