@deepseek-ai/dsh-client-ui-conversation 0.0.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE +28 -0
  2. package/README.i18n.yaml +6 -0
  3. package/README.md +65 -0
  4. package/README.zh.md +65 -0
  5. package/lib/client.js +9612 -0
  6. package/lib/index.js +28 -0
  7. package/lib/invariant.js +25 -0
  8. package/lib/types/client/apply.d.ts +16 -0
  9. package/lib/types/client/chat/AssistantMarkdown.d.ts +19 -0
  10. package/lib/types/client/chat/AssistantNodeView.d.ts +4 -0
  11. package/lib/types/client/chat/ChatNodeSeat.d.ts +11 -0
  12. package/lib/types/client/chat/ChatView.d.ts +7 -0
  13. package/lib/types/client/chat/CommandNodeView.d.ts +9 -0
  14. package/lib/types/client/chat/CompactionCommandCard.d.ts +8 -0
  15. package/lib/types/client/chat/CompactionItem.d.ts +19 -0
  16. package/lib/types/client/chat/ContextBody.d.ts +130 -0
  17. package/lib/types/client/chat/ContextInjectionRow.d.ts +26 -0
  18. package/lib/types/client/chat/GenericCommandCard.d.ts +9 -0
  19. package/lib/types/client/chat/MessageIconActions.d.ts +30 -0
  20. package/lib/types/client/chat/MessageImage.d.ts +20 -0
  21. package/lib/types/client/chat/MessageItem.d.ts +27 -0
  22. package/lib/types/client/chat/ReasoningRow.d.ts +14 -0
  23. package/lib/types/client/chat/StatsLine.d.ts +83 -0
  24. package/lib/types/client/chat/TurnTailNodeView.d.ts +7 -0
  25. package/lib/types/client/chat/message-chrome.d.ts +49 -0
  26. package/lib/types/client/chat/register-node-renderers.d.ts +7 -0
  27. package/lib/types/client/chat/tool-node-reader.d.ts +16 -0
  28. package/lib/types/client/chat/turn-assistant.d.ts +8 -0
  29. package/lib/types/client/chat/turn-metrics.d.ts +38 -0
  30. package/lib/types/client/chat/use-calendar-day.d.ts +6 -0
  31. package/lib/types/client/chat/use-throttled-visual-update.d.ts +8 -0
  32. package/lib/types/client/contract/chat-nodes.d.ts +68 -0
  33. package/lib/types/client/contract/composer-submission.d.ts +8 -0
  34. package/lib/types/client/contract/queue.d.ts +9 -0
  35. package/lib/types/client/contract/slots.d.ts +614 -0
  36. package/lib/types/client/contract/views.d.ts +39 -0
  37. package/lib/types/client/conversation-nodes/assistant.d.ts +35 -0
  38. package/lib/types/client/conversation-nodes/chat-snapshot-builder.d.ts +28 -0
  39. package/lib/types/client/conversation-nodes/command.d.ts +54 -0
  40. package/lib/types/client/conversation-nodes/common.d.ts +37 -0
  41. package/lib/types/client/conversation-nodes/compaction.d.ts +21 -0
  42. package/lib/types/client/conversation-nodes/fallback.d.ts +16 -0
  43. package/lib/types/client/conversation-nodes/inbox.d.ts +21 -0
  44. package/lib/types/client/conversation-nodes/message.d.ts +22 -0
  45. package/lib/types/client/conversation-nodes/register.d.ts +7 -0
  46. package/lib/types/client/conversation-nodes/retry.d.ts +23 -0
  47. package/lib/types/client/conversation-nodes/tool.d.ts +23 -0
  48. package/lib/types/client/conversation-nodes/turn-error.d.ts +27 -0
  49. package/lib/types/client/conversation-nodes/turn-tail.d.ts +28 -0
  50. package/lib/types/client/index.d.ts +29 -0
  51. package/lib/types/client/input/blocks.d.ts +57 -0
  52. package/lib/types/client/input/contract.d.ts +333 -0
  53. package/lib/types/client/input/decorations.d.ts +63 -0
  54. package/lib/types/client/input/facade.d.ts +219 -0
  55. package/lib/types/client/input/hub.d.ts +88 -0
  56. package/lib/types/client/input/machine.d.ts +114 -0
  57. package/lib/types/client/input/submission-policy.d.ts +46 -0
  58. package/lib/types/client/locales.d.ts +312 -0
  59. package/lib/types/client/queue/QueueDock.d.ts +29 -0
  60. package/lib/types/client/queue/store.d.ts +19 -0
  61. package/lib/types/client/service.d.ts +148 -0
  62. package/lib/types/client/settings/EnterBehaviorRow.d.ts +21 -0
  63. package/lib/types/client/skeleton/ApprovalPanel.d.ts +13 -0
  64. package/lib/types/client/skeleton/ContextMeter.d.ts +14 -0
  65. package/lib/types/client/skeleton/ConversationRoot.d.ts +5 -0
  66. package/lib/types/client/skeleton/ConversationSession.d.ts +20 -0
  67. package/lib/types/client/skeleton/DetailsPanel.d.ts +5 -0
  68. package/lib/types/client/skeleton/EmptyHero.d.ts +55 -0
  69. package/lib/types/client/skeleton/ImageLightbox.d.ts +9 -0
  70. package/lib/types/client/skeleton/InputBar.d.ts +16 -0
  71. package/lib/types/client/skeleton/PermissionSelect.d.ts +11 -0
  72. package/lib/types/client/skeleton/TodoPanel.d.ts +28 -0
  73. package/lib/types/client/stores.d.ts +22 -0
  74. package/lib/types/index.d.ts +9 -0
  75. package/lib/types/invariant.d.ts +16 -0
  76. package/lib/types/submission-settings.d.ts +20 -0
  77. package/package.json +105 -0
