@deepseek-ai/dsh-client-ui-tool 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 (32) hide show
  1. package/LICENSE +28 -0
  2. package/README.i18n.yaml +6 -0
  3. package/README.md +49 -0
  4. package/README.zh.md +49 -0
  5. package/lib/client.js +1614 -0
  6. package/lib/index.js +6 -0
  7. package/lib/invariant.js +23 -0
  8. package/lib/types/client/apply.d.ts +10 -0
  9. package/lib/types/client/contract/slots.d.ts +35 -0
  10. package/lib/types/client/index.d.ts +4 -0
  11. package/lib/types/client/locale.d.ts +3 -0
  12. package/lib/types/client/tool/ToolCallTree.d.ts +9 -0
  13. package/lib/types/client/tool/ToolDetails.d.ts +16 -0
  14. package/lib/types/client/tool/components/ToolRow.d.ts +79 -0
  15. package/lib/types/client/tool/models/diff-card-model.d.ts +58 -0
  16. package/lib/types/client/tool/models/read-card-model.d.ts +60 -0
  17. package/lib/types/client/tool/models/search-card-model.d.ts +89 -0
  18. package/lib/types/client/tool/models/terminal-card-model.d.ts +71 -0
  19. package/lib/types/client/tool/models/tool-call-model.d.ts +65 -0
  20. package/lib/types/client/tool/models/web-card-model.d.ts +39 -0
  21. package/lib/types/client/tool/toolviews/GenericToolCard.d.ts +7 -0
  22. package/lib/types/client/tool/toolviews/ask-question-row.d.ts +23 -0
  23. package/lib/types/client/tool/toolviews/bash-sample.d.ts +26 -0
  24. package/lib/types/client/tool/toolviews/file-mutation-row.d.ts +31 -0
  25. package/lib/types/client/tool/toolviews/plan-summary.d.ts +48 -0
  26. package/lib/types/client/tool/toolviews/read-row.d.ts +26 -0
  27. package/lib/types/client/tool/toolviews/search-row.d.ts +31 -0
  28. package/lib/types/client/tool/toolviews/todo-row.d.ts +25 -0
  29. package/lib/types/client/tool/toolviews/web-row.d.ts +26 -0
  30. package/lib/types/index.d.ts +4 -0
  31. package/lib/types/invariant.d.ts +16 -0
  32. package/package.json +82 -0
