@deepseek-ai/dsh-client-ui-tool 0.1.1-rc.2 → 0.1.2-alpha.2

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 (28) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +79 -17
  3. package/README.zh.md +80 -18
  4. package/lib/client.js +868 -418
  5. package/lib/types/client/apply.d.ts +3 -2
  6. package/lib/types/client/contract/slots.d.ts +13 -8
  7. package/lib/types/client/index.d.ts +1 -1
  8. package/lib/types/client/tool/ToolCallTree.d.ts +1 -1
  9. package/lib/types/client/tool/ToolDetails.d.ts +3 -3
  10. package/lib/types/client/tool/components/AskQuestionCard.d.ts +11 -0
  11. package/lib/types/client/tool/components/ToolRow.d.ts +7 -31
  12. package/lib/types/client/tool/models/ask-question-card-model.d.ts +22 -0
  13. package/lib/types/client/tool/models/diff-card-model.d.ts +7 -28
  14. package/lib/types/client/tool/models/primitive-labels.d.ts +36 -0
  15. package/lib/types/client/tool/models/raw-tool-call.d.ts +27 -0
  16. package/lib/types/client/tool/models/read-card-model.d.ts +4 -19
  17. package/lib/types/client/tool/models/search-card-model.d.ts +9 -75
  18. package/lib/types/client/tool/models/terminal-card-model.d.ts +46 -36
  19. package/lib/types/client/tool/models/tool-call-model.d.ts +22 -5
  20. package/lib/types/client/tool/models/web-card-model.d.ts +9 -34
  21. package/lib/types/client/tool/toolviews/ask-question-row.d.ts +2 -11
  22. package/lib/types/client/tool/toolviews/bash-sample.d.ts +2 -14
  23. package/lib/types/client/tool/toolviews/file-mutation-row.d.ts +2 -17
  24. package/lib/types/client/tool/toolviews/read-row.d.ts +2 -12
  25. package/lib/types/client/tool/toolviews/search-row.d.ts +2 -19
  26. package/lib/types/client/tool/toolviews/todo-row.d.ts +2 -13
  27. package/lib/types/client/tool/toolviews/web-row.d.ts +2 -14
  28. package/package.json +17 -19
@@ -1,5 +1,6 @@
1
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
2
- /** Required services: the slot registry and the Host description used for POSIX `~`. */
1
+ /** Register the Tool call tree, details renderer, and built-in atomic views. */
2
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
3
+ /** Required services: the slot registry and the Remote face carrying the Host home used for POSIX `~`. */
3
4
  export declare const inject: string[];
4
5
  /**
5
6
  * Mount the whole-Tool renderers and built-in atomic Tool registrations.
@@ -1,7 +1,7 @@
1
1
  /** Tool UI slot declarations and their composed component props. */
