@deepseek-ai/dsh-client-ui-conversation 0.1.2-alpha.2 → 0.1.2-alpha.4

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.
package/lib/client.js CHANGED
@@ -76,14 +76,53 @@ window.__ModuleLoader__.load({
76
76
  }
77
77
  //#endregion
78
78
  //#region lib/types/client/conversation/location-index.js
79
+ var MutableLocationDataSource = class {
80
+ store;
81
+ key;
82
+ listeners = /* @__PURE__ */ new Set();
83
+ published;
84
+ constructor(store, key) {
85
+ this.store = store;
86
+ this.key = key;
87
+ this.published = store.get(key);
88
+ }
89
+ getSnapshot = () => this.store.get(this.key);
90
+ subscribe = (listener) => {
91
+ this.listeners.add(listener);
92
+ return () => {
93
+ this.listeners.delete(listener);
94
+ };
95
+ };
96
+ publish() {
97
+ const next = this.getSnapshot();
98
+ if (this.published === next) return;
99
+ this.published = next;
100
+ (0, _deepseek_ai_dsh_client_store.notifySubscribers)(this.listeners, `[ui-conversation] Location data ${this.key}`);
101
+ }
102
+ };
79
103
  var MutableLocationDataStore = class {
104
+ markDirty;
80
105
  entries = /* @__PURE__ */ new Map();
106
+ sources = /* @__PURE__ */ new Map();
107
+ dirtyKeys = /* @__PURE__ */ new Set();
108
+ constructor(markDirty) {
109
+ this.markDirty = markDirty;
110
+ }
81
111
  get(key) {
82
112
  return this.entries.get(key)?.value;
83
113
  }
114
+ source(key) {
115
+ let source = this.sources.get(key);
116
+ if (source === void 0) {
117
+ source = new MutableLocationDataSource(this, key);
118
+ this.sources.set(key, source);
119
+ }
120
+ return source;
121
+ }
84
122
  remove(owner, key) {
85
123
  if (this.entries.get(key)?.owner !== owner) return false;
86
124
  this.entries.delete(key);
125
+ this.changed(key);
87
126
  return true;
88
127
  }
89
128
  set(owner, key, value) {
@@ -94,19 +133,29 @@ window.__ModuleLoader__.load({
94
133
  owner,
95
134
  value
96
135
  });
136
+ this.changed(key);
97
137
  return true;
98
138
  }
99
139
  replace(entries) {
100
- let changed = this.entries.size !== entries.size;
101
- if (!changed) for (const [key, value] of entries) {
140
+ const changedKeys = [];
141
+ for (const key of new Set([...this.entries.keys(), ...entries.keys()])) {
102
142
  const current = this.entries.get(key);
103
- if (current?.owner !== value.owner || current.value !== value.value) {
104
- changed = true;
105
- break;
106
- }
143
+ const next = entries.get(key);
144
+ if (current?.owner !== next?.owner || current?.value !== next?.value) changedKeys.push(key);
107
145
  }
108
- if (changed) this.entries = new Map(entries);
109
- return changed;
146
+ if (changedKeys.length === 0) return false;
147
+ this.entries = new Map(entries);
148
+ for (const key of changedKeys) this.changed(key);
149
+ return true;
150
+ }
151
+ publish() {
152
+ const dirty = [...this.dirtyKeys];
153
+ this.dirtyKeys.clear();
154
+ for (const key of dirty) this.sources.get(key)?.publish();
155
+ }
156
+ changed(key) {
157
+ this.dirtyKeys.add(key);
158
+ this.markDirty(this);
110
159
  }
111
160
  };
112
161
  const SESSION_LOCATION = { kind: "session" };
@@ -148,6 +197,7 @@ window.__ModuleLoader__.load({
148
197
  };
149
198
  turnDataStores = /* @__PURE__ */ new Map();
150
199
  stepDataStores = /* @__PURE__ */ new Map();
200
+ dirtyDataStores = /* @__PURE__ */ new Set();
151
201
  currentTurn;
152
202
  currentStep;
153
203
  /**
@@ -200,6 +250,12 @@ window.__ModuleLoader__.load({
200
250
  }
201
251
  return changed;
202
252
  }
253
+ /** Publish committed Location-data changes to their keyed sources. */
254
+ publishData() {
255
+ const dirty = [...this.dirtyDataStores];
256
+ this.dirtyDataStores.clear();
257
+ for (const store of dirty) store.publish();
258
+ }
203
259
  /**
204
260
  * Resolve the latest Location for one event.
205
261
  * @param event - event already ingested into this index.
@@ -444,15 +500,18 @@ window.__ModuleLoader__.load({
444
500
  return this.mutableStepData(stepDataKey(turn, step));
445
501
  }
446
502
  mutableTurnData(turn) {
447
- const current = this.turnDataStores.get(turn) ?? new MutableLocationDataStore();
503
+ const current = this.turnDataStores.get(turn) ?? this.createDataStore();
448
504
  this.turnDataStores.set(turn, current);
449
505
  return current;
450
506
  }
451
507
  mutableStepData(key) {
452
- const current = this.stepDataStores.get(key) ?? new MutableLocationDataStore();
508
+ const current = this.stepDataStores.get(key) ?? this.createDataStore();
453
509
  this.stepDataStores.set(key, current);
454
510
  return current;
455
511
  }
512
+ createDataStore() {
513
+ return new MutableLocationDataStore((store) => this.dirtyDataStores.add(store));
514
+ }
456
515
  storeFor(data) {
457
516
  return data.kind === "turn" ? this.mutableTurnData(data.turn) : this.mutableStepData(stepDataKey(data.turn, requireStep(data)));
458
517
  }
@@ -568,12 +627,15 @@ window.__ModuleLoader__.load({
568
627
  contexts = /* @__PURE__ */ new Map();
569
628
  contextsByKind = /* @__PURE__ */ new Map();
570
629
  contextsBySeq = /* @__PURE__ */ new Map();
630
+ contextsByTarget = /* @__PURE__ */ new Map();
571
631
  inputs = /* @__PURE__ */ new Map();
572
632
  locationIndex = new ConversationLocationIndex();
573
633
  dirty = /* @__PURE__ */ new Set();
634
+ dirtyByTarget = /* @__PURE__ */ new Map();
574
635
  revised = /* @__PURE__ */ new Set();
575
636
  dependents = /* @__PURE__ */ new Map();
576
637
  views = /* @__PURE__ */ new Map();
638
+ activeTargets = /* @__PURE__ */ new Set();
577
639
  hasMore = false;
578
640
  replacePending = true;
579
641
  timelineDirty = true;
@@ -596,8 +658,10 @@ window.__ModuleLoader__.load({
596
658
  this.contexts.clear();
597
659
  this.contextsByKind.clear();
598
660
  this.contextsBySeq.clear();
661
+ this.contextsByTarget.clear();
599
662
  this.inputs.clear();
600
663
  this.dirty.clear();
664
+ this.dirtyByTarget.clear();
601
665
  this.revised.clear();
602
666
  this.dependents.clear();
603
667
  this.hasMore = hasMore;
@@ -608,7 +672,7 @@ window.__ModuleLoader__.load({
608
672
  for (const entry of sorted) this.matchInput(entry);
609
673
  this.replayDependencies();
610
674
  this.revised.clear();
611
- for (const context of this.contexts.values()) this.dirty.add(context);
675
+ for (const context of this.contexts.values()) this.markDirty(context);
612
676
  this.replacePending = true;
613
677
  return "immediate";
614
678
  }
@@ -673,60 +737,73 @@ window.__ModuleLoader__.load({
673
737
  return this.replaceWindow(this.sortedInputs(), this.hasMore);
674
738
  }
675
739
  /**
676
- * Materialize dirty Contexts and advance every registered view builder.
740
+ * Materialize dirty Contexts and advance every active view builder.
677
741
  * @returns whether any view snapshot was rebuilt or incrementally applied.
678
742
  */
679
743
  flush() {
680
744
  if (!this.replacePending && this.dirty.size === 0 && !this.timelineDirty) return false;
681
745
  if (this.replacePending) {
682
746
  this.replaceLocationData();
683
- const allByTarget = /* @__PURE__ */ new Map();
684
- for (const target of this.views.keys()) allByTarget.set(target, []);
685
- for (const context of this.contexts.values()) {
686
- const target = context.definition.target;
687
- if (target === void 0 || !this.views.has(target)) continue;
688
- const node = this.buildNode(context, target);
689
- context.current.set(target, node);
690
- if (node !== null) allByTarget.get(target)?.push(node);
691
- }
692
- for (const view of this.views.values()) view.snapshot = view.builder.replace({
693
- nodes: allByTarget.get(view.target) ?? [],
694
- timeline: this.locationIndex.snapshot()
695
- });
747
+ let published = false;
748
+ for (const target of this.activeTargets) {
749
+ const view = this.views.get(target);
750
+ if (view === void 0) continue;
751
+ const builder = view.builder ?? view.definition.create();
752
+ view.builder = builder;
753
+ view.snapshot = builder.replace({
754
+ nodes: this.buildTargetNodes(target, this.contextsByTarget.get(target)),
755
+ timeline: this.locationIndex.snapshot()
756
+ });
757
+ published = true;
758
+ }
759
+ this.locationIndex.publishData();
696
760
  this.replacePending = false;
697
761
  this.dirty.clear();
762
+ this.dirtyByTarget.clear();
698
763
  this.timelineDirty = false;
699
- return true;
764
+ return published;
700
765
  }
701
- const upsertsByTarget = /* @__PURE__ */ new Map();
702
- for (const target of this.views.keys()) upsertsByTarget.set(target, []);
766
+ let published = false;
703
767
  if (this.applyDirtyLocationData()) this.timelineDirty = true;
704
- for (const context of this.dirty) {
705
- const target = context.definition.target;
706
- if (target === void 0 || !this.views.has(target)) continue;
707
- const previous = context.current.get(target) ?? null;
708
- const node = this.buildNode(context, target);
709
- if (node === null && previous !== null) throw new Error(`conversation Definition "${context.kind}" withdrew materialized target "${target}"; return the same key with hidden visibility instead`);
710
- context.current.set(target, node);
711
- if (node !== null) upsertsByTarget.get(target)?.push(node);
712
- }
713
- this.dirty.clear();
714
768
  const timelineDirty = this.timelineDirty;
715
- this.timelineDirty = false;
716
- for (const view of this.views.values()) {
717
- const upserts = upsertsByTarget.get(view.target) ?? [];
769
+ for (const target of this.activeTargets) {
770
+ const view = this.views.get(target);
771
+ if (view === void 0) continue;
772
+ const builder = view.builder;
773
+ if (builder === void 0) continue;
774
+ const upserts = this.buildTargetUpserts(target, this.dirtyByTarget.get(target));
718
775
  if (upserts.length === 0 && !timelineDirty) continue;
719
- view.snapshot = view.builder.apply({
776
+ view.snapshot = builder.apply({
720
777
  upserts,
721
778
  timeline: this.locationIndex.snapshot()
722
779
  });
780
+ published = true;
723
781
  }
782
+ this.locationIndex.publishData();
783
+ this.dirty.clear();
784
+ this.dirtyByTarget.clear();
785
+ this.timelineDirty = false;
786
+ return published;
787
+ }
788
+ /**
789
+ * Add one target to the monotonic active set and materialize its current snapshot.
790
+ * Pending Context work is flushed before the first complete replacement.
791
+ * @param target - registered or subsequently registered view target.
792
+ * @returns whether any active target snapshot changed.
793
+ */
794
+ activateTarget(target) {
795
+ const view = this.views.get(target);
796
+ if (this.activeTargets.has(target)) return false;
797
+ const published = this.flush();
798
+ this.activeTargets.add(target);
799
+ if (view === void 0) return published;
800
+ this.replaceView(view);
724
801
  return true;
725
802
  }
726
803
  /**
727
804
  * Read the latest snapshot of a registered target.
728
805
  * @param target - registered view target.
729
- * @returns target snapshot, or undefined when no builder is registered.
806
+ * @returns target snapshot, or undefined before registration or activation.
730
807
  */
731
808
  snapshot(target) {
732
809
  return this.views.get(target)?.snapshot;
@@ -736,11 +813,15 @@ window.__ModuleLoader__.load({
736
813
  }
737
814
  /**
738
815
  * Read targets whose owners classify their latest snapshot as visible activity.
739
- * @returns active target ids.
816
+ * @returns target ids contributing visible activity.
740
817
  */
741
- activeTargets() {
818
+ activityTargets() {
742
819
  const active = /* @__PURE__ */ new Set();
743
- for (const view of this.views.values()) if (view.isActive?.(view.snapshot) === true) active.add(view.target);
820
+ for (const target of this.activeTargets) {
821
+ const view = this.views.get(target);
822
+ if (view === void 0) continue;
823
+ if (view.isActive?.(view.snapshot) === true) active.add(view.target);
824
+ }
744
825
  return active;
745
826
  }
746
827
  sortedInputs() {
@@ -781,27 +862,30 @@ window.__ModuleLoader__.load({
781
862
  }
782
863
  return publication;
783
864
  }
865
+ createContext(definition, id, key) {
866
+ const context = {
867
+ key,
868
+ kind: definition.kind,
869
+ id,
870
+ definition,
871
+ startSeq: void 0,
872
+ start: void 0,
873
+ matches: [],
874
+ state: void 0,
875
+ revision: 0,
876
+ current: /* @__PURE__ */ new Map(),
877
+ locationData: emptyLocationData(),
878
+ dependencies: /* @__PURE__ */ new Map()
879
+ };
880
+ this.contexts.set(key, context);
881
+ this.indexTargetContext(context);
882
+ return context;
883
+ }
784
884
  acceptMatch(definition, id, role, input) {
785
885
  const key = conversationContextKey(definition.kind, id);
786
886
  let context = this.contexts.get(key);
787
887
  if (role === "start" && context?.start !== void 0) throw new Error(`conversation Context ${key} received more than one start Match`);
788
- if (context === void 0) {
789
- context = {
790
- key,
791
- kind: definition.kind,
792
- id,
793
- definition,
794
- startSeq: void 0,
795
- start: void 0,
796
- matches: [],
797
- state: void 0,
798
- revision: 0,
799
- current: /* @__PURE__ */ new Map(),
800
- locationData: emptyLocationData(),
801
- dependencies: /* @__PURE__ */ new Map()
802
- };
803
- this.contexts.set(key, context);
804
- }
888
+ context ??= this.createContext(definition, id, key);
805
889
  const match = conversationMatch(key, input, role, this.locationIndex.locationOf(input.event));
806
890
  const previous = context.matches.at(-1);
807
891
  if (previous !== void 0 && previous.event.seq >= input.event.seq) throw new Error(`conversation Context ${key} received non-appended Match ${input.event.seq}`);
@@ -822,7 +906,7 @@ window.__ModuleLoader__.load({
822
906
  context.revision++;
823
907
  this.revised.add(context);
824
908
  }
825
- this.dirty.add(context);
909
+ this.markDirty(context);
826
910
  return definition.publication?.(match) ?? "immediate";
827
911
  }
828
912
  applyPendingMatches(pending, affected) {
@@ -831,23 +915,7 @@ window.__ModuleLoader__.load({
831
915
  const first = entries[0];
832
916
  if (first === void 0) continue;
833
917
  let context = this.contexts.get(key);
834
- if (context === void 0) {
835
- context = {
836
- key,
837
- kind: first.definition.kind,
838
- id: first.id,
839
- definition: first.definition,
840
- startSeq: void 0,
841
- start: void 0,
842
- matches: [],
843
- state: void 0,
844
- revision: 0,
845
- current: /* @__PURE__ */ new Map(),
846
- locationData: emptyLocationData(),
847
- dependencies: /* @__PURE__ */ new Map()
848
- };
849
- this.contexts.set(key, context);
850
- }
918
+ context ??= this.createContext(first.definition, first.id, key);
851
919
  let discoveredStart;
852
920
  const additions = entries.map((entry) => {
853
921
  if (entry.definition !== context.definition || entry.id !== context.id) throw new Error(`conversation Context ${key} received inconsistent Definition identity`);
@@ -870,7 +938,7 @@ window.__ModuleLoader__.load({
870
938
  }
871
939
  if (context.start !== void 0 && context.matches[0] !== context.start) throw new Error(`conversation Context ${context.key} received an update before its start Match`);
872
940
  affected.add(context);
873
- this.dirty.add(context);
941
+ this.markDirty(context);
874
942
  }
875
943
  for (const [kind, contexts] of startsByKind) this.indexStartedContexts(kind, contexts);
876
944
  }
@@ -879,7 +947,7 @@ window.__ModuleLoader__.load({
879
947
  for (const context of ordered) {
880
948
  if (context.start === void 0) {
881
949
  context.state = void 0;
882
- this.dirty.add(context);
950
+ this.markDirty(context);
883
951
  continue;
884
952
  }
885
953
  this.replayContext(context);
@@ -905,7 +973,22 @@ window.__ModuleLoader__.load({
905
973
  }
906
974
  context.revision++;
907
975
  this.revised.add(context);
976
+ this.markDirty(context);
977
+ }
978
+ indexTargetContext(context) {
979
+ const target = context.definition.target;
980
+ if (target === void 0) return;
981
+ const contexts = this.contextsByTarget.get(target) ?? /* @__PURE__ */ new Set();
982
+ contexts.add(context);
983
+ this.contextsByTarget.set(target, contexts);
984
+ }
985
+ markDirty(context) {
908
986
  this.dirty.add(context);
987
+ const target = context.definition.target;
988
+ if (target === void 0 || !this.activeTargets.has(target)) return;
989
+ const contexts = this.dirtyByTarget.get(target) ?? /* @__PURE__ */ new Set();
990
+ contexts.add(context);
991
+ this.dirtyByTarget.set(target, contexts);
909
992
  }
910
993
  replaceDependencies(context, dependencies) {
911
994
  for (const dependency of context.dependencies.values()) {
@@ -1053,9 +1136,37 @@ window.__ModuleLoader__.load({
1053
1136
  if (node.target !== target) throw new Error(`conversation Definition "${context.kind}" returned target "${node.target}" while building "${target}"`);
1054
1137
  return node;
1055
1138
  }
1056
- buildLocationData(context, scope) {
1139
+ replaceView(view) {
1140
+ const builder = view.builder ?? view.definition.create();
1141
+ view.builder = builder;
1142
+ view.snapshot = builder.replace({
1143
+ nodes: this.buildTargetNodes(view.target, this.contextsByTarget.get(view.target)),
1144
+ timeline: this.locationIndex.snapshot()
1145
+ });
1146
+ }
1147
+ buildTargetNodes(target, contexts) {
1148
+ const nodes = [];
1149
+ for (const context of contexts ?? []) {
1150
+ const node = this.buildNode(context, target);
1151
+ context.current.set(target, node);
1152
+ if (node !== null) nodes.push(node);
1153
+ }
1154
+ return nodes;
1155
+ }
1156
+ buildTargetUpserts(target, contexts) {
1157
+ const upserts = [];
1158
+ for (const context of contexts ?? []) {
1159
+ const previous = context.current.get(target) ?? null;
1160
+ const node = this.buildNode(context, target);
1161
+ if (node === null && previous !== null) throw new Error(`conversation Definition "${context.kind}" withdrew materialized target "${target}"; return the same key with hidden visibility instead`);
1162
+ context.current.set(target, node);
1163
+ if (node !== null) upserts.push(node);
1164
+ }
1165
+ return upserts;
1166
+ }
1167
+ buildLocationData(context, scope, previous) {
1057
1168
  if (context.definition.buildLocationData === void 0) return null;
1058
- const data = context.definition.buildLocationData(contextSnapshot(context), scope);
1169
+ const data = context.definition.buildLocationData(contextSnapshot(context), scope, previous);
1059
1170
  if (data === null) return null;
1060
1171
  if (data.kind !== scope) throw new Error(`conversation Definition "${context.kind}" published ${data.kind} data through its ${scope} scope`);
1061
1172
  if (data.key !== context.kind) throw new Error(`conversation Definition "${context.kind}" published Location data key "${data.key}"; expected its owned kind`);
@@ -1067,7 +1178,7 @@ window.__ModuleLoader__.load({
1067
1178
  const entries = [];
1068
1179
  for (const scope of LOCATION_DATA_SCOPES) {
1069
1180
  for (const context of this.contexts.values()) {
1070
- const data = this.buildLocationData(context, scope);
1181
+ const data = this.buildLocationData(context, scope, context.locationData[scope]);
1071
1182
  context.locationData[scope] = data;
1072
1183
  if (data !== null) entries.push({
1073
1184
  owner: context.key,
@@ -1083,9 +1194,10 @@ window.__ModuleLoader__.load({
1083
1194
  const changes = [];
1084
1195
  for (const context of this.dirty) {
1085
1196
  const previous = context.locationData[scope];
1086
- const next = this.buildLocationData(context, scope);
1197
+ const next = this.buildLocationData(context, scope, previous);
1198
+ if (previous === next) continue;
1087
1199
  context.locationData[scope] = next;
1088
- if (previous !== next) changes.push({
1200
+ changes.push({
1089
1201
  owner: context.key,
1090
1202
  previous,
1091
1203
  next
@@ -1098,13 +1210,14 @@ window.__ModuleLoader__.load({
1098
1210
  resetViewBuilders() {
1099
1211
  this.views.clear();
1100
1212
  for (const definition of this.viewDefinitions.entries()) {
1101
- const builder = definition.create();
1102
- this.views.set(definition.target, {
1213
+ const view = {
1103
1214
  target: definition.target,
1104
- builder,
1215
+ definition,
1105
1216
  isActive: definition.isActive === void 0 ? void 0 : (snapshot) => definition.isActive?.(snapshot) === true,
1106
- snapshot: builder.empty
1107
- });
1217
+ builder: void 0,
1218
+ snapshot: void 0
1219
+ };
1220
+ this.views.set(definition.target, view);
1108
1221
  }
1109
1222
  this.replacePending = true;
1110
1223
  }
@@ -1438,19 +1551,23 @@ window.__ModuleLoader__.load({
1438
1551
  source = {
1439
1552
  getSnapshot: () => views.get(target),
1440
1553
  subscribe: (listener) => {
1441
- return this.snapshot.subscribe(listener);
1554
+ const unsubscribe = this.snapshot.subscribe(listener);
1555
+ this.activate(target);
1556
+ return unsubscribe;
1442
1557
  }
1443
1558
  };
1444
1559
  this.targetSources.set(target, source);
1445
1560
  }
1446
1561
  return source;
1447
1562
  }
1563
+ activate(target) {
1564
+ if (this.assembler.activateTarget(target)) this.snapshot.set(this.currentSnapshot());
1565
+ }
1448
1566
  rebuild() {
1449
1567
  this.publish(this.assembler.rebuildRegistry());
1450
1568
  }
1451
1569
  dispose() {
1452
- if (this.frame !== void 0 && typeof cancelAnimationFrame === "function") cancelAnimationFrame(this.frame);
1453
- this.frame = void 0;
1570
+ this.cancelFrame();
1454
1571
  this.disposeFeed();
1455
1572
  }
1456
1573
  replace(window) {
@@ -1483,20 +1600,29 @@ window.__ModuleLoader__.load({
1483
1600
  if (publication === "animation-frame" && typeof requestAnimationFrame === "function") {
1484
1601
  if (this.frame !== void 0) return;
1485
1602
  this.frame = requestAnimationFrame(() => {
1486
- this.frame = void 0;
1487
- this.flush();
1603
+ this.frame = requestAnimationFrame(() => {
1604
+ this.frame = requestAnimationFrame(() => {
1605
+ this.frame = void 0;
1606
+ this.flush();
1607
+ });
1608
+ });
1488
1609
  });
1489
1610
  return;
1490
1611
  }
1612
+ this.cancelFrame();
1491
1613
  this.flush();
1492
1614
  }
1615
+ cancelFrame() {
1616
+ if (this.frame !== void 0 && typeof cancelAnimationFrame === "function") cancelAnimationFrame(this.frame);
1617
+ this.frame = void 0;
1618
+ }
1493
1619
  flush() {
1494
1620
  if (this.assembler.flush()) this.snapshot.set(this.currentSnapshot());
1495
1621
  }
1496
1622
  currentSnapshot() {
1497
1623
  return {
1498
1624
  views: this.viewStore,
1499
- activeTargets: this.assembler.activeTargets()
1625
+ activeTargets: this.assembler.activityTargets()
1500
1626
  };
1501
1627
  }
1502
1628
  };
@@ -1622,6 +1748,7 @@ window.__ModuleLoader__.load({
1622
1748
  //#endregion
1623
1749
  //#region lib/types/client/stores.js
1624
1750
  /** Per-session Conversation store shared by the shell body and header. */
1751
+ const CONVERSATION_STORE_KEY = "dsh.conversation";
1625
1752
  /**
1626
1753
  * Declare per-session draft persistence and View selection.
1627
1754
  * @returns the store handle.
@@ -1633,7 +1760,7 @@ window.__ModuleLoader__.load({
1633
1760
  view: null,
1634
1761
  viewRequest: null
1635
1762
  }),
1636
- persist: "dsh.conversation",
1763
+ persist: CONVERSATION_STORE_KEY,
1637
1764
  actions: {
1638
1765
  setDraft: (d, text) => {
1639
1766
  d.draft = text;
@@ -1654,6 +1781,23 @@ window.__ModuleLoader__.load({
1654
1781
  }
1655
1782
  });
1656
1783
  }
1784
+ /**
1785
+ * Read the persisted View preference before the Slot store is materialized.
1786
+ * @param sessionId - Session-scoped persistence suffix.
1787
+ * @returns the preferred View id, or null when storage has no usable value.
1788
+ */
1789
+ function readConversationViewPreference(sessionId) {
1790
+ if (typeof localStorage === "undefined") return null;
1791
+ try {
1792
+ const raw = localStorage.getItem(`${CONVERSATION_STORE_KEY}.${sessionId}`);
1793
+ if (raw === null) return null;
1794
+ const stored = JSON.parse(raw);
1795
+ if (typeof stored !== "object" || stored === null || !("view" in stored)) return null;
1796
+ return typeof stored.view === "string" ? stored.view : null;
1797
+ } catch {
1798
+ return null;
1799
+ }
1800
+ }
1657
1801
  //#endregion
1658
1802
  //#region lib/types/client/service.js
1659
1803
  /**
@@ -1801,6 +1945,7 @@ window.__ModuleLoader__.load({
1801
1945
  finishRetirement = resolve;
1802
1946
  });
1803
1947
  const submission = session.beginSubmission({
1948
+ mode,
1804
1949
  text,
1805
1950
  images: attachments.map((attachment) => ({
1806
1951
  previewUrl: attachment.previewUrl,
@@ -13177,7 +13322,6 @@ window.__ModuleLoader__.load({
13177
13322
  "image.tooManyPixels": "图片分辨率过大,请压缩后重试",
13178
13323
  "image.dimensionTooLarge": "图片宽高不能超过 {size}px,请缩小后重试",
13179
13324
  "image.modelUnsupported": "当前模型不支持图片,请切换支持图片的模型",
13180
- "image.subagentUnsupported": "子智能体会话暂不支持图片",
13181
13325
  "image.sendFailed": "图片发送失败({reason}),请重新添加图片后再试",
13182
13326
  "context.aria": "上下文已用 {percent}",
13183
13327
  "context.used": "上下文已用",
@@ -13189,7 +13333,7 @@ window.__ModuleLoader__.load({
13189
13333
  "settings.enter.queue": "排队发送",
13190
13334
  "settings.enter.steer": "插话发送",
13191
13335
  "access.preset.readOnly": "仅可查看",
13192
- "access.preset.workspaceWrite": "可写入工作区",
13336
+ "access.preset.workspaceWrite": "工作区内修改",
13193
13337
  "access.preset.fullAccess": "完全权限",
13194
13338
  "access.confirm.title": "确认启用完全权限?",
13195
13339
  "access.confirm.description": "启用完全权限后,智能体将减少确认步骤,并且可以直接执行更多操作,包括敏感操作、文件修改或外部命令。仅建议在你信任当前任务时使用。",
@@ -13263,6 +13407,7 @@ window.__ModuleLoader__.load({
13263
13407
  "web.contentTruncated": "内容已截断",
13264
13408
  "details.running": "运行中…",
13265
13409
  "queue.count": "{n} 条排队消息",
13410
+ "queue.image": "排队消息图片",
13266
13411
  "queue.edit": "编辑排队消息",
13267
13412
  "queue.edit.unsupported": "包含非文本内容,暂不支持编辑",
13268
13413
  "queue.save": "保存排队消息",
@@ -13323,7 +13468,6 @@ window.__ModuleLoader__.load({
13323
13468
  "image.tooManyPixels": "Image resolution is too high; compress it and try again",
13324
13469
  "image.dimensionTooLarge": "Image sides must be at most {size}px; downscale it and try again",
13325
13470
  "image.modelUnsupported": "The current model does not support images; switch to a model that does",
13326
- "image.subagentUnsupported": "Subagent sessions do not support images yet",
13327
13471
  "image.sendFailed": "Sending images failed ({reason}); re-add them and try again",
13328
13472
  "context.aria": "{percent} of context used",
13329
13473
  "context.used": "of context used",
@@ -13409,6 +13553,7 @@ window.__ModuleLoader__.load({
13409
13553
  "web.contentTruncated": "Content truncated",
13410
13554
  "details.running": "Running…",
13411
13555
  "queue.count": "{n} queued messages",
13556
+ "queue.image": "Queued message image",
13412
13557
  "queue.edit": "Edit queued message",
13413
13558
  "queue.edit.unsupported": "Contains non-text content; editing is not supported yet",
13414
13559
  "queue.save": "Save queued message",
@@ -13433,7 +13578,7 @@ window.__ModuleLoader__.load({
13433
13578
  };
13434
13579
  //#endregion
13435
13580
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/queue/QueueDock.module.css.mjs
13436
- const css$7 = "._7yHdaG_dock{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));margin:0 auto calc(0px - var(--dsh-composer-stack-gap) - 3px);padding:0 var(--dsh-composer-dock-inset);flex:none}._7yHdaG_panel{background:var(--dsw-specific-tip);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px 12px 0 0;width:100%;padding:2px 0;position:relative;overflow:hidden}._7yHdaG_panel:after{border:1px solid var(--dsw-alias-border-l1);border-radius:inherit;content:\"\";pointer-events:none;border-bottom:none;position:absolute;inset:0}._7yHdaG_header{box-sizing:border-box;width:100%;height:36px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:8px;align-items:center;gap:10px;padding:4px 12px;display:flex}._7yHdaG_header:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_header:disabled{cursor:default}._7yHdaG_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_count{min-width:0;font-family:Inter, var(--dsw-font-family);flex:auto;font-size:13px;font-weight:500;line-height:24px}._7yHdaG_chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_list{max-height:180px;margin:0;padding:0;list-style:none;overflow-y:auto}._7yHdaG_row{box-sizing:border-box;border-radius:8px;align-items:center;gap:10px;width:100%;height:36px;padding:4px 5px 4px 12px;display:flex}._7yHdaG_row+._7yHdaG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1)}._7yHdaG_preview,._7yHdaG_editor{min-width:0;font:var(--dsw-font-xs-13);font-family:Inter, var(--dsw-font-family);flex:auto}._7yHdaG_preview{color:var(--dsw-alias-label-primary-dimmed);text-overflow:ellipsis;white-space:nowrap;word-break:break-word;overflow:hidden}._7yHdaG_editor{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);height:28px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:0 8px}._7yHdaG_editor:focus{border-color:var(--dsw-alias-state-business-primary)}._7yHdaG_actions{flex:none;align-items:center;gap:10px;display:flex}._7yHdaG_action{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;padding:0;display:grid}._7yHdaG_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7yHdaG_action:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_action:disabled{cursor:default;opacity:.45}";
13581
+ const css$7 = "._7yHdaG_dock{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));margin:0 auto calc(0px - var(--dsh-composer-stack-gap) - 3px);padding:0 var(--dsh-composer-dock-inset);flex:none}._7yHdaG_panel{background:var(--dsw-specific-tip);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px 12px 0 0;width:100%;padding:2px 0;position:relative;overflow:hidden}._7yHdaG_panel:after{border:.5px solid var(--dsw-alias-border-l1);border-radius:inherit;content:\"\";pointer-events:none;border-bottom:none;position:absolute;inset:0}._7yHdaG_header{box-sizing:border-box;width:100%;height:36px;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:8px;align-items:center;gap:10px;padding:4px 12px;display:flex}._7yHdaG_header:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_header:disabled{cursor:default}._7yHdaG_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_count{min-width:0;font-family:Inter, var(--dsw-font-family);flex:auto;font-size:13px;font-weight:500;line-height:24px}._7yHdaG_chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}._7yHdaG_list{max-height:180px;margin:0;padding:0;list-style:none;overflow-y:auto}._7yHdaG_row{box-sizing:border-box;border-radius:8px;align-items:center;gap:10px;width:100%;height:36px;padding:4px 5px 4px 12px;display:flex}._7yHdaG_row+._7yHdaG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1)}._7yHdaG_thumbs{flex:none;gap:4px;display:flex}._7yHdaG_thumb{border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);object-fit:cover;border-radius:4px;width:24px;height:24px}._7yHdaG_preview,._7yHdaG_editor{min-width:0;font:var(--dsw-font-xs-13);font-family:Inter, var(--dsw-font-family);flex:auto}._7yHdaG_preview{color:var(--dsw-alias-label-primary-dimmed);text-overflow:ellipsis;white-space:nowrap;word-break:break-word;overflow:hidden}._7yHdaG_editor{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-base);height:28px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;padding:0 8px}._7yHdaG_editor:focus{border-color:var(--dsw-alias-state-business-primary)}._7yHdaG_actions{flex:none;align-items:center;gap:10px;display:flex}._7yHdaG_action{corner-shape:round;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;padding:0;display:grid}._7yHdaG_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._7yHdaG_action:focus-visible{outline:2px solid var(--dsw-alias-label-tertiary);outline-offset:-2px}._7yHdaG_action:disabled{cursor:default;opacity:.45}";
13437
13582
  const tagId$7 = "@deepseek-ai/dsh-client-ui-conversation/QueueDock.module.css";
13438
13583
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$7) + "]") === null) {
13439
13584
  const tag = document.createElement("style");
@@ -13454,17 +13599,60 @@ window.__ModuleLoader__.load({
13454
13599
  "list": "_7yHdaG_list",
13455
13600
  "panel": "_7yHdaG_panel",
13456
13601
  "preview": "_7yHdaG_preview",
13457
- "row": "_7yHdaG_row"
13602
+ "row": "_7yHdaG_row",
13603
+ "thumb": "_7yHdaG_thumb",
13604
+ "thumbs": "_7yHdaG_thumbs"
13458
13605
  };
13459
13606
  //#endregion
13460
13607
  //#region lib/types/client/queue/QueueDock.js
13461
13608
  /**
13609
+ * Durable references carried by one queued row. Queue frames are wire data
13610
+ * despite their typed face, so an image block without a reference is skipped
13611
+ * rather than trusted.
13612
+ * @param content - the row's wire content blocks.
13613
+ * @returns the row's durable image references in block order.
13614
+ */
13615
+ function queueImageRefs(content) {
13616
+ return content.flatMap((block) => {
13617
+ if (block.type !== "image") return [];
13618
+ const { attachment } = block;
13619
+ return attachment === void 0 ? [] : [attachment];
13620
+ });
13621
+ }
13622
+ /** One durable queued image as a fixed-size thumbnail; a load failure keeps the empty placeholder. */
13623
+ function QueueThumb({ attachment, loadImage, label }) {
13624
+ const [url, setUrl] = (0, react.useState)(null);
13625
+ (0, react.useEffect)(() => {
13626
+ let alive = true;
13627
+ loadImage(attachment).then((resolved) => {
13628
+ if (alive) setUrl(resolved);
13629
+ }, () => {});
13630
+ return () => {
13631
+ alive = false;
13632
+ };
13633
+ }, [attachment, loadImage]);
13634
+ return url === null ? (0, react_jsx_runtime.jsx)("span", {
13635
+ className: QueueDock_module_css_default.thumb,
13636
+ "aria-hidden": true
13637
+ }) : (0, react_jsx_runtime.jsx)("img", {
13638
+ className: QueueDock_module_css_default.thumb,
13639
+ src: url,
13640
+ alt: label
13641
+ });
13642
+ }
13643
+ /**
13462
13644
  * Queue strip: one item renders directly; multiple items default to a
13463
13645
  * collapsible count header; an empty queue renders nothing.
13464
13646
  */
13465
- function QueueDock({ useSession, updateQueue, notify, t }) {
13647
+ function QueueDock({ useSession, updateQueue, notify, loadImage, t }) {
13466
13648
  const inbox = useSession((s) => s.queue);
13467
13649
  const queue = (0, react.useMemo)(() => inbox.filter((row) => row.placement === "queued"), [inbox]);
13650
+ const pendingSubmissions = useSession((s) => s.pendingSubmissions);
13651
+ const pendingQueue = (0, react.useMemo)(() => {
13652
+ const admitted = new Set(queue.flatMap((row) => row.rpcId === void 0 ? [] : [row.rpcId]));
13653
+ return pendingSubmissions.filter((submission) => submission.placement === "queued" && !admitted.has(submission.requestId));
13654
+ }, [pendingSubmissions, queue]);
13655
+ const rowCount = queue.length + pendingQueue.length;
13468
13656
  const running = useSession((s) => s.running);
13469
13657
  const queueMutable = useSession((s) => s.subagent === null);
13470
13658
  const [editing, setEditing] = (0, react.useState)(null);
@@ -13472,18 +13660,19 @@ window.__ModuleLoader__.load({
13472
13660
  const [collapsed, setCollapsed] = (0, react.useState)(true);
13473
13661
  const listId = (0, react.useId)();
13474
13662
  (0, react.useEffect)(() => {
13475
- if (queue.length === 0 && !collapsed) setCollapsed(true);
13663
+ if (rowCount === 0 && !collapsed) setCollapsed(true);
13476
13664
  if (editing !== null && (!queueMutable || !queue.some((row) => row.id === editing.id))) setEditing(null);
13477
13665
  }, [
13478
13666
  collapsed,
13479
13667
  editing,
13480
13668
  queue,
13481
- queueMutable
13669
+ queueMutable,
13670
+ rowCount
13482
13671
  ]);
13483
- if (queue.length === 0) return null;
13672
+ if (rowCount === 0) return null;
13484
13673
  const interactionActive = queueMutable && (editing !== null || busy !== null);
13485
13674
  const expanded = !collapsed || interactionActive;
13486
- const listVisible = queue.length === 1 || expanded;
13675
+ const listVisible = rowCount === 1 || expanded;
13487
13676
  const applyAction = async (itemId, action, failure) => {
13488
13677
  setBusy(itemId);
13489
13678
  try {
@@ -13511,7 +13700,7 @@ window.__ModuleLoader__.load({
13511
13700
  "data-queue-dock": "",
13512
13701
  children: (0, react_jsx_runtime.jsxs)("div", {
13513
13702
  className: QueueDock_module_css_default.panel,
13514
- children: [queue.length > 1 && (0, react_jsx_runtime.jsxs)("button", {
13703
+ children: [rowCount > 1 && (0, react_jsx_runtime.jsxs)("button", {
13515
13704
  type: "button",
13516
13705
  className: QueueDock_module_css_default.header,
13517
13706
  "aria-controls": listId,
@@ -13528,7 +13717,7 @@ window.__ModuleLoader__.load({
13528
13717
  }),
13529
13718
  (0, react_jsx_runtime.jsx)("span", {
13530
13719
  className: QueueDock_module_css_default.count,
13531
- children: t("queue.count", { n: queue.length })
13720
+ children: t("queue.count", { n: rowCount })
13532
13721
  }),
13533
13722
  (0, react_jsx_runtime.jsx)("span", {
13534
13723
  className: QueueDock_module_css_default.chevron,
@@ -13536,130 +13725,162 @@ window.__ModuleLoader__.load({
13536
13725
  children: expanded ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutline14, {})
13537
13726
  })
13538
13727
  ]
13539
- }), (0, react_jsx_runtime.jsx)("ul", {
13728
+ }), (0, react_jsx_runtime.jsxs)("ul", {
13540
13729
  id: listId,
13541
13730
  className: QueueDock_module_css_default.list,
13542
13731
  hidden: !listVisible,
13543
- children: listVisible && queue.map((row) => (0, react_jsx_runtime.jsxs)("li", {
13544
- className: QueueDock_module_css_default.row,
13545
- children: [
13546
- queue.length === 1 && (0, react_jsx_runtime.jsx)("span", {
13547
- className: QueueDock_module_css_default.lead,
13548
- "aria-hidden": true,
13549
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutline14, {})
13550
- }),
13551
- editing?.id === row.id ? (0, react_jsx_runtime.jsx)("input", {
13552
- autoFocus: true,
13553
- className: QueueDock_module_css_default.editor,
13554
- "aria-label": t("queue.edit"),
13555
- value: editing.text,
13556
- onChange: (event) => {
13557
- setEditing({
13558
- id: row.id,
13559
- text: event.currentTarget.value
13560
- });
13561
- },
13562
- onKeyDown: (event) => {
13563
- if (event.key === "Escape") {
13564
- setEditing(null);
13565
- return;
13566
- }
13567
- if (event.key === "Enter" && !event.nativeEvent.isComposing) {
13568
- event.preventDefault();
13569
- saveEdit();
13570
- }
13571
- }
13572
- }) : (0, react_jsx_runtime.jsx)("span", {
13573
- className: QueueDock_module_css_default.preview,
13574
- children: (0, _deepseek_ai_dsh_client_ui_primitives.projectUserText)(row.preview, [])
13575
- }),
13576
- queueMutable && (0, react_jsx_runtime.jsx)("div", {
13577
- className: QueueDock_module_css_default.actions,
13578
- children: editing?.id === row.id ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13579
- label: t("queue.save"),
13580
- side: "bottom",
13581
- delayMs: 500,
13582
- children: (0, react_jsx_runtime.jsx)("button", {
13583
- type: "button",
13584
- className: QueueDock_module_css_default.action,
13585
- "aria-label": t("queue.save"),
13586
- disabled: busy !== null || editing.text.trim() === "",
13587
- onClick: () => {
13588
- saveEdit();
13589
- },
13590
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, { size: 14 })
13591
- })
13592
- }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13593
- label: t("queue.cancelEdit"),
13594
- side: "bottom",
13595
- delayMs: 500,
13596
- children: (0, react_jsx_runtime.jsx)("button", {
13597
- type: "button",
13598
- className: QueueDock_module_css_default.action,
13599
- "aria-label": t("queue.cancelEdit"),
13600
- disabled: busy !== null,
13601
- onClick: () => {
13732
+ children: [listVisible && queue.map((row) => {
13733
+ const imageRefs = queueImageRefs(row.content);
13734
+ return (0, react_jsx_runtime.jsxs)("li", {
13735
+ className: QueueDock_module_css_default.row,
13736
+ children: [
13737
+ rowCount === 1 && (0, react_jsx_runtime.jsx)("span", {
13738
+ className: QueueDock_module_css_default.lead,
13739
+ "aria-hidden": true,
13740
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutline14, {})
13741
+ }),
13742
+ editing?.id === row.id ? (0, react_jsx_runtime.jsx)("input", {
13743
+ autoFocus: true,
13744
+ className: QueueDock_module_css_default.editor,
13745
+ "aria-label": t("queue.edit"),
13746
+ value: editing.text,
13747
+ onChange: (event) => {
13748
+ setEditing({
13749
+ id: row.id,
13750
+ text: event.currentTarget.value
13751
+ });
13752
+ },
13753
+ onKeyDown: (event) => {
13754
+ if (event.key === "Escape") {
13602
13755
  setEditing(null);
13603
- },
13604
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
13605
- })
13606
- })] }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13607
- (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13608
- label: t("queue.edit"),
13756
+ return;
13757
+ }
13758
+ if (event.key === "Enter" && !event.nativeEvent.isComposing) {
13759
+ event.preventDefault();
13760
+ saveEdit();
13761
+ }
13762
+ }
13763
+ }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [imageRefs.length > 0 && (0, react_jsx_runtime.jsx)("span", {
13764
+ className: QueueDock_module_css_default.thumbs,
13765
+ children: imageRefs.map((attachment, index) => (0, react_jsx_runtime.jsx)(QueueThumb, {
13766
+ attachment,
13767
+ loadImage,
13768
+ label: t("queue.image")
13769
+ }, `${attachment.attachmentId}:${index}`))
13770
+ }), (0, react_jsx_runtime.jsx)("span", {
13771
+ className: QueueDock_module_css_default.preview,
13772
+ children: (0, _deepseek_ai_dsh_client_ui_primitives.projectUserText)(row.preview, [])
13773
+ })] }),
13774
+ queueMutable && (0, react_jsx_runtime.jsx)("div", {
13775
+ className: QueueDock_module_css_default.actions,
13776
+ children: editing?.id === row.id ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13777
+ label: t("queue.save"),
13609
13778
  side: "bottom",
13610
13779
  delayMs: 500,
13611
- disabled: row.text === null,
13612
13780
  children: (0, react_jsx_runtime.jsx)("button", {
13613
13781
  type: "button",
13614
13782
  className: QueueDock_module_css_default.action,
13615
- "aria-label": t("queue.edit"),
13616
- title: row.text === null ? t("queue.edit.unsupported") : void 0,
13617
- disabled: busy !== null || row.text === null,
13783
+ "aria-label": t("queue.save"),
13784
+ disabled: busy !== null || editing.text.trim() === "",
13618
13785
  onClick: () => {
13619
- if (row.text !== null) setEditing({
13620
- id: row.id,
13621
- text: row.text
13622
- });
13786
+ saveEdit();
13623
13787
  },
13624
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 })
13788
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, { size: 14 })
13625
13789
  })
13626
- }),
13627
- (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13628
- label: t("queue.remove"),
13790
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13791
+ label: t("queue.cancelEdit"),
13629
13792
  side: "bottom",
13630
13793
  delayMs: 500,
13631
13794
  children: (0, react_jsx_runtime.jsx)("button", {
13632
13795
  type: "button",
13633
13796
  className: QueueDock_module_css_default.action,
13634
- "aria-label": t("queue.remove"),
13797
+ "aria-label": t("queue.cancelEdit"),
13635
13798
  disabled: busy !== null,
13636
13799
  onClick: () => {
13637
- applyAction(row.id, { kind: "remove" }, t("queue.removeFailed"));
13800
+ setEditing(null);
13638
13801
  },
13639
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, { size: 14 })
13802
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
13640
13803
  })
13641
- }),
13642
- (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13643
- label: t("queue.steer"),
13644
- side: "bottom",
13645
- delayMs: 500,
13646
- disabled: !running,
13647
- children: (0, react_jsx_runtime.jsx)("button", {
13648
- type: "button",
13649
- className: QueueDock_module_css_default.action,
13650
- "aria-label": t("queue.steer"),
13651
- title: running ? void 0 : t("queue.steer.unavailable"),
13652
- disabled: busy !== null || !running,
13653
- onClick: () => {
13654
- applyAction(row.id, { kind: "steer" }, t("queue.steerFailed"));
13655
- },
13656
- children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline14, {})
13804
+ })] }) : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
13805
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13806
+ label: t("queue.edit"),
13807
+ side: "bottom",
13808
+ delayMs: 500,
13809
+ disabled: row.text === null,
13810
+ children: (0, react_jsx_runtime.jsx)("button", {
13811
+ type: "button",
13812
+ className: QueueDock_module_css_default.action,
13813
+ "aria-label": t("queue.edit"),
13814
+ title: row.text === null ? t("queue.edit.unsupported") : void 0,
13815
+ disabled: busy !== null || row.text === null,
13816
+ onClick: () => {
13817
+ if (row.text !== null) setEditing({
13818
+ id: row.id,
13819
+ text: row.text
13820
+ });
13821
+ },
13822
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 })
13823
+ })
13824
+ }),
13825
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13826
+ label: t("queue.remove"),
13827
+ side: "bottom",
13828
+ delayMs: 500,
13829
+ children: (0, react_jsx_runtime.jsx)("button", {
13830
+ type: "button",
13831
+ className: QueueDock_module_css_default.action,
13832
+ "aria-label": t("queue.remove"),
13833
+ disabled: busy !== null,
13834
+ onClick: () => {
13835
+ applyAction(row.id, { kind: "remove" }, t("queue.removeFailed"));
13836
+ },
13837
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, { size: 14 })
13838
+ })
13839
+ }),
13840
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
13841
+ label: t("queue.steer"),
13842
+ side: "bottom",
13843
+ delayMs: 500,
13844
+ disabled: !running,
13845
+ children: (0, react_jsx_runtime.jsx)("button", {
13846
+ type: "button",
13847
+ className: QueueDock_module_css_default.action,
13848
+ "aria-label": t("queue.steer"),
13849
+ title: running ? void 0 : t("queue.steer.unavailable"),
13850
+ disabled: busy !== null || !running,
13851
+ onClick: () => {
13852
+ applyAction(row.id, { kind: "steer" }, t("queue.steerFailed"));
13853
+ },
13854
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSendOutline14, {})
13855
+ })
13657
13856
  })
13658
- })
13659
- ] })
13857
+ ] })
13858
+ })
13859
+ ]
13860
+ }, row.id);
13861
+ }), listVisible && pendingQueue.map((submission) => (0, react_jsx_runtime.jsxs)("li", {
13862
+ className: QueueDock_module_css_default.row,
13863
+ "data-submission-echo": "",
13864
+ children: [
13865
+ rowCount === 1 && (0, react_jsx_runtime.jsx)("span", {
13866
+ className: QueueDock_module_css_default.lead,
13867
+ "aria-hidden": true,
13868
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutline14, {})
13869
+ }),
13870
+ submission.images.length > 0 && (0, react_jsx_runtime.jsx)("span", {
13871
+ className: QueueDock_module_css_default.thumbs,
13872
+ children: submission.images.map((image, index) => (0, react_jsx_runtime.jsx)("img", {
13873
+ className: QueueDock_module_css_default.thumb,
13874
+ src: image.previewUrl,
13875
+ alt: t("queue.image")
13876
+ }, `${image.previewUrl}:${index}`))
13877
+ }),
13878
+ (0, react_jsx_runtime.jsx)("span", {
13879
+ className: QueueDock_module_css_default.preview,
13880
+ children: (0, _deepseek_ai_dsh_client_ui_primitives.projectUserText)(submission.text, [])
13660
13881
  })
13661
13882
  ]
13662
- }, row.id))
13883
+ }, submission.requestId))]
13663
13884
  })]
13664
13885
  })
13665
13886
  });
@@ -13670,7 +13891,8 @@ window.__ModuleLoader__.load({
13670
13891
  inject: [
13671
13892
  "slots",
13672
13893
  "conversation",
13673
- "sessions"
13894
+ "sessions",
13895
+ "uiConversation"
13674
13896
  ],
13675
13897
  apply(ctx) {
13676
13898
  ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
@@ -13687,7 +13909,8 @@ window.__ModuleLoader__.load({
13687
13909
  updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),
13688
13910
  notify: (level, text) => {
13689
13911
  conversation.input.for(actx).notify(level, text);
13690
- }
13912
+ },
13913
+ loadImage: (attachment) => ctx.uiConversation.imageUrl(sessionId, attachment)
13691
13914
  };
13692
13915
  }
13693
13916
  }, QueueDock));
@@ -13695,7 +13918,7 @@ window.__ModuleLoader__.load({
13695
13918
  };
13696
13919
  //#endregion
13697
13920
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/settings/EnterBehaviorRow.module.css.mjs
13698
- const css$6 = ".T1PP_q_row{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.T1PP_q_rowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.T1PP_q_title{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.T1PP_q_desc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.T1PP_q_selector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.T1PP_q_selector:hover{background:var(--dsw-alias-interactive-bg-hover)}.T1PP_q_chevron{flex:none}";
13921
+ const css$6 = ".T1PP_q_row{border-bottom:.5px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.T1PP_q_rowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.T1PP_q_title{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.T1PP_q_desc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.T1PP_q_selector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.T1PP_q_selector:hover{background:var(--dsw-alias-interactive-bg-hover)}.T1PP_q_chevron{flex:none}";
13699
13922
  const tagId$6 = "@deepseek-ai/dsh-client-ui-conversation/EnterBehaviorRow.module.css";
13700
13923
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$6) + "]") === null) {
13701
13924
  const tag = document.createElement("style");
@@ -13802,7 +14025,7 @@ window.__ModuleLoader__.load({
13802
14025
  }
13803
14026
  //#endregion
13804
14027
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/HeroShell.module.css.mjs
13805
- const css$5 = ".pXSMma_root{justify-content:center;align-items:center;min-width:0;height:100%;padding:0 24px;display:flex}.pXSMma_stack{width:100%;max-width:var(--dsh-composer-card-max-width);flex-direction:column;align-items:stretch;gap:12px;display:flex;overflow:visible}.pXSMma_headline{color:var(--dsw-alias-label-primary);grid-template-columns:34px auto auto;justify-content:center;align-items:center;column-gap:10px;font-size:26px;font-weight:500;line-height:32px;display:grid}.pXSMma_headlineText{grid-area:1/2}.pXSMma_previewBadge{border:1px solid var(--dsw-alias-interactive-bg-hover);background:var(--dsw-alias-state-business-tertiary);color:var(--dsw-alias-label-primary-bluish);font-family:var(--ds-font-family-code);white-space:nowrap;border-radius:24px;grid-area:1/3;align-self:start;margin-top:2px;margin-left:-3px;padding:1px 7px 0;font-size:12px;font-weight:500;line-height:18px}.pXSMma_fishHitbox{grid-area:1/1;justify-content:center;align-items:center;display:inline-flex}.pXSMma_fish{transform-origin:50% 60%;color:var(--dsw-alias-label-primary);display:block;overflow:visible}@keyframes pXSMma_hero-fish-swim{0%,to{transform:none}35%{transform:rotate(-4deg)translate(-.4px,-.9px)}70%{transform:rotate(1.6deg)translate(.3px,.2px)}}@media (hover:hover) and (prefers-reduced-motion:no-preference){.pXSMma_fishHitbox:hover .pXSMma_fish{animation:1.6s ease-in-out infinite pXSMma_hero-fish-swim}}.pXSMma_body{flex-direction:column;gap:12px;min-width:0;display:flex;position:relative;overflow:visible}.pXSMma_body>*{z-index:1;position:relative}.pXSMma_body>.pXSMma_workspaceRow{z-index:10;align-items:center;min-width:0;padding-left:8px;display:flex}.pXSMma_workspace{max-width:min(100%,360px);min-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:16px;align-items:center;gap:4px;padding:0 8px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.pXSMma_workspace:not(:disabled):hover,.pXSMma_workspace[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.pXSMma_workspace:disabled{cursor:default}.pXSMma_folder{color:var(--dsw-alias-label-primary);flex:none}.pXSMma_workspaceLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.pXSMma_chevron{color:var(--dsw-alias-label-caption);flex:none}.pXSMma_modalInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;height:44px;color:var(--dsw-alias-label-primary);background:0 0;border-radius:22px;outline:none;padding:7px 14px;font-size:14px;font-weight:400;line-height:22px}.pXSMma_modalInput::placeholder{color:var(--dsw-alias-label-caption)}.pXSMma_modalInput:disabled{color:var(--dsw-alias-label-dimmed)}.pXSMma_modalAction{min-width:72px}.pXSMma_modalError{color:var(--dsw-alias-state-error-primary);margin-top:8px;font-size:12px;line-height:18px}";
14028
+ const css$5 = ".pXSMma_root{justify-content:center;align-items:center;min-width:0;height:100%;padding:0 24px;display:flex}.pXSMma_stack{width:100%;max-width:var(--dsh-composer-card-max-width);flex-direction:column;align-items:stretch;gap:12px;display:flex;overflow:visible}.pXSMma_headline{color:var(--dsw-alias-label-primary);grid-template-columns:34px auto auto;justify-content:center;align-items:center;column-gap:10px;font-size:26px;font-weight:500;line-height:32px;display:grid}.pXSMma_headlineText{grid-area:1/2}.pXSMma_previewBadge{border:.5px solid var(--dsw-alias-interactive-bg-hover);background:var(--dsw-alias-state-business-tertiary);color:var(--dsw-alias-label-primary-bluish);font-family:var(--ds-font-family-code);white-space:nowrap;border-radius:24px;grid-area:1/3;align-self:start;margin-top:2px;margin-left:-3px;padding:1px 7px 0;font-size:12px;font-weight:500;line-height:18px}.pXSMma_fishHitbox{grid-area:1/1;justify-content:center;align-items:center;display:inline-flex}.pXSMma_fish{transform-origin:50% 60%;color:var(--dsw-alias-label-primary);display:block;overflow:visible}@keyframes pXSMma_hero-fish-swim{0%,to{transform:none}35%{transform:rotate(-4deg)translate(-.4px,-.9px)}70%{transform:rotate(1.6deg)translate(.3px,.2px)}}@media (hover:hover) and (prefers-reduced-motion:no-preference){.pXSMma_fishHitbox:hover .pXSMma_fish{animation:1.6s ease-in-out infinite pXSMma_hero-fish-swim}}.pXSMma_body{flex-direction:column;gap:12px;min-width:0;display:flex;position:relative;overflow:visible}.pXSMma_body>*{z-index:1;position:relative}.pXSMma_body>.pXSMma_workspaceRow{z-index:10;align-items:center;min-width:0;padding-left:8px;display:flex}.pXSMma_workspace{max-width:min(100%,360px);min-height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:16px;align-items:center;gap:4px;padding:0 8px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.pXSMma_workspace:not(:disabled):hover,.pXSMma_workspace[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.pXSMma_workspace:disabled{cursor:default}.pXSMma_folder{color:var(--dsw-alias-label-primary);flex:none}.pXSMma_workspaceLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.pXSMma_chevron{color:var(--dsw-alias-label-caption);flex:none}.pXSMma_modalInput{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:44px;color:var(--dsw-alias-label-primary);background:0 0;border-radius:22px;outline:none;padding:7px 14px;font-size:14px;font-weight:400;line-height:22px}.pXSMma_modalInput::placeholder{color:var(--dsw-alias-label-caption)}.pXSMma_modalInput:disabled{color:var(--dsw-alias-label-dimmed)}.pXSMma_modalAction{min-width:72px}.pXSMma_modalError{color:var(--dsw-alias-state-error-primary);margin-top:8px;font-size:12px;line-height:18px}";
13806
14029
  const tagId$5 = "@deepseek-ai/dsh-client-ui-conversation/HeroShell.module.css";
13807
14030
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$5) + "]") === null) {
13808
14031
  const tag = document.createElement("style");
@@ -13959,7 +14182,7 @@ window.__ModuleLoader__.load({
13959
14182
  }
13960
14183
  //#endregion
13961
14184
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css.mjs
13962
- const css$4 = ".wSkVaW_root{background:var(--dsw-alias-bg-base);--dsh-chat-content-width:var(--dsh-chat-user-width,clamp(680px, calc(var(--dsh-conversation-column-width,0px) * .64), 920px));--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:16px;--dsh-composer-dock-inset:8px;flex-direction:column;min-width:0;height:100%;display:flex;position:relative}.wSkVaW_header{border-bottom:1px solid #0000;flex:none;padding:12px 28px 0 20px;position:relative}.wSkVaW_header:after{content:\"\";z-index:0;background:var(--dsw-alias-border-l2);pointer-events:none;height:1px;position:absolute;bottom:1px;left:0;right:0}.wSkVaW_headerHidden{display:none}.wSkVaW_titleRow{align-items:center;gap:0;min-height:32px;display:flex}.wSkVaW_titleCluster{flex:1;align-items:center;gap:10px;min-width:0;display:flex}.wSkVaW_crumbs{white-space:nowrap;align-items:center;gap:4px;min-width:0;display:flex;overflow:hidden}.wSkVaW_crumbSeg{align-items:center;gap:4px;min-width:0;display:inline-flex}.wSkVaW_crumbSep{color:var(--dsw-alias-label-caption);font-size:14px;line-height:20px}.wSkVaW_crumb{max-width:220px;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:12px;padding:4px 8px;font-size:14px;line-height:20px;overflow:hidden}.wSkVaW_crumbSubagent{font-size:12px;line-height:18px}.wSkVaW_crumb:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.wSkVaW_crumbCurrent{color:var(--dsw-alias-label-primary);cursor:default;font-weight:500}.wSkVaW_headerActions{flex:none;align-items:center;gap:8px;display:flex}.wSkVaW_headerUtilities{flex:none;align-items:center;gap:8px;margin-left:20px;display:flex}.wSkVaW_headerUtilities:empty{display:none}.wSkVaW_tabs{z-index:1;gap:36px;margin-top:4px;padding-left:8px;display:flex;position:relative}.wSkVaW_tab{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:0 0 11px;font-size:13px;font-weight:500;line-height:16px;position:relative}.wSkVaW_tab:after{content:\"\";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:1px;left:0;right:0}.wSkVaW_tabActive{color:var(--dsw-alias-state-business-primary)}.wSkVaW_tabActive:after{background:var(--dsw-alias-state-business-primary)}.wSkVaW_viewArea{flex-direction:column;flex:1;min-height:0;display:flex}.wSkVaW_widthHandle{z-index:8;width:min(40px, calc((100% - var(--dsh-chat-content-width)) / 2 - 24px - 24px));cursor:col-resize;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]{right:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle[data-side=right]{left:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle:after{content:\"\";background:linear-gradient(to bottom, transparent calc(var(--dsh-width-handle-pointer-y,50%) - 52px), var(--dsw-alias-scrollbar-hover-l1) calc(var(--dsh-width-handle-pointer-y,50%) - 12px), var(--dsw-alias-scrollbar-hover-l1) calc(var(--dsh-width-handle-pointer-y,50%) + 12px), transparent calc(var(--dsh-width-handle-pointer-y,50%) + 52px));opacity:0;pointer-events:none;border-radius:3px;width:3px;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]:after{right:16px}.wSkVaW_widthHandle[data-side=right]:after{left:16px}.wSkVaW_widthHandle:hover:after,.wSkVaW_widthHandle[data-dragging]:after{opacity:1}.wSkVaW_root:has([data-conversation-composer-overlay]) .wSkVaW_widthHandle{display:none}.wSkVaW_composerStack{--dsh-composer-stack-gap:6px;gap:var(--dsh-composer-stack-gap);flex-direction:column;display:flex}.wSkVaW_composerSeat{--dsh-composer-text-max-height:336px;flex-direction:column;flex:none;display:flex}.wSkVaW_root[data-phase=active]{overflow:hidden}.wSkVaW_root[data-phase=active] .wSkVaW_header{flex:none}.wSkVaW_body{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.wSkVaW_scrollBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;display:flex;overflow-y:auto}.wSkVaW_root[data-phase=active] .wSkVaW_viewArea{flex:1 0 auto;min-height:auto}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat{z-index:7;background:linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-base) 0%, transparent) 0px, var(--dsw-alias-bg-base) 36px);position:sticky;bottom:0}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat:has([data-trigger-menu]){z-index:9}.wSkVaW_scrollBody:has([data-conversation-composer-overlay]){scrollbar-gutter:auto;position:relative;overflow:hidden auto}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>[data-slot=conversation\\.session]>.wSkVaW_viewArea{flex:1 1 0;min-height:0;overflow:hidden}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>.wSkVaW_composerSeat{right:var(--dsh-scrollbar-width);position:absolute;bottom:0;left:0}.wSkVaW_composerHero{width:min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance)), 100%);z-index:1;align-self:center;gap:8px;padding-bottom:32px}.wSkVaW_heroWorkspaceRow{align-items:center;gap:2px;min-width:0;margin-top:4px;padding-left:20px;display:flex}.wSkVaW_root[data-phase=hero] .wSkVaW_scrollBody{justify-content:center;overflow-y:auto}.wSkVaW_root[data-phase=settling] .wSkVaW_composerSeat{visibility:hidden}";
14185
+ const css$4 = ".wSkVaW_root{background:var(--dsw-alias-bg-base);--dsh-chat-content-width:var(--dsh-chat-user-width,clamp(680px, calc(var(--dsh-conversation-column-width,0px) * .64), 920px));--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:16px;--dsh-composer-dock-inset:8px;flex-direction:column;min-width:0;height:100%;display:flex;position:relative}.wSkVaW_header{border-bottom:1px solid #0000;flex:none;padding:12px 28px 0 20px;position:relative}.wSkVaW_header:after{content:\"\";z-index:0;background:var(--dsw-alias-border-l3);pointer-events:none;height:.5px;position:absolute;bottom:1px;left:0;right:0}.wSkVaW_headerHidden{display:none}.wSkVaW_titleRow{align-items:center;gap:0;min-height:32px;display:flex}.wSkVaW_titleCluster{flex:1;align-items:center;gap:10px;min-width:0;display:flex}.wSkVaW_crumbs{white-space:nowrap;align-items:center;gap:4px;min-width:0;display:flex;overflow:hidden}.wSkVaW_crumbSeg{align-items:center;gap:4px;min-width:0;display:inline-flex}.wSkVaW_crumbSep{color:var(--dsw-alias-label-caption);font-size:14px;line-height:20px}.wSkVaW_crumb{max-width:220px;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:12px;padding:4px 8px;font-size:14px;line-height:20px;overflow:hidden}.wSkVaW_crumbSubagent{font-size:12px;line-height:18px}.wSkVaW_crumb:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.wSkVaW_crumbCurrent{color:var(--dsw-alias-label-primary);cursor:default;font-weight:500}.wSkVaW_headerActions{flex:none;align-items:center;gap:8px;display:flex}.wSkVaW_headerUtilities{flex:none;align-items:center;gap:8px;margin-left:20px;display:flex}.wSkVaW_headerUtilities:empty{display:none}.wSkVaW_tabs{z-index:1;gap:36px;margin-top:4px;padding-left:8px;display:flex;position:relative}.wSkVaW_tab{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:0 0 11px;font-size:13px;font-weight:500;line-height:16px;position:relative}.wSkVaW_tab:after{content:\"\";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:1px;left:0;right:0}.wSkVaW_tabActive{color:var(--dsw-alias-state-business-primary)}.wSkVaW_tabActive:after{background:var(--dsw-alias-state-business-primary)}.wSkVaW_viewArea{flex-direction:column;flex:1;min-height:0;display:flex}.wSkVaW_widthHandle{z-index:8;width:min(40px, calc((100% - var(--dsh-chat-content-width)) / 2 - 24px - 24px));cursor:col-resize;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]{right:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle[data-side=right]{left:calc(50% + var(--dsh-chat-content-width) / 2 + 24px)}.wSkVaW_widthHandle:after{content:\"\";background:linear-gradient(to bottom, transparent calc(var(--dsh-width-handle-pointer-y,50%) - 52px), var(--dsw-alias-scrollbar-hover-l1) calc(var(--dsh-width-handle-pointer-y,50%) - 12px), var(--dsw-alias-scrollbar-hover-l1) calc(var(--dsh-width-handle-pointer-y,50%) + 12px), transparent calc(var(--dsh-width-handle-pointer-y,50%) + 52px));opacity:0;pointer-events:none;border-radius:3px;width:3px;position:absolute;top:0;bottom:0}.wSkVaW_widthHandle[data-side=left]:after{right:16px}.wSkVaW_widthHandle[data-side=right]:after{left:16px}.wSkVaW_widthHandle:hover:after,.wSkVaW_widthHandle[data-dragging]:after{opacity:1}.wSkVaW_root:has([data-conversation-composer-overlay]) .wSkVaW_widthHandle{display:none}.wSkVaW_composerStack{--dsh-composer-stack-gap:6px;gap:var(--dsh-composer-stack-gap);flex-direction:column;display:flex}.wSkVaW_composerSeat{--dsh-composer-text-max-height:336px;flex-direction:column;flex:none;display:flex}.wSkVaW_root[data-phase=active]{overflow:hidden}.wSkVaW_root[data-phase=active] .wSkVaW_header{flex:none}.wSkVaW_body{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.wSkVaW_scrollBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;display:flex;overflow-y:auto}.wSkVaW_root[data-phase=active] .wSkVaW_viewArea{flex:1 0 auto;min-height:auto}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat{z-index:7;background:linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-base) 0%, transparent) 0px, var(--dsw-alias-bg-base) 36px);position:sticky;bottom:0}.wSkVaW_root[data-phase=active] .wSkVaW_composerSeat:has([data-trigger-menu]){z-index:9}.wSkVaW_scrollBody:has([data-conversation-composer-overlay]){scrollbar-gutter:auto;position:relative;overflow:hidden auto}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>[data-slot=conversation\\.session]>.wSkVaW_viewArea{flex:1 1 0;min-height:0;overflow:hidden}.wSkVaW_scrollBody:has([data-conversation-composer-overlay])>.wSkVaW_composerSeat{right:var(--dsh-scrollbar-width);position:absolute;bottom:0;left:0}.wSkVaW_composerHero{width:min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance)), 100%);z-index:1;align-self:center;gap:8px;padding-bottom:32px}.wSkVaW_heroWorkspaceRow{align-items:center;gap:2px;min-width:0;margin-top:4px;padding-left:20px;display:flex}.wSkVaW_root[data-phase=hero] .wSkVaW_scrollBody{justify-content:center;overflow-y:auto}.wSkVaW_root[data-phase=settling] .wSkVaW_composerSeat{visibility:hidden}";
13963
14186
  const tagId$4 = "@deepseek-ai/dsh-client-ui-conversation/ConversationRoot.module.css";
13964
14187
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
13965
14188
  const tag = document.createElement("style");
@@ -14223,11 +14446,7 @@ window.__ModuleLoader__.load({
14223
14446
  } : !inert && composerBlock !== void 0 ? {
14224
14447
  blocked: composerBlock,
14225
14448
  placeholder: composerBlock.reason
14226
- } : hero ? { placeholder: t("placeholder.hero") } : {},
14227
- overlay: sessionId === void 0 ? void 0 : renderSlot("conversation.input.overlay", {}),
14228
- leftItems: zone === void 0 ? null : renderSlot("conversation.input.left", zone),
14229
- rightItems: zone === void 0 ? null : renderSlot("conversation.input.right", zone),
14230
- footer: !hero && zone !== void 0 ? renderSlot("conversation.composer.dock", zone) : null
14449
+ } : hero ? { placeholder: t("placeholder.hero") } : {}
14231
14450
  });
14232
14451
  const composerBar = (0, react_jsx_runtime.jsxs)("div", {
14233
14452
  className: clsx(ConversationRoot_module_css_default.composerStack, hero && ConversationRoot_module_css_default.composerHero),
@@ -14278,13 +14497,20 @@ window.__ModuleLoader__.load({
14278
14497
  });
14279
14498
  }
14280
14499
  //#endregion
14281
- //#region lib/types/client/skeleton/ConversationSession.js
14282
- /** Strict per-session header/body content inserted into the resident conversation layout. */
14500
+ //#region lib/types/client/view-selection.js
14283
14501
  const DEFAULT_VIEW_ID = "chat";
14284
- /** Resolve a persisted selection, then registered Chat, without choosing another View. */
14502
+ /**
14503
+ * Resolve a preferred registered View, then Chat, without choosing another View.
14504
+ * @param tabs - currently registered Views.
14505
+ * @param selectedId - preferred View identity, when one is stored.
14506
+ * @returns the selected View, Chat fallback, or undefined when neither is registered.
14507
+ */
14285
14508
  function resolveActiveView(tabs, selectedId) {
14286
14509
  return (selectedId === null ? void 0 : tabs.find((view) => view.id === selectedId)) ?? tabs.find((view) => view.id === DEFAULT_VIEW_ID);
14287
14510
  }
14511
+ //#endregion
14512
+ //#region lib/types/client/skeleton/ConversationSession.js
14513
+ /** Strict per-session header/body content inserted into the resident conversation layout. */
14288
14514
  function deriveAncestry(list, id) {
14289
14515
  const chain = [];
14290
14516
  const seen = /* @__PURE__ */ new Set();
@@ -14315,7 +14541,7 @@ window.__ModuleLoader__.load({
14315
14541
  * @param props - Strict Session store, view ledger, navigation, render, and locale shares.
14316
14542
  * @returns the hidden blank-session header or visible title and tabs.
14317
14543
  */
14318
- function ConversationSessionHeader({ sessionId, useSession, useSessions, useConversation, useConversationViews, useStore, actions, renderSlot, open, t }) {
14544
+ function ConversationSessionHeader({ sessionId, useSession, useSessions, useConversation, useConversationViews, useStore, renderSlot, open, selectView, t }) {
14319
14545
  const tabs = useConversationViews((value) => value);
14320
14546
  const active = resolveActiveView(tabs, useStore((s) => s.view));
14321
14547
  const ancestry = useSessions((s) => deriveAncestry(s, sessionId), equalBreadcrumbs);
@@ -14379,7 +14605,7 @@ window.__ModuleLoader__.load({
14379
14605
  "aria-selected": viewTab.id === active?.id,
14380
14606
  className: clsx(ConversationRoot_module_css_default.tab, viewTab.id === active?.id && ConversationRoot_module_css_default.tabActive),
14381
14607
  onClick: () => {
14382
- actions.setView(viewTab.id);
14608
+ selectView(viewTab.id);
14383
14609
  },
14384
14610
  children: viewTab.label
14385
14611
  }, viewTab.id))
@@ -14392,7 +14618,7 @@ window.__ModuleLoader__.load({
14392
14618
  * @param props - Strict Session input/store, view ledger, and render shares.
14393
14619
  * @returns the active view area, or null while the Session remains blank.
14394
14620
  */
14395
- function ConversationSession({ useSession, useConversation, useConversationViews, useInput, inputActions, useStore, actions, renderSlot, bindDraftMirror }) {
14621
+ function ConversationSession({ useSession, useConversation, useConversationViews, useInput, inputActions, useStore, actions, renderSlot, bindDraftMirror, openView }) {
14396
14622
  const active = resolveActiveView(useConversationViews((value) => value), useStore((s) => s.view));
14397
14623
  const session = useSession((s) => s);
14398
14624
  const conversation = useConversation((s) => s);
@@ -14411,7 +14637,7 @@ window.__ModuleLoader__.load({
14411
14637
  className: ConversationRoot_module_css_default.viewArea,
14412
14638
  children: active !== void 0 && renderSlot("conversation.view", {
14413
14639
  viewRequest,
14414
- openView: actions.openView,
14640
+ openView,
14415
14641
  completeViewRequest: actions.completeViewRequest
14416
14642
  }, { only: active.id })
14417
14643
  });
@@ -14507,7 +14733,7 @@ window.__ModuleLoader__.load({
14507
14733
  const recentlyComposing = () => composing || Date.now() < composingUntil;
14508
14734
  const arrow = (key) => (event) => {
14509
14735
  const inComposition = event !== null && isComposingEvent(event, recentlyComposing);
14510
- if (handlers.arbitrate(key, inComposition) === "consumed") {
14736
+ if (handlers.arbitrate(key, inComposition) !== "pass") {
14511
14737
  event?.preventDefault();
14512
14738
  return true;
14513
14739
  }
@@ -14574,7 +14800,7 @@ window.__ModuleLoader__.load({
14574
14800
  }
14575
14801
  /**
14576
14802
  * Product copy for a host attachment rejection (the `details.reason` of
14577
- * `session/attachment-invalid` or `subagent/attachment-unsupported`).
14803
+ * `session/attachment-invalid` or `subagent/attachment-invalid`).
14578
14804
  * User-solvable reasons name the limit and the way out;
14579
14805
  * reasons the user cannot act on fold into one send-failed line carrying the
14580
14806
  * reason code for a bug report.
@@ -14586,7 +14812,6 @@ window.__ModuleLoader__.load({
14586
14812
  function attachmentErrorText(t, reason, limits) {
14587
14813
  switch (reason) {
14588
14814
  case "MODEL_DOES_NOT_SUPPORT_IMAGES": return t("image.modelUnsupported");
14589
- case "SUBAGENT_IMAGE_UNSUPPORTED": return t("image.subagentUnsupported");
14590
14815
  case "IMAGE_TOO_MANY_PIXELS": return t("image.tooManyPixels");
14591
14816
  case "IMAGE_DIMENSION_TOO_LARGE":
14592
14817
  if (limits !== void 0) return t("image.dimensionTooLarge", { size: limits.maxImageDimension });
@@ -14624,7 +14849,7 @@ window.__ModuleLoader__.load({
14624
14849
  }
14625
14850
  //#endregion
14626
14851
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/ContextMeter.module.css.mjs
14627
- const css$3 = ".JObwrW_root{display:inline-flex;position:relative}.JObwrW_trigger{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;display:grid}.JObwrW_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.JObwrW_track{fill:none;stroke:var(--dsw-alias-border-l3);stroke-width:2px}.JObwrW_fill{fill:none;stroke:var(--dsw-alias-label-tertiary);stroke-width:2px;stroke-linecap:round}.JObwrW_panel{z-index:100;box-sizing:border-box;border:1px solid var(--dsw-alias-border-inverted);background:var(--dsw-specific-menu);width:264px;box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-secondary);cursor:default;border-radius:12px;padding:12px;font-size:12px;line-height:20px;position:absolute;bottom:calc(100% + 8px);right:0}.JObwrW_header{align-items:center;gap:6px;display:flex}.JObwrW_figures{font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);margin-left:auto;font-weight:500}.JObwrW_percent{color:var(--dsw-alias-label-primary);font-weight:500}.JObwrW_headline{color:var(--dsw-alias-label-tertiary)}.JObwrW_headline:empty{display:none}.JObwrW_bar{background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;gap:1px;height:4px;margin:10px 0 12px;display:flex;overflow:hidden}.JObwrW_segment{background:var(--meter-tint,var(--dsw-alias-label-tertiary));border-radius:1px;flex:none;min-width:2px;height:100%}.JObwrW_swatch{background:var(--meter-tint);vertical-align:baseline;border-radius:2px;width:8px;height:8px;margin-right:6px;display:inline-block}.JObwrW_colorSystem{--meter-tint:var(--dsw-static-neutral-bluish-400)}.JObwrW_colorTools{--meter-tint:#a78bfa}.JObwrW_colorMessages{--meter-tint:var(--dsw-static-blue-450)}.JObwrW_rows{margin:6px 0 0}.JObwrW_row{justify-content:space-between;align-items:center;gap:12px;padding:2px 0;display:flex}.JObwrW_row dt{color:var(--dsw-alias-label-secondary)}.JObwrW_row dd{font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);margin:0}";
14852
+ const css$3 = ".JObwrW_root{display:inline-flex;position:relative}.JObwrW_trigger{corner-shape:round;width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:999px;flex:none;place-items:center;display:grid}.JObwrW_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.JObwrW_track{fill:none;stroke:var(--dsw-alias-border-l3);stroke-width:2px}.JObwrW_fill{fill:none;stroke:var(--dsw-alias-label-tertiary);stroke-width:2px;stroke-linecap:round}.JObwrW_panel{z-index:100;box-sizing:border-box;background:var(--dsw-specific-menu);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);width:264px;box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-secondary);cursor:default;border:0;border-radius:12px;padding:12px;font-size:12px;line-height:20px;position:absolute;bottom:calc(100% + 8px);right:0}.JObwrW_header{align-items:center;gap:6px;display:flex}.JObwrW_figures{font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);margin-left:auto;font-weight:500}.JObwrW_percent{color:var(--dsw-alias-label-primary);font-weight:500}.JObwrW_headline{color:var(--dsw-alias-label-tertiary)}.JObwrW_headline:empty{display:none}.JObwrW_bar{corner-shape:round;background:var(--dsw-alias-interactive-bg-hover);border-radius:999px;gap:1px;height:4px;margin:10px 0 12px;display:flex;overflow:hidden}.JObwrW_segment{background:var(--meter-tint,var(--dsw-alias-label-tertiary));border-radius:1px;flex:none;min-width:2px;height:100%}.JObwrW_swatch{background:var(--meter-tint);vertical-align:baseline;border-radius:2px;width:8px;height:8px;margin-right:6px;display:inline-block}.JObwrW_colorSystem{--meter-tint:var(--dsw-static-neutral-bluish-400)}.JObwrW_colorTools{--meter-tint:#a78bfa}.JObwrW_colorMessages{--meter-tint:var(--dsw-static-blue-450)}.JObwrW_rows{margin:6px 0 0}.JObwrW_row{justify-content:space-between;align-items:center;gap:12px;padding:2px 0;display:flex}.JObwrW_row dt{color:var(--dsw-alias-label-secondary)}.JObwrW_row dd{font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);margin:0}";
14628
14853
  const tagId$3 = "@deepseek-ai/dsh-client-ui-conversation/ContextMeter.module.css";
14629
14854
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
14630
14855
  const tag = document.createElement("style");
@@ -15042,7 +15267,7 @@ window.__ModuleLoader__.load({
15042
15267
  }
15043
15268
  //#endregion
15044
15269
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/InputBar.module.css.mjs
15045
- const css$1 = ".uV2eYG_root{padding:0 var(--dsh-composer-side-clearance) 8px;flex-direction:column;align-items:center;display:flex}.uV2eYG_hero{padding:0 var(--dsh-composer-side-clearance)}.uV2eYG_notice{width:100%;max-width:var(--dsh-composer-card-max-width);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:8px;margin-bottom:6px;padding:4px 8px;font-size:12px;line-height:18px}.uV2eYG_card{box-sizing:border-box;width:100%;max-width:var(--dsh-composer-card-max-width);border:1px solid var(--dsw-alias-border-l2-darkmode-thin);background:var(--dsw-specific-input-major);box-shadow:var(--dsw-shadow-lv2);font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px));--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:22px;flex-direction:column;gap:12px;padding-top:10px;display:flex;position:relative}.uV2eYG_cardWorkspaceTrigger{cursor:pointer;border-color:#0000}.uV2eYG_cardWorkspaceTrigger:after{content:\"\";background:var(--dsw-alias-border-l4);pointer-events:none;border-radius:22px;transition:background-color .1s;position:absolute;inset:-1px;-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='none' rx='22' ry='22' stroke='black' stroke-width='2' stroke-dasharray='4 4'/%3E%3C/svg%3E\");mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='none' rx='22' ry='22' stroke='black' stroke-width='2' stroke-dasharray='4 4'/%3E%3C/svg%3E\")}.uV2eYG_cardWorkspaceTrigger :disabled{pointer-events:none}.uV2eYG_cardWorkspaceTrigger:hover:after{background:var(--dsw-alias-state-business-primary)}.uV2eYG_accessory{align-items:center;gap:8px;padding:10px 12px 0;display:flex}.uV2eYG_overlayAnchor{height:0;position:absolute;inset:0 0 auto}.uV2eYG_scroll{max-height:var(--dsh-composer-text-max-height);margin-right:4px;overflow-y:auto}.uV2eYG_scroll::-webkit-scrollbar-track{margin-top:8px}.uV2eYG_grow{position:relative}.uV2eYG_pending{background:var(--dsw-alias-state-business-primary);border-radius:50%;width:8px;height:8px;animation:1s ease-in-out infinite alternate uV2eYG_input-pending}@keyframes uV2eYG_input-pending{0%{opacity:.35}to{opacity:1}}.uV2eYG_input{box-sizing:border-box;font-family:var(--dsw-font-family);font-size:inherit;line-height:inherit;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;color:var(--dsw-alias-label-primary);caret-color:var(--dsw-alias-state-business-primary);outline:none;padding:4px 8px 0 16px}.uV2eYG_input p{margin:0}.uV2eYG_input p:last-child:after{content:var(--dsh-composer-hint);color:var(--dsw-alias-label-caption)}.uV2eYG_placeholder{color:var(--dsw-alias-label-caption);pointer-events:none;user-select:none;position:absolute;inset:4px 8px auto 16px}.uV2eYG_inputDisabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed}.uV2eYG_input[aria-haspopup=menu]{cursor:pointer}.uV2eYG_hero .uV2eYG_input{min-height:52px}.uV2eYG_row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;min-width:0;padding:2px 8px 6px;display:flex;container-type:inline-size}.uV2eYG_tools,.uV2eYG_modes,.uV2eYG_trailing{align-items:center;min-width:0;display:flex}.uV2eYG_tools{gap:16px}.uV2eYG_modes{gap:12px}.uV2eYG_trailing{flex:none;gap:12px;margin-left:auto}.uV2eYG_add{background:var(--dsw-specific-selector);width:28px;height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;display:grid}.uV2eYG_add:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.uV2eYG_add:disabled{opacity:.5;cursor:default}.uV2eYG_select{max-width:220px;height:28px;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer;appearance:none;background-color:#0000;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 4px center;background-repeat:no-repeat;background-size:12px 12px;border:none;border-radius:8px;outline:none;padding:0 20px 0 8px;font-size:13px;font-weight:500;line-height:20px}.uV2eYG_select:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover)}.uV2eYG_select:disabled{opacity:.5;cursor:default}.uV2eYG_primary{background:var(--dsw-alias-button-info-fill);color:#fff;cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;width:34px;height:34px;transition:background-color .1s;display:grid;transform:translateY(-2px)}.uV2eYG_primary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}.uV2eYG_primary:disabled{opacity:.4;cursor:default}.uV2eYG_retry{color:inherit;cursor:pointer;background:0 0;border:1px solid;border-radius:4px;margin-left:8px;padding:1px 8px;font-size:12px}";
15270
+ const css$1 = ".uV2eYG_root{padding:0 var(--dsh-composer-side-clearance) 8px;flex-direction:column;align-items:center;display:flex}.uV2eYG_hero{padding:0 var(--dsh-composer-side-clearance)}.uV2eYG_notice{width:100%;max-width:var(--dsh-composer-card-max-width);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:8px;margin-bottom:6px;padding:4px 8px;font-size:12px;line-height:18px}.uV2eYG_card{box-sizing:border-box;width:100%;max-width:var(--dsh-composer-card-max-width);--dsw-elevation-stroke-color:var(--dsw-alias-border-l2);background:var(--dsw-specific-input-major);box-shadow:var(--dsw-elevation-soft);font-size:var(--dsh-content-font-size,14px);line-height:calc(24px + var(--dsh-content-font-delta,0px));--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border:0;border-radius:22px;flex-direction:column;gap:12px;padding-top:10px;display:flex;position:relative}.uV2eYG_cardWorkspaceTrigger{--dsw-elevation-stroke-color:transparent;cursor:pointer}.uV2eYG_cardWorkspaceTrigger:after{content:\"\";background:var(--dsw-alias-border-l4);pointer-events:none;border-radius:22px;transition:background-color .1s;position:absolute;inset:-1px;-webkit-mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='none' rx='22' ry='22' stroke='black' stroke-width='2' stroke-dasharray='4 4'/%3E%3C/svg%3E\");mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='none' rx='22' ry='22' stroke='black' stroke-width='2' stroke-dasharray='4 4'/%3E%3C/svg%3E\")}.uV2eYG_cardWorkspaceTrigger :disabled{pointer-events:none}.uV2eYG_cardWorkspaceTrigger:hover:after{background:var(--dsw-alias-state-business-primary)}.uV2eYG_accessory{align-items:center;gap:8px;padding:10px 12px 0;display:flex}.uV2eYG_overlayAnchor{height:0;position:absolute;inset:0 0 auto}.uV2eYG_scroll{max-height:var(--dsh-composer-text-max-height);margin-right:4px;overflow-y:auto}.uV2eYG_scroll::-webkit-scrollbar-track{margin-top:8px}.uV2eYG_grow{position:relative}.uV2eYG_pending{corner-shape:round;background:var(--dsw-alias-state-business-primary);border-radius:50%;width:8px;height:8px;animation:1s ease-in-out infinite alternate uV2eYG_input-pending}@keyframes uV2eYG_input-pending{0%{opacity:.35}to{opacity:1}}.uV2eYG_input{box-sizing:border-box;font-family:var(--dsw-font-family);font-size:inherit;line-height:inherit;white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere;color:var(--dsw-alias-label-primary);caret-color:var(--dsw-alias-state-business-primary);outline:none;padding:4px 8px 0 16px}.uV2eYG_input p{margin:0}.uV2eYG_input p:last-child:after{content:var(--dsh-composer-hint);color:var(--dsw-alias-label-caption)}.uV2eYG_placeholder{color:var(--dsw-alias-label-caption);pointer-events:none;user-select:none;position:absolute;inset:4px 8px auto 16px}.uV2eYG_inputDisabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed}.uV2eYG_input[aria-haspopup=menu]{cursor:pointer}.uV2eYG_hero .uV2eYG_input{min-height:52px}.uV2eYG_row{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;min-width:0;padding:2px 8px 6px;display:flex;container-type:inline-size}.uV2eYG_tools,.uV2eYG_modes,.uV2eYG_trailing{align-items:center;min-width:0;display:flex}.uV2eYG_tools{gap:16px}.uV2eYG_modes{gap:12px}.uV2eYG_trailing{flex:none;gap:12px;margin-left:auto}.uV2eYG_add{corner-shape:round;background:var(--dsw-specific-selector);width:28px;height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;display:grid}.uV2eYG_add:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.uV2eYG_add:disabled{opacity:.5;cursor:default}.uV2eYG_select{max-width:220px;height:28px;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer;appearance:none;background-color:#0000;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 4px center;background-repeat:no-repeat;background-size:12px 12px;border:none;border-radius:8px;outline:none;padding:0 20px 0 8px;font-size:13px;font-weight:500;line-height:20px}.uV2eYG_select:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover)}.uV2eYG_select:disabled{opacity:.5;cursor:default}.uV2eYG_primary{corner-shape:round;background:var(--dsw-alias-button-info-fill);color:#fff;cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;width:34px;height:34px;transition:background-color .1s;display:grid;transform:translateY(-2px)}.uV2eYG_primary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover)}.uV2eYG_primary:disabled{opacity:.4;cursor:default}.uV2eYG_retry{color:inherit;cursor:pointer;background:0 0;border:1px solid;border-radius:4px;margin-left:8px;padding:1px 8px;font-size:12px}";
15046
15271
  const tagId$1 = "@deepseek-ai/dsh-client-ui-conversation/InputBar.module.css";
15047
15272
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
15048
15273
  const tag = document.createElement("style");
@@ -15081,8 +15306,8 @@ window.__ModuleLoader__.load({
15081
15306
  * Machine state arrives through the standard provide channel
15082
15307
  * (useInput + inputActions); the keyboard/DOM command face and stop arrive
15083
15308
  * through this entry's own inject, whose hooks compartment binds
15084
- * useNotices/useLexicon; layout-phase inputs (variant, placeholder,
15085
- * region-slot content) ride the owner props. Session facts
15309
+ * useNotices/useLexicon; layout-phase inputs (variant and placeholder) ride
15310
+ * the owner props. Session facts
15086
15311
  * (running/removed/promptError) are self-selected via useSession.
15087
15312
  *
15088
15313
  * The text surface is the shell-owned Lexical editor bound here through
@@ -15091,7 +15316,7 @@ window.__ModuleLoader__.load({
15091
15316
  * The no-session state renders the SAME div inert as the Workspace-picker
15092
15317
  * trigger instead of a parallel tree.
15093
15318
  */
15094
- function InputBar({ useSession, useInput, inputActions, keyboard, addImages, removeImage, draftImages, resolveSubmitMode, toggleCommandMenu, stop, command, t, renderSlot, useNotices, useLexicon, useMenuLauncher, useProjection, sessionId, variant, disabled: inert = false, blocked, workspacePickerOpen = false, onRequestWorkspace, placeholder, accessory, overlay, leftItems, rightItems, footer }) {
15319
+ const InputBar = (0, react.memo)(function InputBar({ useSession, useInput, inputActions, keyboard, addImages, removeImage, draftImages, resolveSubmitMode, toggleCommandMenu, stop, command, t, renderSlot, useNotices, useLexicon, useMenuLauncher, useProjection, sessionId, variant, disabled: inert = false, blocked, workspacePickerOpen = false, onRequestWorkspace, placeholder, accessory }) {
15095
15320
  const input = useInput((s) => s);
15096
15321
  const notice = useNotices((s) => s);
15097
15322
  const commandMenuOpen = useMenuLauncher((source) => source === "command");
@@ -15122,7 +15347,7 @@ window.__ModuleLoader__.load({
15122
15347
  (0, react.useEffect)(() => {
15123
15348
  if (promptError === null) return;
15124
15349
  const { error } = promptError;
15125
- showToast(error.code === "session/attachment-invalid" || error.code === "subagent/attachment-unsupported" ? attachmentErrorText(t, error.details.reason, imageLimits) : `${error.message} (${error.code})`);
15350
+ showToast(error.code === "session/attachment-invalid" || error.code === "subagent/attachment-invalid" ? attachmentErrorText(t, error.details.reason, imageLimits) : `${error.message} (${error.code})`);
15126
15351
  }, [
15127
15352
  promptError,
15128
15353
  showToast,
@@ -15333,9 +15558,9 @@ window.__ModuleLoader__.load({
15333
15558
  e.stopPropagation();
15334
15559
  } : void 0,
15335
15560
  children: [
15336
- overlay !== void 0 && (0, react_jsx_runtime.jsx)("div", {
15561
+ sessionId !== void 0 && (0, react_jsx_runtime.jsx)("div", {
15337
15562
  className: InputBar_module_css_default.overlayAnchor,
15338
- children: overlay
15563
+ children: renderSlot("conversation.input.overlay", {})
15339
15564
  }),
15340
15565
  accessory !== void 0 && (0, react_jsx_runtime.jsx)("div", {
15341
15566
  className: InputBar_module_css_default.accessory,
@@ -15409,12 +15634,12 @@ window.__ModuleLoader__.load({
15409
15634
  className: InputBar_module_css_default.modes,
15410
15635
  children: [accessSelect, sessionId === void 0 ? null : renderSlot("conversation.input.plan", { locked })]
15411
15636
  }),
15412
- leftItems
15637
+ input === void 0 || sessionId === void 0 ? null : renderSlot("conversation.input.left", {})
15413
15638
  ]
15414
15639
  }), (0, react_jsx_runtime.jsxs)("div", {
15415
15640
  className: InputBar_module_css_default.trailing,
15416
15641
  children: [
15417
- rightItems,
15642
+ input === void 0 || sessionId === void 0 ? null : renderSlot("conversation.input.right", {}),
15418
15643
  sessionId === void 0 ? null : renderSlot("conversation.input.model", { locked: modelSeatLocked }),
15419
15644
  (0, react_jsx_runtime.jsx)(ContextMeter, {
15420
15645
  useProjection,
@@ -15488,13 +15713,13 @@ window.__ModuleLoader__.load({
15488
15713
  })
15489
15714
  ]
15490
15715
  }),
15491
- footer
15716
+ variant === "composer" && input !== void 0 && sessionId !== void 0 ? renderSlot("conversation.composer.dock", {}) : null
15492
15717
  ]
15493
15718
  });
15494
- }
15719
+ });
15495
15720
  //#endregion
15496
15721
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-conversation/src/client/skeleton/TodoPanel.module.css.mjs
15497
- const css = ".lXshSW_root{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-specific-tip);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex:none;margin:0 auto;overflow:hidden}.lXshSW_body{flex-direction:column;gap:8px;padding:6px 12px;display:flex}.lXshSW_header{text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:10px;width:100%;padding:0;display:flex}.lXshSW_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}.lXshSW_title{color:var(--dsw-alias-label-primary);flex:none;font-size:13px;font-weight:500;line-height:24px}.lXshSW_progress{min-width:0;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:auto;font-size:13px;font-weight:400;line-height:20px;overflow:hidden}.lXshSW_chevron{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}.lXshSW_list{flex-direction:column;gap:8px;max-height:180px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.lXshSW_item{min-width:0;color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:13px;line-height:20px;display:flex}.lXshSW_glyph{flex:none;place-items:center;width:16px;height:16px;display:grid}.lXshSW_glyphCompleted{color:var(--dsw-alias-state-success-primary)}.lXshSW_glyphPending{color:var(--dsw-alias-label-caption)}.lXshSW_glyphProgress{color:var(--dsw-alias-state-business-primary);animation:1s linear infinite lXshSW_todo-progress-spin}@keyframes lXshSW_todo-progress-spin{to{transform:rotate(360deg)}}.lXshSW_content{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}";
15722
+ const css = ".lXshSW_root{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));max-width:calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));border:.5px solid var(--dsw-alias-border-l1);background:var(--dsw-specific-tip);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex:none;margin:0 auto;overflow:hidden}.lXshSW_body{flex-direction:column;gap:8px;padding:6px 12px;display:flex}.lXshSW_header{text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:10px;width:100%;padding:0;display:flex}.lXshSW_lead{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}.lXshSW_title{color:var(--dsw-alias-label-primary);flex:none;font-size:13px;font-weight:500;line-height:24px}.lXshSW_progress{min-width:0;color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:auto;font-size:13px;font-weight:400;line-height:20px;overflow:hidden}.lXshSW_chevron{color:var(--dsw-alias-label-tertiary);flex:none;place-items:center;display:grid}.lXshSW_list{flex-direction:column;gap:8px;max-height:180px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.lXshSW_item{min-width:0;color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:13px;line-height:20px;display:flex}.lXshSW_glyph{flex:none;place-items:center;width:16px;height:16px;display:grid}.lXshSW_glyphCompleted{color:var(--dsw-alias-state-success-primary)}.lXshSW_glyphPending{color:var(--dsw-alias-label-caption)}.lXshSW_glyphProgress{color:var(--dsw-alias-state-business-primary);animation:1s linear infinite lXshSW_todo-progress-spin}@keyframes lXshSW_todo-progress-spin{to{transform:rotate(360deg)}}.lXshSW_content{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}";
15498
15723
  const tagId = "@deepseek-ai/dsh-client-ui-conversation/TodoPanel.module.css";
15499
15724
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
15500
15725
  const tag = document.createElement("style");
@@ -15774,24 +15999,43 @@ window.__ModuleLoader__.load({
15774
15999
  }
15775
16000
  return tabs;
15776
16001
  };
16002
+ const activateView = (sessionId, preferred) => {
16003
+ const active = resolveActiveView(viewTabs(), preferred);
16004
+ if (active !== void 0) uiConversation.binding(sessionId).activate(active.id);
16005
+ };
16006
+ const restoreView = (sessionId) => {
16007
+ activateView(sessionId, readConversationViewPreference(sessionId));
16008
+ };
16009
+ const restoreCurrentView = () => {
16010
+ const sessionId = sessions.list.getSnapshot().current;
16011
+ if (sessionId !== void 0 && sessions.binding(sessionId) !== void 0) restoreView(sessionId);
16012
+ };
15777
16013
  const conversationViews = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(viewTabs());
15778
16014
  const refreshViews = () => {
15779
16015
  const current = conversationViews.getSnapshot();
15780
16016
  const next = viewTabs();
15781
- if (current.length === next.length && current.every((tab, index) => {
16017
+ if (!(current.length === next.length && current.every((tab, index) => {
15782
16018
  const candidate = next.at(index);
15783
16019
  return candidate !== void 0 && tab.id === candidate.id && tab.label === candidate.label;
15784
- })) return;
15785
- conversationViews.set(next);
16020
+ }))) conversationViews.set(next);
16021
+ restoreCurrentView();
15786
16022
  };
15787
16023
  ctx.effect(() => {
16024
+ let currentSessionId = sessions.list.getSnapshot().current;
15788
16025
  const disposeViews = slots.subscribe("conversation.view", refreshViews);
15789
16026
  const disposeLocale = ctx.locale.subscribe(refreshViews);
16027
+ const disposeCurrent = sessions.list.subscribe(() => {
16028
+ const nextSessionId = sessions.list.getSnapshot().current;
16029
+ if (nextSessionId === currentSessionId) return;
16030
+ currentSessionId = nextSessionId;
16031
+ restoreCurrentView();
16032
+ });
15790
16033
  return () => {
16034
+ disposeCurrent();
15791
16035
  disposeLocale();
15792
16036
  disposeViews();
15793
16037
  };
15794
- }, "ui-conversation: View roster");
16038
+ }, "ui-conversation: View selection");
15795
16039
  const inputHub = new InputHub(ctx, t);
15796
16040
  const composerBlocks = new ComposerBlockRegistry();
15797
16041
  ctx.uiSession.provide({
@@ -15799,9 +16043,11 @@ window.__ModuleLoader__.load({
15799
16043
  props: ["inputActions"],
15800
16044
  resolve: (binding) => {
15801
16045
  const shell = inputHub.shellFor(binding);
16046
+ const conversation = uiConversation.binding(binding);
16047
+ restoreView(binding.sessionId);
15802
16048
  return {
15803
16049
  hooks: {
15804
- conversation: uiConversation.binding(binding).snapshot,
16050
+ conversation: conversation.snapshot,
15805
16051
  input: shell.state
15806
16052
  },
15807
16053
  props: { inputActions: shell.actions }
@@ -15828,26 +16074,10 @@ window.__ModuleLoader__.load({
15828
16074
  kind: "single",
15829
16075
  scope: "session-maybe"
15830
16076
  },
15831
- "conversation.input.overlay": {
15832
- kind: "list",
15833
- scope: "session"
15834
- },
15835
16077
  "conversation.input.dock": {
15836
16078
  kind: "list",
15837
16079
  scope: "session"
15838
16080
  },
15839
- "conversation.composer.dock": {
15840
- kind: "list",
15841
- scope: "session"
15842
- },
15843
- "conversation.input.left": {
15844
- kind: "list",
15845
- scope: "session"
15846
- },
15847
- "conversation.input.right": {
15848
- kind: "list",
15849
- scope: "session"
15850
- },
15851
16081
  "conversation.hero.brand.mark": {
15852
16082
  kind: "single",
15853
16083
  scope: "root"
@@ -15889,9 +16119,13 @@ window.__ModuleLoader__.load({
15889
16119
  scope: "session"
15890
16120
  } },
15891
16121
  store: conversationStore,
15892
- inject: (sessionId, _actions) => ({
16122
+ inject: (sessionId, actions) => ({
15893
16123
  hooks: { conversationViews },
15894
- bindDraftMirror: (write) => inputHub.shell(sessionId).bindMirror(write)
16124
+ bindDraftMirror: (write) => inputHub.shell(sessionId).bindMirror(write),
16125
+ openView: (view, focus) => {
16126
+ activateView(sessionId, view);
16127
+ actions.openView(view, focus);
16128
+ }
15895
16129
  })
15896
16130
  }, ConversationSession);
15897
16131
  const registerConversationHeader = () => slots.register({
@@ -15912,10 +16146,14 @@ window.__ModuleLoader__.load({
15912
16146
  }
15913
16147
  },
15914
16148
  store: conversationStore,
15915
- inject: () => ({
16149
+ inject: (sessionId, actions) => ({
15916
16150
  hooks: { conversationViews },
15917
16151
  open: (id) => {
15918
16152
  sessions.open(id);
16153
+ },
16154
+ selectView: (view) => {
16155
+ activateView(sessionId, view);
16156
+ actions.setView(view);
15919
16157
  }
15920
16158
  })
15921
16159
  }, ConversationSessionHeader);
@@ -15927,13 +16165,29 @@ window.__ModuleLoader__.load({
15927
16165
  kind: "single",
15928
16166
  scope: "session-maybe"
15929
16167
  },
16168
+ "conversation.input.overlay": {
16169
+ kind: "list",
16170
+ scope: "session"
16171
+ },
16172
+ "conversation.input.left": {
16173
+ kind: "list",
16174
+ scope: "session"
16175
+ },
15930
16176
  "conversation.input.plan": {
15931
16177
  kind: "single",
15932
16178
  scope: "session"
15933
16179
  },
16180
+ "conversation.input.right": {
16181
+ kind: "list",
16182
+ scope: "session"
16183
+ },
15934
16184
  "conversation.input.model": {
15935
16185
  kind: "single",
15936
16186
  scope: "session"
16187
+ },
16188
+ "conversation.composer.dock": {
16189
+ kind: "list",
16190
+ scope: "session"
15937
16191
  }
15938
16192
  },
15939
16193
  inject: (sessionId) => {