@deepseek-harness-tui/dsh-tui 0.7.3 → 0.8.0

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 (69) hide show
  1. package/README.md +2 -2
  2. package/bin/dsh-tui.js +19 -3
  3. package/cordis.patch.yml +24 -11
  4. package/cordis.yml +9 -1
  5. package/lib/types/commands.d.ts.map +1 -1
  6. package/lib/types/commands.js +2 -1
  7. package/lib/types/components/MessageList.d.ts +3 -1
  8. package/lib/types/components/MessageList.d.ts.map +1 -1
  9. package/lib/types/components/MessageList.js +4 -4
  10. package/lib/types/components/PluginSceneBoundary.d.ts +31 -0
  11. package/lib/types/components/PluginSceneBoundary.d.ts.map +1 -0
  12. package/lib/types/components/PluginSceneBoundary.js +29 -0
  13. package/lib/types/components/SkillsPicker.d.ts +18 -0
  14. package/lib/types/components/SkillsPicker.d.ts.map +1 -0
  15. package/lib/types/components/SkillsPicker.js +50 -0
  16. package/lib/types/components/SplitDiffView.d.ts +28 -0
  17. package/lib/types/components/SplitDiffView.d.ts.map +1 -0
  18. package/lib/types/components/SplitDiffView.js +417 -0
  19. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +3 -1
  20. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  21. package/lib/types/components/messages/AssistantToolUseMessage.js +17 -7
  22. package/lib/types/dsh-adapter/channel.d.ts +68 -0
  23. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  24. package/lib/types/dsh-adapter/channel.js +120 -5
  25. package/lib/types/dsh-adapter/contract.d.ts +1 -1
  26. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  27. package/lib/types/dsh-adapter/contract.js +1 -0
  28. package/lib/types/dsh-adapter/index.d.ts +4 -0
  29. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  30. package/lib/types/dsh-adapter/index.js +1 -0
  31. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  32. package/lib/types/dsh-adapter/plugin.js +59 -0
  33. package/lib/types/dsh-adapter/promptDebug.d.ts +10 -0
  34. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -0
  35. package/lib/types/dsh-adapter/promptDebug.js +148 -0
  36. package/lib/types/dsh-adapter/scenes.d.ts +75 -0
  37. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -0
  38. package/lib/types/dsh-adapter/scenes.js +78 -0
  39. package/lib/types/dsh-adapter/settings-sections.d.ts +116 -0
  40. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -0
  41. package/lib/types/dsh-adapter/settings-sections.js +63 -0
  42. package/lib/types/dsh-adapter/settingsEditor.d.ts +128 -0
  43. package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -0
  44. package/lib/types/dsh-adapter/settingsEditor.js +244 -0
  45. package/lib/types/i18n.d.ts +137 -10
  46. package/lib/types/i18n.d.ts.map +1 -1
  47. package/lib/types/i18n.js +36 -3
  48. package/lib/types/jsx-runtime.d.ts +2 -0
  49. package/lib/types/jsx-runtime.d.ts.map +1 -0
  50. package/lib/types/jsx-runtime.js +13 -0
  51. package/lib/types/modelRoute.d.ts +10 -2
  52. package/lib/types/modelRoute.d.ts.map +1 -1
  53. package/lib/types/modelRoute.js +33 -4
  54. package/lib/types/scenes.d.ts +3 -0
  55. package/lib/types/scenes.d.ts.map +1 -0
  56. package/lib/types/scenes.js +4 -0
  57. package/lib/types/screens/Chat.d.ts.map +1 -1
  58. package/lib/types/screens/Chat.js +107 -11
  59. package/lib/types/screens/Settings.d.ts +20 -0
  60. package/lib/types/screens/Settings.d.ts.map +1 -0
  61. package/lib/types/screens/Settings.js +333 -0
  62. package/lib/types/screens/StatusLine.js +1 -1
  63. package/lib/types/settings-sections.d.ts +3 -0
  64. package/lib/types/settings-sections.d.ts.map +1 -0
  65. package/lib/types/settings-sections.js +4 -0
  66. package/lib/types/theme.d.ts +12 -0
  67. package/lib/types/theme.d.ts.map +1 -1
  68. package/lib/types/theme.js +36 -0
  69. package/package.json +17 -1