2
- import type { HostDescriptionSource } from '@deepseek-ai/dsh-client-connection/client';
3
- import type { InjectFace, PropsLocale, PropsRenderSlots, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
4
- import type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client';
2
+ import type { HostObservable, InjectFace, PropsLocale, PropsRenderSlots, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { RemoteHostFacts } from '@deepseek-ai/dsh-api-remotes/client';
4
+ import type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-chat/client';
5
5
  declare module '@deepseek-ai/dsh-client-ui-slots' {
6
6
  interface SlotMap {
7
7
  /**
@@ -45,14 +45,19 @@ export interface ToolCallOwnerProps {
45
45
  /** Full props of a registered atomic Tool view. */
46
46
  export type ToolCallViewProps = PropsRuntime<'tool.call.toolview'>;
47
47
  /** Injected Host description for POSIX home-path display. */
48
- export type ToolHostDescriptionInjected = {
48
+ export type ToolHostInfoInjected = {
49
49
  hooks: {
50
- /** Current generation's Host description, bound by the slot renderer. */
51
- hostDescription: HostDescriptionSource;
50
+ /**
51
+ * Fixed Host facts, reached through a hook rather than injected as values:
52
+ * the renderer memoizes an entry's inject result for the registration's
53
+ * lifetime, so facts read there would freeze at whatever the first render
54
+ * saw. Select the field the view needs (`info => info.home`).
55
+ */
56
+ hostInfo: HostObservable<RemoteHostFacts>;
52
57
  };
53
58
  };
54
59
  /** Full props of the Tool call-tree renderer registered as a `tool-call` Chat Node. */
55
- export type ToolTreeProps = PropsRuntime<'conversation.chat.node', 'tool-call'> & PropsRenderSlots<'tool.call.toolview'> & PropsLocale<'conversation'> & InjectFace<ToolHostDescriptionInjected>;
60
+ export type ToolTreeProps = PropsRuntime<'conversation.chat.node', 'tool-call'> & PropsRenderSlots<'tool.call.toolview'> & PropsLocale<'conversation'> & InjectFace<ToolHostInfoInjected>;
56
61
  /** Full props of the selected Tool output renderer in the details panel. */
57
- export type ToolDetailsProps = PropsRuntime<'conversation.details.tool'> & PropsLocale<'conversation'> & InjectFace<ToolHostDescriptionInjected>;
62
+ export type ToolDetailsProps = PropsRuntime<'conversation.details.tool'> & PropsLocale<'conversation'> & InjectFace<ToolHostInfoInjected>;
58
63
  //# sourceMappingURL=slots.d.ts.map
@@ -1,4 +1,4 @@
1
1
  /** Browser Tool plugin: whole-call composition and keyed atomic Tool views. */
2
2
  export { apply, inject } from './apply.ts';
3
- export type { ToolCallOwnerProps, ToolCallViewProps, ToolDetailsProps, ToolHostDescriptionInjected, ToolTreeProps, } from './contract/slots.ts';
3
+ export type { ToolCallOwnerProps, ToolCallViewProps, ToolDetailsProps, ToolHostInfoInjected, ToolTreeProps, } from './contract/slots.ts';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -5,5 +5,5 @@ import type { ToolTreeProps } from '../contract/slots.ts';
5
5
  * @param props - whole-Tool owner data and the Tool-owned child-slot share.
6
6
  * @returns the Tool call tree.
7
7
  */
8
- export declare function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, useHostDescription, t, }: ToolTreeProps): import("react").JSX.Element;
8
+ export declare function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, useHostInfo, t, }: ToolTreeProps): import("react").JSX.Element;
9
9
  //# sourceMappingURL=ToolCallTree.d.ts.map
@@ -1,9 +1,9 @@
1
1
  import type { ToolDetailsProps } from '../contract/slots.ts';
2
2
  /**
3
- * Render the selected Tool call's structured output when its presentation
4
- * intent is known, otherwise preserve the flattened result text.
3
+ * Render the selected Tool call's structured output when its raw fields form a
4
+ * supported root card, otherwise preserve the flattened result text.
5
5
  * @param props - selected call slice, workspace root, host home, and locale seat.
6
6
  * @returns the details output body.
7
7
  */
8
- export declare function ToolDetails({ block, cwd, useHostDescription, t, }: Pick<ToolDetailsProps, 'block' | 'cwd' | 'useHostDescription' | 't'>): import("react").JSX.Element;
8
+ export declare function ToolDetails({ block, cwd, useHostInfo, t, }: Pick<ToolDetailsProps, 'block' | 'cwd' | 'useHostInfo' | 't'>): import("react").JSX.Element;
9
9
  //# sourceMappingURL=ToolDetails.d.ts.map
@@ -0,0 +1,11 @@
1
+ /** Ask-user transcript rendering from validated plain card data. @module */
2
+ import type { AskQuestionCardModel } from '../models/ask-question-card-model.ts';
3
+ /**
4
+ * Render a validated ask-user transcript from plain card data.
5
+ * @param props - Localized transcript card data.
6
+ * @returns the readable answered or unanswered question list.
7
+ */
8
+ export declare function AskQuestionCard({ card }: {
9
+ card: AskQuestionCardModel;
10
+ }): import("react").JSX.Element;
11
+ //# sourceMappingURL=AskQuestionCard.d.ts.map
@@ -1,18 +1,17 @@
1
1
  import { type ReactNode } from 'react';
2
- import type { WebBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
3
2
  import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
4
3
  import { type DiffCardModel } from '../models/diff-card-model.ts';
5
4
  import { type ReadCardModel } from '../models/read-card-model.ts';
6
5
  import { type SearchCardModel } from '../models/search-card-model.ts';
7
6
  import { type TerminalCardModel } from '../models/terminal-card-model.ts';
7
+ import type { AskQuestionCardModel } from '../models/ask-question-card-model.ts';
8
8
  import type { ToolRowState, ToolRowVariant } from '../models/tool-call-model.ts';
9
+ import type { WebCardModelProps } from '../models/web-card-model.ts';
9
10
  export interface ToolRowProps {
10
- /** The render site's conversation locale seat (terminal/code body copy). */
11
11
  t: TranslateNS<'conversation'>;
12
12
  variant: ToolRowVariant;
13
13
  /** Wire tool name for tool-owned styling layered over the generic variant. */
14
14
  toolName?: string | undefined;
15
- /** Leading 16px tool icon, shown while collapsed and not running/failed. */
16
15
  icon: ReactNode;
17
16
  title: string;
18
17
  summary: string;
@@ -28,39 +27,16 @@ export interface ToolRowProps {
28
27
  body: string | null;
29
28
  /** Flattened result text for the expanded Output section; null/absent = no output section. */
30
29
  output?: string | null | undefined;
30
+ /** Ask-user transcript card; card fields are mutually exclusive and replace text sections. */
31
+ askQuestion?: AskQuestionCardModel | null | undefined;
31
32
  /** Error first line shown as the collapsed summary on an error row; null/absent = keep `summary`. */
32
33
  errorSummary?: string | null | undefined;
33
- /**
34
- * Terminal-card material for a call whose render intent is a terminal card
35
- * (derived by `terminalCardModel`); it replaces the text sections when
36
- * present. A call carries at most one card kind, so the card props below are
37
- * mutually exclusive.
38
- */
34
+ /** Terminal card; card fields are mutually exclusive and replace text sections. */
39
35
  terminal?: TerminalCardModel | null | undefined;
40
- /**
41
- * Diff-card material for a call whose render intent is a diff card (derived by
42
- * `diffCardModel`); it replaces the text body when present, the same way
43
- * `terminal` does.
44
- */
45
36
  diff?: DiffCardModel | null | undefined;
46
- /**
47
- * Read-card material for a call whose render intent is a read card (derived by
48
- * `readCardModel`); it replaces the text body with the file's line-numbered,
49
- * syntax-highlighted window when present.
50
- */
51
37
  read?: ReadCardModel | null | undefined;
52
- /**
53
- * Search-card material for a call whose render intent is a search card
54
- * (derived by `searchCardModel`); it replaces the text body with grouped
55
- * matches or a path list when present.
56
- */
57
38
  search?: SearchCardModel | null | undefined;
58
- /**
59
- * Web-card material for a call whose render intent is a web card (derived by
60
- * `webCardModel`); it replaces the text body with the retrieval's citation
61
- * list or fetched-source card when present.
62
- */
63
- web?: WebBlockProps | null | undefined;
39
+ web?: WebCardModelProps | null | undefined;
64
40
  state: ToolRowState;
65
41
  /**
66
42
  * Filesystem path from tool args; when set with onOpenFile, the summary
@@ -75,5 +51,5 @@ export interface ToolRowProps {
75
51
  */
76
52
  inspect?: (() => void) | undefined;
77
53
  }
78
- export declare function ToolRow({ t, variant, toolName, icon, title, summary, summarySuffix, body, output, errorSummary, terminal, diff, read, search, web, state, filePath, onOpenFile, inspect, }: ToolRowProps): import("react").JSX.Element;
54
+ export declare function ToolRow({ t, variant, toolName, icon, title, summary, summarySuffix, body, output, askQuestion, errorSummary, terminal, diff, read, search, web, state, filePath, onOpenFile, inspect, }: ToolRowProps): import("react").JSX.Element;
79
55
  //# sourceMappingURL=ToolRow.d.ts.map
@@ -0,0 +1,22 @@
1
+ /** Pure ask-user transcript card data shared by its presenter and renderer. @module */
2
+ interface AnsweredQuestionCardItem {
3
+ id: string;
4
+ question: string;
5
+ answers: readonly string[];
6
+ }
7
+ interface UnansweredQuestionCardItem {
8
+ id: string;
9
+ question: string;
10
+ }
11
+ /** Validated, localized data rendered by the ask-user transcript card. */
12
+ export type AskQuestionCardModel = {
13
+ kind: 'answered';
14
+ questions: readonly AnsweredQuestionCardItem[];
15
+ skippedLabel: string;
16
+ } | {
17
+ kind: 'unanswered';
18
+ questions: readonly UnansweredQuestionCardItem[];
19
+ verdict: string;
20
+ };
21
+ export {};
22
+ //# sourceMappingURL=ask-question-card-model.d.ts.map
@@ -1,12 +1,4 @@
1
- /**
2
- * Pure derivation of the diff-card props from a frozen call slice: the
3
- * `card:'diff'` render intent the write/edit tools declare arrives on the
4
- * snapshot as `callView`/`resultView`, and this is the one place that turns
5
- * that pair into what {@link DiffBlock} draws. Both conversation render sites
6
- * (the chat tool row's expanded body and the details panel's Output section)
7
- * call this, so the hunks they show are derived once.
8
- * @module
9
- */
1
+ /** Pure diff-card derivation from raw file-mutation calls and result metadata. @module */
10
2
  import type { DiffBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
11
3
  import type { ToolCallBlock } from './tool-call-model.ts';
12
4
  /**
@@ -33,25 +25,12 @@ export interface DiffCardModel {
33
25
  card: Pick<DiffBlockProps, 'diffs'>;
34
26
  }
35
27
  /**
36
- * Derive the diff-card props for a tool call, or null when this call is not a
37
- * diff card and belongs on the generic path.
38
- *
39
- * The result side is authoritative once the call settles: the write/edit tools
40
- * return the applied contextual hunks there (an edit's real before/after, a
41
- * create's whole-file diff), which replace the call-time diff derived from the
42
- * arguments alone. While the call is still running only the call side exists,
43
- * so a running write/edit shows its intended change. Null is the documented
44
- * generic-card default and covers every non-diff card — including a `card`
45
- * value this UI version does not know, which arrives over the wire and cannot
46
- * be trusted to be one of the compiled variants — and a settled call whose
47
- * result view is generic (how write/edit keep their execution errors on the
48
- * generic path).
49
- *
50
- * This derivation consumes only `diffs`; the render intent's `title` field is
51
- * deliberately dropped. The row supplies its own title (`Edit`/`Write · path`
52
- * from the args), which outranks the view's `title`. A tool that names its own
53
- * diff header therefore does not surface that text on the Web row.
54
- * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
28
+ * Derive running diffs for root write/edit and `str_replace_editor`
29
+ * create/replace calls, plus applied settled diffs for root write/edit calls.
30
+ * A successful write with valid empty metadata uses its argument-derived
31
+ * whole-file diff, matching create and identical-overwrite presentation;
32
+ * `str_replace_editor` settles through Generic because it has no result view.
33
+ * @param block - running or settled Tool block.
55
34
  * @returns the diff-card props, or null for the generic path.
56
35
  */
57
36
  export declare function diffCardModel(block: ToolCallBlock): DiffCardModel | null;
@@ -0,0 +1,36 @@
1
+ /** Localized copy adapters for Cordis-free UI primitives used by Tool cards. */
2
+ import type { DiffBlockLabels, MarkdownLabels, ReadBlockLabels, SearchBlockLabels, WebBlockLabels } from '@deepseek-ai/dsh-client-ui-primitives';
3
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
4
+ type T = TranslateNS<'conversation'>;
5
+ /**
6
+ * Build localized Markdown chrome labels.
7
+ * @param t - Conversation locale seat.
8
+ * @returns Markdown chrome labels.
9
+ */
10
+ export declare function markdownLabels(t: T): MarkdownLabels;
11
+ /**
12
+ * Build localized diff-card chrome labels.
13
+ * @param t - Conversation locale seat.
14
+ * @returns Diff-card chrome labels.
15
+ */
16
+ export declare function diffBlockLabels(t: T): DiffBlockLabels;
17
+ /**
18
+ * Build localized read-card chrome labels.
19
+ * @param t - Conversation locale seat.
20
+ * @returns Read-card chrome labels.
21
+ */
22
+ export declare function readBlockLabels(t: T): ReadBlockLabels;
23
+ /**
24
+ * Build localized search-card chrome labels.
25
+ * @param t - Conversation locale seat.
26
+ * @returns Search-card chrome labels.
27
+ */
28
+ export declare function searchBlockLabels(t: T): SearchBlockLabels;
29
+ /**
30
+ * Build localized web-card chrome labels.
31
+ * @param t - Conversation locale seat.
32
+ * @returns Web-card chrome labels.
33
+ */
34
+ export declare function webBlockLabels(t: T): WebBlockLabels;
35
+ export {};
36
+ //# sourceMappingURL=primitive-labels.d.ts.map
@@ -0,0 +1,27 @@
1
+ /** Shared narrowing for raw Tool call and result fields consumed by card models. */
2
+ import type { ToolCallBlock, ToolResultNode } from '@deepseek-ai/dsh-client-ui-chat/client';
3
+ /** A parsed, in-window Tool call whose arguments are a JSON object. */
4
+ export interface ParsedToolCall {
5
+ name: string;
6
+ args: Record<string, unknown>;
7
+ }
8
+ /**
9
+ * Parse the call head paired with one immutable Tool block.
10
+ * @param block - running or settled Tool block.
11
+ * @returns the Tool name and object arguments, or null when the call head or valid JSON object is unavailable.
12
+ */
13
+ export declare function parsedToolCall(block: ToolCallBlock): ParsedToolCall | null;
14
+ /**
15
+ * Read the exact single text block consumed by first-party card derivations.
16
+ * @param block - settled Tool result.
17
+ * @returns its text, or undefined for any other content layout.
18
+ */
19
+ export declare function singleResultText(block: ToolResultNode): string | undefined;
20
+ /**
21
+ * Validate the optional escalation pair shared by first-party shell and file
22
+ * mutation tools.
23
+ * @param args - parsed open-root Tool arguments.
24
+ * @returns whether the declared escalation fields form a valid pair.
25
+ */
26
+ export declare function validEscalationFields(args: Record<string, unknown>): boolean;
27
+ //# sourceMappingURL=raw-tool-call.d.ts.map
@@ -1,3 +1,4 @@
1
+ /** Pure read-card derivation from raw result content and metadata. @module */
1
2
  import type { ReadBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
2
3
  import { type ToolCallBlock } from './tool-call-model.ts';
3
4
  /**
@@ -18,25 +19,9 @@ export declare const CHAT_READ_MAX_LINES = 8;
18
19
  */
19
20
  export type ReadCardModel = Pick<ReadBlockProps, 'label' | 'lines' | 'totalLines' | 'lang'>;
20
21
  /**
21
- * Derive the read-card props for a tool call, or null when this call is not a
22
- * read card and belongs on the generic path.
23
- *
24
- * The read card is result-side only, so only a settled call whose result view
25
- * declares `card:'read'` produces one. Every other case is null — the
26
- * documented generic-card default:
27
- *
28
- * - A running call: it has no result view yet, and a read carries no content at
29
- * call time.
30
- * - A settled call whose result view is not a read card — including a `card`
31
- * value this UI version does not know, which arrives over the wire and cannot
32
- * be trusted to be one of the compiled variants, and the read tool's own
33
- * generic fallback for an error result or a non-envelope body.
34
- *
35
- * The label is the read view's `title` when the tool supplied one (the
36
- * presentation contract's replacement-title rule), otherwise the file path
37
- * shortened the same way the row summary is: workspace-relative first, then
38
- * POSIX `~` for a leftover host-home path.
39
- * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
22
+ * Derive a settled root read card after validating its persisted metadata and
23
+ * model-facing read envelope.
24
+ * @param block - running or settled Tool block.
40
25
  * @param sessionCwd - the session workspace root; a workspace-rooted absolute
41
26
  * path label displays relative to it. Absent leaves the path as authored.
42
27
  * @param home - host account home; a leftover POSIX home path displays as `~`.
@@ -1,88 +1,22 @@
1
- /**
2
- * Pure derivation of the search-card props from a frozen call slice: the
3
- * `card:'search'` render intent the `grep` and `glob` tools declare arrives on
4
- * the snapshot as `resultView`, and this is the one place that turns it into
5
- * what {@link SearchBlock} draws. Both conversation render sites (the chat tool
6
- * row's resident body and the details panel's Output section) call this, so the
7
- * grouped matches or the path list they show are derived once.
8
- *
9
- * The search card is result-time only: a search call has no matches or paths
10
- * before `execute`, so its pending state stays a `GenericCallView`
11
- * ({@link module:@deepseek-ai/dsh-tools/src/presentation}). This derivation
12
- * therefore reads only `resultView` and returns null for a still-running call,
13
- * unlike the terminal card whose call view carries the command before
14
- * execution.
15
- *
16
- * A capped result also carries a recovery locator (grep/glob's `Full … stored
17
- * at …` footer) in the raw `tool/result` content, not in the structured
18
- * matches/paths the view carries. Since both render sites replace that raw
19
- * result with the card, this derivation surfaces the block's own result text as
20
- * {@link SearchCardModel.recovery} so the one path to the dropped rows is not
21
- * lost.
22
- * @module
23
- */
1
+ /** Pure search-card derivation from raw grep/glob result metadata. @module */
24
2
  import type { SearchBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
25
3
  import type { ToolCallBlock } from './tool-call-model.ts';
26
- /**
27
- * Distributive `Omit`: a plain `Omit<A | B, K>` keeps only the keys common to
28
- * both members, which would drop the `files`/`paths` discriminated fields.
29
- * Distributing over the naked type parameter `T` preserves each shape.
30
- */
31
4
  type DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;
32
5
  /** The {@link SearchBlockProps} union minus each render site's own fields. */
33
- type SearchBlockModelProps = DistributiveOmit<SearchBlockProps, 'maxLines' | 'className'>;
34
- /**
35
- * Result rows the chat row's resident search body shows before collapsing the
36
- * middle — half the primitive's own default, which the details panel keeps. A
37
- * chat row is a summary surface inside the message flow: the flow must stay
38
- * scannable across many calls, while the details panel is the single-call
39
- * reading surface. A design constant of this UI's row geometry, not a
40
- * deployment choice, so it is fixed here rather than a plugin Config field.
41
- */
6
+ type SearchBlockModelProps = DistributiveOmit<SearchBlockProps, 'labels' | 'maxLines' | 'className'>;
7
+ /** Result rows retained in a Chat card before its middle collapses. */
42
8
  export declare const CHAT_SEARCH_MAX_LINES = 8;
43
- /**
44
- * The {@link SearchBlock} props this derivation owns. Held as a nested object
45
- * (`card`) so a render site spreads exactly the primitive's own surface and can
46
- * never leak a neighbouring field into it. `maxLines`/`className` belong to each
47
- * render site.
48
- */
9
+ /** Search-card props plus an optional locator for a capped full result. */
49
10
  export interface SearchCardModel {
50
- /**
51
- * The props {@link SearchBlock} draws, minus each render site's own
52
- * `maxLines`/`className`.
53
- */
11
+ /** Props consumed by {@link SearchBlock}. */
54
12
  card: SearchBlockModelProps;
55
- /**
56
- * The result view's replacement title, which the presentation contract lets a
57
- * search tool set at settle time. Absent when the presenter supplied none; a
58
- * row then keeps its args-derived summary.
59
- */
60
- title: string | undefined;
61
- /**
62
- * The raw `tool/result` text, flattened, surfaced only when the search was
63
- * capped. The card renders the retained matches or paths, but the recovery
64
- * locator a capped result carries — grep/glob's `Full … stored at: <locator>`
65
- * footer, the one way to reach the rows the cap dropped — lives only in the raw
66
- * result text, which the card replaces. A UI that shows the card would
67
- * otherwise lose it. Absent when the result was not capped (the card holds
68
- * every result) or the block carries no text.
69
- */
13
+ /** Raw result text containing the full-result locator for a capped search. */
70
14
  recovery: string | undefined;
71
15
  }
72
16
  /**
73
- * Derive the search-card props for a tool call, or null when this call is not a
74
- * search card and belongs on the generic path.
75
- *
76
- * Only the result side matters: the search card carries no call-time state, so
77
- * a still-running call (no result view) is null, as is a settled call whose
78
- * result view is not a search card — including a `card` value this UI version
79
- * does not know, which arrives over the wire and cannot be trusted to be one of
80
- * the compiled variants, a `card: 'search'` view whose `shape` is neither
81
- * `matches` nor `paths` (equally untrusted wire data), and a generic result a
82
- * `grep`/`glob` failure or nested `run_code` dispatch produces (its text keeps
83
- * the generic path).
84
- * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
85
- * @returns the search-card props, or null for the generic path.
17
+ * Derive a settled root grep/glob card from persisted metadata.
18
+ * @param block - running or settled Tool block.
19
+ * @returns search-card props, or null for the generic path.
86
20
  */
87
21
  export declare function searchCardModel(block: ToolCallBlock): SearchCardModel | null;
88
22
  export {};
@@ -1,3 +1,4 @@
1
+ /** Pure terminal-card derivation from raw Tool call and result fields. @module */
1
2
  import type { TerminalBlockLabels, TerminalBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
2
3
  import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
3
4
  import type { ToolCallBlock } from './tool-call-model.ts';
@@ -12,25 +13,41 @@ import type { ToolCallBlock } from './tool-call-model.ts';
12
13
  export declare function terminalBlockLabels(t: TranslateNS<'conversation'>): TerminalBlockLabels;
13
14
  /**
14
15
  * The {@link TerminalBlock} props this derivation owns. Picked off the
15
- * primitive's props so the two stay in step; `home` is absent because the web
16
- * client has no home path for the session host (a cwd renders as its last
17
- * path segment), and `maxLines`/`className` belong to each render site.
16
+ * primitive's props so the two stay in step; `maxLines`/`className` belong to
17
+ * each render site.
18
18
  */
19
19
  export interface TerminalCardModel {
20
20
  /**
21
- * The props {@link TerminalBlock} draws. Held as a nested object so a render
22
- * site spreads exactly the primitive's own surface and can never leak a
23
- * neighbouring field into it.
21
+ * The locale-neutral props {@link TerminalBlock} draws. The render site adds
22
+ * `command` after resolving {@link copy} through its locale seat.
24
23
  */
25
- card: Pick<TerminalBlockProps, 'command' | 'cwd' | 'output' | 'exitCode' | 'signal' | 'running'>;
24
+ card: Pick<TerminalBlockProps, 'cwd' | 'output' | 'exitCode' | 'signal' | 'running'>;
26
25
  /**
27
- * The call view's model-authored description, which the contract defines as
28
- * rendering ABOVE the card (the card itself has no description slot). Absent
29
- * when the presenter supplied none, or when the window dropped the call side;
30
- * a row then keeps its args-derived summary.
26
+ * Verbatim Tool data or semantic `terminal_send` data. Product copy stays
27
+ * unresolved until a render site supplies its locale seat.
31
28
  */
32
- description: string | undefined;
29
+ copy: {
30
+ readonly kind: 'shell';
31
+ readonly command: string;
32
+ readonly description: string | undefined;
33
+ } | {
34
+ readonly kind: 'terminal-send';
35
+ readonly text: string;
36
+ readonly sessionId: string;
37
+ };
33
38
  }
39
+ interface LocalizedTerminalCardModel {
40
+ readonly card: Pick<TerminalBlockProps, 'command' | 'cwd' | 'output' | 'exitCode' | 'signal' | 'running'>;
41
+ readonly description: string | undefined;
42
+ }
43
+ /**
44
+ * Resolve locale-owned `terminal_send` copy while preserving Tool-authored
45
+ * shell commands and descriptions verbatim.
46
+ * @param model - locale-neutral terminal card data.
47
+ * @param t - the render site's conversation locale seat.
48
+ * @returns terminal props and description ready for rendering.
49
+ */
50
+ export declare function localizeTerminalCardModel(model: TerminalCardModel, t: TranslateNS<'conversation'>): LocalizedTerminalCardModel;
34
51
  /**
35
52
  * True when a settled terminal card reports a failing exit — a non-zero code
36
53
  * or a terminating signal. The bash tool settles a failing command as a
@@ -42,30 +59,23 @@ export interface TerminalCardModel {
42
59
  */
43
60
  export declare function terminalFailed(model: TerminalCardModel): boolean;
44
61
  /**
45
- * Derive the terminal-card props for a tool call, or null when this call is
46
- * not a terminal card and belongs on the generic path.
47
- *
48
- * The call side supplies the command and its working directory; the result
49
- * side supplies the captured output and exit status. Three cases produce
50
- * null, all of them the documented generic-card default:
51
- *
52
- * - Neither side declares `card:'terminal'` — including a `card` value this
53
- * UI version does not know, which arrives over the wire and therefore
54
- * cannot be trusted to be one of the compiled variants.
55
- * - A settled call whose result view is not a terminal card: the result
56
- * presentation decides how the settled call renders, and the bash tool
57
- * returns a generic fenced card for an execution error or a background
58
- * start, whose text and error styling the generic path preserves.
59
- *
60
- * Window truncation can drop the call head from a settled result (see
61
- * `ToolResultNode.call`/`callView` in dsh-client-runtime), leaving a terminal
62
- * result with no call side. That still renders: the command falls back to the
63
- * result view's replacement title, then to an empty command (the prompt line
64
- * draws bare), and the prompt shows no cwd.
65
- * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
66
- * @param sessionCwd - the session workspace root, which resolves an omitted or
67
- * relative view cwd (see {@link resolveTerminalCwd}); absent leaves both unresolved.
68
- * @returns the terminal-card props, or null for the generic path.
62
+ * Identify a settled root call from the persistent Bash or PowerShell tool.
63
+ * Its result stays on the generic input/output path because the persistent
64
+ * shell can report resets and partial output without one process exit status.
65
+ * @param block - running or settled Tool block.
66
+ * @returns whether the block is a settled persistent-shell call.
67
+ */
68
+ export declare function isSettledPersistentShellCall(block: ToolCallBlock): boolean;
69
+ /**
70
+ * Derive terminal props for supported root shell and terminal-send calls.
71
+ * Standard shell results parse their final status marker; persistent shell
72
+ * results, background calls, errors, malformed input, or child dispatches use
73
+ * the generic path. {@link isSettledPersistentShellCall} lets that generic
74
+ * persistent result remain expandable without inventing one process status.
75
+ * @param block - running or settled Tool block.
76
+ * @param sessionCwd - session workspace root used to resolve workdir.
77
+ * @returns locale-neutral terminal-card data, or null for the generic path.
69
78
  */
70
79
  export declare function terminalCardModel(block: ToolCallBlock, sessionCwd?: string): TerminalCardModel | null;
80
+ export {};
71
81
  //# sourceMappingURL=terminal-card-model.d.ts.map
@@ -1,11 +1,28 @@
1
- import type { ToolCallBlock, ToolResultNode } from '@deepseek-ai/dsh-client-runtime/client';
2
- export type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client';
1
+ /**
2
+ * Pure row-model derivation for tool summary rows: variant classification,
3
+ * one-line summary, expanded-body text, and flattened result output from the
4
+ * frozen call slice. Input material comes from the call ARGUMENTS; output and
5
+ * error material from the settled result node. A supported terminal call gets
6
+ * its expanded body from `terminalCardModel` instead.
7
+ */
8
+ import type { ToolCallBlock, ToolResultNode } from '@deepseek-ai/dsh-client-ui-chat/client';
9
+ import type { LocaleKeysOf } from '@deepseek-ai/dsh-client-ui-slots';
10
+ export type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-chat/client';
3
11
  /** Tool-call row variants selected by the generic atomic renderer. */
4
12
  export type ToolRowVariant = 'search' | 'read' | 'bash' | 'write' | 'edit' | 'code' | 'others';
5
13
  /** Row state semantic; colors self-supplied via StateDot (design gives none). */
6
14
  export type ToolRowState = 'running' | 'ok' | 'error' | 'stopped';
7
- /** Figma row titles per variant (design literals, not translatable copy). */
8
- export declare const VARIANT_TITLES: Record<ToolRowVariant, string>;
15
+ type ToolTitleKey = Extract<LocaleKeysOf<'conversation'>, `tool.title.${string}`>;
16
+ /** Locale key per generic row variant. */
17
+ export declare const VARIANT_TITLE_KEYS: {
18
+ readonly search: "tool.title.search";
19
+ readonly read: "tool.title.read";
20
+ readonly bash: "tool.title.bash";
21
+ readonly write: "tool.title.write";
22
+ readonly edit: "tool.title.edit";
23
+ readonly code: "tool.title.code";
24
+ readonly others: "tool.title.generic";
25
+ };
9
26
  /**
10
27
  * Classify a tool name into its row variant.
11
28
  * @param toolName - wire tool name.
@@ -15,7 +32,7 @@ export declare function classifyTool(toolName: string): ToolRowVariant;
15
32
  /** Everything ToolRow needs, derived once from the frozen slice. */
16
33
  export interface ToolRowModel {
17
34
  variant: ToolRowVariant;
18
- title: string;
35
+ titleKey: ToolTitleKey;
19
36
  summary: string;
20
37
  /**
21
38
  * Filesystem path from args (`path` / `file_path`) when the row is a file
@@ -1,39 +1,14 @@
1
- /**
2
- * Pure derivation of the web-card props from a frozen call slice: the
3
- * `card:'web'` render intent the `web_search`/`web_fetch` tools declare at
4
- * result time arrives on the snapshot as `resultView`, and this is the one
5
- * place that turns it into what {@link WebBlock} draws. Both conversation
6
- * render sites (the chat tool row's resident/expanded body and the details
7
- * panel's Output section) call this, so the sources and fetch summary they
8
- * show are derived once.
9
- *
10
- * The web card is result-only by contract: those tools keep a generic pending
11
- * call view, so there is nothing to derive while the call is still running and
12
- * a running call always takes the generic path.
13
- * @module
14
- */
1
+ /** Pure web-card derivation from raw web result metadata. @module */
15
2
  import type { WebBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
16
3
  import type { ToolCallBlock } from './tool-call-model.ts';
4
+ type DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;
5
+ /** Web-card data owned by the presenter; render sites add localized labels and classes. */
6
+ export type WebCardModelProps = DistributiveOmit<WebBlockProps, 'labels' | 'className'>;
17
7
  /**
18
- * Derive the web-card props for a tool call, or null when this call is not a
19
- * web card and belongs on the generic path.
20
- *
21
- * The result side supplies the whole card: the sources and answer for a
22
- * `search`, the URL and status for a `fetch`. Cases producing null, all of
23
- * them the documented generic-card default:
24
- *
25
- * - A running call (no `resultView` yet): the web tools keep a generic pending
26
- * card, so nothing web-shaped exists until the call settles.
27
- * - A settled call whose result view is not a web card — including a `card`
28
- * value this UI version does not know, which arrives over the wire and so
29
- * cannot be trusted to be one of the compiled variants, and a generic result
30
- * view (a web tool's error path returns the generic card, whose text the
31
- * generic path preserves).
32
- * - A web card whose `kind` this UI version does not know (a newer host's
33
- * value): the wire cannot be trusted to be `search` or `fetch`, so it takes
34
- * the generic path rather than rendering as a malformed fetch.
35
- * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
36
- * @returns the web-card props, or null for the generic path.
8
+ * Derive a settled root web-search or web-fetch card from persisted metadata.
9
+ * @param block - running or settled Tool block.
10
+ * @returns web-card props, or null for the generic path.
37
11
  */
38
- export declare function webCardModel(block: ToolCallBlock): WebBlockProps | null;
12
+ export declare function webCardModel(block: ToolCallBlock): WebCardModelProps | null;
13
+ export {};
39
14
  //# sourceMappingURL=web-card-model.d.ts.map