@xiaoso/dsh-tool-plus 0.1.7 → 0.1.8-beta.3

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 (96) hide show
  1. package/lib/{abort-Caqff3M6.mjs → abort-BtBy5Svf.mjs} +1 -1
  2. package/lib/{alibaba-coding-plan-DTupMiAi.mjs → alibaba-coding-plan-oxHCHJtG.mjs} +2 -2
  3. package/lib/{alibaba-token-plan-Dj3OZhEE.mjs → alibaba-token-plan-B0WzvYnB.mjs} +2 -2
  4. package/lib/{amazon-bedrock-DbFSYXfJ.mjs → amazon-bedrock-BvfYGhrD.mjs} +6 -6
  5. package/lib/{anthropic-CXfWlp-x.mjs → anthropic-C6-vdduI.mjs} +1 -1
  6. package/lib/{anthropic-CTJ3IQVa.mjs → anthropic-Id561lwb.mjs} +13 -13
  7. package/lib/{anthropic-wire-CKuhDwZ1.mjs → anthropic-wire-Cb8AQ1tS.mjs} +13 -13
  8. package/lib/{api-key-validation-CGCJFbFr.mjs → api-key-validation-BXJKlsJg.mjs} +1 -1
  9. package/lib/{azure-openai-responses-ChFbWaGj.mjs → azure-openai-responses-CGws_ijz.mjs} +8 -8
  10. package/lib/{browser-render-9o0Rknop.mjs → browser-render-i7uYOl4f.mjs} +2 -2
  11. package/lib/client.js +2205 -19
  12. package/lib/{cloudflare-ai-gateway-BupNXyKK.mjs → cloudflare-ai-gateway-BK6eadm9.mjs} +2 -2
  13. package/lib/{cloudflare-ai-gateway-EWo0VkP5.mjs → cloudflare-ai-gateway-B_kWnF30.mjs} +1 -1
  14. package/lib/{collapse-DOR8sOGf.mjs → collapse-DU3g7d3B.mjs} +1 -1
  15. package/lib/{coreweave-Ct8cF-da.mjs → coreweave-CkR_FlQi.mjs} +2 -2
  16. package/lib/{cursor-LKGjucn2.mjs → cursor-BXx_5h4a.mjs} +2 -2
  17. package/lib/{cursor-DJV_dcgB.mjs → cursor-BcHwv8qq.mjs} +10 -10
  18. package/lib/{cursor-B95LzVWV.mjs → cursor-BjWbJJLe.mjs} +1 -1
  19. package/lib/{cursor-proto-B8Wj8bv9.mjs → cursor-proto-DPXXYx8S.mjs} +1 -1
  20. package/lib/{devin-DSp0Rw_E.mjs → devin-BZBfzyIz.mjs} +6 -6
  21. package/lib/{devin-BMTdx_hx.mjs → devin-Ce3Wz8_E.mjs} +5 -5
  22. package/lib/{devin-proto-Br8fdyNl.mjs → devin-proto-B6HwDwHK.mjs} +1 -1
  23. package/lib/{error-CORgGg5a.mjs → error-DdCn4m1q.mjs} +3 -3
  24. package/lib/{event-stream-ulcDenZD.mjs → event-stream-ldcUvOA0.mjs} +1 -1
  25. package/lib/{github-copilot-Dstq1D3s.mjs → github-copilot-BT5dkIJl.mjs} +2 -2
  26. package/lib/{github-copilot-headers-DOh1gt_w.mjs → github-copilot-headers-BGL8JO5c.mjs} +2 -2
  27. package/lib/{gitlab-duo-DSCMrU0m.mjs → gitlab-duo-B0qSYCa3.mjs} +1 -1
  28. package/lib/{google-CtsKkOQK.mjs → google-6cRgRmh0.mjs} +3 -3
  29. package/lib/{google-antigravity-z-5KsEci.mjs → google-antigravity-D1llOVad.mjs} +3 -3
  30. package/lib/{google-auth-ieLBaneO.mjs → google-auth-DYhqX1rJ.mjs} +5 -5
  31. package/lib/{google-gemini-cli-CAIPSl7e.mjs → google-gemini-cli-ByQUuKp9.mjs} +7 -7
  32. package/lib/{google-gemini-cli-C6NE5mWz.mjs → google-gemini-cli-CjHy6mFG.mjs} +3 -3
  33. package/lib/{google-oauth-shared-DhMllAkt.mjs → google-oauth-shared-CSwCT0Yl.mjs} +1 -1
  34. package/lib/{google-shared-B0aNCYEH.mjs → google-shared-DYjJp0mQ.mjs} +5 -5
  35. package/lib/{google-vertex-Bbd1tYNc.mjs → google-vertex-CbOvlE5j.mjs} +4 -4
  36. package/lib/{idle-iterator-DlUkEfzW.mjs → idle-iterator-DTBaEIbM.mjs} +2 -2
  37. package/lib/index.mjs +1278 -184
  38. package/lib/{kilo-ChJL54wq.mjs → kilo-cVG1aNZM.mjs} +1 -1
  39. package/lib/{kimi-C2c_Zq8A.mjs → kimi-BFfnFDhu.mjs} +4 -4
  40. package/lib/{launch-DKDH71En.mjs → launch-Uq7920ng.mjs} +7 -7
  41. package/lib/{markit-CmRfm4E2.mjs → markit-BmsfOFVh.mjs} +18 -18
  42. package/lib/{muse-code-Di1VZmB1.mjs → muse-code-CtcevJab.mjs} +1 -1
  43. package/lib/{ollama-B8ic3sEp.mjs → ollama-B5hR1P1p.mjs} +8 -8
  44. package/lib/{openai-codex-DuJNC99x.mjs → openai-codex-CxkPyvyt.mjs} +2 -2
  45. package/lib/{openai-codex-responses-BL29nh9K.mjs → openai-codex-responses-BbM3Q7nJ.mjs} +9 -9
  46. package/lib/{openai-completions-BK2f2dBv.mjs → openai-completions-CffXVOCL.mjs} +13 -13
  47. package/lib/{openai-reasoning-fallback-BdB3RCbj.mjs → openai-reasoning-fallback-DFdD1ok5.mjs} +2 -2
  48. package/lib/{openai-responses-CGQPlIIy.mjs → openai-responses-DgqOvSn_.mjs} +9 -9
  49. package/lib/{perplexity-TBjz3VMB.mjs → perplexity-JFp3knZN.mjs} +2 -2
  50. package/lib/{protobuf-aab1UGVn.mjs → protobuf-BJHNU9-E.mjs} +1 -1
  51. package/lib/{proxy-5nWqRL1f.mjs → proxy-B51IWEMt.mjs} +2 -2
  52. package/lib/{scrapers-CtQrQ5kG.mjs → scrapers-DU4u4-Co.mjs} +7 -7
  53. package/lib/{src-BwW51vA5.mjs → src-DUUqyo9y.mjs} +42 -42
  54. package/lib/{stream-B_7qN-bA.mjs → stream-DHdFrAG4.mjs} +54 -54
  55. package/lib/{stream-markup-healing-DKT1lnkW.mjs → stream-markup-healing-DlJ9abTw.mjs} +2 -2
  56. package/lib/{thinking-CiLa2LFB.mjs → thinking-D6LJxkz_.mjs} +1 -1
  57. package/lib/types/client/locales.d.ts +1 -1
  58. package/lib/types/config/settings.d.ts +8 -0
  59. package/lib/types/tools/ast-grep/adapter/index.d.ts +23 -0
  60. package/lib/types/tools/edit/adapter/index.d.ts +3 -0
  61. package/lib/types/tools/glob/adapter/index.d.ts +2 -0
  62. package/lib/types/tools/grep/adapter/index.d.ts +4 -0
  63. package/lib/types/tools/read/adapter/index.d.ts +18 -0
  64. package/lib/types/tools/write/adapter/index.d.ts +2 -0
  65. package/lib/types/web/client/ToolCardShell.d.ts +111 -0
  66. package/lib/types/web/client/labels.d.ts +36 -0
  67. package/lib/types/web/client/registerToolCards.d.ts +35 -0
  68. package/lib/types/web/client/row-utils.d.ts +177 -0
  69. package/lib/types/web/client/rows/AstEditRow.d.ts +22 -0
  70. package/lib/types/web/client/rows/FileMutationRow.d.ts +23 -0
  71. package/lib/types/web/client/rows/ReadRow.d.ts +31 -0
  72. package/lib/types/web/client/rows/SearchRow.d.ts +21 -0
  73. package/lib/types/web/client/rows/TerminalRow.d.ts +24 -0
  74. package/lib/types/web/client/rows/WriteRow.d.ts +22 -0
  75. package/lib/types/web/client/rows/command-card-facts.d.ts +45 -0
  76. package/lib/types/web/client/rows/image-card.d.ts +60 -0
  77. package/lib/types/web/client/rows/read-card-facts.d.ts +33 -0
  78. package/lib/types/web/client/rows/search-card-facts.d.ts +37 -0
  79. package/lib/types/web/contract.d.ts +249 -0
  80. package/lib/types/web/host/ast-edit.d.ts +10 -0
  81. package/lib/types/web/host/bash.d.ts +30 -0
  82. package/lib/types/web/host/edit.d.ts +33 -0
  83. package/lib/types/web/host/read.d.ts +48 -0
  84. package/lib/types/web/host/search.d.ts +41 -0
  85. package/lib/types/web/host/write.d.ts +13 -0
  86. package/lib/{types-PVueGi9S.mjs → types-DT9vgZ3S.mjs} +1 -1
  87. package/lib/{utils-CUPhpw9A.mjs → utils-BMmwLB0f.mjs} +2 -2
  88. package/lib/{utils-ECAwvaPQ.mjs → utils-C-Lo_JC6.mjs} +41 -41
  89. package/lib/{utils-DeWqNWV8.mjs → utils-D31VFael.mjs} +1 -1
  90. package/lib/{vision-guard-_XwsL1DF.mjs → vision-guard-BlAAqGUC.mjs} +1 -1
  91. package/lib/{xai-oauth-CXhnz0gO.mjs → xai-oauth-QPyScm4X.mjs} +1 -1
  92. package/lib/{xiaomi-psoUItal.mjs → xiaomi-CLzjxHAi.mjs} +1 -1
  93. package/lib/{zai-ApJ8HBgT.mjs → zai-wDp0g7VC.mjs} +1 -1
  94. package/lib/{zip-Kd602XNe.mjs → zip-CNtIFfyV.mjs} +7 -7
  95. package/package.json +3 -1
  96. package/presets/package.json +1 -1