package/README.md CHANGED
@@ -138,7 +138,7 @@ macOS 自带 Terminal.app 会自行消费 `⌘` 快捷键,请继续使用 `Ctr
138
138
  | 会话 | `/new` 新会话 · `/resume` 会话浏览器(搜索、预览、跨项目、折叠子 agent 运行) · `/rename` 重命名会话 · `/workspace resume|rename|open` 管理工作区 · `/clear` 清屏 · `/compact` 压缩 · `/export` 导出 Markdown · `/trace` 轨迹场景(亦可 `Ctrl+T`) |
139
139
  | 状态 | `/status` 会话信息 · `/cost` token 用量 · `/doctor` 环境自检 · `/config` 配置来源 · `/init` 创建 AGENTS.md |
140
140
  | 模型 | `/model` 选择器 · `/thinking` 思考显示 · `/tokens` token 明细 · `/theme` 主题选择器 · `/lang` 中英界面切换 |
141
- | 账号/策略 | `/provider` 添加模型提供方 · `/login` 凭证状态 · `/logout` 登出说明 · `/permissions` 权限说明 · `/add-dir` 文件策略范围 · `/hooks` · `/mcp` · `/memory` |
141
+ | 账号/策略 | `/provider` 添加模型提供方 · `/login` 凭证状态 · `/logout` 登出说明 · `/permissions` 权限说明 · `/add-dir` 文件策略范围 · `/hooks` · `/mcp` |
142
142
  | 技能 | `/audit` 代码审计 · `/bug` bug 报告 · `/review` 代码评审 · `/practice` 编程练习 · `/pr_comments` PR 评论 · `/release-notes` 发布说明 · `/vuln-check` 漏洞检查 |
143
143
  | 其它 | `/agents` 子代理列表 · `/update` 自动更新并重启 · `/vim` · `/terminal-setup` · `/connect` · `/help` · `/exit` |
144
144
  | 注册表 | `/plan` `/goal`(DSH 命令注册表插件,随插件自动并入 `/` 菜单) |
@@ -231,7 +231,7 @@ compaction 和持久化继续由 DSH 服务拥有。更详细的模块边界与
231
231
  权限提升命令会弹出审批条。`/permission` 预设切换由 dsh-base 的
232
232
  `permission-presets` 插件提供,profile 组合默认可用;裸组合 `cordis.yml`
233
233
  未挂载该插件(无 `/permission` 命令)。
234
- - `/vim` `/connect` `/hooks` `/memory` 为 CC 同名占位:对应能力在 DSH 侧无等价
234
+ - `/vim` `/connect` `/hooks` 为 CC 同名占位:对应能力在 DSH 侧无等价
235
235
  机制,命令会给出明确说明而非静默。
236
236
 
237
237
  完整已知限制与安全边界见[架构与限制](docs/architecture.md)。
package/bin/dsh-tui.js CHANGED
@@ -55,9 +55,13 @@ const MSG = {
55
55
  en: `[dsh-tui] First run — initializing the ${PROFILE} profile (${PACKAGE}@${ownVersion})…`,
56
56
  zh: `[dsh-tui] 首次运行,正在初始化 ${PROFILE} profile(${PACKAGE}@${ownVersion})…`,
57
57
  },
58
+ bootstrapRetryW: {
59
+ en: '[dsh-tui] pnpm refused to add to the workspace root (ERR_PNPM_ADDING_TO_ROOT) — retrying with -w…',
60
+ zh: '[dsh-tui] pnpm 拒绝写入 workspace 根(ERR_PNPM_ADDING_TO_ROOT)——带 -w 重试…',
61
+ },
58
62
  installFailed: {
59
- en: `[dsh-tui] Plugin install failed. Retry manually later:\n dsh plugin --profile ${PROFILE} add ${PACKAGE}@${ownVersion}`,
60
- zh: `[dsh-tui] 插件安装失败。可稍后手工重试:\n dsh plugin --profile ${PROFILE} add ${PACKAGE}@${ownVersion}`,
63
+ en: `[dsh-tui] Plugin install failed. Retry manually later:\n dsh plugin --profile ${PROFILE} add -w ${PACKAGE}@${ownVersion}`,
64
+ zh: `[dsh-tui] 插件安装失败。可稍后手工重试:\n dsh plugin --profile ${PROFILE} add -w ${PACKAGE}@${ownVersion}`,
61
65
  },
62
66
  versionMismatch: {
63
67
  en: (installed, own) =>
@@ -151,7 +155,19 @@ if (installedVersion === undefined) {
151
155
  process.exit(1)
152
156
  }
153
157
  console.log(msg('bootstrapStart'))
154
- const add = spawnSync(...cmd('dsh', ['plugin', '--profile', PROFILE, 'add', `${PACKAGE}@${ownVersion}`]), { stdio: 'inherit', ...shellOpt })
158
+ // pnpm ≥11 在带 pnpm-workspace.yaml 的 profile 目录里可能拒绝向
159
+ // workspace root 写依赖(ERR_PNPM_ADDING_TO_ROOT,issue #239):识别该
160
+ // 错误时带 -w 重试一次。stderr 走 pipe 捕获供识别,stdout 保持
161
+ // inherit 让用户实时看到安装进度;手工重试提示同步带 -w。
162
+ const runAdd = extraArgs => spawnSync(
163
+ ...cmd('dsh', ['plugin', '--profile', PROFILE, 'add', ...extraArgs, `${PACKAGE}@${ownVersion}`]),
164
+ { stdio: ['inherit', 'inherit', 'pipe'], ...shellOpt },
165
+ )
166
+ let add = runAdd([])
167
+ if (add.status !== 0 && String(add.stderr).includes('ERR_PNPM_ADDING_TO_ROOT')) {
168
+ console.log(msg('bootstrapRetryW'))
169
+ add = runAdd(['-w'])
170
+ }
155
171
  if (add.status !== 0) {
156
172
  console.error(msg('installFailed'))
157
173
  process.exit(add.status ?? 1)
package/cordis.patch.yml CHANGED
@@ -187,6 +187,16 @@
187
187
  # execution and durable command events remain owned by dsh-commands.
188
188
  - id: dsh-tui-command-trees
189
189
  name: '@deepseek-harness-tui/dsh-tui/command-trees'
190
+ # Optional plugins declare editable settings sections here (issue #165);
191
+ # storage, validation and writes remain owned by the dsh settings service.
192
+ - id: dsh-tui-settings-sections
193
+ name: '@deepseek-harness-tui/dsh-tui/settings-sections'
194
+
195
+ # Optional plugins register full-screen scenes (trajectory-style whole-
196
+ # terminal views) here and open them from their own command handlers;
197
+ # rendering and input ownership remain owned by the TUI's Chat screen.
198
+ - id: dsh-tui-scenes
199
+ name: '@deepseek-harness-tui/dsh-tui/scenes'
190
200
 
191
201
  # The agent-preset roster (issue #8): `ctx.agentPresets`, the service the
192
202
  # TUI composes every session's model-facing world from. No `roots` here —
@@ -217,17 +227,17 @@
217
227
  name: '@deepseek-harness-tui/dsh-tui'
218
228
  # The entry-level dependency augments the plugin's `agents` inject and
219
229
  # prevents startup Session creation from racing WorkspaceRegistry init.
220
- inject: [workspaceRegistry, agents, tuiWorkspaces]
221
- # `tuiWorkspaces` lives in the entry-level inject ONLY as an ordering
222
- # guarantee alongside the dsh-tui-workspaces row above — it is
223
- # deliberately absent from the plugin's code-level inject (issue
224
- # #183): the dsh CLI may read this patch from an older copy of the
225
- # package than the plugin module it loads, and a hard code-level
226
- # inject then deadlocks the tree at boot ("pending (waiting for
227
- # service: tuiWorkspaces)"). Without the row the TUI degrades to a
228
- # local-only workspace runtime instead. (The comment sits below the
229
- # inject line: verify-workspace-attachment.mjs asserts the
230
- # name→inject distance.)
230
+ inject: [workspaceRegistry, agents, tuiWorkspaces, tuiScenes]
231
+ # `tuiWorkspaces`/`tuiScenes` live in the entry-level inject ONLY as an
232
+ # ordering (and reload-rebind) guarantee alongside their service rows
233
+ # above — they are deliberately absent from the plugin's code-level
234
+ # inject (issue #183): the dsh CLI may read this patch from an older
235
+ # copy of the package than the plugin module it loads, and a hard
236
+ # code-level inject then deadlocks the tree at boot ("pending (waiting
237
+ # for service: tuiWorkspaces)"). Without the rows the TUI degrades:
238
+ # /workspace falls back to the local-only runtime, plugin scenes never
239
+ # open. (The comment sits below the inject line:
240
+ # verify-workspace-attachment.mjs asserts the name→inject distance.)
231
241
  config:
232
242
  provider: deepseek-official
233
243
  # Alt-screen fullscreen(CC 同款):应用内鼠标选区(选择即复制, OSC 52 +
@@ -235,6 +245,9 @@
235
245
  # inline 模式下由终端原生选择/复制/scrollback 接管;想用 fullscreen 在
236
246
  # profile 用户层 cordis.patch.yml 同 id 覆盖整行 config(fullscreen: true)。
237
247
  fullscreen: false
248
+ # Edit/Write diff 呈现:auto(≥110 列双栏对照,窄屏统一式)/
249
+ # split(强制双栏)/ unified(强制统一式)。/settings 屏可实时改。
250
+ # diffLayout: auto
238
251
  # 每个请求实际生效的推理强度,按当前路由的 adapter 档位校验
239
252
  # (deepseek: off/high/max)——不在档位表里的值被忽略,回落 adapter
240
253
  # 默认值。优先于持久化的 Shift+Tab 选择(~/.dsh-tui/effort.json);
package/cordis.yml CHANGED
@@ -29,9 +29,17 @@
29
29
  - id: dsh-tui-command-trees
30
30
  name: '@deepseek-harness-tui/dsh-tui/command-trees'
31
31
 
32
+ # Optional plugins declare editable settings sections here (issue #165);
33
+ # storage, validation and writes remain owned by the dsh settings service.
34
+ - id: dsh-tui-settings-sections
35
+ name: '@deepseek-harness-tui/dsh-tui/settings-sections'
36
+
37
+ - id: dsh-tui-scenes
38
+ name: '@deepseek-harness-tui/dsh-tui/scenes'
39
+
32
40
  - id: dsh-tui
33
41
  name: '@deepseek-harness-tui/dsh-tui'
34
- inject: [agents, tuiWorkspaces]
42
+ inject: [agents, tuiWorkspaces, tuiScenes]
35
43
  config:
36
44
  provider: deepseek-official
37
45
  # Alt-screen fullscreen (CC 同款): 应用内鼠标选区(选择即复制, OSC 52 +
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,qBAAqB,EAAE,CAAA;AAEpG;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EAuDxC,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIhG;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,YAAY,EAAE,CAKhB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,SAAS,YAAY,EAAmB,EAC/C,QAAQ,GAAE,eAA0B,GACnC,iBAAiB,EAAE,CAoCrB"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,qBAAqB,EAAE,CAAA;AAEpG;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EAwDxC,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIhG;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,YAAY,EAAE,CAKhB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,SAAS,YAAY,EAAmB,EAC/C,QAAQ,GAAE,eAA0B,GACnC,iBAAiB,EAAE,CAoCrB"}
@@ -26,6 +26,7 @@ export const LOCAL_COMMANDS = [
26
26
  { name: 'status', description: 'Show session status' },
27
27
  { name: 'cost', description: 'Show session token usage' },
28
28
  { name: 'config', description: 'Show the dsh-tui configuration source' },
29
+ { name: 'settings', description: 'View and edit plugin settings' },
29
30
  { name: 'doctor', description: 'Run environment checks' },
30
31
  { name: 'init', description: 'Create AGENTS.md in the working directory' },
31
32
  { name: 'agents', description: 'Show subagents of this session' },
@@ -46,7 +47,7 @@ export const LOCAL_COMMANDS = [
46
47
  { name: 'add-dir', description: 'Show the filesystem policy scope' },
47
48
  { name: 'hooks', description: 'Show hooks status' },
48
49
  { name: 'mcp', description: 'Show MCP status' },
49
- { name: 'memory', description: 'Show memory status' },
50
+ { name: 'skills', description: 'List available skills' },
50
51
  { name: 'update', description: 'Update dsh-tui and restart' },
51
52
  // Built-in skills (CC's skill commands, driven through DSH skills)
52
53
  { name: 'audit', description: 'Run a comprehensive code audit on this project' },
@@ -2,13 +2,15 @@ import React from 'react';
2
2
  import { type ScrollBoxHandle } from '../ui.js';
3
3
  import type { ChatRow } from '../dsh-adapter/channel.js';
4
4
  import type { DOMElement } from '../ink/dom.js';
5
- export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, showAll, onToggleAll, onLoadOlder, thinkingVisible, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }: {
5
+ export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout, showAll, onToggleAll, onLoadOlder, thinkingVisible, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }: {
6
6
  rows: readonly ChatRow[];
7
7
  expanded: boolean;
8
8
  expandedRows: ReadonlySet<number>;
9
9
  selectedId: number | null;
10
10
  onToggleRow: (rowId: number) => void;
11
11
  model: string;
12
+ /** Edit/Write diff presentation preference (forwarded to tool cards). */
13
+ diffLayout?: 'auto' | 'split' | 'unified';
12
14
  showAll: boolean;
13
15
  onToggleAll: () => void;
14
16
  /** Restore folded-away older rows from the session log (CC-style "load
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAuC/C,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,qBAwPA;AAuQD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,KAAK,CAAC,SAAS,CAMlB"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAuC/C,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,UAAmB,EACnB,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,qBAyPA;AA2QD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,KAAK,CAAC,SAAS,CAMlB"}
@@ -37,7 +37,7 @@ const DEFAULT_ROW_HEIGHT = 2;
37
37
  /** Cold-start estimate of the header block above the rows; corrected by the
38
38
  * first layout measurement. */
39
39
  const DEFAULT_HEADER_LINES = 14;
40
- export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, showAll, onToggleAll, onLoadOlder, thinkingVisible = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }) {
40
+ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout = 'auto', showAll, onToggleAll, onLoadOlder, thinkingVisible = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }) {
41
41
  const hiddenCount = rows.length - MAX_RENDERED_ROWS;
42
42
  // The thinking filter runs BEFORE virtualization so window indices line up.
43
43
  const visibleRows = (showAll || hiddenCount <= 0
@@ -232,10 +232,10 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
232
232
  // spacing; only the very first row of the whole list has none.
233
233
  const addMargin = margins.get(row.id) === true;
234
234
  const tool = row.tool;
235
- return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: row.text, executionTarget: row.executionTarget, streaming: row.streaming === true, durationMs: row.durationMs, time: row.time, addMargin: addMargin, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, background: rowBackground(row.id), toolCallId: tool?.callId, toolName: tool?.name, toolArgsText: tool?.argsText, toolArgsFull: tool?.argsFull, toolStatus: tool?.status, toolResultText: tool?.resultText, toolResultFull: tool?.resultFull, toolErrorText: tool?.errorText, toolFootnote: failureHintRowId === row.id ? failureHint : undefined, toolCallView: tool?.callView, toolResultView: tool?.resultView, toolStartedAt: tool?.startedAt, toolDurationMs: tool?.durationMs, nowSec: tool?.status === 'running' ? nowSec : undefined, onToggleRow: onToggleRow, setRowRef: setRowRef }, row.id));
235
+ return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: row.text, executionTarget: row.executionTarget, streaming: row.streaming === true, durationMs: row.durationMs, time: row.time, addMargin: addMargin, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, diffLayout: diffLayout, background: rowBackground(row.id), toolCallId: tool?.callId, toolName: tool?.name, toolArgsText: tool?.argsText, toolArgsFull: tool?.argsFull, toolStatus: tool?.status, toolResultText: tool?.resultText, toolResultFull: tool?.resultFull, toolErrorText: tool?.errorText, toolFootnote: failureHintRowId === row.id ? failureHint : undefined, toolCallView: tool?.callView, toolResultView: tool?.resultView, toolStartedAt: tool?.startedAt, toolDurationMs: tool?.durationMs, nowSec: tool?.status === 'running' ? nowSec : undefined, onToggleRow: onToggleRow, setRowRef: setRowRef }, row.id));
236
236
  }), bottomPad > 0 && _jsx(Box, { height: bottomPad, flexShrink: 0 })] }));
237
237
  }
238
- function TranscriptRow({ rowId, kind, text, executionTarget, streaming, durationMs, time, addMargin, isSelected, isExpanded, expanded, model, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, onToggleRow, setRowRef, }) {
238
+ function TranscriptRow({ rowId, kind, text, executionTarget, streaming, durationMs, time, addMargin, isSelected, isExpanded, expanded, model, diffLayout, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, onToggleRow, setRowRef, }) {
239
239
  const ref = React.useCallback((el) => {
240
240
  setRowRef(rowId, el);
241
241
  }, [setRowRef, rowId]);
@@ -277,7 +277,7 @@ function TranscriptRow({ rowId, kind, text, executionTarget, streaming, duration
277
277
  startedAt: toolStartedAt,
278
278
  durationMs: toolDurationMs,
279
279
  };
280
- return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantToolUseMessage, { tool: tool, addMargin: addMargin, verbose: isExpanded || expanded, isSelected: isSelected, isExpanded: isExpanded, footnote: toolFootnote }) }));
280
+ return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantToolUseMessage, { tool: tool, addMargin: addMargin, verbose: isExpanded || expanded, isSelected: isSelected, isExpanded: isExpanded, footnote: toolFootnote, diffLayout: diffLayout }) }));
281
281
  }
282
282
  case 'notice':
283
283
  return (_jsx(Box, { marginTop: 1, ref: ref, children: _jsx(Divider, { title: ` ${text} ` }) }));
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Error boundary for plugin scenes (dsh-tui-scenes). A scene component is
3
+ * third-party code rendered inside Chat's tree: without a boundary a render
4
+ * error propagates to ink's app-level boundary (src/ink/components/App.tsx)
5
+ * and takes the whole TUI down with it. Catching here collapses the blast
6
+ * radius to the scene itself — the host reports the error to the transcript
7
+ * and closes the scene, landing the user back on the conversation.
8
+ *
9
+ * Boundaries catch render/lifecycle errors only; errors thrown from async
10
+ * handlers and effects remain the scene's own responsibility (see the
11
+ * 场景红线 section in docs/plugins.md).
12
+ */
13
+ import React from 'react';
14
+ type PluginSceneBoundaryProps = {
15
+ /** Scene id, echoed into the error report. */
16
+ readonly id: string;
17
+ /** Called once per caught error; the host reports it and closes the scene. */
18
+ readonly onError: (id: string, error: Error) => void;
19
+ readonly children: React.ReactNode;
20
+ };
21
+ type PluginSceneBoundaryState = {
22
+ readonly crashed: boolean;
23
+ };
24
+ export declare class PluginSceneBoundary extends React.Component<PluginSceneBoundaryProps, PluginSceneBoundaryState> {
25
+ state: PluginSceneBoundaryState;
26
+ static getDerivedStateFromError(): PluginSceneBoundaryState;
27
+ componentDidCatch(error: Error): void;
28
+ render(): React.ReactNode;
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=PluginSceneBoundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginSceneBoundary.d.ts","sourceRoot":"","sources":["../../../src/components/PluginSceneBoundary.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,KAAK,wBAAwB,GAAG;IAC9B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IACpD,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CACnC,CAAA;AAED,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,qBAAa,mBAAoB,SAAQ,KAAK,CAAC,SAAS,CACtD,wBAAwB,EACxB,wBAAwB,CACzB;IACU,KAAK,EAAE,wBAAwB,CAAqB;IAE7D,MAAM,CAAC,wBAAwB,IAAI,wBAAwB;IAQlD,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIrC,MAAM,IAAI,KAAK,CAAC,SAAS;CAGnC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Error boundary for plugin scenes (dsh-tui-scenes). A scene component is
3
+ * third-party code rendered inside Chat's tree: without a boundary a render
4
+ * error propagates to ink's app-level boundary (src/ink/components/App.tsx)
5
+ * and takes the whole TUI down with it. Catching here collapses the blast
6
+ * radius to the scene itself — the host reports the error to the transcript
7
+ * and closes the scene, landing the user back on the conversation.
8
+ *
9
+ * Boundaries catch render/lifecycle errors only; errors thrown from async
10
+ * handlers and effects remain the scene's own responsibility (see the
11
+ * 场景红线 section in docs/plugins.md).
12
+ */
13
+ import React from 'react';
14
+ export class PluginSceneBoundary extends React.Component {
15
+ state = { crashed: false };
16
+ static getDerivedStateFromError() {
17
+ // Suppress the scene's next render. The host's onError closes the scene
18
+ // in the same commit turn, so this null fallback normally never paints;
19
+ // it exists only to keep a closed-nowhere crash from remounting the
20
+ // throwing component in a loop.
21
+ return { crashed: true };
22
+ }
23
+ componentDidCatch(error) {
24
+ this.props.onError(this.props.id, error);
25
+ }
26
+ render() {
27
+ return this.state.crashed ? null : this.props.children;
28
+ }
29
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import type { SkillInfo } from '../dsh-adapter/channel.js';
3
+ /**
4
+ * `/skills` picker (issue #204) in the ModelPicker style: a
5
+ * permission-colored Pane listing the live agent's skill catalog —
6
+ * user-invocable skills lead with `/name`(它们在 / 菜单里也是这个形态),
7
+ * 描述行是「来源 · 简述」。Enter 由 Chat 填回 `/name `,Esc 关闭。
8
+ *
9
+ * 长列表按焦点窗口化(ModelPicker 同款):picker 经 OverlayAbove 浮层挂载后
10
+ * 有 maxHeight 裁剪,全量渲染会让焦点行被裁掉(看不到焦点按 Enter)。
11
+ */
12
+ export declare function SkillsPicker({ skills, focusIndex, }: {
13
+ skills: readonly SkillInfo[];
14
+ focusIndex: number;
15
+ }): React.ReactNode;
16
+ /** `/skills` while the registry snapshot is still in flight (ModelPickerLoading 同款). */
17
+ export declare function SkillsPickerLoading(): React.ReactNode;
18
+ //# sourceMappingURL=SkillsPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkillsPicker.d.ts","sourceRoot":"","sources":["../../../src/components/SkillsPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AA2B1D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,UAAU,GACX,EAAE;IACD,MAAM,EAAE,SAAS,SAAS,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,KAAK,CAAC,SAAS,CAyClB;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,IAAI,KAAK,CAAC,SAAS,CAerD"}
@@ -0,0 +1,50 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { t } from '../i18n.js';
3
+ import { Box, Text, useTerminalSize } from '../ui.js';
4
+ import { Pane } from './design-system/Pane.js';
5
+ import { ListItem } from './design-system/ListItem.js';
6
+ import { HintLine } from './design-system/HintLine.js';
7
+ import { LoadingState } from './design-system/LoadingState.js';
8
+ import { listWindow } from './listWindow.js';
9
+ /** 来源桶 → 本地化标签(未知桶原样显示,SkillSource 对自定义桶开放)。 */
10
+ function sourceLabel(source) {
11
+ switch (source) {
12
+ case 'bundled':
13
+ return t('skills-source-bundled');
14
+ case 'user-dsh':
15
+ case 'user-agents':
16
+ return t('skills-source-user');
17
+ case 'project-dsh':
18
+ case 'project-agents':
19
+ return t('skills-source-project');
20
+ case 'runtime':
21
+ return t('skills-source-runtime');
22
+ case 'custom':
23
+ return t('skills-source-custom');
24
+ default:
25
+ return source;
26
+ }
27
+ }
28
+ /**
29
+ * `/skills` picker (issue #204) in the ModelPicker style: a
30
+ * permission-colored Pane listing the live agent's skill catalog —
31
+ * user-invocable skills lead with `/name`(它们在 / 菜单里也是这个形态),
32
+ * 描述行是「来源 · 简述」。Enter 由 Chat 填回 `/name `,Esc 关闭。
33
+ *
34
+ * 长列表按焦点窗口化(ModelPicker 同款):picker 经 OverlayAbove 浮层挂载后
35
+ * 有 maxHeight 裁剪,全量渲染会让焦点行被裁掉(看不到焦点按 Enter)。
36
+ */
37
+ export function SkillsPicker({ skills, focusIndex, }) {
38
+ const { rows: terminalRows } = useTerminalSize();
39
+ // 每项恒占 2 行(正文 + 来源/简述描述行,均 truncate 成单行)。
40
+ // 框架行:浮层预留 8 + Pane 2 + 标题 2 + 页脚 1 = 13(ModelPicker 同款)。
41
+ const { start, end } = listWindow(skills.map(() => 2), focusIndex, Math.max(terminalRows - 13, 2));
42
+ return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('picker-title-skills') }) }), skills.length === 0 ? (_jsx(Text, { dimColor: true, children: t('skills-empty') })) : (skills.slice(start, end).map((skill, index) => {
43
+ const absoluteIndex = start + index;
44
+ return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: `${sourceLabel(skill.source)}${skill.description === '' ? '' : ` · ${skill.description}`}`, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < skills.length, children: skill.userInvocable ? `/${skill.name}` : skill.name }, skill.name));
45
+ }))] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-fill-exit') }) })] }));
46
+ }
47
+ /** `/skills` while the registry snapshot is still in flight (ModelPickerLoading 同款). */
48
+ export function SkillsPickerLoading() {
49
+ return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { bold: true, color: "permission", children: t('picker-title-skills') }), _jsx(LoadingState, { message: t('skills-loading'), bold: true, subtitle: t('skills-loading-subtitle') })] }) }));
50
+ }
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import type { ToolFileDiff } from '../dsh-adapter/channel.js';
3
+ import { type CliHighlight } from '../cc/cliHighlight.js';
4
+ /** chalk style for one raw theme value. Accepts every form the theme
5
+ * loader documents: #rgb, #rrggbb, #rrggbbaa (alpha stripped), rgb() with
6
+ * or without spaces, ansi256(n), ansi:name (issue #250, P2-5). */
7
+ export declare function chalkFromToken(token: string): (text: string) => string;
8
+ /** Parse a cli-highlight ANSI string into colored runs, preserving open
9
+ * spans across embedded newlines (multi-line strings/comments). Handles
10
+ * truecolor 38;2, 256-color 38;5 (tmux / FORCE_COLOR=2, issue #250 P1-1),
11
+ * and single-code 16-color SGR. */
12
+ export declare function parseAnsiRuns(text: string): {
13
+ text: string;
14
+ color?: string;
15
+ }[];
16
+ export declare function highlightLines(text: string, language: string | undefined, hl: CliHighlight | null, chTheme: Record<string, (text: string) => string> | undefined, themeSig: string): readonly {
17
+ text: string;
18
+ color?: string;
19
+ }[][] | undefined;
20
+ export declare function SplitDiffView({ diffs, width, maxRows, verbose, }: {
21
+ readonly diffs: readonly ToolFileDiff[];
22
+ /** Content width available to the whole two-pane block (divider included). */
23
+ readonly width: number;
24
+ /** Row budget when not verbose; overflow folds into one hint row. */
25
+ readonly maxRows: number;
26
+ readonly verbose: boolean;
27
+ }): React.ReactNode;
28
+ //# sourceMappingURL=SplitDiffView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SplitDiffView.d.ts","sourceRoot":"","sources":["../../../src/components/SplitDiffView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAwFjF;;mEAEmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAmBtE;AAUD;;;oCAGoC;AACpC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAuB9E;AAuBD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,EAAE,EAAE,YAAY,GAAG,IAAI,EACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,EAC7D,QAAQ,EAAE,MAAM,GACf,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EAAE,GAAG,SAAS,CAe3D;AA6ND,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,GACR,EAAE;IACD,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B,GAAG,KAAK,CAAC,SAAS,CAiGlB"}