@workbench-kit/shell-react 0.0.2-prototype.0.2.43 → 0.0.2-prototype.0.2.45

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.
@@ -10,12 +10,18 @@ import {
10
10
  } from 'react';
11
11
  import {
12
12
  createBuiltinValueTransformRegistry,
13
+ createFieldRemapDocument,
14
+ deserializeFieldRemapImport,
15
+ FieldRemapImportAdmissionError,
13
16
  findParentChildMappingConflicts,
14
17
  projectSourceFields,
15
18
  projectTargetSlots,
16
19
  pruneMappingEdgesForShapes,
20
+ serializeFieldRemapDocument,
17
21
  sourceFieldsFromPlainObject,
18
22
  targetSlotsFromPlainObject,
23
+ UnsupportedFieldRemapDocumentVersionError,
24
+ type FieldRemapDocument,
19
25
  type MappingEdge,
20
26
  type MappingOperator,
21
27
  type SourceField,
@@ -52,6 +58,7 @@ import {
52
58
  import { createFieldRemapPreviewController } from './preview-controller.js';
53
59
  import type { FieldRemapPreviewState } from './preview.js';
54
60
  import { isFieldRemapEditableShortcutTarget } from './keyboard.js';
61
+ import { FieldRemapDocumentIo, type FieldRemapDocumentImportActionResult } from './document-io.js';
55
62
  import './view.css';
56
63
 
57
64
  export type { FieldRemapHistorySnapshot } from './history.js';
@@ -111,6 +118,11 @@ export interface FieldRemapPanelProps {
111
118
  /** Optional controlled n→m operators (document v2). */
112
119
  readonly operators?: readonly MappingOperator[] | undefined;
113
120
  readonly onOperatorsChange?: ((operators: readonly MappingOperator[]) => void) | undefined;
121
+ /**
122
+ * Atomic whole-document replacement proposal for controlled or mixed-control imports.
123
+ * Incremental edge/operator callbacks remain unchanged.
124
+ */
125
+ readonly onDocumentReplace?: ((document: FieldRemapDocument) => void) | undefined;
114
126
  /**
115
127
  * Composite history owner for controlled or mixed-control mapping state. When either durable
116
128
  * channel is controlled, the Panel never creates a partial private history.
@@ -264,6 +276,7 @@ export function FieldRemapPanel({
264
276
  onEdgesChange,
265
277
  operators: operatorsProp,
266
278
  onOperatorsChange,
279
+ onDocumentReplace,
267
280
  historyOwner,
268
281
  historyActionsRef,
269
282
  onHistoryAvailabilityChange,
@@ -437,6 +450,40 @@ export function FieldRemapPanel({
437
450
  applyHistorySnapshot(next);
438
451
  };
439
452
 
453
+ const documentImportAvailable =
454
+ !readOnly && (historyOwnedByPanel || onDocumentReplace !== undefined);
455
+
456
+ const importDocumentText = (text: string): FieldRemapDocumentImportActionResult => {
457
+ let document: FieldRemapDocument;
458
+ try {
459
+ document = deserializeFieldRemapImport(text, {
460
+ sources: sourceFields,
461
+ targets: targetSlots,
462
+ transforms: registry,
463
+ });
464
+ } catch (error) {
465
+ if (error instanceof UnsupportedFieldRemapDocumentVersionError) {
466
+ return { status: 'rejected', code: 'unsupported-version' };
467
+ }
468
+ if (error instanceof FieldRemapImportAdmissionError) {
469
+ return { status: 'rejected', code: error.code };
470
+ }
471
+ return { status: 'rejected', code: 'invalid-document' };
472
+ }
473
+
474
+ if (historyOwnedByPanel) {
475
+ recordSemanticSnapshot(
476
+ createFieldRemapHistorySnapshot(document.edges, document.operators ?? []),
477
+ );
478
+ return { status: 'accepted' };
479
+ }
480
+ if (!onDocumentReplace) {
481
+ return { status: 'rejected', code: 'invalid-document' };
482
+ }
483
+ onDocumentReplace(document);
484
+ return { status: 'accepted' };
485
+ };
486
+
440
487
  const commitFlowEdges = (next: readonly MappingEdge[]) => {
441
488
  if (includeHidden) {
442
489
  recordSemanticSnapshot(createFieldRemapHistorySnapshot(next, operators));
@@ -693,6 +740,19 @@ export function FieldRemapPanel({
693
740
  <header className="workbench-field-remap-demo__header">
694
741
  <h2 className="workbench-field-remap-demo__title">{sample.title}</h2>
695
742
  <p className="workbench-field-remap-demo__intro">{sample.description}</p>
743
+ <FieldRemapDocumentIo
744
+ getDocumentJson={() =>
745
+ serializeFieldRemapDocument(
746
+ createFieldRemapDocument(edges, {
747
+ ...(operators.length > 0 ? { operators } : {}),
748
+ }),
749
+ )
750
+ }
751
+ importAvailable={documentImportAvailable}
752
+ labels={labels}
753
+ t={t}
754
+ onImportText={importDocumentText}
755
+ />
696
756
  </header>
697
757
 
698
758
  {ioChrome === 'edit' ? (
@@ -1,5 +1,12 @@
1
1
  import { useEffect, useId, useState, type JSX } from 'react';
2
- import { Button } from '@workbench-kit/react/primitives';
2
+ import {
3
+ Button,
4
+ Checkbox,
5
+ NumberInput,
6
+ TextInput,
7
+ WorkbenchPropertyRow,
8
+ WorkbenchPropertyStack,
9
+ } from '@workbench-kit/react/primitives';
3
10
  import type { TransformOptionField } from '@workbench-kit/field-remap';
4
11
 
5
12
  export interface TransformOptionsEditorProps {
@@ -128,12 +135,14 @@ function StringMapEditor({
128
135
  }
129
136
 
130
137
  function JsonOptionEditor({
138
+ controlId,
131
139
  field,
132
140
  value,
133
141
  disabled,
134
142
  onChange,
135
143
  testId,
136
144
  }: {
145
+ readonly controlId: string;
137
146
  readonly field: TransformOptionField;
138
147
  readonly value: unknown;
139
148
  readonly disabled: boolean;
@@ -153,6 +162,7 @@ function JsonOptionEditor({
153
162
  return (
154
163
  <div className="workbench-field-remap-options__json">
155
164
  <textarea
165
+ id={controlId}
156
166
  aria-label={field.label}
157
167
  data-testid={testId}
158
168
  disabled={disabled}
@@ -225,69 +235,71 @@ export function TransformOptionsEditor({
225
235
  };
226
236
 
227
237
  return (
228
- <div
238
+ <WorkbenchPropertyStack
229
239
  className="workbench-field-remap-options"
230
240
  data-field-remap-shortcuts="ignore"
231
241
  data-testid={`${testIdPrefix}-editor`}
242
+ gap="sm"
232
243
  >
233
244
  {fields.map((field) => {
234
245
  const controlId = `${baseId}-${field.key}`;
235
246
  const testId = `${testIdPrefix}-${field.key}`;
236
247
  const current = value[field.key];
237
248
 
238
- return (
239
- <label
240
- key={field.key}
241
- className="workbench-field-remap-options__field"
242
- htmlFor={field.kind === 'boolean' ? controlId : undefined}
243
- >
244
- <span className="workbench-field-remap-options__label">{field.label}</span>
245
- {field.kind === 'string' ? (
246
- <input
249
+ if (field.kind === 'string') {
250
+ return (
251
+ <WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
252
+ <TextInput
247
253
  id={controlId}
248
- type="text"
254
+ controlWidth="full"
249
255
  data-testid={testId}
250
256
  disabled={disabled}
251
257
  aria-label={field.label}
252
258
  value={
253
259
  typeof current === 'string' ? current : current == null ? '' : String(current)
254
260
  }
255
- onChange={(event) => setKey(field.key, event.target.value)}
261
+ onValueChange={(next) => setKey(field.key, next)}
256
262
  />
257
- ) : null}
258
- {field.kind === 'number' ? (
259
- <input
263
+ </WorkbenchPropertyRow>
264
+ );
265
+ }
266
+
267
+ if (field.kind === 'number') {
268
+ return (
269
+ <WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
270
+ <NumberInput
260
271
  id={controlId}
261
- type="number"
272
+ controlWidth="full"
262
273
  data-testid={testId}
263
274
  disabled={disabled}
264
275
  aria-label={field.label}
265
- value={typeof current === 'number' ? current : ''}
266
- onChange={(event) => {
267
- const raw = event.target.value;
268
- if (raw === '') {
269
- setKey(field.key, undefined);
270
- return;
271
- }
272
- const parsed = Number(raw);
273
- if (Number.isFinite(parsed)) {
274
- setKey(field.key, parsed);
275
- }
276
- }}
276
+ nullable
277
+ value={typeof current === 'number' ? current : undefined}
278
+ onEmptyValue={() => setKey(field.key, undefined)}
279
+ onValueChange={(next) => setKey(field.key, next)}
277
280
  />
278
- ) : null}
279
- {field.kind === 'boolean' ? (
280
- <input
281
+ </WorkbenchPropertyRow>
282
+ );
283
+ }
284
+
285
+ if (field.kind === 'boolean') {
286
+ return (
287
+ <WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
288
+ <Checkbox
281
289
  id={controlId}
282
- type="checkbox"
283
290
  data-testid={testId}
284
291
  disabled={disabled}
285
292
  aria-label={field.label}
286
293
  checked={Boolean(current)}
287
- onChange={(event) => setKey(field.key, event.target.checked)}
294
+ onCheckedChange={(next) => setKey(field.key, next)}
288
295
  />
289
- ) : null}
290
- {field.kind === 'stringMap' ? (
296
+ </WorkbenchPropertyRow>
297
+ );
298
+ }
299
+
300
+ if (field.kind === 'stringMap') {
301
+ return (
302
+ <WorkbenchPropertyRow key={field.key} label={field.label}>
291
303
  <StringMapEditor
292
304
  field={field}
293
305
  value={current}
@@ -297,19 +309,23 @@ export function TransformOptionsEditor({
297
309
  setKey(field.key, Object.keys(next).length > 0 ? next : undefined)
298
310
  }
299
311
  />
300
- ) : null}
301
- {field.kind === 'json' ? (
302
- <JsonOptionEditor
303
- field={field}
304
- value={current}
305
- disabled={disabled}
306
- testId={testId}
307
- onChange={(next) => setKey(field.key, next)}
308
- />
309
- ) : null}
310
- </label>
312
+ </WorkbenchPropertyRow>
313
+ );
314
+ }
315
+
316
+ return (
317
+ <WorkbenchPropertyRow key={field.key} htmlFor={controlId} label={field.label}>
318
+ <JsonOptionEditor
319
+ controlId={controlId}
320
+ field={field}
321
+ value={current}
322
+ disabled={disabled}
323
+ testId={testId}
324
+ onChange={(next) => setKey(field.key, next)}
325
+ />
326
+ </WorkbenchPropertyRow>
311
327
  );
312
328
  })}
313
- </div>
329
+ </WorkbenchPropertyStack>
314
330
  );
315
331
  }
@@ -53,6 +53,50 @@
53
53
  font-size: 0.8em;
54
54
  }
55
55
 
56
+ .workbench-field-remap-document-io {
57
+ display: flex;
58
+ flex-wrap: wrap;
59
+ align-items: center;
60
+ gap: 0.5rem 0.75rem;
61
+ margin-top: 0.25rem;
62
+ }
63
+
64
+ .workbench-field-remap-document-io__actions {
65
+ display: flex;
66
+ flex-wrap: wrap;
67
+ gap: 0.5rem;
68
+ }
69
+
70
+ .workbench-field-remap-document-io__availability,
71
+ .workbench-field-remap-document-io__status {
72
+ color: var(--vscode-descriptionForeground, var(--color-text-muted));
73
+ font-size: 0.8rem;
74
+ }
75
+
76
+ .workbench-field-remap-document-io__status[data-status='error'],
77
+ .workbench-field-remap-document-import__error {
78
+ color: var(--vscode-errorForeground, var(--color-danger));
79
+ }
80
+
81
+ .workbench-field-remap-document-export__description,
82
+ .workbench-field-remap-document-import__description,
83
+ .workbench-field-remap-document-import__error {
84
+ margin: 0;
85
+ font-size: 0.875rem;
86
+ line-height: 1.45;
87
+ }
88
+
89
+ .workbench-field-remap-document-export__label,
90
+ .workbench-field-remap-document-import__label {
91
+ font-size: 0.875rem;
92
+ font-weight: 600;
93
+ }
94
+
95
+ .workbench-field-remap-document-export__body textarea,
96
+ .workbench-field-remap-document-import__body textarea {
97
+ min-height: 14rem;
98
+ }
99
+
56
100
  .workbench-field-remap-demo__error {
57
101
  margin: 0;
58
102
  color: var(--vscode-errorForeground, var(--color-danger));
@@ -486,22 +530,6 @@
486
530
  gap: 0.35rem;
487
531
  }
488
532
 
489
- .workbench-field-remap-detail__draft-ports {
490
- display: grid;
491
- gap: 0.5rem;
492
- margin: 0;
493
- }
494
-
495
- .workbench-field-remap-detail__draft-ports dt {
496
- font-size: 0.7rem;
497
- text-transform: uppercase;
498
- color: var(--vscode-descriptionForeground, var(--color-text-muted));
499
- }
500
-
501
- .workbench-field-remap-detail__draft-ports dd {
502
- margin: 0;
503
- }
504
-
505
533
  .workbench-field-remap-flow__canvas {
506
534
  height: min(40rem, 70vh);
507
535
  min-height: 26rem;
@@ -864,39 +892,6 @@
864
892
  background: var(--vscode-editor-background, var(--color-bg));
865
893
  }
866
894
 
867
- .workbench-field-remap-convert-note__header {
868
- display: flex;
869
- align-items: flex-start;
870
- justify-content: space-between;
871
- gap: 0.5rem;
872
- }
873
-
874
- .workbench-field-remap-convert-note__eyebrow {
875
- margin: 0 0 0.2rem;
876
- font-size: 0.7rem;
877
- font-weight: 600;
878
- letter-spacing: 0.04em;
879
- text-transform: uppercase;
880
- color: var(--vscode-focusBorder, var(--color-accent, #3794ff));
881
- }
882
-
883
- .workbench-field-remap-convert-note__header h4,
884
- .workbench-field-remap-convert-note__section h5 {
885
- margin: 0 0 0.35rem;
886
- font-size: 0.75rem;
887
- font-weight: 600;
888
- text-transform: uppercase;
889
- letter-spacing: 0.03em;
890
- color: var(--vscode-descriptionForeground, var(--color-text-muted));
891
- }
892
-
893
- .workbench-field-remap-convert-note__header h4 {
894
- font-size: 1rem;
895
- text-transform: none;
896
- letter-spacing: normal;
897
- color: var(--vscode-foreground, var(--color-text));
898
- }
899
-
900
895
  .workbench-field-remap-convert-note__binding,
901
896
  .workbench-field-remap-convert-note__muted {
902
897
  display: block;
@@ -912,68 +907,15 @@
912
907
  gap: 0.35rem;
913
908
  }
914
909
 
915
- .workbench-field-remap-convert-note__section,
916
- .workbench-field-remap-convert-note__field {
917
- display: flex;
918
- flex-direction: column;
919
- gap: 0.5rem;
920
- }
921
-
922
- .workbench-field-remap-convert-note__field {
923
- gap: 0.2rem;
924
- }
925
-
926
- .workbench-field-remap-convert-note select {
927
- box-sizing: border-box;
928
- width: 100%;
929
- margin-top: 0.2rem;
930
- padding: 0.3rem 0.4rem;
931
- border: 1px solid var(--vscode-panel-border, var(--color-border));
932
- border-radius: 0.25rem;
933
- background: var(--vscode-input-background, var(--color-bg));
934
- color: var(--vscode-input-foreground, var(--color-text));
935
- font: inherit;
936
- }
937
-
938
- .workbench-field-remap-convert-note__footer {
939
- margin-top: auto;
940
- padding-top: 0.5rem;
941
- border-top: 1px solid var(--vscode-panel-border, var(--color-border));
942
- }
943
-
944
910
  .workbench-field-remap-detail--empty {
945
911
  color: var(--vscode-descriptionForeground, var(--color-text-muted));
946
912
  }
947
913
 
948
- .workbench-field-remap-detail__header {
949
- display: flex;
950
- align-items: flex-start;
951
- justify-content: space-between;
952
- gap: 0.5rem;
953
- }
954
-
955
- .workbench-field-remap-detail__header h4,
956
- .workbench-field-remap-detail__section h5 {
957
- margin: 0 0 0.35rem;
958
- font-size: 0.75rem;
959
- font-weight: 600;
960
- text-transform: uppercase;
961
- letter-spacing: 0.03em;
962
- color: var(--vscode-descriptionForeground, var(--color-text-muted));
963
- }
964
-
965
- .workbench-field-remap-detail__header code,
966
914
  .workbench-field-remap-detail__steps code {
967
915
  font-size: 0.75rem;
968
916
  word-break: break-all;
969
917
  }
970
918
 
971
- .workbench-field-remap-detail__section {
972
- display: flex;
973
- flex-direction: column;
974
- gap: 0.5rem;
975
- }
976
-
977
919
  .workbench-field-remap-detail__muted {
978
920
  margin: 0;
979
921
  color: var(--vscode-descriptionForeground, var(--color-text-muted));
@@ -1020,31 +962,12 @@
1020
962
  color: var(--vscode-descriptionForeground, var(--color-text-muted));
1021
963
  }
1022
964
 
1023
- .workbench-field-remap-detail__palette,
1024
- .workbench-field-remap-detail__item-pickers,
1025
- .workbench-field-remap-detail__field {
1026
- display: flex;
1027
- flex-direction: column;
1028
- gap: 0.35rem;
1029
- }
1030
-
1031
965
  .workbench-field-remap-detail__palette {
1032
- flex-direction: row;
1033
966
  flex-wrap: wrap;
1034
- align-items: flex-end;
1035
- }
1036
-
1037
- .workbench-field-remap-detail__palette label,
1038
- .workbench-field-remap-detail__item-pickers label,
1039
- .workbench-field-remap-detail__field {
1040
- flex: 1 1 10rem;
1041
- min-width: 0;
1042
967
  }
1043
968
 
1044
- .workbench-field-remap-detail select,
1045
- .workbench-field-remap-options input[type='text'],
1046
- .workbench-field-remap-options input[type='number'],
1047
- .workbench-field-remap-options textarea {
969
+ .workbench-field-remap-options__string-map input[type='text'],
970
+ .workbench-field-remap-options__json textarea {
1048
971
  box-sizing: border-box;
1049
972
  width: 100%;
1050
973
  margin-top: 0.2rem;
@@ -1056,13 +979,6 @@
1056
979
  font: inherit;
1057
980
  }
1058
981
 
1059
- .workbench-field-remap-detail__list-context-bar {
1060
- display: flex;
1061
- align-items: center;
1062
- justify-content: space-between;
1063
- gap: 0.5rem;
1064
- }
1065
-
1066
982
  .workbench-field-remap-detail__item-edges {
1067
983
  list-style: none;
1068
984
  margin: 0;
@@ -1079,23 +995,6 @@
1079
995
  gap: 0.35rem;
1080
996
  }
1081
997
 
1082
- .workbench-field-remap-options {
1083
- display: flex;
1084
- flex-direction: column;
1085
- gap: 0.55rem;
1086
- }
1087
-
1088
- .workbench-field-remap-options__field {
1089
- display: flex;
1090
- flex-direction: column;
1091
- gap: 0.2rem;
1092
- }
1093
-
1094
- .workbench-field-remap-options__label {
1095
- font-size: 0.75rem;
1096
- color: var(--vscode-descriptionForeground, var(--color-text-muted));
1097
- }
1098
-
1099
998
  .workbench-field-remap-options__empty,
1100
999
  .workbench-field-remap-options__error {
1101
1000
  margin: 0;
@@ -0,0 +1,4 @@
1
+ export {
2
+ WorkbenchKeybindingManagementSettingsView,
3
+ type WorkbenchKeybindingManagementSettingsViewProps,
4
+ } from './management/keybinding-settings-view.js';
@@ -0,0 +1,31 @@
1
+ import type { KeybindingManagementEntry, WorkbenchShortcutPlatform } from '@workbench-kit/platform';
2
+ import { KeybindingManagementPanel } from '@workbench-kit/react/workbench/management';
3
+
4
+ export interface WorkbenchKeybindingManagementSettingsViewProps {
5
+ readonly editingDisabledReason?: string | undefined;
6
+ readonly entries: readonly KeybindingManagementEntry[];
7
+ readonly overrideCount: number;
8
+ readonly platform: WorkbenchShortcutPlatform;
9
+ readonly resetKeybinding: (commandId: string) => void;
10
+ readonly setKeybinding: (commandId: string, key: string | undefined) => void;
11
+ }
12
+
13
+ export function WorkbenchKeybindingManagementSettingsView({
14
+ editingDisabledReason,
15
+ entries,
16
+ overrideCount,
17
+ platform,
18
+ resetKeybinding,
19
+ setKeybinding,
20
+ }: WorkbenchKeybindingManagementSettingsViewProps) {
21
+ return (
22
+ <KeybindingManagementPanel
23
+ editingDisabledReason={editingDisabledReason}
24
+ entries={entries}
25
+ platform={platform}
26
+ summaryLabel={`${entries.length} command${entries.length === 1 ? '' : 's'} · ${overrideCount} user override${overrideCount === 1 ? '' : 's'}`}
27
+ onResetKeybinding={resetKeybinding}
28
+ onSetKeybinding={setKeybinding}
29
+ />
30
+ );
31
+ }
@@ -1,25 +1,8 @@
1
- import { KeybindingManagementPanel } from '@workbench-kit/react/workbench/management';
2
-
3
- import { useKeybindingManagementModel } from './use-keybinding-management.js';
1
+ import { useWorkbenchKeybindingManagementBinding } from '../shell/provider.js';
2
+ import { WorkbenchKeybindingManagementSettingsView } from './keybinding-settings-view.js';
4
3
 
5
4
  export function WorkbenchKeybindingManagementSettings() {
6
- const {
7
- editingDisabledReason,
8
- entries,
9
- overrideCount,
10
- platform,
11
- resetKeybinding,
12
- setKeybinding,
13
- } = useKeybindingManagementModel();
5
+ const binding = useWorkbenchKeybindingManagementBinding();
14
6
 
15
- return (
16
- <KeybindingManagementPanel
17
- editingDisabledReason={editingDisabledReason}
18
- entries={entries}
19
- platform={platform}
20
- summaryLabel={`${entries.length} command${entries.length === 1 ? '' : 's'} · ${overrideCount} user override${overrideCount === 1 ? '' : 's'}`}
21
- onResetKeybinding={resetKeybinding}
22
- onSetKeybinding={setKeybinding}
23
- />
24
- );
7
+ return <WorkbenchKeybindingManagementSettingsView {...binding} />;
25
8
  }
@@ -1,12 +1,12 @@
1
1
  import { useLayoutEffect, useMemo, useState } from 'react';
2
2
  import { createKeybindingManagementModel } from '@workbench-kit/platform';
3
- import { createWorkbenchShellCommands } from '@workbench-kit/react/workbench';
3
+ import { createWorkbenchShellCommands } from '@workbench-kit/react/workbench/commands';
4
4
 
5
- import { useWorkbench, type WorkbenchContextValue } from '../shell/provider.js';
5
+ import type { WorkbenchContextValue } from '../shell/provider.js';
6
6
  import { resolveShellCommandActivities } from '../workbench/command-palette.js';
7
7
  import { normalizeExtensionKeybindingCandidates } from '../workbench/keybinding-bridge.js';
8
8
 
9
- export function useKeybindingManagementModel() {
9
+ export function useKeybindingManagementModel(context: WorkbenchContextValue) {
10
10
  const {
11
11
  activities,
12
12
  commands,
@@ -19,7 +19,7 @@ export function useKeybindingManagementModel() {
19
19
  resetCommandKeybindingOverride,
20
20
  setCommandKeybindingOverride,
21
21
  views,
22
- } = useWorkbench();
22
+ } = context;
23
23
 
24
24
  const [keybindingRevision, setKeybindingRevision] = useState(() => keybindings.revision);
25
25
  useLayoutEffect(() => {
@@ -9,6 +9,8 @@ import {
9
9
  useState,
10
10
  type ReactNode,
11
11
  } from 'react';
12
+ import type { WorkbenchKeybindingManagementSettingsViewProps } from '../management/keybinding-settings-view.js';
13
+ import { useKeybindingManagementModel } from '../management/use-keybinding-management.js';
12
14
  import {
13
15
  collectConfigurationDefaults,
14
16
  createEditorService,
@@ -1048,7 +1050,10 @@ export function WorkbenchProvider({
1048
1050
  <WorkbenchPersistenceDiagnosticContext.Provider value={onPersistenceDiagnostic}>
1049
1051
  <WorkbenchContext.Provider value={value}>
1050
1052
  <ExtensionEnablementContext.Provider value={services.extensionEnablement}>
1051
- <EditorWorkspaceReconciler />
1053
+ <EditorWorkspaceReconciler
1054
+ editorService={services.editorService}
1055
+ workspaceHostService={services.workspaceHostPort?.service}
1056
+ />
1052
1057
  {children}
1053
1058
  </ExtensionEnablementContext.Provider>
1054
1059
  </WorkbenchContext.Provider>
@@ -1064,3 +1069,7 @@ export function useWorkbench(): WorkbenchContextValue {
1064
1069
 
1065
1070
  return value;
1066
1071
  }
1072
+
1073
+ export function useWorkbenchKeybindingManagementBinding(): WorkbenchKeybindingManagementSettingsViewProps {
1074
+ return useKeybindingManagementModel(useWorkbench());
1075
+ }