@@ -25,6 +25,8 @@ export interface GlobToolOutput {
25
25
  text: string;
26
26
  fileCount?: number;
27
27
  truncated?: boolean;
28
+ /** 引擎的结果路径列表(display 相对路径),卡片按它出 paths 卡。 */
29
+ paths?: string[];
28
30
  }
29
31
  /**
30
32
  * 把 OMP AgentToolResult 转成 DSH glob 工具输出。
@@ -26,6 +26,10 @@ export interface GrepToolOutput {
26
26
  files?: string[];
27
27
  scopePath?: string;
28
28
  truncated?: boolean;
29
+ /** 引擎给渲染器的分组显示文本(`# dir/` + `## file` + `*N│line` 代码帧)。 */
30
+ displayContent?: string;
31
+ /** 搜索时的会话 cwd:display 头里的相对路径按它还原成绝对路径。 */
32
+ cwd?: string;
29
33
  }
30
34
  /**
31
35
  * 把 OMP AgentToolResult 转成 DSH grep 工具输出。
@@ -27,6 +27,24 @@ export interface ReadToolOutput {
27
27
  truncated?: boolean;
28
28
  /** 拍板#22:图片读取的附件提交结果(信封文本已并入 text,此字段供 UI/审计)。 */
29
29
  image?: SavedImageRef;