package/lib/index.js ADDED
@@ -0,0 +1,6 @@
1
+ //#region lib/types/index.js
2
+ /** Host loader entry for the browser-only Tool UI plugin. */
3
+ /** Provides no host-side behavior. */
4
+ function apply() {}
5
+ //#endregion
6
+ export { apply };
@@ -0,0 +1,23 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@deepseek-ai/dsh-client-ui-tool`.
4
+ * @module @deepseek-ai/dsh-client-ui-tool/invariant
5
+ */
6
+ const PACKAGE_NAME = "@deepseek-ai/dsh-client-ui-tool";
7
+ /** Cordis companion plugin name. */
8
+ const name = "client-ui-tool-invariant";
9
+ /** Service required before the companion can reserve package ownership. */
10
+ const inject = ["invariants"];
11
+ /**
12
+ * No runtime invariant: Tool composition is browser-only and contributes no
13
+ * events or cross-plugin mutable state; slot ownership is checked by ui-slots.
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 };
@@ -0,0 +1,10 @@
1
+ /** Register the Tool call tree, details renderer, and built-in atomic views. */
2
+ import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
3
+ /** Required service: the slot registry that owns both Tool render seats. */
4
+ export declare const inject: string[];
5
+ /**
6
+ * Mount the whole-Tool renderers and built-in atomic Tool registrations.
7
+ * @param ctx - Client root context.
8
+ */
9
+ export declare function apply(ctx: ClientContext): void;
10
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1,35 @@
1
+ /** Tool UI slot declarations and their composed component props. */
2
+ import type { PropsLocale, PropsRenderSlots, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client';
4
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
5
+ interface SlotMap {
6
+ /** Keyed atomic Tool call view, dispatched by the wire Tool name. */
7
+ 'tool.call.toolview': {
8
+ kind: 'keyed';
9
+ scope: 'session';
10
+ owner: ToolCallOwnerProps;
11
+ };
12
+ }
13
+ }
14
+ /** Standard owner currency supplied to every atomic Tool view. */
15
+ export interface ToolCallOwnerProps {
16
+ /** Tool call identity, stable across running and settled forms. */
17
+ callId: string;
18
+ /** Wire Tool name and keyed dispatch value. */
19
+ toolName: string;
20
+ /** Frozen running call or settled result node. */
21
+ block: ToolCallBlock;
22
+ /** Session workspace root for relative summaries. */
23
+ cwd?: string | undefined;
24
+ /** Open a Tool argument path through the Host. */
25
+ openFile: (path: string) => void;
26
+ /** Inspect this call in the trajectory view when available. */
27
+ inspect?: (() => void) | undefined;
28
+ }
29
+ /** Full props of a registered atomic Tool view. */
30
+ export type ToolCallViewProps = PropsRuntime<'tool.call.toolview'>;
31
+ /** Full props of the Tool call-tree renderer registered as a `tool-call` Chat Node. */
32
+ export type ToolTreeProps = PropsRuntime<'conversation.chat.node', 'tool-call'> & PropsRenderSlots<'tool.call.toolview'> & PropsLocale<'conversation'>;
33
+ /** Full props of the selected Tool output renderer in the details panel. */
34
+ export type ToolDetailsProps = PropsRuntime<'conversation.details.tool'> & PropsLocale<'conversation'>;
35
+ //# sourceMappingURL=slots.d.ts.map
@@ -0,0 +1,4 @@
1
+ /** Browser Tool plugin: whole-call composition and keyed atomic Tool views. */
2
+ export { apply, inject } from './apply.ts';
3
+ export type { ToolCallOwnerProps, ToolCallViewProps, ToolDetailsProps, ToolTreeProps } from './contract/slots.ts';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ /** Locale namespace supplied by the conversation owner to Tool renderers. */
2
+ export declare const CONVERSATION_NS = "conversation";
3
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { ToolTreeProps } from '../contract/slots.ts';
2
+ /**
3
+ * Render one root Tool call and its recursive children through the same
4
+ * atomic keyed dispatch.
5
+ * @param props - whole-Tool owner data and the Tool-owned child-slot share.
6
+ * @returns the Tool call tree.
7
+ */
8
+ export declare function ToolCallTree({ renderSlot, node, selectedCallId, cwd, openFile, inspectCall, t, }: ToolTreeProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=ToolCallTree.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { ToolDetailsProps } from '../contract/slots.ts';
2
+ /** Pure details-body inputs; framework session seats stay at the slot boundary. */
3
+ interface ToolDetailsContentProps {
4
+ block: ToolDetailsProps['block'];
5
+ cwd?: ToolDetailsProps['cwd'];
6
+ t: ToolDetailsProps['t'];
7
+ }
8
+ /**
9
+ * Render the selected Tool call's structured output when its presentation
10
+ * intent is known, otherwise preserve the flattened result text.
11
+ * @param props - selected call slice, workspace root, and locale seat.
12
+ * @returns the details output body.
13
+ */
14
+ export declare function ToolDetails({ block, cwd, t }: ToolDetailsContentProps): import("react").JSX.Element;
15
+ export {};
16
+ //# sourceMappingURL=ToolDetails.d.ts.map
@@ -0,0 +1,79 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { WebBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
3
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
4
+ import { type DiffCardModel } from '../models/diff-card-model.ts';
5
+ import { type ReadCardModel } from '../models/read-card-model.ts';
6
+ import { type SearchCardModel } from '../models/search-card-model.ts';
7
+ import { type TerminalCardModel } from '../models/terminal-card-model.ts';
8
+ import type { ToolRowState, ToolRowVariant } from '../models/tool-call-model.ts';
9
+ export interface ToolRowProps {
10
+ /** The render site's conversation locale seat (terminal/code body copy). */
11
+ t: TranslateNS<'conversation'>;
12
+ variant: ToolRowVariant;
13
+ /** Wire tool name for tool-owned styling layered over the generic variant. */
14
+ toolName?: string | undefined;
15
+ /** Leading 16px tool icon, shown while collapsed and not running/failed. */
16
+ icon: ReactNode;
17
+ title: string;
18
+ summary: string;
19
+ /**
20
+ * Trailing summary fragment rendered outside the ellipsized summary text, so
21
+ * a narrow row clips the summary before this. For a fragment whose whole
22
+ * value is surviving that clip — the todo row's parallel-active count.
23
+ * null/absent = the summary is the whole collapsed content. Dropped on an
24
+ * error row, whose collapsed summary is the failure line instead.
25
+ */
26
+ summarySuffix?: string | null | undefined;
27
+ /** Expanded-body input text; null = no input section. */
28
+ body: string | null;
29
+ /** Flattened result text for the expanded Output section; null/absent = no output section. */
30
+ output?: string | null | undefined;
31
+ /** Error first line shown as the collapsed summary on an error row; null/absent = keep `summary`. */
32
+ 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
+ */
39
+ 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
+ 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
+ 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
+ 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;
64
+ state: ToolRowState;
65
+ /**
66
+ * Filesystem path from tool args; when set with onOpenFile, the summary
67
+ * renders as a hover-underline link that opens the host default app.
68
+ */
69
+ filePath?: string | undefined;
70
+ /** Open the path with the host OS default application (already cwd-resolved). */
71
+ onOpenFile?: ((path: string) => void) | undefined;
72
+ /**
73
+ * Jump to this call in the trajectory view: a hover-revealed Inspect pill
74
+ * over the expanded body. Absent = no affordance.
75
+ */
76
+ inspect?: (() => void) | undefined;
77
+ }
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;
79
+ //# sourceMappingURL=ToolRow.d.ts.map
@@ -0,0 +1,58 @@
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
+ */
10
+ import type { DiffBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
11
+ import type { ToolCallBlock } from './tool-call-model.ts';
12
+ /**
13
+ * Diff-body lines the chat row shows before collapsing the middle — half the
14
+ * primitive's own default, which the details panel keeps. A chat row is a
15
+ * summary surface inside the message flow: the flow must stay scannable across
16
+ * many calls, while the details panel is the single-call reading surface. The
17
+ * same split {@link CHAT_TERMINAL_MAX_LINES} draws for a terminal card, so the
18
+ * two card kinds cap a long body at the same place in the flow. A design
19
+ * constant of this UI's row geometry, not a deployment choice.
20
+ */
21
+ export declare const CHAT_DIFF_MAX_LINES = 8;
22
+ /**
23
+ * The {@link DiffBlock} props this derivation owns. Picked off the primitive's
24
+ * props so the two stay in step; `maxLines`/`className` belong to each render
25
+ * site.
26
+ */
27
+ export interface DiffCardModel {
28
+ /**
29
+ * The props {@link DiffBlock} draws. Held as a nested object so a render site
30
+ * spreads exactly the primitive's own surface and can never leak a
31
+ * neighbouring field into it.
32
+ */
33
+ card: Pick<DiffBlockProps, 'diffs'>;
34
+ }
35
+ /**
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.
55
+ * @returns the diff-card props, or null for the generic path.
56
+ */
57
+ export declare function diffCardModel(block: ToolCallBlock): DiffCardModel | null;
58
+ //# sourceMappingURL=diff-card-model.d.ts.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Pure derivation of the read-card props from a frozen call slice: the
3
+ * `card:'read'` render intent the read tool declares arrives on the snapshot as
4
+ * the settled result node's `resultView`, and this is the one place that turns
5
+ * it into what {@link ReadBlock} draws. Both conversation render sites (the chat
6
+ * tool row's resident body and the details panel's Output section) call this, so
7
+ * the path, lines, total, and language they show are derived once.
8
+ *
9
+ * The read card is result-side only ([read card note](../../../../../../.agents/notes/implemented/feature/2026-07-30-web-read-card.md)):
10
+ * a call carries no file content until `execute` returns, so the pending call
11
+ * stays a generic card (`kind: 'read'`). A running read therefore has no read
12
+ * card, and this returns null for it — the row keeps its args-derived summary
13
+ * until the result arrives.
14
+ * @module
15
+ */
16
+ import type { ReadBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
17
+ import { type ToolCallBlock } from './tool-call-model.ts';
18
+ /**
19
+ * Content lines the chat row's resident read body shows before collapsing the
20
+ * middle — half the primitive's own default, which the details panel keeps. A
21
+ * chat row is a summary surface inside the message flow: the flow must stay
22
+ * scannable across many calls, while the details panel is the single-call
23
+ * reading surface. A design constant of this UI's row geometry, not a
24
+ * deployment choice, so it is fixed here rather than a plugin Config field. The
25
+ * same split [`CHAT_TERMINAL_MAX_LINES`](./terminal-card-model.ts) draws for
26
+ * terminal output.
27
+ */
28
+ export declare const CHAT_READ_MAX_LINES = 8;
29
+ /**
30
+ * The {@link ReadBlock} props this derivation owns. Picked off the primitive's
31
+ * props so the two stay in step; `maxLines`/`className` belong to each render
32
+ * site.
33
+ */
34
+ export type ReadCardModel = Pick<ReadBlockProps, 'label' | 'lines' | 'totalLines' | 'lang'>;
35
+ /**
36
+ * Derive the read-card props for a tool call, or null when this call is not a
37
+ * read card and belongs on the generic path.
38
+ *
39
+ * The read card is result-side only, so only a settled call whose result view
40
+ * declares `card:'read'` produces one. Every other case is null — the
41
+ * documented generic-card default:
42
+ *
43
+ * - A running call: it has no result view yet, and a read carries no content at
44
+ * call time.
45
+ * - A settled call whose result view is not a read card — including a `card`
46
+ * value this UI version does not know, which arrives over the wire and cannot
47
+ * be trusted to be one of the compiled variants, and the read tool's own
48
+ * generic fallback for an error result or a non-envelope body.
49
+ *
50
+ * The label is the read view's `title` when the tool supplied one (the
51
+ * presentation contract's replacement-title rule), otherwise the file path
52
+ * relativized to the session workspace so a workspace-rooted absolute path
53
+ * displays the same short form the row summary shows.
54
+ * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
55
+ * @param sessionCwd - the session workspace root; a workspace-rooted absolute
56
+ * path label displays relative to it. Absent leaves the path as authored.
57
+ * @returns the read-card props, or null for the generic path.
58
+ */
59
+ export declare function readCardModel(block: ToolCallBlock, sessionCwd?: string): ReadCardModel | null;
60
+ //# sourceMappingURL=read-card-model.d.ts.map
@@ -0,0 +1,89 @@
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
+ */
24
+ import type { SearchBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
25
+ 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
+ type DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;
32
+ /** 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
+ */
42
+ 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
+ */
49
+ export interface SearchCardModel {
50
+ /**
51
+ * The props {@link SearchBlock} draws, minus each render site's own
52
+ * `maxLines`/`className`.
53
+ */
54
+ 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
+ */
70
+ recovery: string | undefined;
71
+ }
72
+ /**
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.
86
+ */
87
+ export declare function searchCardModel(block: ToolCallBlock): SearchCardModel | null;
88
+ export {};
89
+ //# sourceMappingURL=search-card-model.d.ts.map
@@ -0,0 +1,71 @@
1
+ import type { TerminalBlockLabels, TerminalBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
2
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { ToolCallBlock } from './tool-call-model.ts';
4
+ /**
5
+ * Build the TerminalBlock display copy from the conversation locale seat —
6
+ * the one place the primitive's label surface pairs with this package's
7
+ * dictionary, shared by every terminal render site (chat row, bash row,
8
+ * details panel).
9
+ * @param t - the render site's conversation locale seat.
10
+ * @returns the full label set for {@link TerminalBlockProps}'s `labels`.
11
+ */
12
+ export declare function terminalBlockLabels(t: TranslateNS<'conversation'>): TerminalBlockLabels;
13
+ /**
14
+ * 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.
18
+ */
19
+ export interface TerminalCardModel {
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.
24
+ */
25
+ card: Pick<TerminalBlockProps, 'command' | 'cwd' | 'output' | 'exitCode' | 'signal' | 'running'>;
26
+ /**
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.
31
+ */
32
+ description: string | undefined;
33
+ }
34
+ /**
35
+ * True when a settled terminal card reports a failing exit — a non-zero code
36
+ * or a terminating signal. The bash tool settles a failing command as a
37
+ * completed call (`isError` stays false: the exit status is result data), so
38
+ * this is the collapsed row's only failure signal; without it the red exit
39
+ * pill would be visible only after expanding the card.
40
+ * @param model - a derived terminal card.
41
+ * @returns whether the card's exit status is a failure.
42
+ */
43
+ export declare function terminalFailed(model: TerminalCardModel): boolean;
44
+ /**
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.
69
+ */
70
+ export declare function terminalCardModel(block: ToolCallBlock, sessionCwd?: string): TerminalCardModel | null;
71
+ //# sourceMappingURL=terminal-card-model.d.ts.map
@@ -0,0 +1,65 @@
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 call whose render intent is
6
+ * a terminal card gets its expanded body from the views instead, through
7
+ * `terminalCardModel` in terminal-card-model.ts.
8
+ */
9
+ import type { ToolCallBlock, ToolResultNode } from '@deepseek-ai/dsh-client-runtime/client';
10
+ export type { ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client';
11
+ /** Tool-call row variants selected by the generic atomic renderer. */
12
+ export type ToolRowVariant = 'search' | 'read' | 'bash' | 'write' | 'edit' | 'code' | 'others';
13
+ /** Row state semantic; colors self-supplied via StateDot (design gives none). */
14
+ export type ToolRowState = 'running' | 'ok' | 'error' | 'stopped';
15
+ /** Figma row titles per variant (design literals, not translatable copy). */
16
+ export declare const VARIANT_TITLES: Record<ToolRowVariant, string>;
17
+ /**
18
+ * Classify a tool name into its row variant.
19
+ * @param toolName - wire tool name.
20
+ * @returns matching variant, others when unknown.
21
+ */
22
+ export declare function classifyTool(toolName: string): ToolRowVariant;
23
+ /** Everything ToolRow needs, derived once from the frozen slice. */
24
+ export interface ToolRowModel {
25
+ variant: ToolRowVariant;
26
+ title: string;
27
+ summary: string;
28
+ /**
29
+ * Filesystem path from args (`path` / `file_path`) when the row is a file
30
+ * tool; absent for URL reads and non-file tools. The chat view resolves
31
+ * relative values against the session cwd before opening.
32
+ */
33
+ filePath: string | undefined;
34
+ /** Expanded-body input text (pretty args); null = no input section. */
35
+ body: string | null;
36
+ /** Flattened result text ({@link resultText}); null while running or when the result carries no text. */
37
+ output: string | null;
38
+ /** First line of the result text on an error row; null for every other state. */
39
+ errorSummary: string | null;
40
+ state: ToolRowState;
41
+ }
42
+ /**
43
+ * Flatten a settled result's content blocks to display text: text blocks
44
+ * verbatim, other block shapes as pretty JSON. Empty content on a failed call
45
+ * falls back to the structured error's `name: code` line.
46
+ * @param node - the settled result node.
47
+ * @returns the flattened result text (may be empty).
48
+ */
49
+ export declare function resultText(node: ToolResultNode): string;
50
+ /**
51
+ * Strip the workspace root from a workspace-rooted absolute path (display only).
52
+ * @param text - the path to shorten.
53
+ * @param cwd - session workspace root; absent or empty leaves the path unchanged.
54
+ * @returns the path relative to the workspace root, or unchanged when it is not rooted there.
55
+ */
56
+ export declare function relativizeToCwd(text: string, cwd: string | undefined): string;
57
+ /**
58
+ * Derive the full row model from a frozen call slice.
59
+ * @param toolName - wire tool name (dispatch-supplied; survives windowless results).
60
+ * @param block - RunningToolCall or ToolResultNode off the snapshot caches.
61
+ * @param cwd - session workspace root; workspace-rooted path summaries display relative to it.
62
+ * @returns the row model.
63
+ */
64
+ export declare function toolRowModel(toolName: string, block: ToolCallBlock, cwd?: string): ToolRowModel;
65
+ //# sourceMappingURL=tool-call-model.d.ts.map
@@ -0,0 +1,39 @@
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
+ */
15
+ import type { WebBlockProps } from '@deepseek-ai/dsh-client-ui-primitives';
16
+ import type { ToolCallBlock } from './tool-call-model.ts';
17
+ /**
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.
37
+ */
38
+ export declare function webCardModel(block: ToolCallBlock): WebBlockProps | null;
39
+ //# sourceMappingURL=web-card-model.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { ToolCallOwnerProps, ToolTreeProps } from '../../contract/slots.ts';
2
+ /** Card props: the owner payload plus the render site's locale seat (plain prop). */
3
+ export interface GenericToolCardProps extends ToolCallOwnerProps {
4
+ t: ToolTreeProps['t'];
5
+ }
6
+ export declare function GenericToolCard({ toolName, block, cwd, openFile, inspect, t }: GenericToolCardProps): import("react").JSX.Element;
7
+ //# sourceMappingURL=GenericToolCard.d.ts.map
@@ -0,0 +1,23 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { ToolCallViewProps } from '../../contract/slots.ts';
4
+ /** Full row props: the toolview runtime share plus the standard locale seat. */
5
+ type AskQuestionRowProps = ToolCallViewProps & PropsLocale<'conversation'>;
6
+ /** One-line question-interaction row (the whole row toggles the call's
7
+ * Input/Output sections, ToolRow's unified expand). */
8
+ export declare function AskQuestionRow({ toolName, block, inspect, t }: AskQuestionRowProps): import("react").JSX.Element;
9
+ /**
10
+ * The ask-question row as a plain registrant plugin following the chat
11
+ * toolview declaration across independent activation and reload lifetimes.
12
+ */
13
+ export declare const askQuestionToolview: {
14
+ name: string;
15
+ inject: string[];
16
+ /**
17
+ * Register the ask-question row into the Tool-owned keyed view slot.
18
+ * @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
19
+ */
20
+ apply(ctx: Context): void;
21
+ };
22
+ export {};
23
+ //# sourceMappingURL=ask-question-row.d.ts.map
@@ -0,0 +1,26 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
3
+ import type { ToolCallViewProps } from '../../contract/slots.ts';
4
+ /** Bash row props: the toolview runtime share plus the standard locale seat. */
5
+ type BashRowProps = ToolCallViewProps & PropsLocale<'conversation'>;
6
+ /**
7
+ * Bash row: icon + Bash · {description} in the shared ToolRow chrome, the
8
+ * whole row toggling the command's terminal or generic error card (ToolRow's unified
9
+ * expand interaction, replicated locally per the registrant posture).
10
+ */
11
+ export declare function BashRow({ toolName, block, sessionId, useSessions, inspect, t }: BashRowProps): import("react").JSX.Element;
12
+ /**
13
+ * The sample as a plain registrant plugin. Slot injection follows the chat
14
+ * toolview declaration across independent activation and reload lifetimes.
15
+ */
16
+ export declare const bashToolviewSample: {
17
+ name: string;
18
+ inject: string[];
19
+ /**
20
+ * Register the bash row into the Tool-owned keyed view slot.
21
+ * @param ctx - registrant context (disposal rides ctx.effect inside slots.register).
22
+ */
23
+ apply(ctx: Context): void;
24
+ };
25
+ export {};
26
+ //# sourceMappingURL=bash-sample.d.ts.map