package/lib/index.js ADDED
@@ -0,0 +1,28 @@
1
+ import { settingsNamespace } from "@deepseek-ai/dsh-settings";
2
+ import z from "@deepseek-ai/schemastery";
3
+ //#region lib/types/submission-settings.js
4
+ /** Busy-Enter preference stored in the Host user-settings document. */
5
+ /** Settings namespace owned by the conversation plugin. */
6
+ const CONVERSATION_SETTINGS_NAMESPACE = "ui-conversation";
7
+ /** Field carrying the delivery mode for plain Enter while an agent is busy. */
8
+ const BUSY_ENTER_FIELD = "busyEnter";
9
+ /** Busy-Enter behaviors accepted at settings and input boundaries. */
10
+ const BUSY_ENTER_BEHAVIORS = ["queue", "steer"];
11
+ /** Default preserves Enter-as-Queue for running conversations. */
12
+ const DEFAULT_BUSY_ENTER_BEHAVIOR = "queue";
13
+ /** Durable conversation schema; also the wire envelope the browser scope validates against. */
14
+ const ConversationSettingsSchema = z.object({ [BUSY_ENTER_FIELD]: z.union([...BUSY_ENTER_BEHAVIORS]).default(DEFAULT_BUSY_ENTER_BEHAVIOR) });
15
+ //#endregion
16
+ //#region lib/types/index.js
17
+ /** Host registration for browser conversation preferences. */
18
+ /**
19
+ * Register the durable conversation section when a settings provider exists.
20
+ * @param ctx - Host context whose optional settings service owns the section.
21
+ */
22
+ function apply(ctx) {
23
+ ctx.inject(["settings"], (settingsCtx) => {
24
+ settingsCtx.settings.register(settingsNamespace(CONVERSATION_SETTINGS_NAMESPACE), ConversationSettingsSchema);
25
+ });
26
+ }
27
+ //#endregion
28
+ export { BUSY_ENTER_BEHAVIORS, BUSY_ENTER_FIELD, CONVERSATION_SETTINGS_NAMESPACE, DEFAULT_BUSY_ENTER_BEHAVIOR, apply };
@@ -0,0 +1,25 @@
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: the conversation service emits no cordis events, and
13
+ * both rings this package owns (the 'conversation.view' tab ring and the
14
+ * 'conversation.chat.node' business renderer seat) ride the slot system, whose ledger
15
+ * invariants live with the runtime slots package.
16
+ */
17
+ const install = () => {};
18
+ /**
19
+ * Register this package's invariant companion.
20
+ * @param ctx - Cordis context carrying the invariant service.
21
+ * @returns the installed registration's disposer after setup succeeds.
22
+ */
23
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
24
+ //#endregion
25
+ export { apply, inject, name };
@@ -0,0 +1,16 @@
1
+ /** Registers the conversation components, shared store, and service callbacks. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import { type ConversationKey } from './locales.ts';
4
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
5
+ interface LocaleNamespaceMap {
6
+ /** The conversation skeleton, chat flow, commands, details, and docks copy. */
7
+ conversation: ConversationKey;
8
+ }
9
+ }
10
+ /** Services required by the conversation plugin. */
11
+ export declare const inject: string[];
12
+ /** Mounts the conversation plugin.
13
+ * @param ctx - Client root context.
14
+ */
15
+ export declare function apply(ctx: Context): void;
16
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type { AssistantBlock } from '@deepseek-ai/dsh-client-runtime/client';
2
+ import type { MarkdownFileMentions } from '@deepseek-ai/dsh-client-ui-primitives';
3
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
4
+ import { type ImageLoader } from './MessageImage.tsx';
5
+ export interface AssistantMarkdownProps {
6
+ blocks: readonly AssistantBlock[];
7
+ streaming: boolean;
8
+ /** Frozen partial of an aborted turn: rendered with a stopped marker. */
9
+ interrupted?: boolean | undefined;
10
+ /** Session-authorized durable image loader. */
11
+ loadImage?: ImageLoader;
12
+ /** Resolved prose file mentions for this Assistant's closing turn. */
13
+ mentions?: MarkdownFileMentions | undefined;
14
+ /** The owning view's locale seat, passed down as a plain prop. */
15
+ t: ChatViewSlotProps['t'];
16
+ }
17
+ /** Reasoning block as the Think variant summary row (figma 39:28304). */
18
+ export declare const AssistantMarkdown: import("react").MemoExoticComponent<({ blocks, streaming, interrupted, loadImage, mentions, t, }: AssistantMarkdownProps) => import("react").JSX.Element | null>;
19
+ //# sourceMappingURL=AssistantMarkdown.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { ChatNodeViewProps } from '../contract/slots.ts';
2
+ /** Streaming, settled, and interrupted Assistant states share one keyed renderer instance. */
3
+ export declare const AssistantNodeView: import("react").MemoExoticComponent<({ node, useTurnData, openFile, loadImage, fileMentions, t, }: ChatNodeViewProps<"assistant-step">) => import("react").JSX.Element>;
4
+ //# sourceMappingURL=AssistantNodeView.d.ts.map
@@ -0,0 +1,11 @@
1
+ import type { ChatNodeOwnerProps, ChatViewSlotProps } from '../contract/slots.ts';
2
+ interface ChatNodeSeatProps extends ChatNodeOwnerProps {
3
+ readonly nodeKey: string;
4
+ readonly useSession: ChatViewSlotProps['useSession'];
5
+ readonly renderSlot: ChatViewSlotProps['renderSlot'];
6
+ readonly t: ChatViewSlotProps['t'];
7
+ }
8
+ /** Subscribe and dispatch one stable Context key without observing sibling Nodes. */
9
+ export declare const ChatNodeSeat: import("react").MemoExoticComponent<({ nodeKey, selectedCallId, cwd, openFile, inspectCall, forkAt, loadImage, fileMentions, useSession, renderSlot, t, }: ChatNodeSeatProps) => import("react").JSX.Element | null>;
10
+ export {};
11
+ //# sourceMappingURL=ChatNodeSeat.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
2
+ /**
3
+ * The chat view slot entry: pure component over the composed props; each
4
+ * ordered business Node crosses the keyed renderer seat.
5
+ */
6
+ export declare function ChatView({ useSession, useSessions, useStore, renderSlot, sessionId, openFile, loadOlder, loadImage, inspectCall, chatScroll, forkAt, fileMentions, t, }: ChatViewSlotProps): import("react").JSX.Element;
7
+ //# sourceMappingURL=ChatView.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { PropsRenderSlots } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import type { ChatNodeViewProps } from '../contract/slots.ts';
3
+ type CommandNodeViewProps = ChatNodeViewProps<'command'> & PropsRenderSlots<'conversation.chat.commandview'>;
4
+ /** Ordinary command lifecycle renderer with command-name keyed specialization. */
5
+ export declare const CommandNodeView: import("react").MemoExoticComponent<({ node, renderSlot, t }: CommandNodeViewProps) => import("react").JSX.Element>;
6
+ /** One integrated `/compact` command and compaction transaction renderer. */
7
+ export declare const ManualCompactionNodeView: import("react").MemoExoticComponent<({ node, t, }: ChatNodeViewProps<"manual-compaction">) => import("react").JSX.Element>;
8
+ export {};
9
+ //# sourceMappingURL=CommandNodeView.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { ChatViewSlotProps, CommandRowOwnerProps } from '../contract/slots.ts';
2
+ interface CompactionCommandCardProps extends CommandRowOwnerProps {
3
+ t: ChatViewSlotProps['t'];
4
+ }
5
+ /** Render one manual compaction lifecycle without duplicating its checkpoint marker. */
6
+ export declare function CompactionCommandCard({ node, compaction, t }: CompactionCommandCardProps): import("react").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=CompactionCommandCard.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type { CompactionSummaryNode } from '@deepseek-ai/dsh-client-runtime/client';
2
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
3
+ interface CompactionItemProps {
4
+ node: CompactionSummaryNode;
5
+ /** Optional command title for a manual compaction folded into this marker. */
6
+ title?: string;
7
+ /** Command settlement text used when structured compaction counts are unavailable. */
8
+ fallbackSummary?: string | null;
9
+ /** The owning view's locale seat. */
10
+ t: ChatViewSlotProps['t'];
11
+ }
12
+ /**
13
+ * The collapsed-by-default compaction marker.
14
+ * @param props - the marker node off the snapshot cache.
15
+ * @returns the marker row, with the summary disclosure when one is available.
16
+ */
17
+ export declare const CompactionItem: import("react").MemoExoticComponent<({ node, title, fallbackSummary, t, }: CompactionItemProps) => import("react").JSX.Element>;
18
+ export {};
19
+ //# sourceMappingURL=CompactionItem.d.ts.map
@@ -0,0 +1,130 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ContextMessageNode, KnownContextForm } from '@deepseek-ai/dsh-client-runtime/client';
3
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
4
+ type Translate = ChatViewSlotProps['t'];
5
+ /**
6
+ * Default presentation: the model-facing text as text, with its real line
7
+ * breaks, and the remaining source fields beneath it. This is what every form
8
+ * this UI version does not recognize renders as.
9
+ * @param props - Durable content, its source, and the locale seat.
10
+ * @returns The opaque context body.
11
+ */
12
+ export declare function OpaqueBody({ content, source, t }: {
13
+ content: ContextMessageNode['content'];
14
+ source: unknown;
15
+ t: Translate;
16
+ }): ReactNode;
17
+ /**
18
+ * `instructions` form: the files this context reconciled, then their text.
19
+ *
20
+ * The text keeps its `<system-reminder>` framing verbatim — the framing is part
21
+ * of what the model read, so hiding it would misreport the request.
22
+ * @param props - Durable content, its source, and the locale seat.
23
+ * @returns The instructions context body, or the opaque body when the change
24
+ * list is unreadable.
25
+ */
26
+ export declare function InstructionsBody({ content, source, t }: {
27
+ content: ContextMessageNode['content'];
28
+ source: unknown;
29
+ t: Translate;
30
+ }): ReactNode;
31
+ /**
32
+ * `catalog` form: the published entries as a list, read from the source rather
33
+ * than re-parsed out of the model-facing prose.
34
+ *
35
+ * A catalog whose source carries no usable entries falls through to the opaque
36
+ * body, so an older or hand-edited log still shows its text.
37
+ * @param props - Durable content, its source, and the locale seat.
38
+ * @returns The catalog context body, or the opaque body when the entry list is
39
+ * unreadable.
40
+ */
41
+ export declare function CatalogBody({ content, source, t }: {
42
+ content: ContextMessageNode['content'];
43
+ source: unknown;
44
+ t: Translate;
45
+ }): ReactNode;
46
+ /**
47
+ * `snapshot` form: the named contributions this snapshot assembled, in order.
48
+ *
49
+ * The sections are the same bytes the model read, split at the boundaries the
50
+ * producer assembled them on, so a reader sees which subsystem contributed
51
+ * which state instead of one undifferentiated wall.
52
+ *
53
+ * One sentence of the model-facing text is NOT in any section: the producer's
54
+ * framing line declaring that this snapshot supersedes earlier ones. Unlike the
55
+ * `<system-reminder>` wrapper an instruction context carries — which wraps
56
+ * content and cannot be separated from it — that line states the form's own
57
+ * semantics, so the body states them as a caption instead of reprinting the
58
+ * joined prose beside the sections it was split from.
59
+ * @param props - Durable content, its source, and the locale seat.
60
+ * @returns The snapshot context body, or the opaque body when unreadable.
61
+ */
62
+ export declare function SnapshotBody({ content, source, t }: {
63
+ content: ContextMessageNode['content'];
64
+ source: unknown;
65
+ t: Translate;
66
+ }): ReactNode;
67
+ /**
68
+ * `notice` form: what just happened, with the model-facing text beneath it.
69
+ *
70
+ * The one-line account also rides the collapsed row ({@link contextBody}), so a
71
+ * notice is usually readable without expanding at all.
72
+ * @param props - Durable content, its source, and the locale seat.
73
+ * @returns The notice context body.
74
+ */
75
+ export declare function NoticeBody({ content, t }: {
76
+ content: ContextMessageNode['content'];
77
+ source: unknown;
78
+ t: Translate;
79
+ }): ReactNode;
80
+ /**
81
+ * `relay` form: which agent sent this, then what it said.
82
+ *
83
+ * The sender is an opaque session id; it is shown as a field rather than a
84
+ * label, because this client cannot resolve it to a title.
85
+ * @param props - Durable content, its source, and the locale seat.
86
+ * @returns The relay context body.
87
+ */
88
+ export declare function RelayBody({ content, source, t }: {
89
+ content: ContextMessageNode['content'];
90
+ source: unknown;
91
+ t: Translate;
92
+ }): ReactNode;
93
+ /**
94
+ * `recall` form: which sessions this material came from and how much of each
95
+ * survived the read, then the material itself.
96
+ *
97
+ * Completeness is the fact a reader needs first: recalled context is bounded on
98
+ * the way in, so a card that hid the omitted count would overstate what the
99
+ * model received.
100
+ * @param props - Durable content, its source, and the locale seat.
101
+ * @returns The recall context body, or the opaque body when unreadable.
102
+ */
103
+ export declare function RecallBody({ content, source, t }: {
104
+ content: ContextMessageNode['content'];
105
+ source: unknown;
106
+ t: Translate;
107
+ }): ReactNode;
108
+ /**
109
+ * Choose the body for one context node.
110
+ *
111
+ * Returns the form the body actually rendered as, which is not always the
112
+ * declared one: a declared form whose fields are unreadable falls back to
113
+ * opaque, and the caller labels the row with what it really shows.
114
+ * `summary` is the collapsed row's one-line account, which only a `notice`
115
+ * records: its whole point is being readable without expanding.
116
+ * @param form - the producer-declared form projected onto the node.
117
+ * @param props - durable content, its source, and the locale seat.
118
+ * @returns the rendered form (null for opaque), its collapsed summary, and its body.
119
+ */
120
+ export declare function contextBody(form: ContextMessageNode['form'], props: {
121
+ content: ContextMessageNode['content'];
122
+ source: unknown;
123
+ t: Translate;
124
+ }): {
125
+ rendered: KnownContextForm | null;
126
+ summary: string | null;
127
+ body: ReactNode;
128
+ };
129
+ export {};
130
+ //# sourceMappingURL=ContextBody.d.ts.map
@@ -0,0 +1,26 @@
1
+ import type { ContextMessageNode } from '@deepseek-ai/dsh-client-runtime/client';
2
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
3
+ /** Props for the logged non-user message presentation. */
4
+ export interface ContextInjectionRowProps {
5
+ content: ContextMessageNode['content'];
6
+ source: ContextMessageNode['source'];
7
+ /** Role and producer name projected from the durable source. */
8
+ provenance: ContextMessageNode['provenance'];
9
+ /** Producer-declared information form; null renders the opaque body. */
10
+ form: ContextMessageNode['form'];
11
+ /** The owning view's locale seat, passed down as a plain prop. */
12
+ t: ChatViewSlotProps['t'];
13
+ }
14
+ /**
15
+ * Render logged context with the Tool calls disclosure chrome from Figma.
16
+ *
17
+ * The header names the role the context plays and, beside it, the producer the
18
+ * durable source identifies, so a reader can tell an injected skill catalog
19
+ * from a workspace instruction file or a recalled session without expanding.
20
+ * The expanded body follows the producer-declared form; an absent or unknown
21
+ * form renders the opaque body.
22
+ * @param props - Durable content, its projected producer role/name and form, and the locale seat.
23
+ * @returns A collapsed context row with a bounded, form-specific body.
24
+ */
25
+ export declare function ContextInjectionRow({ content, source, provenance, form, t }: ContextInjectionRowProps): import("react").JSX.Element;
26
+ //# sourceMappingURL=ContextInjectionRow.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { ChatViewSlotProps, CommandRowOwnerProps } from '../contract/slots.ts';
2
+ /** Card props: the owner payload plus the render site's locale seat (plain prop). */
3
+ export interface GenericCommandCardProps extends CommandRowOwnerProps {
4
+ t: ChatViewSlotProps['t'];
5
+ /** Command-specific running copy; absent uses the generic command label. */
6
+ runningSummary?: string | undefined;
7
+ }
8
+ export declare function GenericCommandCard({ node, t, runningSummary }: GenericCommandCardProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=GenericCommandCard.d.ts.map
@@ -0,0 +1,30 @@
1
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
2
+ export interface MessageIconActionsProps {
3
+ /** Plain text the copy action writes. */
4
+ text: string;
5
+ /** Unix epoch ms for the clock label; omitted for transient messages. */
6
+ time?: number | undefined;
7
+ /** Turn wall time in ms, appended to the clock as `· Ran for 15s`; omitted when the turn's start is unknown. */
8
+ runMs?: number | undefined;
9
+ /** Turn first-step TTFT in ms, appended as `· TTFT 1.2s`; omitted when unrecorded. */
10
+ ttftMs?: number | undefined;
11
+ /** Turn decode throughput, appended as `· 34 tok/s`; omitted when unrecorded. */
12
+ tokensPerSecond?: number | undefined;
13
+ /** Clock before icons (user) or after (assistant). */
14
+ clock: 'start' | 'end';
15
+ /** Fork the session at this message; omission hides the branch action. */
16
+ onBranch?: (() => void) | undefined;
17
+ /** The message is not a completed transcript tail, so branch stays visible but unavailable. */
18
+ branchUnavailable?: boolean | undefined;
19
+ /** Parent layout class composed onto the actions row. */
20
+ className?: string | undefined;
21
+ /** The owning view's locale seat, passed down as a plain prop. */
22
+ t: ChatViewSlotProps['t'];
23
+ }
24
+ /**
25
+ * Copy / branch (/ clock) IconActions row shared by user and assistant chrome.
26
+ * @param props - Copy text, event time, clock side, branch callback, className.
27
+ * @returns The actions row element.
28
+ */
29
+ export declare function MessageIconActions({ text, time, runMs, ttftMs, tokensPerSecond, clock, onBranch, branchUnavailable, className, t, }: MessageIconActionsProps): import("react").JSX.Element;
30
+ //# sourceMappingURL=MessageIconActions.d.ts.map
@@ -0,0 +1,20 @@
1
+ import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
2
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
3
+ /** Loads a session-authorized durable image URL. */
4
+ export type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>;
5
+ /** Compact history renderer with retryable loading and double-click original preview. */
6
+ export declare function MessageImage({ attachment, load, t }: {
7
+ attachment: ImageAttachmentRef;
8
+ load: ImageLoader;
9
+ t: ChatViewSlotProps['t'];
10
+ }): import("react").JSX.Element;
11
+ /** Wrapping image group shared by user and assistant history. */
12
+ export declare function ImageGallery({ images, load, align, t }: {
13
+ images: readonly {
14
+ attachment: ImageAttachmentRef;
15
+ }[];
16
+ load: ImageLoader;
17
+ align: 'start' | 'end';
18
+ t: ChatViewSlotProps['t'];
19
+ }): import("react").JSX.Element | null;
20
+ //# sourceMappingURL=MessageImage.d.ts.map
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ChatNodeViewProps, ChatViewSlotProps } from '../contract/slots.ts';
3
+ import { type ImageLoader } from './MessageImage.tsx';
4
+ /**
5
+ * Render one Host-authoritative pending steering item with the same visual
6
+ * language as its eventual durable transcript node.
7
+ * @param props - Pending message content and conversation translator.
8
+ * @returns the pending steering bubble.
9
+ */
10
+ export declare function PendingSteeringBubble({ content, loadImage, t }: {
11
+ content: readonly unknown[];
12
+ loadImage?: ImageLoader;
13
+ t: ChatViewSlotProps['t'];
14
+ }): ReactNode;
15
+ /** User and admitted-steering keyed Chat renderer. */
16
+ export declare const UserMessageNodeView: import("react").MemoExoticComponent<({ node, loadImage, t, }: ChatNodeViewProps<"user" | "steering">) => import("react").JSX.Element>;
17
+ /** Injected-context keyed Chat renderer. */
18
+ export declare const ContextMessageNodeView: import("react").MemoExoticComponent<({ node, t }: ChatNodeViewProps<"context">) => import("react").JSX.Element>;
19
+ /** Automatic compaction keyed Chat renderer. */
20
+ export declare const CompactionNodeView: import("react").MemoExoticComponent<({ node, t }: ChatNodeViewProps<"compaction">) => import("react").JSX.Element>;
21
+ /** Correlated retry-chain keyed Chat renderer. */
22
+ export declare const RetryNodeView: import("react").MemoExoticComponent<({ node, t }: ChatNodeViewProps<"model-retry">) => import("react").JSX.Element>;
23
+ /** Terminal turn-error keyed Chat renderer. */
24
+ export declare const TurnErrorNodeView: import("react").MemoExoticComponent<({ node, t }: ChatNodeViewProps<"turn-error">) => import("react").JSX.Element>;
25
+ /** Explicit unknown-surface keyed Chat renderer. */
26
+ export declare const UnknownNodeView: import("react").MemoExoticComponent<({ node, t }: ChatNodeViewProps<"unknown">) => import("react").JSX.Element>;
27
+ //# sourceMappingURL=MessageItem.d.ts.map
@@ -0,0 +1,14 @@
1
+ import type { ChatViewSlotProps } from '../contract/slots.ts';
2
+ /**
3
+ * Render one assistant reasoning block as the Think disclosure row.
4
+ * @param props.text - complete or streaming reasoning text.
5
+ * @param props.running - whether this block is the streaming tail.
6
+ * @param props.t - conversation locale seat for the running status.
7
+ * @returns the reasoning disclosure.
8
+ */
9
+ export declare function ReasoningRow({ text, running, t }: {
10
+ text: string;
11
+ running: boolean;
12
+ t: ChatViewSlotProps['t'];
13
+ }): import("react").JSX.Element;
14
+ //# sourceMappingURL=ReasoningRow.d.ts.map
@@ -0,0 +1,83 @@
1
+ import type { ConversationSnapshot, UseProjection } from '@deepseek-ai/dsh-client-runtime/client';
2
+ import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { ContextPressureProjection, TokenUsageProjection } from '@deepseek-ai/dsh-token-meter/client';
4
+ import type { ComposerBarProps } from '../contract/slots.ts';
5
+ interface WindowStats {
6
+ turns: number;
7
+ steps: number;
8
+ /** Summed request wall time (step/start → assistant/message); 0 when no node carries timing. */
9
+ llmMs: number;
10
+ /** Summed tool wall time (tool/call → tool/result); 0 when no pair is in-window. */
11
+ toolMs: number;
12
+ /** Summed first-token latency over `ttftSteps`; 0 when no step records it. */
13
+ ttftMs: number;
14
+ /** Steps carrying a recorded TTFT. */
15
+ ttftSteps: number;
16
+ /** Summed decode wall time over steps that also report output tokens. */
17
+ decodeMs: number;
18
+ /** Summed output tokens over the same decode-timed steps. */
19
+ decodeTokens: number;
20
+ }
21
+ /**
22
+ * Fold assistant and tool-result nodes into the window-scoped display totals.
23
+ *
24
+ * Counts and wall times describe the loaded window on purpose — they answer
25
+ * "what is on screen". Token accounting deliberately does NOT come from here:
26
+ * the window is paged and compaction rewrites it, so billing rides the durable
27
+ * `tokenUsage` projection instead.
28
+ * @param nodes - snapshot nodes.
29
+ * @returns visible counts and summed wall times.
30
+ */
31
+ export declare function deriveStats(nodes: ConversationSnapshot['nodes']): WindowStats;
32
+ /**
33
+ * Compact token count: 517 / 12.2K / 517K / 1.2M (one decimal under three digits).
34
+ * @param n - token count.
35
+ * @returns display string.
36
+ */
37
+ export declare function formatTokens(n: number): string;
38
+ /**
39
+ * Compact duration: 45.2s under a minute, 2m42s from there on.
40
+ * @param ms - duration in milliseconds.
41
+ * @returns display string.
42
+ */
43
+ export declare function formatDuration(ms: number): string;
44
+ /**
45
+ * Cache-hit share of prompt-side input over the whole durable log.
46
+ * @param usage - the session's token-usage projection value.
47
+ * @returns rounded integer percent, or null when no input was billed.
48
+ */
49
+ export declare function cacheHitPercent(usage: TokenUsageProjection): number | null;
50
+ /**
51
+ * Sum the three disjoint prompt-side billing buckets.
52
+ * @param usage - the session's token-usage projection value.
53
+ * @returns billed input tokens.
54
+ */
55
+ export declare function billedInputTokens(usage: TokenUsageProjection): number;
56
+ interface ContextOccupancy {
57
+ percent: number;
58
+ usedTokens: number;
59
+ contextWindow: number;
60
+ }
61
+ /**
62
+ * Approximate context occupancy, using the TUI's integer rounding and upper
63
+ * clamp. The numerator is `projectedTokens` — the provider sample carried
64
+ * forward over the surface's movement since — so compaction shows immediately
65
+ * instead of waiting for the next request to report usage; it falls back to the
66
+ * bare sample only for a log whose projection predates that field. Numerator
67
+ * and capacity remain independent last-wins projection fields, so this is a
68
+ * reference figure rather than an exact measurement of one request (see the
69
+ * token-meter README).
70
+ * @param pressure - the session's context-pressure projection value.
71
+ * @returns occupancy with its numerator and denominator, or null until both values are known.
72
+ */
73
+ export declare function contextOccupancy(pressure: ContextPressureProjection | undefined): ContextOccupancy | null;
74
+ /** Props: the conversation-snapshot selector plus the projection read seat. */
75
+ export interface StatsLineProps {
76
+ useSession: SnapshotSelectorHook<ConversationSnapshot>;
77
+ useProjection: UseProjection;
78
+ /** The owning dock's locale seat. */
79
+ t: ComposerBarProps['t'];
80
+ }
81
+ export declare const StatsLine: import("react").MemoExoticComponent<({ useSession, useProjection, t }: StatsLineProps) => import("react").JSX.Element | null>;
82
+ export {};
83
+ //# sourceMappingURL=StatsLine.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { PropsRenderSlots } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import type { ChatNodeViewProps } from '../contract/slots.ts';
3
+ type TurnTailNodeViewProps = ChatNodeViewProps<'turn-tail'> & PropsRenderSlots<'conversation.chat.turnTail'>;
4
+ /** Turn-local actions and feature tail over the Location index, independent of Assistant placement. */
5
+ export declare const TurnTailNodeView: import("react").MemoExoticComponent<({ node, openFile, forkAt, renderSlotChain, t, useSession, }: TurnTailNodeViewProps) => import("react").JSX.Element | null>;
6
+ export {};
7
+ //# sourceMappingURL=TurnTailNodeView.d.ts.map
@@ -0,0 +1,49 @@
1
+ import type { Translate } from '@deepseek-ai/dsh-client-ui-slots';
2
+ /** The date-template share of the conversation dictionary the clock consumes. */
3
+ export type ClockTranslate = Translate<'clock.md' | 'clock.ymd'>;
4
+ /** The elapsed-duration share of the conversation dictionary. */
5
+ export type RunDurationTranslate = Translate<'duration.seconds' | 'duration.minutes'>;
6
+ /**
7
+ * Local calendar-day epoch (ms at local midnight) for an instant.
8
+ * @param ms - Unix epoch ms.
9
+ * @returns Midnight of that local calendar day.
10
+ */
11
+ export declare function startOfLocalDay(ms: number): number;
12
+ /**
13
+ * Delay until the next local midnight after `ms` (at least 1ms).
14
+ * @param ms - Unix epoch ms.
15
+ * @returns Milliseconds until the following local midnight.
16
+ */
17
+ export declare function msUntilNextLocalMidnight(ms: number): number;
18
+ /**
19
+ * Localized elapsed-time label shared by running and settled turn chrome.
20
+ * @param ms - Elapsed duration in milliseconds (negatives clamp to zero).
21
+ * @param t - Translate seat supplying the duration templates.
22
+ * @returns Display string in whole seconds.
23
+ */
24
+ export declare function formatRunDuration(ms: number, t: RunDurationTranslate): string;
25
+ /**
26
+ * Sub-turn latency figure: one decimal under ten seconds, whole seconds
27
+ * beyond. Unit-less so the locale template owns the second suffix.
28
+ * @param ms - Latency in milliseconds (negatives clamp to zero).
29
+ * @returns Display number in seconds without unit.
30
+ */
31
+ export declare function formatLatencySeconds(ms: number): string;
32
+ /**
33
+ * Decode-throughput figure: whole tokens from ten up, one decimal below.
34
+ * @param tps - Tokens per second.
35
+ * @returns Display number without unit.
36
+ */
37
+ export declare function formatTokensPerSecond(tps: number): string;
38
+ /**
39
+ * Compact local timestamp for message IconActions. Same calendar day →
40
+ * `HH:mm`; earlier this year → the `clock.md` date template + clock; other
41
+ * years → the `clock.ymd` template + clock. Pure: the date templates arrive
42
+ * through the caller's locale seat.
43
+ * @param time - Unix epoch ms from the source session event.
44
+ * @param t - translate seat supplying the `clock.md` / `clock.ymd` templates.
45
+ * @param now - Reference instant for the day/year cut (defaults to wall clock).
46
+ * @returns Date-aware clock string (24-hour, zero-padded time).
47
+ */
48
+ export declare function formatMessageClock(time: number, t: ClockTranslate, now?: number): string;
49
+ //# sourceMappingURL=message-chrome.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ /**
3
+ * Register this package's business renderers behind the keyed Chat Node seat.
4
+ * @param ctx - owning UI Conversation context.
5
+ */
6
+ export declare function registerChatNodeRenderers(ctx: Context): void;
7
+ //# sourceMappingURL=register-node-renderers.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { ConversationSnapshot, ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client';
2
+ /**
3
+ * Read one root Tool lifecycle through the internal Chat Node index.
4
+ * @param snapshot - current Conversation snapshot.
5
+ * @param rootCallId - root call identity and Tool Context identity.
6
+ * @returns root lifecycle when it is materialized in the current window.
7
+ */
8
+ export declare function rootToolCall(snapshot: ConversationSnapshot, rootCallId: string): ToolCallBlock | undefined;
9
+ /**
10
+ * Find any root or nested Tool lifecycle through the internal Node store.
11
+ * @param snapshot - current Conversation snapshot.
12
+ * @param callId - root or nested call identity.
13
+ * @returns current Tool lifecycle when materialized in the loaded window.
14
+ */
15
+ export declare function findToolCall(snapshot: ConversationSnapshot, callId: string): ToolCallBlock | undefined;
16
+ //# sourceMappingURL=tool-node-reader.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { AssistantBlock } from '@deepseek-ai/dsh-client-runtime/client';
2
+ /**
3
+ * Collect visible prose from one Assistant lifecycle.
4
+ * @param blocks - Assistant content blocks.
5
+ * @returns concatenated text blocks.
6
+ */
7
+ export declare function assistantText(blocks: readonly AssistantBlock[]): string;
8
+ //# sourceMappingURL=turn-assistant.d.ts.map
@@ -0,0 +1,38 @@
1
+ import type { AssistantMessageNode, ConversationNode } from '@deepseek-ai/dsh-client-runtime/client';
2
+ /** Latency and decode-throughput readings for one turn's footer. */
3
+ export interface TurnMetrics {
4
+ /** First-step TTFT in ms; absent when that step carries no recorded timing. */
5
+ ttftMs?: number;
6
+ /** Decode throughput over steps carrying both timing and provider usage. */
7
+ tokensPerSecond?: number;
8
+ }
9
+ /** One assistant step's derivable latency facts; null marks an unrecorded part. */
10
+ export interface StepReading {
11
+ /** step/start → first token delta, in ms. */
12
+ ttftMs: number | null;
13
+ /** First token delta → final message, in ms. */
14
+ decodeMs: number | null;
15
+ /** Provider-reported completion tokens. */
16
+ outputTokens: number | null;
17
+ }
18
+ type AssistantNode = AssistantMessageNode;
19
+ /**
20
+ * Read one assistant node's TTFT, decode wall time, and output tokens.
21
+ * @param node - A settled assistant node.
22
+ * @returns Per-part readings with `null` for unrecorded values.
23
+ */
24
+ export declare function assistantStepReading(node: AssistantNode): StepReading;
25
+ /**
26
+ * Fold assistant nodes into per-turn footer metrics.
27
+ *
28
+ * TTFT is the turn's lowest-step request-dispatch-to-first-token reading, so
29
+ * it is only meaningful when the turn's start is inside
30
+ * the loaded window (the caller gates on `turnTimings`, which shares that
31
+ * window). Throughput divides summed output tokens by summed decode wall time,
32
+ * counting only steps that carry both.
33
+ * @param nodes - Snapshot nodes of the loaded window.
34
+ * @returns Turn number → available metrics; turns with none are absent.
35
+ */
36
+ export declare function deriveTurnMetrics(nodes: readonly ConversationNode[]): Map<number, TurnMetrics>;
37
+ export {};
38
+ //# sourceMappingURL=turn-metrics.d.ts.map