30
+ /**
31
+ * 引擎给渲染器的无前缀窗口(read.ts 的 `details.displayContent`):卡片
32
+ * meta 的唯一数据源,不含 hashline/行号前缀,供 gutter 自绘。
33
+ */
34
+ display?: {
35
+ text: string;
36
+ startLine: number;
37
+ lineNumbers?: Array<number | null>;
38
+ };
39
+ /** 引擎的 source meta(`{type:'path'|'url'|'internal', value}`)——卡片取路径用。 */
40
+ source?: {
41
+ type: string;
42
+ value: string;
43
+ };
44
+ /** 目录列举读取(不出行号卡)。 */
45
+ isDirectory?: boolean;
46
+ /** 结果里 text 块的个数(>1 说明是多目标/信封读取,不出行号卡)。 */
47
+ textBlocks?: number;
30
48
  }
31
49
  /**
32
50
  * 把 OMP AgentToolResult 转成 DSH read 工具输出。
@@ -19,6 +19,8 @@ export type { ToolSession } from '../../omp/sdk.ts';
19
19
  export interface WriteToolOutput {
20
20
  path: string;
21
21
  text: string;
22
+ /** 卡片用语法提示;认不出语言时不带该键(meta 里不许出现 undefined)。 */
23
+ lang?: string;
22
24
  }
23
25
  /** 完整执行链路(defineTool.execute 与单测共用)。 */
24
26
  export declare function executeWriteTool(exec: any, cfg: RuntimeConfig, args: any): Promise<WriteToolOutput>;
