@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.
@@ -11,6 +11,13 @@ export interface ConversationTurnDataMap {
11
11
  /** Merge-extensible business values published against one Step. */
12
12
  export interface ConversationStepDataMap {
13
13
  }
14
+ /** Observable value for one independently owned Location-data key. */
15
+ export interface ConversationLocationDataSource<Value> {
16
+ /** @returns the current value. */
17
+ readonly getSnapshot: () => Value;
18
+ /** @param listener - callback for value changes. @returns the unsubscribe function. */
19
+ readonly subscribe: (listener: () => void) => () => void;
20
+ }
14
21
  /** Stable keyed reader for independently owned Location business values. */
15
22
  export interface ConversationLocationDataStore<DataMap extends object> {
16
23
  /**
@@ -19,6 +26,12 @@ export interface ConversationLocationDataStore<DataMap extends object> {
19
26
  * @returns latest immutable value, when its owning Context has published one.
20
27
  */
21
28
  get<Key extends keyof DataMap & string>(key: Key): Readonly<DataMap[Key]> | undefined;
29
+ /**
30
+ * Observe one business value without subscribing to unrelated Location keys.
31
+ * @param key - declaration-merged business key.
32
+ * @returns identity-stable source for the current value.
33
+ */
34
+ source<Key extends keyof DataMap & string>(key: Key): ConversationLocationDataSource<Readonly<DataMap[Key]> | undefined>;
22
35
  }
23
36
  interface ConversationLocationDataValue {
24
37
  readonly kind: 'turn' | 'step';
@@ -27,27 +40,28 @@ interface ConversationLocationDataValue {
27
40
  readonly key: string;
28
41
  readonly value: unknown;
29
42
  }
30
- type RegisteredTurnData = {
31
- [Key in keyof ConversationTurnDataMap & string]: {
43
+ type RegisteredTurnData<DataMap extends object> = {
44
+ [Key in Extract<keyof DataMap, string>]: {
32
45
  readonly kind: 'turn';
33
46
  readonly turn: number;
34
47
  readonly key: Key;
35
- readonly value: ConversationTurnDataMap[Key];
48
+ readonly value: DataMap[Key];
36
49
  };
37
- }[keyof ConversationTurnDataMap & string];
38
- type RegisteredStepData = {
39
- [Key in keyof ConversationStepDataMap & string]: {
50
+ }[Extract<keyof DataMap, string>];
51
+ type RegisteredStepData<DataMap extends object> = {
52
+ [Key in Extract<keyof DataMap, string>]: {
40
53
  readonly kind: 'step';
41
54
  readonly turn: number;
42
55
  readonly step: number;
43
56
  readonly key: Key;
44
- readonly value: ConversationStepDataMap[Key];
57
+ readonly value: DataMap[Key];
45
58
  };
46
- }[keyof ConversationStepDataMap & string];
59
+ }[Extract<keyof DataMap, string>];
60
+ type ConversationLocationDataOf<TurnData extends object, StepData extends object> = [
61
+ keyof TurnData | keyof StepData
62
+ ] extends [never] ? ConversationLocationDataValue : RegisteredTurnData<TurnData> | RegisteredStepData<StepData>;
47
63
  /** One Definition-owned value attached to an Engine-owned Turn or Step. */
48
- export type ConversationLocationData = [
49
- keyof ConversationTurnDataMap | keyof ConversationStepDataMap
50
- ] extends [never] ? ConversationLocationDataValue : RegisteredTurnData | RegisteredStepData;
64
+ export type ConversationLocationData = ConversationLocationDataOf<ConversationTurnDataMap, ConversationStepDataMap>;
51
65
  /** Immutable resolved boundary for one Agent step. */
52
66
  export interface StepLocation {
53
67
  readonly turn: number;
@@ -135,7 +149,7 @@ export interface ConversationContextReader {
135
149
  */
136
150
  previous<State>(kind: string): ConversationPreviousContext<State> | undefined;
137
151
  }
138
- /** Requested cadence for materializing updated business State into view Nodes. */
152
+ /** Requested cadence; `animation-frame` materializes after three browser animation frames. */
139
153
  export type ConversationPublication = 'none' | 'animation-frame' | 'immediate';
140
154
  /** Engine-owned Location data publication phase. */
141
155
  export type ConversationLocationDataScope = 'step' | 'turn';
@@ -180,9 +194,11 @@ export interface ConversationNodeDefinition<State = unknown> {
180
194
  * the same Location key.
181
195
  * @param context - latest complete Context.
182
196
  * @param scope - Location hierarchy level currently being materialized.
183
- * @returns current Location value, or null while unavailable.
197
+ * @param previous - value from the preceding materialization; return it when unchanged.
198
+ * @returns current Location value, preserving value identity while unchanged,
199
+ * or null while unavailable.
184
200
  */
185
- buildLocationData?(context: ConversationNodeContext<State>, scope: ConversationLocationDataScope): ConversationLocationData | null;
201
+ buildLocationData?(context: ConversationNodeContext<State>, scope: ConversationLocationDataScope, previous: ConversationLocationData | null): ConversationLocationData | null;
186
202
  /**
187
203
  * Materialize one final Node for this Definition's declared view target.
188
204
  * @param context - latest complete Context.
@@ -217,7 +233,7 @@ export interface ConversationViewBuilder<Node extends ConversationViewNode = Con
217
233
  readonly timeline: ConversationTimelineSnapshot;
218
234
  }): Snapshot;
219
235
  }
220
- /** Registry contribution that creates one isolated view builder per Session. */
236
+ /** Registry contribution that creates an isolated builder when a Session first uses this target. */
221
237
  export interface ConversationViewDefinition<Node extends ConversationViewNode = ConversationViewNode, Snapshot = unknown> {
222
238
  readonly target: string;
223
239
  /** @returns a new Session-owned incremental builder. */
@@ -152,19 +152,16 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
152
152
  'conversation.composer.dock': {
153
153
  kind: 'list';
154
154
  scope: 'session';
155
- owner: InputZone;
156
155
  };
157
156
  /** Compact controls at the left of the composer tool row. */
158
157
  'conversation.input.left': {
159
158
  kind: 'list';
160
159
  scope: 'session';
161
- owner: InputZone;
162
160
  };
163
161
  /** Compact controls before the composer submit action. */
164
162
  'conversation.input.right': {
165
163
  kind: 'list';
166
164
  scope: 'session';
167
- owner: InputZone;
168
165
  };
169
166
  /** Resident composer body, including the no-Session inert state. */
170
167
  'conversation.composer.bar': {
@@ -264,6 +261,8 @@ export interface ConversationSessionInjected {
264
261
  };
265
262
  /** Bind input draft persistence to the Session-owned store instance. */
266
263
  bindDraftMirror: (write: (text: string) => void) => () => void;
264
+ /** Select and activate one View while addressing an opaque focus request to it. */
265
+ openView: (view: string, focus: string) => void;
267
266
  }
268
267
  /** Business callbacks injected into the strict Session header. */
269
268
  export interface ConversationSessionHeaderInjected {
@@ -273,6 +272,8 @@ export interface ConversationSessionHeaderInjected {
273
272
  };
274
273
  /** Select a Session through the Session Controller. */
275
274
  open: (sessionId: SessionId) => void;
275
+ /** Select and activate one registered Conversation View. */
276
+ selectView: (view: string) => void;
276
277
  }
277
278
  /** Owner share of the resident composer bar. */
278
279
  export interface ComposerBarOwnerProps {
@@ -291,14 +292,6 @@ export interface ComposerBarOwnerProps {
291
292
  placeholder?: string;
292
293
  /** Optional content rendered above the composer surface. */
293
294
  accessory?: ReactNode;
294
- /** Floating overlay content rendered inside the composer card. */
295
- overlay?: ReactNode;
296
- /** Left-side input controls. */
297
- leftItems?: ReactNode;
298
- /** Right-side input controls. */
299
- rightItems?: ReactNode;
300
- /** Ambient content below the card. */
301
- footer?: ReactNode;
302
295
  }
303
296
  /** Package-private operations injected into the resident composer bar. */
304
297
  export interface ComposerBarInjected {
@@ -322,7 +315,7 @@ export interface InputControlOwnerProps {
322
315
  locked: boolean;
323
316
  }
324
317
  /** Full props of the resident composer bar. */
325
- export type ComposerBarProps = PropsRuntime<'conversation.composer.bar'> & PropsRenderSlots<'conversation.input.attachments' | 'conversation.input.plan' | 'conversation.input.model'> & InjectFace<ComposerBarInjected> & PropsLocale<'conversation'>;
318
+ export type ComposerBarProps = PropsRuntime<'conversation.composer.bar'> & PropsRenderSlots<'conversation.input.attachments' | 'conversation.input.overlay' | 'conversation.input.left' | 'conversation.input.plan' | 'conversation.input.right' | 'conversation.input.model' | 'conversation.composer.dock'> & InjectFace<ComposerBarInjected> & PropsLocale<'conversation'>;
326
319
  /** Owner values used to elect a composer takeover. */
327
320
  export interface ComposerChainProps {
328
321
  /** Current Session identity used by temporary business-owned entries. */
@@ -340,7 +333,7 @@ export interface HeroBrandMarkOwnerProps {
340
333
  className?: string | undefined;
341
334
  }
342
335
  /** Full props of the resident optional-Session Conversation shell. */
343
- export type ConversationSlotProps = PropsRuntime<'conversation'> & PropsRenderSlots<'conversation.session' | 'conversation.session.header' | 'conversation.composer' | 'conversation.composer.bar' | 'conversation.input.overlay' | 'conversation.input.dock' | 'conversation.composer.dock' | 'conversation.input.left' | 'conversation.input.right' | 'conversation.hero.brand.mark' | 'conversation.hero.workspace' | 'conversation.hero.agentPreset'> & InjectFace<ConversationInjected> & PropsLocale<'conversation'>;
336
+ export type ConversationSlotProps = PropsRuntime<'conversation'> & PropsRenderSlots<'conversation.session' | 'conversation.session.header' | 'conversation.composer' | 'conversation.composer.bar' | 'conversation.input.dock' | 'conversation.hero.brand.mark' | 'conversation.hero.workspace' | 'conversation.hero.agentPreset'> & InjectFace<ConversationInjected> & PropsLocale<'conversation'>;
344
337
  /** Shared target-neutral Conversation store handle. */
345
338
  export type ConversationStore = ReturnType<typeof createConversationStore>;
346
339
  /** Full props of the strict Session body. */
@@ -22,12 +22,15 @@ export declare class ConversationNodeAssembler implements ConversationViewSnapsh
22
22
  private readonly contexts;
23
23
  private readonly contextsByKind;
24
24
  private readonly contextsBySeq;
25
+ private readonly contextsByTarget;
25
26
  private readonly inputs;
26
27
  private readonly locationIndex;
27
28
  private readonly dirty;
29
+ private readonly dirtyByTarget;
28
30
  private readonly revised;
29
31
  private readonly dependents;
30
32
  private readonly views;
33
+ private readonly activeTargets;
31
34
  private hasMore;
32
35
  private replacePending;
33
36
  private timelineDirty;
@@ -62,30 +65,40 @@ export declare class ConversationNodeAssembler implements ConversationViewSnapsh
62
65
  */
63
66
  rebuildRegistry(): ConversationPublication;
64
67
  /**
65
- * Materialize dirty Contexts and advance every registered view builder.
68
+ * Materialize dirty Contexts and advance every active view builder.
66
69
  * @returns whether any view snapshot was rebuilt or incrementally applied.
67
70
  */
68
71
  flush(): boolean;
72
+ /**
73
+ * Add one target to the monotonic active set and materialize its current snapshot.
74
+ * Pending Context work is flushed before the first complete replacement.
75
+ * @param target - registered or subsequently registered view target.
76
+ * @returns whether any active target snapshot changed.
77
+ */
78
+ activateTarget(target: string): boolean;
69
79
  /**
70
80
  * Read the latest snapshot of a registered target.
71
81
  * @param target - registered view target.
72
- * @returns target snapshot, or undefined when no builder is registered.
82
+ * @returns target snapshot, or undefined before registration or activation.
73
83
  */
74
84
  snapshot(target: string): unknown;
75
85
  get<Target extends Extract<keyof ConversationViewSnapshotMap, string>>(target: Target): ConversationViewSnapshotMap[Target] | undefined;
76
86
  /**
77
87
  * Read targets whose owners classify their latest snapshot as visible activity.
78
- * @returns active target ids.
88
+ * @returns target ids contributing visible activity.
79
89
  */
80
- activeTargets(): ReadonlySet<string>;
90
+ activityTargets(): ReadonlySet<string>;
81
91
  private sortedInputs;
82
92
  private matchInput;
83
93
  private collectInput;
84
94
  private dispatchInput;
95
+ private createContext;
85
96
  private acceptMatch;
86
97
  private applyPendingMatches;
87
98
  private replayContexts;
88
99
  private replayContext;
100
+ private indexTargetContext;
101
+ private markDirty;
89
102
  private replaceDependencies;
90
103
  private replayRevisedDependents;
91
104
  private readerFor;
@@ -96,6 +109,9 @@ export declare class ConversationNodeAssembler implements ConversationViewSnapsh
96
109
  private replayDependencies;
97
110
  private refreshMatchLocations;
98
111
  private buildNode;
112
+ private replaceView;
113
+ private buildTargetNodes;
114
+ private buildTargetUpserts;
99
115
  private buildLocationData;
100
116
  private replaceLocationData;
101
117
  private applyDirtyLocationData;
@@ -12,8 +12,15 @@ import { ConversationViewRegistry } from './view-registry.ts';
12
12
  /** Observable faces published for one Session's Conversation assembly. */
13
13
  export interface ConversationBinding {
14
14
  readonly snapshot: ObservableSnapshot<ConversationSnapshot>;
15
+ /**
16
+ * Add one selected target to the Session's monotonic active set.
17
+ * @param target - registered or subsequently registered Conversation target.
18
+ */
19
+ activate(target: string): void;
15
20
  /**
16
21
  * Resolve one target-owned snapshot source.
22
+ * The first subscriber activates the target unless shell selection already
23
+ * activated it; activation lasts for the remaining Session lifetime.
17
24
  * @param target - registered Conversation target.
18
25
  * @returns identity-stable source following the target.
19
26
  */
@@ -15,6 +15,7 @@ export declare class ConversationLocationIndex {
15
15
  private timeline;
16
16
  private readonly turnDataStores;
17
17
  private readonly stepDataStores;
18
+ private readonly dirtyDataStores;
18
19
  private currentTurn;
19
20
  private currentStep;
20
21
  /**
@@ -37,6 +38,8 @@ export declare class ConversationLocationIndex {
37
38
  * @returns whether any published Location data changed.
38
39
  */
39
40
  applyData(changes: readonly ConversationLocationDataChange[]): boolean;
41
+ /** Publish committed Location-data changes to their keyed sources. */
42
+ publishData(): void;
40
43
  /**
41
44
  * Resolve the latest Location for one event.
42
45
  * @param event - event already ingested into this index.
@@ -65,6 +68,7 @@ export declare class ConversationLocationIndex {
65
68
  private stepData;
66
69
  private mutableTurnData;
67
70
  private mutableStepData;
71
+ private createDataStore;
68
72
  private storeFor;
69
73
  private resolve;
70
74
  }
@@ -10,7 +10,7 @@ import type { ConversationKey } from './locales.ts';
10
10
  export declare function imageSizeText(bytes: number): string;
11
11
  /**
12
12
  * Product copy for a host attachment rejection (the `details.reason` of
13
- * `session/attachment-invalid` or `subagent/attachment-unsupported`).
13
+ * `session/attachment-invalid` or `subagent/attachment-invalid`).
14
14
  * User-solvable reasons name the limit and the way out;
15
15
  * reasons the user cannot act on fold into one send-failed line carrying the
16
16
  * reason code for a bug report.
@@ -4,7 +4,7 @@ export { UiConversation } from './conversation/assembly.ts';
4
4
  export type { ConversationBinding } from './conversation/assembly.ts';
5
5
  export { ConversationController, UnsupportedImageMediaTypeError } from './service.ts';
6
6
  export type { IConversation } from './service.ts';
7
- export type { ConversationContextReader, ConversationLocation, ConversationLocationData, ConversationLocationDataScope, ConversationLocationDataStore, ConversationMatch, ConversationMatchResult, ConversationNodeContext, ConversationNodeDefinition, ConversationPreviousContext, ConversationPublication, ConversationStartMatch, ConversationStepDataMap, ConversationTimelineSnapshot, ConversationTurnDataMap, ConversationViewBuilder, ConversationViewDefinition, ConversationViewNode, ConversationViewSnapshotMap, ConversationViewSnapshotStore, StepLocation, TurnLocation, } from './contract/conversation.ts';
7
+ export type { ConversationContextReader, ConversationLocation, ConversationLocationData, ConversationLocationDataScope, ConversationLocationDataSource, ConversationLocationDataStore, ConversationMatch, ConversationMatchResult, ConversationNodeContext, ConversationNodeDefinition, ConversationPreviousContext, ConversationPublication, ConversationStartMatch, ConversationStepDataMap, ConversationTimelineSnapshot, ConversationTurnDataMap, ConversationViewBuilder, ConversationViewDefinition, ConversationViewNode, ConversationViewSnapshotMap, ConversationViewSnapshotStore, StepLocation, TurnLocation, } from './contract/conversation.ts';
8
8
  export { EMPTY_CONVERSATION_SNAPSHOT, conversationPhase } from './contract/snapshot.ts';
9
9
  export type { ConversationPhase, ConversationSnapshot, } from './contract/snapshot.ts';
10
10
  export type { AssistantBlock, AssistantMessageNode, AssistantProvenanceView, AssistantRequestConfig, AssistantTiming, CommandNode, CompactionSummaryNode, ContextMessageNode, ConversationNode, ModelRetryNode, PartialAssistant, RunningToolCall, SteeringMessageNode, TodoItem, ToolCallBlock, ToolResultNode, TurnErrorNode, TurnMaxTokensNode, UnknownSurfaceNode, UserMessageNode, } from './contract/records.ts';
@@ -39,7 +39,6 @@ export declare const zh: {
39
39
  'image.tooManyPixels': string;
40
40
  'image.dimensionTooLarge': string;
41
41
  'image.modelUnsupported': string;
42
- 'image.subagentUnsupported': string;
43
42
  'image.sendFailed': string;
44
43
  'context.aria': string;
45
44
  'context.used': string;
@@ -125,6 +124,7 @@ export declare const zh: {
125
124
  'web.contentTruncated': string;
126
125
  'details.running': string;
127
126
  'queue.count': string;
127
+ 'queue.image': string;
128
128
  'queue.edit': string;
129
129
  'queue.edit.unsupported': string;
130
130
  'queue.save': string;
@@ -187,7 +187,6 @@ export declare const en: {
187
187
  'image.tooManyPixels': string;
188
188
  'image.dimensionTooLarge': string;
189
189
  'image.modelUnsupported': string;
190
- 'image.subagentUnsupported': string;
191
190
  'image.sendFailed': string;
192
191
  'context.aria': string;
193
192
  'context.used': string;
@@ -273,6 +272,7 @@ export declare const en: {
273
272
  'web.contentTruncated': string;
274
273
  'details.running': string;
275
274
  'queue.count': string;
275
+ 'queue.image': string;
276
276
  'queue.edit': string;
277
277
  'queue.edit.unsupported': string;
278
278
  'queue.save': string;
@@ -1,10 +1,13 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
+ import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
2
3
  import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
4
  import type { QueueAction, QueueItemId } from '../contract/queue.ts';
4
5
  /** Queue operations injected by the session-scoped registration. */
5
6
  export interface QueueDockInjected {
6
7
  updateQueue: (itemId: QueueItemId, action: QueueAction) => Promise<void>;
7
8
  notify: (level: 'info' | 'error', text: string) => void;
9
+ /** Resolve one durable queued image into a session-scoped browser URL. */
10
+ loadImage: (attachment: ImageAttachmentRef) => Promise<string>;
8
11
  }
9
12
  /** Full props of a dock entry: InputZone owner share + session standard kit + global seat + the locale seat. */
10
13
  export type QueueDockProps = PropsRuntime<'conversation.input.dock'> & QueueDockInjected & PropsLocale<'conversation'>;
@@ -12,7 +15,7 @@ export type QueueDockProps = PropsRuntime<'conversation.input.dock'> & QueueDock
12
15
  * Queue strip: one item renders directly; multiple items default to a
13
16
  * collapsible count header; an empty queue renders nothing.
14
17
  */
15
- export declare function QueueDock({ useSession, updateQueue, notify, t }: QueueDockProps): import("react").JSX.Element | null;
18
+ export declare function QueueDock({ useSession, updateQueue, notify, loadImage, t }: QueueDockProps): import("react").JSX.Element | null;
16
19
  /** Registers queue actions backed by the session-scoped conversation service. */
17
20
  export declare const queueDockEntry: {
18
21
  name: string;
@@ -9,12 +9,12 @@ export type ConversationSessionHeaderProps = ConversationSessionHeaderSlotProps;
9
9
  * @param props - Strict Session store, view ledger, navigation, render, and locale shares.
10
10
  * @returns the hidden blank-session header or visible title and tabs.
11
11
  */
12
- export declare function ConversationSessionHeader({ sessionId, useSession, useSessions, useConversation, useConversationViews, useStore, actions, renderSlot, open, t, }: ConversationSessionHeaderProps): import("react").JSX.Element;
12
+ export declare function ConversationSessionHeader({ sessionId, useSession, useSessions, useConversation, useConversationViews, useStore, renderSlot, open, selectView, t, }: ConversationSessionHeaderProps): import("react").JSX.Element;
13
13
  /**
14
14
  * Renders the active Session view inside the resident scrollport and keeps
15
15
  * the input draft mirrored while blank Hero chrome is visible.
16
16
  * @param props - Strict Session input/store, view ledger, and render shares.
17
17
  * @returns the active view area, or null while the Session remains blank.
18
18
  */
19
- export declare function ConversationSession({ useSession, useConversation, useConversationViews, useInput, inputActions, useStore, actions, renderSlot, bindDraftMirror, }: ConversationSessionProps): import("react").JSX.Element | null;
19
+ export declare function ConversationSession({ useSession, useConversation, useConversationViews, useInput, inputActions, useStore, actions, renderSlot, bindDraftMirror, openView, }: ConversationSessionProps): import("react").JSX.Element | null;
20
20
  //# sourceMappingURL=ConversationSession.d.ts.map
@@ -2,8 +2,8 @@
2
2
  * Machine state arrives through the standard provide channel
3
3
  * (useInput + inputActions); the keyboard/DOM command face and stop arrive
4
4
  * through this entry's own inject, whose hooks compartment binds
5
- * useNotices/useLexicon; layout-phase inputs (variant, placeholder,
6
- * region-slot content) ride the owner props. Session facts
5
+ * useNotices/useLexicon; layout-phase inputs (variant and placeholder) ride
6
+ * the owner props. Session facts
7
7
  * (running/removed/promptError) are self-selected via useSession.
8
8
  *
9
9
  * The text surface is the shell-owned Lexical editor bound here through
@@ -14,5 +14,5 @@
14
14
  */
15
15
  import type { ComposerBarProps } from '../contract/slots.ts';
16
16
  export type InputBarProps = ComposerBarProps;
17
- export declare function InputBar({ useSession, useInput, inputActions, keyboard, addImages, removeImage, draftImages, resolveSubmitMode, toggleCommandMenu, stop, command, t, renderSlot, useNotices, useLexicon, useMenuLauncher, useProjection, sessionId, variant, disabled: inert, blocked, workspacePickerOpen, onRequestWorkspace, placeholder, accessory, overlay, leftItems, rightItems, footer, }: InputBarProps): import("react").JSX.Element;
17
+ export declare const InputBar: import("react").MemoExoticComponent<({ useSession, useInput, inputActions, keyboard, addImages, removeImage, draftImages, resolveSubmitMode, toggleCommandMenu, stop, command, t, renderSlot, useNotices, useLexicon, useMenuLauncher, useProjection, sessionId, variant, disabled: inert, blocked, workspacePickerOpen, onRequestWorkspace, placeholder, accessory, }: InputBarProps) => import("react").JSX.Element>;
18
18
  //# sourceMappingURL=InputBar.d.ts.map
@@ -1,5 +1,6 @@
1
1
  /** Per-session Conversation store shared by the shell body and header. */
2
2
  import { type EngineStoreHandle } from '@deepseek-ai/dsh-client-store';
3
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
3
4
  import type { ConversationStoreState } from './contract/views.ts';
4
5
  /** Declared write set for the Conversation shell. */
5
6
  type ConversationActions = {
@@ -13,5 +14,11 @@ type ConversationActions = {
13
14
  * @returns the store handle.
14
15
  */
15
16
  export declare function createConversationStore(): EngineStoreHandle<ConversationStoreState, ConversationActions>;
17
+ /**
18
+ * Read the persisted View preference before the Slot store is materialized.
19
+ * @param sessionId - Session-scoped persistence suffix.
20
+ * @returns the preferred View id, or null when storage has no usable value.
21
+ */
22
+ export declare function readConversationViewPreference(sessionId: SessionId): string | null;
16
23
  export {};
17
24
  //# sourceMappingURL=stores.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { ViewTab } from './contract/views.ts';
2
+ /**
3
+ * Resolve a preferred registered View, then Chat, without choosing another View.
4
+ * @param tabs - currently registered Views.
5
+ * @param selectedId - preferred View identity, when one is stored.
6
+ * @returns the selected View, Chat fallback, or undefined when neither is registered.
7
+ */
8
+ export declare function resolveActiveView(tabs: readonly ViewTab[], selectedId: string | null): ViewTab | undefined;
9
+ //# sourceMappingURL=view-selection.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-conversation",
3
3
  "description": "Target-neutral Conversation assembly, shell, composer, queue, and view navigation",
4
- "version": "0.1.2-alpha.2",
4
+ "version": "0.1.2-alpha.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -18,10 +18,6 @@
18
18
  "types": "./lib/types/index.d.ts",
19
19
  "default": "./lib/index.js"
20
20
  },
21
- "./invariant": {
22
- "types": "./lib/types/invariant.d.ts",
23
- "default": "./lib/invariant.js"
24
- },
25
21
  "./client": {
26
22
  "types": "./lib/types/client/index.d.ts",
27
23
  "default": "./lib/client.js"
@@ -63,40 +59,38 @@
63
59
  "react-dom": "^18.2.0",
64
60
  "@types/react-dom": "~18.3.0",
65
61
  "zod": "^4.4.3",
62
+ "@deepseek-ai/dsh-api-remotes": "^0.1.2-alpha.4",
66
63
  "@deepseek-ai/cordis": "^4.0.2",
67
- "@deepseek-ai/dsh-api-remotes": "^0.1.2-alpha.2",
68
- "@deepseek-ai/dsh-api-session-controller": "^0.1.2-alpha.2",
69
- "@deepseek-ai/dsh-api-workspace-controller": "^0.1.2-alpha.2",
70
- "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.2",
71
- "@deepseek-ai/dsh-brand": "^0.1.2-alpha.2",
72
- "@deepseek-ai/dsh-client-store": "^0.1.2-alpha.2",
73
- "@deepseek-ai/dsh-client-test-runtime": "^0.1.2-alpha.2",
74
- "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
75
- "@deepseek-ai/dsh-client-ui-layout": "^0.1.2-alpha.2",
76
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.2",
77
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-alpha.2",
78
- "@deepseek-ai/dsh-client-ui-session": "^0.1.2-alpha.2",
79
- "@deepseek-ai/dsh-client-ui-workspace": "^0.1.2-alpha.2",
80
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.2",
81
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
82
- "@deepseek-ai/dsh-commands": "^0.1.2-alpha.2",
83
- "@deepseek-ai/dsh-goal": "^0.1.2-alpha.2",
84
- "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
85
- "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
86
- "@deepseek-ai/dsh-llm-retry": "^0.1.2-alpha.2",
87
- "@deepseek-ai/dsh-permission-presets": "^0.1.2-alpha.2",
88
- "@deepseek-ai/dsh-plan-mode": "^0.1.2-alpha.2",
89
- "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
90
- "@deepseek-ai/dsh-token-meter": "^0.1.2-alpha.2",
91
- "@deepseek-ai/dsh-tool-todo": "^0.1.2-alpha.2",
92
- "@deepseek-ai/dsh-util-crypto": "^0.1.2-alpha.2",
93
- "@deepseek-ai/dsh-workspace": "^0.1.2-alpha.2",
94
- "@deepseek-ai/dsh-util-workspace-path": "^0.1.2-alpha.2",
95
- "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2"
64
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.2-alpha.4",
65
+ "@deepseek-ai/dsh-api-workspace-controller": "^0.1.2-alpha.4",
66
+ "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.4",
67
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.4",
68
+ "@deepseek-ai/dsh-brand": "^0.1.2-alpha.4",
69
+ "@deepseek-ai/dsh-client-store": "^0.1.2-alpha.4",
70
+ "@deepseek-ai/dsh-client-ui-layout": "^0.1.2-alpha.4",
71
+ "@deepseek-ai/dsh-client-test-runtime": "^0.1.2-alpha.4",
72
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.4",
73
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-alpha.4",
74
+ "@deepseek-ai/dsh-client-ui-session": "^0.1.2-alpha.4",
75
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.4",
76
+ "@deepseek-ai/dsh-client-ui-workspace": "^0.1.2-alpha.4",
77
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.4",
78
+ "@deepseek-ai/dsh-goal": "^0.1.2-alpha.4",
79
+ "@deepseek-ai/dsh-commands": "^0.1.2-alpha.4",
80
+ "@deepseek-ai/dsh-llm-retry": "^0.1.2-alpha.4",
81
+ "@deepseek-ai/dsh-permission-presets": "^0.1.2-alpha.4",
82
+ "@deepseek-ai/dsh-plan-mode": "^0.1.2-alpha.4",
83
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.4",
84
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.4",
85
+ "@deepseek-ai/dsh-token-meter": "^0.1.2-alpha.4",
86
+ "@deepseek-ai/dsh-tool-todo": "^0.1.2-alpha.4",
87
+ "@deepseek-ai/dsh-util-crypto": "^0.1.2-alpha.4",
88
+ "@deepseek-ai/dsh-workspace": "^0.1.2-alpha.4",
89
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.2-alpha.4",
90
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.4"
96
91
  },
97
92
  "files": [
98
93
  "lib/index.js",
99
- "lib/invariant.js",
100
94
  "lib/client.js",
101
95
  "lib/types/**/*.d.ts"
102
96
  ],
package/lib/invariant.js DELETED
@@ -1,23 +0,0 @@
1
- //#region lib/types/invariant.js
2
- /**
3
- * Package-owned invariant companion for `@deepseek-ai/dsh-client-ui-conversation`.
4
- * @module @deepseek-ai/dsh-client-ui-conversation/invariant
5
- */
6
- const PACKAGE_NAME = "@deepseek-ai/dsh-client-ui-conversation";
7
- /** Cordis companion plugin name. */
8
- const name = "client-ui-conversation-invariant";
9
- /** Service required before the companion can reserve package ownership. */
10
- const inject = ["invariants"];
11
- /**
12
- * No runtime invariant: Conversation Definitions, target builders, and Views
13
- * are already validated by their owning registries and the Slot ledger.
14
- */
15
- const install = () => {};
16
- /**
17
- * Register this package's invariant companion.
18
- * @param ctx - Cordis context carrying the invariant service.
19
- * @returns the installed registration's disposer after setup succeeds.
20
- */
21
- const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
22
- //#endregion
23
- export { apply, inject, name };
@@ -1,16 +0,0 @@
1
- /**
2
- * Package-owned invariant companion for `@deepseek-ai/dsh-client-ui-conversation`.
3
- * @module @deepseek-ai/dsh-client-ui-conversation/invariant
4
- */
5
- import type { Context } from '@deepseek-ai/cordis';
6
- /** Cordis companion plugin name. */
7
- export declare const name = "client-ui-conversation-invariant";
8
- /** Service required before the companion can reserve package ownership. */
9
- export declare const inject: string[];
10
- /**
11
- * Register this package's invariant companion.
12
- * @param ctx - Cordis context carrying the invariant service.
13
- * @returns the installed registration's disposer after setup succeeds.
14
- */
15
- export declare const apply: (ctx: Context) => Promise<() => void>;
16
- //# sourceMappingURL=invariant.d.ts.map