@@ -0,0 +1,111 @@
1
+ /**
2
+ * The shared card shell every row renders through.
3
+ *
4
+ * The shipped `ToolRow` is not reusable from a plugin (ui-tool is not part of
5
+ * the client platform baseline), so this is our own: one 24px header line
6
+ * (state dot + title + separator + ellipsized summary + optional `+N -M`
7
+ * suffix + clickable path), a keyboard-reachable disclosure, and a body that
8
+ * is either the card a row built or the flattened result text.
9
+ *
10
+ * Two properties matter more than the visuals:
11
+ * - **Never throw.** Every value is coerced defensively, and {@link CardBoundary}
12
+ * turns a crash inside a card into the same generic shell, because an
13
+ * exception reaching the slot retires the cell and abdicates the call to the
14
+ * shipped row.
15
+ * - **Theme tokens only.** The sheet below reads `--dsw-alias-*` (plus the two
16
+ * published content-font vars) and hard-codes no colour, so light and dark
17
+ * both come out right.
18
+ * @module @xiaoso/dsh-tool-plus/web/client/ToolCardShell
19
+ */
20
+ import { Component, type ReactNode } from 'react';
21
+ import { type CardBlockView, type CardOpenFileOptions, type CardState, type CardTranslate } from './row-utils.ts';
22
+ /** Props of {@link ToolCardShell}. */
23
+ export interface ToolCardShellProps {
24
+ /** Card translate seat. */
25
+ t: CardTranslate;
26
+ /** Run state driving the leading dot and the status word. */
27
+ state: CardState;
28
+ /** Single-line title (the tool name). */
29
+ title: string;
30
+ /** Collapsed summary after the separator; empty renders no separator. */
31
+ summary?: string | null | undefined;
32
+ /** Trailing fragment kept outside the summary's ellipsis (e.g. `+3 -1`). */
33
+ summarySuffix?: string | null | undefined;
34
+ /** Render the summary in the error tone (a failure line, not a description). */
35
+ summaryTone?: 'default' | 'error' | undefined;
36
+ /** Filesystem path to offer as a clickable link; requires `openFile`. */
37
+ filePath?: string | null | undefined;
38
+ /** 1-based line the call was about; absent opens the file at its start. */
39
+ filePathLine?: number | null | undefined;
40
+ /** Opens `filePath` in the host's file viewer. */
41
+ openFile?: ((path: string, options?: CardOpenFileOptions) => void) | undefined;
42
+ /** Jump to this call in the trajectory view; absent renders no affordance. */
43
+ inspect?: (() => void) | undefined;
44
+ /** Body text used when no `children` card is supplied. */
45
+ text?: string | null | undefined;
46
+ /** Start expanded. */
47
+ defaultOpen?: boolean | undefined;
48
+ /** Card body; wins over `text` when supplied. */
49
+ children?: ReactNode;
50
+ }
51
+ /**
52
+ * Render the shared card shell.
53
+ * @param props - see {@link ToolCardShellProps}.
54
+ * @returns the card row and, when expanded, its body.
55
+ */
56
+ export declare function ToolCardShell(props: ToolCardShellProps): import("react").JSX.Element;
57
+ /** Props of {@link GenericCard}. */
58
+ export interface GenericCardProps {
59
+ /** Card translate seat. */
60
+ t: CardTranslate;
61
+ /** Localized card title. */
62
+ title: string;
63
+ /** The frozen call node. */
64
+ block: CardBlockView;
65
+ /** The call's parsed arguments, when there are any. */
66
+ args: Record<string, unknown> | null;
67
+ /** Jump to this call in the trajectory view. */
68
+ inspect?: (() => void) | undefined;
69
+ }
70
+ /**
71
+ * The generic card: every row's degradation path.
72
+ *
73
+ * A card is only drawn once its metadata passed a `narrow*` guard, so anything
74
+ * else — a running call, a window-truncated call, a Code Dispatch child, a
75
+ * failure, a payload from another plugin version — lands here with the call's
76
+ * own title, run state, argument count, and result text.
77
+ * @param props - see {@link GenericCardProps}.
78
+ * @returns the generic shell.
79
+ */
80
+ export declare function GenericCard({ t, title, block, args, inspect }: GenericCardProps): import("react").JSX.Element;
81
+ /** Props of {@link CardBoundary}. */
82
+ export interface CardBoundaryProps {
83
+ /** Card translate seat, forwarded to the fallback shell. */
84
+ t: CardTranslate;
85
+ /** Title the fallback shell shows. */
86
+ title: string;
87
+ /** The call node, so the fallback can still offer its result text. */
88
+ block?: CardBlockView | undefined;
89
+ /** Summary the fallback shell shows before the failure line replaces it. */
90
+ summary?: string | null | undefined;
91
+ /** The card to protect. */
92
+ children: ReactNode;
93
+ }
94
+ /** State of {@link CardBoundary}: the caught failure, once there is one. */
95
+ interface CardBoundaryState {
96
+ failure: string | null;
97
+ }
98
+ /**
99
+ * Contain a card's render failure: the fallback is a generic shell (never the
100
+ * card's own chrome), so one malformed payload cannot take the call's cell —
101
+ * or the whole slot — down with it.
102
+ */
103
+ export declare class CardBoundary extends Component<CardBoundaryProps, CardBoundaryState> {
104
+ state: CardBoundaryState;
105
+ /** React's error-boundary hook: record the failure and render the fallback. */
106
+ static getDerivedStateFromError(error: unknown): CardBoundaryState;
107
+ /** Report the failure without rethrowing. */
108
+ componentDidCatch(error: unknown): void;
109
+ render(): ReactNode;
110
+ }
111
+ export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Card copy for the browser tool views: every string the six row components
3
+ * and the shared shell draw, in its own locale namespace so it can never
4
+ * collide with the settings card's `tool-plus` bundle (the slots registry
5
+ * merges namespaces, and re-declaring one would be a compile error).
6
+ *
7
+ * zh is the source of truth for the key set; both dictionaries are
8
+ * `Record<ToolCardLocaleKey, string>`, so a missing or extra key in either is
9
+ * a compile error. Template parameters use the host's `{name}` placeholder
10
+ * convention (the seat interpolates the params record into the string).
11
+ *
12
+ * The wording mirrors the shipped conversation namespace for the same
13
+ * primitives (diff / read / search / terminal chrome) so a takeover does not
14
+ * change how the cards read; tool titles and the generic-row copy are ours.
15
+ * @module @xiaoso/dsh-tool-plus/web/client/labels
16
+ */
17
+ /** Locale namespace of the tool-card bundle (registered by `registerToolCards`). */
18
+ export declare const CARD_LOCALE_NS = "tool-plus-cards";
19
+ /** Every copy key of the tool-card namespace. */
20
+ export type ToolCardLocaleKey = 'copy' | 'copied' | 'collapse' | 'expand' | 'collapseAria' | 'expandAria' | 'expandRest' | 'files.one' | 'files.other' | 'running' | 'done' | 'failed' | 'cancelled' | 'timedOut' | 'noOutput' | 'title.bash' | 'title.read' | 'title.write' | 'title.edit' | 'title.grep' | 'title.glob' | 'title.astGrep' | 'title.astEdit' | 'write.lines' | 'write.madeExecutable' | 'astEdit.replacements' | 'astEdit.files' | 'astEdit.parseErrors' | 'astEdit.rules' | 'astEdit.rulesRest' | 'read.window' | 'read.collapseAria' | 'read.expandAria' | 'read.expandRest' | 'search.paths' | 'search.paths.truncated' | 'search.matches' | 'search.matches.truncated' | 'search.noResults' | 'search.scope' | 'search.collapseAria' | 'search.expandAria' | 'search.expandRest' | 'terminal.signal' | 'terminal.exitCode' | 'terminal.running' | 'terminal.failed' | 'terminal.done' | 'terminal.noOutput' | 'bash.background' | 'image.loading' | 'image.loadFailed' | 'image.open' | 'image.openNamed' | 'image.dialog' | 'image.close' | 'image.unnamed' | 'image.caption' | 'generic.params' | 'generic.noDetail' | 'inspect';
21
+ /** Simplified Chinese copy (the source dictionary). */
22
+ export declare const zh: Record<ToolCardLocaleKey, string>;
23
+ /** English dictionary, checked complete against the zh key set. */
24
+ export declare const en: Record<ToolCardLocaleKey, string>;
25
+ /** The bilingual bundle handed to `ctx.locale.register(CARD_LOCALE_NS, …)`. */
26
+ export declare const cardLocales: {
27
+ zh: Record<ToolCardLocaleKey, string>;
28
+ en: Record<ToolCardLocaleKey, string>;
29
+ };
30
+ /** Merge this plugin's card namespace into the slot locale table (official pattern). */
31
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
32
+ interface LocaleNamespaceMap {
33
+ /** Copy for the browser tool cards. */
34
+ 'tool-plus-cards': ToolCardLocaleKey;
35
+ }
36
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Register every tool card this plugin renders through the keyed
3
+ * `tool.call.toolview` slot.
4
+ *
5
+ * Two shapes live here:
6
+ * - `ast_grep` / `ast_edit` are this plugin's own tool names, so their keys are
7
+ * unclaimed and registering them is purely additive;
8
+ * - `bash` / `read` / `write` / `edit` / `grep` / `glob` have a shipped row at
9
+ * the slot's default priority, which we shadow by registering at
10
+ * {@link CARD_TAKEOVER_PRIORITY} (the lowest live entry of a cell renders).
11
+ *
12
+ * The shadowing mechanism is a public API but has no published design note, so
13
+ * this module never trusts it blindly: right after registering it reads the
14
+ * cell winners back and, when one of them is not our row, it reports the lost
15
+ * key (`console.error`) and keeps its own entries anyway — a mixed tool view is
16
+ * the deliberate signal that the takeover assumption broke, never a silent
17
+ * fallback to the shipped rows. The `webCards` settings switch (default on)
18
+ * mounts and unmounts the cards on demand.
19
+ *
20
+ * Registration runs inside `ctx.slots.inject`, so it waits for the shipped
21
+ * declaration and is torn down with the plugin fiber. A crash inside a row is
22
+ * contained by that row's own boundary rather than thrown at the slot.
23
+ *
24
+ * @module @xiaoso/dsh-tool-plus/web/client/registerToolCards
25
+ */
26
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
27
+ /**
28
+ * Mount the tool cards.
29
+ *
30
+ * Registers the card dictionaries and one entry per tool key, then keeps the
31
+ * registration in step with the `webCards` switch. Everything
32
+ * installed here rides the caller's fiber, so plugin unload removes it all.
33
+ * @param ctx - the browser plugin context.
34
+ */
35
+ export declare function registerToolCards(ctx: ClientContext): void;
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Defensive readers shared by the tool-card rows, plus the adapters that bind
3
+ * this plugin's card dictionary onto the cordis-free UI primitives.
4
+ *
5
+ * The rows render data the model never sees: a call's frozen node, its raw
6
+ * arguments, its result text, and the Host-projected metadata. Every read here
7
+ * is written to survive a malformed input — a window-truncated call, a
8
+ * hand-rolled argument payload, a metadata blob from another plugin version —
9
+ * and to return a "no data" answer instead of throwing: an exception inside a
10
+ * row reaches the slot, which retires the cell and hands the call back to the
11
+ * shipped row with the failure surfaced in the console.
12
+ *
13
+ * Metadata is only ever read through `src/web/contract.ts`'s `narrow*` guards;
14
+ * nothing here touches a raw `meta` field directly.
15
+ * @module @xiaoso/dsh-tool-plus/web/client/row-utils
16
+ */
17
+ import type { DiffBlockLabels, ReadBlockLabels, SearchBlockLabels, StateDotState, TerminalBlockLabels } from '@deepseek-ai/dsh-client-ui-primitives';
18
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
19
+ import type { CARD_LOCALE_NS, ToolCardLocaleKey } from './labels.ts';
20
+ /** Translate seat of this plugin's card namespace. */
21
+ export type CardTranslate = TranslateNS<typeof CARD_LOCALE_NS>;
22
+ /**
23
+ * Structural view of the frozen running-or-settled node a row receives. It
24
+ * names only the fields the cards actually read, so an upstream node shape
25
+ * change degrades a card instead of breaking the row.
26
+ */
27
+ export interface CardBlockView {
28
+ readonly kind?: unknown;
29
+ readonly callId?: unknown;
30
+ readonly parentCallId?: unknown;
31
+ readonly name?: unknown;
32
+ readonly argsRaw?: unknown;
33
+ readonly call?: {
34
+ readonly name?: unknown;
35
+ readonly argsRaw?: unknown;
36
+ } | null;
37
+ readonly content?: unknown;
38
+ readonly isError?: unknown;
39
+ readonly meta?: unknown;
40
+ }
41
+ /** Card run state, one step off the shipped `ToolRowState` (no `stopped`). */
42
+ export type CardState = 'running' | 'ok' | 'error' | 'warning';
43
+ /** Whether a block is the settled half of a call pair. */
44
+ export declare function isSettled(block: CardBlockView): boolean;
45
+ /**
46
+ * Parse the call's raw argument JSON.
47
+ *
48
+ * The parsed object is memoized per node (the node is immutable), so repeated
49
+ * renders of one card pay for a single parse.
50
+ * @param block - the frozen running-or-settled call node.
51
+ * @returns the argument object, or `null` when the head is missing or its JSON
52
+ * is not an object.
53
+ */
54
+ export declare function parseCardArgs(block: CardBlockView): Record<string, unknown> | null;
55
+ /**
56
+ * Run state of one call.
57
+ *
58
+ * A settled `isError` result is an error; a foreground command that timed out
59
+ * or was cancelled is amber rather than green (the shipped terminal model
60
+ * reads only the trailing exit marker, which is exactly what the card owner
61
+ * was told not to trust). A non-zero exit stays `ok`: bash reports a failing
62
+ * command as result data, and the card's own status pill carries the red.
63
+ * @param block - the frozen running-or-settled call node.
64
+ * @returns the card run state.
65
+ */
66
+ export declare function cardState(block: CardBlockView): CardState;
67
+ /** Map a card run state onto the primitive's dot semantics. */
68
+ export declare function dotState(state: CardState): StateDotState;
69
+ /**
70
+ * The assistive-technology status word for a run state, or `null` when the
71
+ * state is already carried by the row's content.
72
+ */
73
+ export declare function stateStatus(state: CardState, t: CardTranslate): string | null;
74
+ /**
75
+ * Flatten a settled result's text blocks.
76
+ * @param block - the frozen call node.
77
+ * @returns the joined text blocks (empty for a running call or non-text output).
78
+ */
79
+ export declare function resultText(block: CardBlockView): string;
80
+ /**
81
+ * The opaque metadata a call's result carried, exactly as the transport
82
+ * delivered it. Callers must run it through a `narrow*` guard before reading.
83
+ * @param block - the frozen call node.
84
+ * @returns the raw metadata, or `undefined` while the call is running.
85
+ */
86
+ export declare function cardMeta(block: CardBlockView): unknown;
87
+ /**
88
+ * Whether the call was dispatched by another tool (a Code Dispatch child).
89
+ * The card rows fall back to the generic shell for those, mirroring the
90
+ * shipped rows: a child diff/read/search inside a parent card would nest a
91
+ * surface inside the parent's own body.
92
+ */
93
+ export declare function isSubCall(block: CardBlockView): boolean;
94
+ /**
95
+ * The first non-empty line of a text, trimmed — the collapsed summary of an
96
+ * error, and the closing line of the generic shell's body.
97
+ * @param text - the source text.
98
+ * @returns the first line, clipped to a row-sized maximum (never throws).
99
+ */
100
+ export declare function firstLine(text: string): string;
101
+ /**
102
+ * A string argument by name.
103
+ * @param args - parsed arguments, or `null`.
104
+ * @param name - the argument key.
105
+ * @returns its value when it is a non-empty string, else `null`.
106
+ */
107
+ export declare function argText(args: Record<string, unknown> | null, name: string): string | null;
108
+ /** Options object passed to the owner's `openFile` (a line to land on). */
109
+ export interface CardOpenFileOptions {
110
+ line?: number;
111
+ }
112
+ /**
113
+ * Shorten an absolute path against the session workspace so a summary stays
114
+ * readable in a narrow row.
115
+ * @param path - the path to display.
116
+ * @param cwd - the session workspace root, when known.
117
+ * @returns the path relative to `cwd`, or `path` unchanged.
118
+ */
119
+ export declare function displayPath(path: string, cwd: string | undefined): string;
120
+ /**
121
+ * The collapsed summary for a call whose card could not be built: how many
122
+ * arguments the model sent, so the row is not blank.
123
+ * @param args - parsed arguments, or `null`.
124
+ * @param t - the card translate seat.
125
+ * @returns the localized parameter count.
126
+ */
127
+ export declare function argsSummary(args: Record<string, unknown> | null, t: CardTranslate): string;
128
+ /**
129
+ * The card title for a wire tool name.
130
+ *
131
+ * The same row component can be registered under several keys (one search row
132
+ * serves `grep`, `glob`, and `ast_grep`), and a window-truncated call has no
133
+ * name at all, so the caller names the key it was registered for as a fallback.
134
+ * @param toolName - the node's wire tool name (empty when truncated).
135
+ * @param t - the card translate seat.
136
+ * @param fallback - title key to use when the name is unknown.
137
+ * @returns the localized title.
138
+ */
139
+ export declare function cardTitle(toolName: string, t: CardTranslate, fallback: ToolCardLocaleKey): string;
140
+ /**
141
+ * Count a preview's content lines, ignoring the single trailing newline that
142
+ * terminates the last line.
143
+ * @param text - the preview text.
144
+ * @returns its line count (0 for empty text).
145
+ */
146
+ export declare function lineCount(text: string): number;
147
+ /** A shell result's trailing status markers, and the text they were stripped from. */
148
+ export interface ShellStatus {
149
+ /** The output text with its trailing marker lines removed. */
150
+ output: string;
151
+ /** Marked exit code; `null` when the marker itself carried no code. */
152
+ exitCode: number | null | undefined;
153
+ /** Terminating signal name, when a marker named one. */
154
+ signal: string | undefined;
155
+ /** A timeout marker was present. */
156
+ timedOut: boolean;
157
+ }
158
+ /**
159
+ * Split a settled shell result into its output and the status markers the
160
+ * renderer appended (timeout, terminating signal, exit code — in that order,
161
+ * so every marker is at the end and any run of them is stripped).
162
+ *
163
+ * The Host metadata already carries the run state; parsing is what keeps the
164
+ * markers out of the terminal card's output pane, and it is the only source
165
+ * for a signal name the projection does not carry.
166
+ * @param text - the result text.
167
+ * @returns the marker-free output and the facts the markers named.
168
+ */
169
+ export declare function parseShellStatus(text: string): ShellStatus;
170
+ /** Bind the card dictionary to the diff primitive's chrome labels. */
171
+ export declare function diffBlockLabels(t: CardTranslate): DiffBlockLabels;
172
+ /** Bind the card dictionary to the read primitive's chrome labels. */
173
+ export declare function readBlockLabels(t: CardTranslate): ReadBlockLabels;
174
+ /** Bind the card dictionary to the search primitive's chrome labels. */
175
+ export declare function searchBlockLabels(t: CardTranslate): SearchBlockLabels;
176
+ /** Bind the card dictionary to the terminal primitive's chrome labels. */
177
+ export declare function terminalBlockLabels(t: CardTranslate): TerminalBlockLabels;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `ast_edit` row: the engine's own change preview.
3
+ *
4
+ * The AST engine already renders a grouped preview (file header, replacement
5
+ * count, the first line of each change) and hands it to the Host as
6
+ * `displayContent`; that text is what this card shows, because the exact
7
+ * before/after hunks are dropped inside the ported tool and the write happens
8
+ * in the native engine. No diff is computed here, and no `±` totals are shown.
9
+ * @module @xiaoso/dsh-tool-plus/web/client/rows/AstEditRow
10
+ */
11
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
12
+ import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
13
+ import { CARD_LOCALE_NS } from '../labels.ts';
14
+ /** Props the slot hands this row, plus its own locale seat. */
15
+ type RowProps = ToolCallViewProps & PropsLocale<typeof CARD_LOCALE_NS>;
16
+ /**
17
+ * Render an `ast_edit` call as a change preview.
18
+ * @param props - the slot's owner props and this plugin's translate seat.
19
+ * @returns the preview card, or the generic shell when there is no preview.
20
+ */
21
+ export default function AstEditRow(props: RowProps): import("react").JSX.Element;
22
+ export {};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `edit` row: a diff card.
3
+ *
4
+ * Two sources, in order: the Host projection (`meta.diffs`, built from the
5
+ * engine's own unified diff — the change is already computed and needs no
6
+ * extra I/O), then the replace-form arguments while the call is still running
7
+ * (or when the Host could not project a diff). Every other edit mode (patch,
8
+ * hashline, apply_patch) has no diff until it settles, so it falls back to the
9
+ * generic shell rather than guessing from `patch`/`input` text.
10
+ * @module @xiaoso/dsh-tool-plus/web/client/rows/FileMutationRow
11
+ */
12
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
13
+ import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
14
+ import { CARD_LOCALE_NS } from '../labels.ts';
15
+ /** Props the slot hands this row, plus its own locale seat. */
16
+ type RowProps = ToolCallViewProps & PropsLocale<typeof CARD_LOCALE_NS>;
17
+ /**
18
+ * Render an `edit` call as a diff card.
19
+ * @param props - the slot's owner props and this plugin's translate seat.
20
+ * @returns the diff card, or the generic shell for a mode with no diff yet.
21
+ */
22
+ export default function FileMutationRow(props: RowProps): import("react").JSX.Element;
23
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `read` row: a line-numbered window view, or the image the read returned.
3
+ *
4
+ * Two mutually exclusive bodies hang off one call:
5
+ * - The Host projected a readable window (`meta`) → the line-numbered text card.
6
+ * - It did not (an image, a directory, a sqlite or archive target, an internal
7
+ * URL, a multi-range `:raw` read) → this row tries the image branch, which
8
+ * draws the result's image blocks through the session-authorized loader the
9
+ * slot hands every tool view. Anything else keeps the generic shell and its
10
+ * result text.
11
+ *
12
+ * The image branch reimplements the shipped message-image interaction — the
13
+ * `singleFit` box, 64px gallery tiles, a retry control on a failed load, and a
14
+ * body-portal lightbox for the original — so a tool-card image and a message
15
+ * image of the same file behave identically. It lives here rather than in
16
+ * `image-card.ts` because that module stays pure: this file owns the loader
17
+ * calls, their cancellation, and the DOM.
18
+ * @module @xiaoso/dsh-tool-plus/web/client/rows/ReadRow
19
+ */
20
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
21
+ import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
22
+ import { CARD_LOCALE_NS } from '../labels.ts';
23
+ /** Props the slot hands this row, plus its own locale seat. */
24
+ type RowProps = ToolCallViewProps & PropsLocale<typeof CARD_LOCALE_NS>;
25
+ /**
26
+ * Render a `read` call as a line-numbered window or an image.
27
+ * @param props - the slot's owner props and this plugin's translate seat.
28
+ * @returns the read card, or the generic shell when nothing else fits.
29
+ */
30
+ export default function ReadRow(props: RowProps): import("react").JSX.Element;
31
+ export {};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `grep` / `glob` / `ast_grep` row: a search result card.
3
+ *
4
+ * One component serves all three keys because the Host projects one
5
+ * `shape`-discriminated metadata form for them: grouped matches for the two
6
+ * grep engines, a flat path list for glob. The title follows the call's own
7
+ * wire name, so the same component reads as Grep, Glob, or AST Grep.
8
+ * @module @xiaoso/dsh-tool-plus/web/client/rows/SearchRow
9
+ */
10
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
11
+ import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
12
+ import { CARD_LOCALE_NS } from '../labels.ts';
13
+ /** Props the slot hands this row, plus its own locale seat. */
14
+ type RowProps = ToolCallViewProps & PropsLocale<typeof CARD_LOCALE_NS>;
15
+ /**
16
+ * Render a search call as a result card.
17
+ * @param props - the slot's owner props and this plugin's translate seat.
18
+ * @returns the search card, or the generic shell with the result text.
19
+ */
20
+ export default function SearchRow(props: RowProps): import("react").JSX.Element;
21
+ export {};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * `bash` row: a terminal card for foreground runs, a generic row for jobs.
3
+ *
4
+ * The card's command comes from the arguments, its working directory from the
5
+ * arguments falling back to the Host projection and then the session root, and
6
+ * its exit status from the Host projection — the trailing `[exit code: N]`
7
+ * marker is only parsed to keep it out of the output pane (and to recover the
8
+ * signal name the projection does not carry). A call the Host handed to a
9
+ * background job shows the job id instead: its result is a hand-off notice,
10
+ * not a finished command.
11
+ * @module @xiaoso/dsh-tool-plus/web/client/rows/TerminalRow
12
+ */
13
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
14
+ import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
15
+ import { CARD_LOCALE_NS } from '../labels.ts';
16
+ /** Props the slot hands this row, plus its own locale seat. */
17
+ type RowProps = ToolCallViewProps & PropsLocale<typeof CARD_LOCALE_NS>;
18
+ /**
19
+ * Render a `bash` call as a terminal card.
20
+ * @param props - the slot's owner props and this plugin's translate seat.
21
+ * @returns the terminal card, the job hand-off row, or the generic shell.
22
+ */
23
+ export default function TerminalRow(props: RowProps): import("react").JSX.Element;
24
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `write` row: a content preview card.
3
+ *
4
+ * The engine's write card is a preview of what was written, not a diff, and
5
+ * the content is in the arguments — so the card is complete while the call is
6
+ * still running, and the line count is counted on the client exactly as the
7
+ * engine's own header does. The language hint comes from the Host projection
8
+ * (`meta.lang`), which is the only part the arguments cannot supply.
9
+ * @module @xiaoso/dsh-tool-plus/web/client/rows/WriteRow
10
+ */
11
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
12
+ import type { ToolCallViewProps } from '@deepseek-ai/dsh-client-ui-tool/client';
13
+ import { CARD_LOCALE_NS } from '../labels.ts';
14
+ /** Props the slot hands this row, plus its own locale seat. */
15
+ type RowProps = ToolCallViewProps & PropsLocale<typeof CARD_LOCALE_NS>;
16
+ /**
17
+ * Render a `write` call as a content preview.
18
+ * @param props - the slot's owner props and this plugin's translate seat.
19
+ * @returns the card, or the generic shell when the arguments are unusable.
20
+ */
21
+ export default function WriteRow(props: RowProps): import("react").JSX.Element;
22
+ export {};
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Collapsed-fact builders for the two command-shaped cards: the command a
3
+ * `bash` description hides, and the rewrite rule an `ast_edit` preview only
4
+ * shows once expanded.
5
+ *
6
+ * Both cards collapse to one head line. `bash`'s head used to be the model's
7
+ * own `description` — a sentence about intent, never the command that ran — so
8
+ * the only way to learn what executed was to expand the card. `ast_edit`'s head
9
+ * names the file and the replacement count, and its body previews the *result*:
10
+ * the rule that produced that result lives only in the call's `ops` argument,
11
+ * which no card showed at all. Each builder recovers one fact from the call's
12
+ * own arguments, so nothing is inferred from output, and a call head that fell
13
+ * outside the session window degrades to the facts the card already holds.
14
+ * @module @xiaoso/dsh-tool-plus/web/client/rows/command-card-facts
15
+ */
16
+ import { type CardTranslate } from '../row-utils.ts';
17
+ /**
18
+ * The `bash` card's collapsed summary: what ran, placed after the sentence
19
+ * saying why.
20
+ *
21
+ * The command is the fact the head must carry, so the description can never be
22
+ * the whole summary — it is a prefix at most. Only its first line is used: a
23
+ * summary is one row high, and the rest of a multi-line command belongs to the
24
+ * expanded body, which draws the whole thing.
25
+ * @param description - the model's one-line intent, or `null` when absent.
26
+ * @param command - the command actually executed (never empty).
27
+ * @param outcome - the interruption word (`timedOut` / `cancelled`), or `null`.
28
+ * @returns the outcome alone when the run was interrupted; otherwise the
29
+ * description joined to the command's first line, or that line alone.
30
+ */
31
+ export declare function bashCardSummary(description: string | null, command: string, outcome: string | null): string;
32
+ /**
33
+ * The `ast_edit` card's rule line: the first usable `ops` entry, written the
34
+ * way the tool's own `ops` argument writes it (`pat → out`).
35
+ *
36
+ * Only the first rule is stated, with the count of the entries behind it: the
37
+ * card exists to preview one change, and a call may carry many rules whose
38
+ * patterns are whole AST fragments — listing them would bury the preview. The
39
+ * remaining count is the array tail, not the number of *usable* entries, so it
40
+ * always describes the call as it was made.
41
+ * @param args - the call's parsed arguments, or `null` when its head is gone.
42
+ * @param t - this plugin's card translate seat.
43
+ * @returns the rule line, or `null` when the call carries no usable rule.
44
+ */
45
+ export declare function astEditRuleLine(args: Record<string, unknown> | null, t: CardTranslate): string | null;