@xp266/dshtui 0.1.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.
- package/bin/dshtui.js +65 -0
- package/cordis.patch.yml +81 -0
- package/lib/contract/index.d.mts +2 -0
- package/lib/contract/index.mjs +5 -0
- package/lib/dialog.d.mts +156 -0
- package/lib/dialog.mjs +3 -0
- package/lib/index-DqnaSXqP.d.mts +823 -0
- package/lib/index.d.mts +17 -0
- package/lib/index.mjs +11404 -0
- package/lib/prod-react-Dzof4qJx.mjs +4 -0
- package/lib/surface-DdxzIgIY.mjs +3126 -0
- package/lib/vendor.d.mts +3 -0
- package/lib/vendor.mjs +4 -0
- package/package.json +128 -0
- package/src/apply-theme.ts +8 -0
- package/src/boot-log.ts +35 -0
- package/src/chat/blocks.ts +41 -0
- package/src/chat/bridge.ts +1076 -0
- package/src/chat/builtin-tool-views.ts +53 -0
- package/src/chat/chat-face.ts +16 -0
- package/src/chat/chat-nodes.ts +53 -0
- package/src/chat/efforts.ts +4 -0
- package/src/chat/interactions.ts +329 -0
- package/src/chat/models.ts +263 -0
- package/src/chat/partial-json.ts +125 -0
- package/src/chat/presets.ts +26 -0
- package/src/chat/question-view.ts +106 -0
- package/src/chat/retry-status.ts +33 -0
- package/src/chat/session-groups.ts +34 -0
- package/src/chat/session-list.ts +311 -0
- package/src/chat/store.ts +636 -0
- package/src/chat/todo-view.ts +66 -0
- package/src/chat/tool-view.ts +311 -0
- package/src/chat/tool-views.ts +114 -0
- package/src/contract/index.ts +704 -0
- package/src/contract/upstream.ts +165 -0
- package/src/core/caret-nonce.ts +19 -0
- package/src/core/composer-layout.ts +65 -0
- package/src/core/edit.ts +152 -0
- package/src/core/field-view.ts +52 -0
- package/src/core/fields.ts +185 -0
- package/src/core/metrics.ts +26 -0
- package/src/core/paste.ts +149 -0
- package/src/core/segments.ts +112 -0
- package/src/core/text.ts +290 -0
- package/src/dialog.ts +11 -0
- package/src/env.ts +38 -0
- package/src/harness-home.ts +22 -0
- package/src/hot-theme.ts +56 -0
- package/src/index.tsx +185 -0
- package/src/kernel/registry.ts +102 -0
- package/src/kernel/surface.ts +33 -0
- package/src/log.ts +249 -0
- package/src/model/message.ts +89 -0
- package/src/model/selection.ts +63 -0
- package/src/performance-guard.ts +28 -0
- package/src/runtime/prod-react.ts +10 -0
- package/src/terminal/background.ts +66 -0
- package/src/terminal/capabilities.ts +54 -0
- package/src/terminal/clipboard-backends.ts +69 -0
- package/src/terminal/clipboard.ts +161 -0
- package/src/terminal/cursor-shape.ts +13 -0
- package/src/terminal/glyphs.ts +44 -0
- package/src/terminal/mouse.ts +154 -0
- package/src/terminal/probe.ts +61 -0
- package/src/terminal/screen.ts +349 -0
- package/src/theme-settings.ts +31 -0
- package/src/theme.ts +319 -0
- package/src/ui/app.tsx +454 -0
- package/src/ui/chrome/caps.tsx +9 -0
- package/src/ui/chrome/hint-service.ts +87 -0
- package/src/ui/chrome/input-status.ts +27 -0
- package/src/ui/chrome/key-gate.tsx +29 -0
- package/src/ui/chrome/status-bar.tsx +147 -0
- package/src/ui/contributions.ts +47 -0
- package/src/ui/dialog/defaults-dialog.tsx +152 -0
- package/src/ui/dialog/dialog-item.tsx +38 -0
- package/src/ui/dialog/dialog.tsx +386 -0
- package/src/ui/dialog/effort-dialog.tsx +45 -0
- package/src/ui/dialog/geometry.ts +131 -0
- package/src/ui/dialog/items.ts +124 -0
- package/src/ui/dialog/list-dialog.tsx +63 -0
- package/src/ui/dialog/models-dialog.tsx +203 -0
- package/src/ui/dialog/presets-dialog.tsx +46 -0
- package/src/ui/dialog/providers-dialog.tsx +313 -0
- package/src/ui/dialog/sessions-dialog.tsx +163 -0
- package/src/ui/dialog/sizes.ts +7 -0
- package/src/ui/dialog/status-lines.ts +11 -0
- package/src/ui/dialog/todo-dialog.tsx +29 -0
- package/src/ui/dialog/use-dialog-input.ts +186 -0
- package/src/ui/extension-point.ts +188 -0
- package/src/ui/home-logo.ts +132 -0
- package/src/ui/hooks/use-async-action.ts +25 -0
- package/src/ui/hooks/use-async-list.ts +71 -0
- package/src/ui/hooks/use-caret.ts +24 -0
- package/src/ui/hooks/use-chat-events.ts +153 -0
- package/src/ui/hooks/use-mouse-selection.ts +352 -0
- package/src/ui/hooks/use-scroll.ts +49 -0
- package/src/ui/hooks/use-terminal-size.ts +20 -0
- package/src/ui/input/commands.ts +118 -0
- package/src/ui/input/composer-bus.ts +14 -0
- package/src/ui/input/composer-fields.ts +111 -0
- package/src/ui/input/composer-keys.ts +21 -0
- package/src/ui/input/composer-paste.ts +20 -0
- package/src/ui/input/input-bar.tsx +279 -0
- package/src/ui/input/use-composer.ts +495 -0
- package/src/ui/key-arbiter.ts +37 -0
- package/src/ui/keymap.ts +15 -0
- package/src/ui/layout-service.ts +77 -0
- package/src/ui/message/layout.ts +763 -0
- package/src/ui/message/md/block.ts +247 -0
- package/src/ui/message/md/engine.ts +430 -0
- package/src/ui/message/md/extensions.ts +58 -0
- package/src/ui/message/md/highlight.ts +626 -0
- package/src/ui/message/md/index.ts +14 -0
- package/src/ui/message/md/inline.ts +97 -0
- package/src/ui/message/md/palette.ts +87 -0
- package/src/ui/message/message-list.tsx +69 -0
- package/src/ui/message/message-row.tsx +137 -0
- package/src/ui/message/message-views.ts +16 -0
- package/src/ui/message/renderers.ts +39 -0
- package/src/ui/message/tool-diff.ts +188 -0
- package/src/ui/message/warmup.ts +41 -0
- package/src/ui/message/wave.ts +98 -0
- package/src/ui/overlay.ts +22 -0
- package/src/ui/panels/approval-panel.tsx +193 -0
- package/src/ui/panels/exports.ts +3 -0
- package/src/ui/panels/question-model.ts +424 -0
- package/src/ui/panels/question-panel.tsx +154 -0
- package/src/ui/panels/surface.tsx +106 -0
- package/src/ui/panels-builtin.tsx +86 -0
- package/src/ui/pointer/builtins.ts +281 -0
- package/src/ui/pointer/registry.ts +25 -0
- package/src/ui/region.tsx +31 -0
- package/src/ui/selection/service.ts +92 -0
- package/src/ui/selection-registry.ts +88 -0
- package/src/ui/selection.tsx +148 -0
- package/src/ui/spinner-tick.tsx +24 -0
- package/src/ui/use-available-windows.ts +31 -0
- package/src/ui/widgets/actions.tsx +84 -0
- package/src/ui/widgets/button.tsx +57 -0
- package/src/ui/widgets/checkbox.tsx +58 -0
- package/src/ui/widgets/header.tsx +36 -0
- package/src/ui/widgets/index.ts +8 -0
- package/src/ui/widgets/input.tsx +76 -0
- package/src/ui/widgets/registry.ts +32 -0
- package/src/ui/widgets/search.tsx +59 -0
- package/src/ui/widgets/select.tsx +97 -0
- package/src/ui/widgets/static.tsx +37 -0
- package/src/ui/widgets/types.ts +1 -0
- package/src/ui/window-services-bridge.ts +71 -0
- package/src/ui/window-services.ts +20 -0
- package/src/ui/windows/models-window.tsx +15 -0
- package/src/ui/windows/providers-window.tsx +14 -0
- package/src/ui/windows/service-window.tsx +18 -0
- package/src/ui/windows/sessions-window.tsx +25 -0
- package/src/ui/windows-builtin.tsx +94 -0
- package/src/ui/windows.ts +18 -0
- package/src/vendor.ts +12 -0
|
@@ -0,0 +1,704 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode, Ref } from 'react'
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
3
|
+
import type { ContentBlock } from '@deepseek-ai/dsh-llm'
|
|
4
|
+
import type { SessionEvent } from '@deepseek-ai/dsh-session'
|
|
5
|
+
import type { Token } from 'marked'
|
|
6
|
+
import type { MarkStyle, Segment } from '../core/segments.ts'
|
|
7
|
+
import type { MdPalette } from '../ui/message/md/palette.ts'
|
|
8
|
+
import type { PendingImage } from '../core/paste.ts'
|
|
9
|
+
import type { LineSelection } from '../model/selection.ts'
|
|
10
|
+
import type { Message, MessageKind } from '../model/message.ts'
|
|
11
|
+
export type { MessageKind } from '../model/message.ts'
|
|
12
|
+
import type { MouseEventData } from '../terminal/mouse.ts'
|
|
13
|
+
import type { ScrollSnapshot } from '../ui/hooks/use-scroll.ts'
|
|
14
|
+
|
|
15
|
+
export type { PendingImage } from '../core/paste.ts'
|
|
16
|
+
export type { LineSelection } from '../model/selection.ts'
|
|
17
|
+
export type { MouseEventData, MouseEventType } from '../terminal/mouse.ts'
|
|
18
|
+
export type { ScrollSnapshot } from '../ui/hooks/use-scroll.ts'
|
|
19
|
+
|
|
20
|
+
export interface WindowHandle {
|
|
21
|
+
clickAt(y: number, x: number): void
|
|
22
|
+
wheelAt(y: number, dir: -1 | 1): boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface WindowProps {
|
|
26
|
+
open: boolean
|
|
27
|
+
onClose(): void
|
|
28
|
+
handleRef?: Ref<WindowHandle>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface WindowCommandSpec {
|
|
32
|
+
name: string
|
|
33
|
+
description: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WindowContribution {
|
|
37
|
+
id: string
|
|
38
|
+
title: string
|
|
39
|
+
component: ComponentType<WindowProps>
|
|
40
|
+
order?: number
|
|
41
|
+
command?: WindowCommandSpec
|
|
42
|
+
required?: readonly string[]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface TuiWindowsFace {
|
|
46
|
+
register(contribution: WindowContribution): () => void
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface StatusLineContribution {
|
|
50
|
+
id: string
|
|
51
|
+
order?: number
|
|
52
|
+
render(props: { columns: number }): string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface OverlayContribution {
|
|
56
|
+
id: string
|
|
57
|
+
render(props: { onClose(): void }): ReactNode
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface TuiServicesFace {
|
|
61
|
+
register(name: string, service: unknown): () => void
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface PaintArgs<I> {
|
|
65
|
+
item: I
|
|
66
|
+
focused: boolean
|
|
67
|
+
subCol: number
|
|
68
|
+
cursor?: number
|
|
69
|
+
width: number
|
|
70
|
+
y: number
|
|
71
|
+
x: number
|
|
72
|
+
pressed: 'left' | 'right' | null
|
|
73
|
+
clip: number
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ClickHit {
|
|
77
|
+
localX: number
|
|
78
|
+
localY: number
|
|
79
|
+
width: number
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface ClickActions {
|
|
83
|
+
focus(subCol: number): void
|
|
84
|
+
flash(side: 'left' | 'right'): void
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface WidgetKeyApi {
|
|
88
|
+
cursor: number
|
|
89
|
+
subCol: number
|
|
90
|
+
setCursor(next: number): void
|
|
91
|
+
navigate(direction: 'up' | 'down' | 'left' | 'right'): void
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface WidgetDef<I extends { type: string }> {
|
|
95
|
+
height(item: I, width: number): number
|
|
96
|
+
paintWidth(item: I): number
|
|
97
|
+
render(paint: PaintArgs<I>): ReactNode
|
|
98
|
+
searchTexts?(item: I, searchRight: boolean): string[]
|
|
99
|
+
stops?(item: I): number
|
|
100
|
+
fullRowFocus?: boolean
|
|
101
|
+
selectable?: boolean
|
|
102
|
+
editable?: boolean
|
|
103
|
+
caret?(item: I, cursor: number, width: number): { dy: number; dx: number }
|
|
104
|
+
onLeftRight?(item: I, direction: -1 | 1, api: WidgetKeyApi): boolean
|
|
105
|
+
onEnter?(item: I, api: WidgetKeyApi): boolean
|
|
106
|
+
onSpace?(item: I): void
|
|
107
|
+
onClick?(item: I, hit: ClickHit, actions: ClickActions): boolean
|
|
108
|
+
activate?(item: I): void
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface TuiWidgetsFace {
|
|
112
|
+
register<I extends { type: string }>(type: I['type'], def: WidgetDef<I>): () => void
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Open registry for plugin dialog item kinds. Declaration-merge a property
|
|
117
|
+
* named after your item kind (any key) whose value is the item object type
|
|
118
|
+
* carrying a `type` discriminant; the merged types join the `DialogItem`
|
|
119
|
+
* union so your widget def stays fully typed.
|
|
120
|
+
*/
|
|
121
|
+
export interface DialogItemKinds {}
|
|
122
|
+
|
|
123
|
+
export interface ThemePaletteContribution {
|
|
124
|
+
id: string
|
|
125
|
+
order?: number
|
|
126
|
+
/** Which theme mode(s) this palette patch applies to; defaults to 'both'. */
|
|
127
|
+
mode?: 'dark' | 'light' | 'both'
|
|
128
|
+
/** Color name (a `Theme` palette key) to replacement hex/text value. */
|
|
129
|
+
colors: Readonly<Record<string, string>>
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface TuiPaletteFace {
|
|
133
|
+
register(contribution: ThemePaletteContribution): () => void
|
|
134
|
+
/** Read a palette color by key, including plugin-contributed keys. */
|
|
135
|
+
color(key: string): string | undefined
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface ClipboardBackendContribution {
|
|
139
|
+
id: string
|
|
140
|
+
order?: number
|
|
141
|
+
readText?(): string | undefined | Promise<string | undefined>
|
|
142
|
+
readImage?(): { data: Uint8Array; mediaType: string } | undefined | Promise<{ data: Uint8Array; mediaType: string } | undefined>
|
|
143
|
+
writeText?(text: string): boolean
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface TuiClipboardFace {
|
|
147
|
+
register(contribution: ClipboardBackendContribution): () => void
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface TuiKey {
|
|
151
|
+
upArrow: boolean
|
|
152
|
+
downArrow: boolean
|
|
153
|
+
leftArrow: boolean
|
|
154
|
+
rightArrow: boolean
|
|
155
|
+
pageDown: boolean
|
|
156
|
+
pageUp: boolean
|
|
157
|
+
home?: boolean
|
|
158
|
+
end?: boolean
|
|
159
|
+
return: boolean
|
|
160
|
+
escape: boolean
|
|
161
|
+
ctrl: boolean
|
|
162
|
+
shift: boolean
|
|
163
|
+
tab: boolean
|
|
164
|
+
backspace: boolean
|
|
165
|
+
delete: boolean
|
|
166
|
+
meta: boolean
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface KeyBindingContribution {
|
|
170
|
+
id: string
|
|
171
|
+
order?: number
|
|
172
|
+
/**
|
|
173
|
+
* Invoked for every terminal key event before builtin shell handling.
|
|
174
|
+
* Return true to consume the key; later bindings and builtin handling
|
|
175
|
+
* are skipped for that event.
|
|
176
|
+
*/
|
|
177
|
+
handle(input: string, key: TuiKey): boolean
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface TuiKeymapFace {
|
|
181
|
+
register(contribution: KeyBindingContribution): () => void
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface PointerUiContext {
|
|
185
|
+
dialogOpen: boolean
|
|
186
|
+
panelActive: boolean
|
|
187
|
+
hintRegion: { top: number; bottom: number } | null
|
|
188
|
+
rows: number
|
|
189
|
+
columns: number
|
|
190
|
+
messageHeight: number
|
|
191
|
+
inputHeight: number
|
|
192
|
+
scrollTop: number
|
|
193
|
+
getScroll(): ScrollSnapshot
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface PointerSession {
|
|
197
|
+
getSelection(): LineSelection | null
|
|
198
|
+
setSelection(next: LineSelection | null): void
|
|
199
|
+
scroll(next: number): void
|
|
200
|
+
/** Start (-1/1) or stop (0) drag-follow auto scrolling of the message area. */
|
|
201
|
+
autoScroll(direction: -1 | 1 | 0): void
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface PointerEventFrame {
|
|
205
|
+
event: MouseEventData
|
|
206
|
+
session: PointerSession
|
|
207
|
+
ui: PointerUiContext
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export interface PointerHandlerContribution {
|
|
211
|
+
id: string
|
|
212
|
+
order?: number
|
|
213
|
+
/** Return true to claim the gesture; drag and up are then routed here exclusively. */
|
|
214
|
+
onDown(frame: PointerEventFrame): boolean
|
|
215
|
+
onDrag?(frame: PointerEventFrame): void
|
|
216
|
+
onUp?(frame: PointerEventFrame): void
|
|
217
|
+
onWheel?(frame: PointerEventFrame): boolean
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Builtin gesture handlers live at order 100..190; see registerPointerHandler. */
|
|
221
|
+
export const POINTER_PLUGIN_ORDER = 300
|
|
222
|
+
|
|
223
|
+
export interface HintMatcherContribution {
|
|
224
|
+
id: string
|
|
225
|
+
order?: number
|
|
226
|
+
match(entries: readonly HintEntry[], context: { value: string; query: string }): HintEntry[] | null
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export interface HintEntry {
|
|
230
|
+
command: string
|
|
231
|
+
description: string
|
|
232
|
+
hint?: string
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export interface HintArgsContribution {
|
|
236
|
+
id: string
|
|
237
|
+
order?: number
|
|
238
|
+
args(name: string): string[] | null | Promise<string[] | null>
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface TuiHintFace {
|
|
242
|
+
matchers: { register(contribution: HintMatcherContribution): () => void }
|
|
243
|
+
args: { register(contribution: HintArgsContribution): () => void }
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface TuiPointerFace {
|
|
247
|
+
register(contribution: PointerHandlerContribution): () => void
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface SelectionExtractContext {
|
|
251
|
+
messageText(sel: LineSelection): string
|
|
252
|
+
chromeText(sel: LineSelection): string
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export interface SelectionDomainContribution {
|
|
256
|
+
id: string
|
|
257
|
+
order?: number
|
|
258
|
+
hit(sel: LineSelection): boolean
|
|
259
|
+
extract(sel: LineSelection, context: SelectionExtractContext): string | null
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface SelectionTransformerContribution {
|
|
263
|
+
id: string
|
|
264
|
+
order?: number
|
|
265
|
+
transform(text: string): string
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface SelectionClipboardContribution {
|
|
269
|
+
id: string
|
|
270
|
+
order?: number
|
|
271
|
+
copy(text: string): boolean
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export interface TuiSelectionFace {
|
|
275
|
+
domains: { register(contribution: SelectionDomainContribution): () => void }
|
|
276
|
+
transformers: { register(contribution: SelectionTransformerContribution): () => void }
|
|
277
|
+
clipboard: { register(contribution: SelectionClipboardContribution): () => void }
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export interface InputStatusContext {
|
|
281
|
+
columns: number
|
|
282
|
+
rows: number
|
|
283
|
+
busy: boolean
|
|
284
|
+
running: boolean
|
|
285
|
+
modelName: string
|
|
286
|
+
permissionMode: string
|
|
287
|
+
effortName: string | undefined
|
|
288
|
+
presetName: string | undefined
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export interface InputStatusPart {
|
|
292
|
+
text: string
|
|
293
|
+
color?: string
|
|
294
|
+
bold?: boolean
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export interface InputStatusContribution {
|
|
298
|
+
id: string
|
|
299
|
+
order?: number
|
|
300
|
+
/** Return one part, an array of parts, or null to contribute nothing this render. */
|
|
301
|
+
render(context: InputStatusContext): InputStatusPart | InputStatusPart[] | null
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export interface HomeLogoContribution {
|
|
305
|
+
id: string
|
|
306
|
+
order?: number
|
|
307
|
+
/** Logo artwork rendered as the first chat-styled bubble on the home page, one string per terminal row. */
|
|
308
|
+
lines: readonly string[]
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export interface TuiHomeLogoFace {
|
|
312
|
+
register(contribution: HomeLogoContribution): () => void
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export interface TuiChromeFace {
|
|
316
|
+
statusLine: { register(contribution: StatusLineContribution): () => void }
|
|
317
|
+
overlays: { register(contribution: OverlayContribution): () => void }
|
|
318
|
+
widgets: TuiWidgetsFace
|
|
319
|
+
palette: TuiPaletteFace
|
|
320
|
+
keys: TuiKeymapFace
|
|
321
|
+
inputStatus: { register(contribution: InputStatusContribution): () => void }
|
|
322
|
+
logo: TuiHomeLogoFace
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export interface CommandDef {
|
|
326
|
+
id: string
|
|
327
|
+
command: string
|
|
328
|
+
description: string
|
|
329
|
+
hint?: string
|
|
330
|
+
args?: readonly string[]
|
|
331
|
+
run?: () => void
|
|
332
|
+
order?: number
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export interface TuiCommandsFace {
|
|
336
|
+
register(def: CommandDef): () => void
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export type DiffLineKind = 'ctx' | 'del' | 'add'
|
|
340
|
+
|
|
341
|
+
export interface DiffLine {
|
|
342
|
+
kind: DiffLineKind
|
|
343
|
+
text: string
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export type DiffHunk = readonly DiffLine[]
|
|
347
|
+
|
|
348
|
+
export interface ToolViewDiff {
|
|
349
|
+
path: string
|
|
350
|
+
hunks: readonly DiffHunk[]
|
|
351
|
+
/**
|
|
352
|
+
* Paint whole-line red/green backgrounds behind removed and added lines.
|
|
353
|
+
* Defaults to true when any line is a removal, false for pure additions.
|
|
354
|
+
* Set it explicitly to override that heuristic.
|
|
355
|
+
*/
|
|
356
|
+
backgrounds?: boolean
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export interface ToolResultView {
|
|
360
|
+
content: readonly ContentBlock[]
|
|
361
|
+
isError: boolean
|
|
362
|
+
meta?: unknown
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export interface ToolViewCallContext {
|
|
366
|
+
tool: string
|
|
367
|
+
callId: string
|
|
368
|
+
args: unknown
|
|
369
|
+
argumentsRaw: string
|
|
370
|
+
cwd: string
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export interface ToolViewResultContext {
|
|
374
|
+
tool: string
|
|
375
|
+
callId: string
|
|
376
|
+
args: unknown
|
|
377
|
+
result: ToolResultView
|
|
378
|
+
cwd: string
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export interface ToolCallPresentation {
|
|
382
|
+
label?: string
|
|
383
|
+
body?: string
|
|
384
|
+
bodyCol?: number
|
|
385
|
+
diff?: ToolViewDiff
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export interface ToolResultPresentation {
|
|
389
|
+
kind: 'replace' | 'append'
|
|
390
|
+
text: string
|
|
391
|
+
/** Header replacement applied when kind is 'replace' ('' clears the suffix). */
|
|
392
|
+
label?: string
|
|
393
|
+
/** Call-side body replacement ('' clears it), for settled views that supersede the args. */
|
|
394
|
+
argsBody?: string
|
|
395
|
+
exitCode?: number
|
|
396
|
+
signal?: string
|
|
397
|
+
bodyCol?: number
|
|
398
|
+
diff?: ToolViewDiff
|
|
399
|
+
/** Structured read window; rendered as a numbered code card. */
|
|
400
|
+
read?: ToolReadView
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/** One numbered line of a structured read result. */
|
|
404
|
+
export interface ToolReadLine {
|
|
405
|
+
number: number
|
|
406
|
+
text: string
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/** The `card: 'read'` projection: a numbered file window plus its totals. */
|
|
410
|
+
export interface ToolReadView {
|
|
411
|
+
path?: string
|
|
412
|
+
lines: readonly ToolReadLine[]
|
|
413
|
+
/** 1-based first line of the window when it carries no lines. */
|
|
414
|
+
offset?: number
|
|
415
|
+
/** Total lines in the file, for a "lines N of M" footer. */
|
|
416
|
+
totalLines?: number
|
|
417
|
+
/** Syntax highlighting hint (e.g. `ts`). */
|
|
418
|
+
lang?: string
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
export interface ToolViewContribution {
|
|
422
|
+
tool: string
|
|
423
|
+
order?: number
|
|
424
|
+
/**
|
|
425
|
+
* When true, the builtin presenter never runs for this tool: a call or
|
|
426
|
+
* result handler returning undefined renders as a bare card instead of
|
|
427
|
+
* falling through to the builtin presentation.
|
|
428
|
+
*/
|
|
429
|
+
takeover?: boolean
|
|
430
|
+
call?(context: ToolViewCallContext): ToolCallPresentation | undefined
|
|
431
|
+
result?(context: ToolViewResultContext): ToolResultPresentation | undefined
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
export interface TuiToolsFace {
|
|
435
|
+
register(contribution: ToolViewContribution): () => void
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export interface CustomMessage {
|
|
439
|
+
kind: 'custom'
|
|
440
|
+
id: string
|
|
441
|
+
view: string
|
|
442
|
+
data: unknown
|
|
443
|
+
running?: boolean
|
|
444
|
+
streaming?: boolean
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export type CustomMessageSeed = Omit<CustomMessage, 'kind' | 'id'>
|
|
448
|
+
|
|
449
|
+
export interface ChatNodeDefinition {
|
|
450
|
+
id: string
|
|
451
|
+
order?: number
|
|
452
|
+
match(event: SessionEvent): boolean
|
|
453
|
+
start(event: SessionEvent): CustomMessageSeed
|
|
454
|
+
update?(event: SessionEvent, message: CustomMessage): CustomMessageSeed | null
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export interface MessageViewContext {
|
|
458
|
+
message: CustomMessage
|
|
459
|
+
width: number
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
export interface MessageViewRender {
|
|
463
|
+
label?: string
|
|
464
|
+
lines: readonly string[]
|
|
465
|
+
wrap?: boolean
|
|
466
|
+
muted?: boolean
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export interface MessageViewContribution {
|
|
470
|
+
view: string
|
|
471
|
+
order?: number
|
|
472
|
+
render(context: MessageViewContext): MessageViewRender
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
export interface MessageRendererResult {
|
|
476
|
+
lines: string[]
|
|
477
|
+
rows?: Segment[][] | null
|
|
478
|
+
bgs?: (string | undefined)[] | null
|
|
479
|
+
customLabel?: string
|
|
480
|
+
customMuted?: boolean
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export interface MessageRendererContribution {
|
|
484
|
+
/** Message kind to take over: 'bubble' | 'collapsible' | 'tool-card' | 'compaction' | 'custom'. */
|
|
485
|
+
kind: string
|
|
486
|
+
order?: number
|
|
487
|
+
/** Return undefined to fall through to the builtin rendering. */
|
|
488
|
+
render(message: Message, width: number): MessageRendererResult | undefined
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export interface TuiContentFace {
|
|
492
|
+
nodes: { register(definition: ChatNodeDefinition): () => void }
|
|
493
|
+
views: { register(contribution: MessageViewContribution): () => void }
|
|
494
|
+
renderers: { register(contribution: MessageRendererContribution): () => void }
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export interface TuiStartupSink {
|
|
498
|
+
id: string
|
|
499
|
+
/** Invoked for each boot progress line while the shell is starting. */
|
|
500
|
+
write(line: string): void
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
export interface TuiStartupFace {
|
|
504
|
+
registerSink(sink: TuiStartupSink): () => void
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
export interface SpecialFieldStyle {
|
|
508
|
+
color: string
|
|
509
|
+
background: string
|
|
510
|
+
bold?: boolean
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export interface SpecialFieldContribution {
|
|
514
|
+
kind: string
|
|
515
|
+
style(): SpecialFieldStyle
|
|
516
|
+
/** Text injected into the sent message for a field of this kind; defaults to the label. */
|
|
517
|
+
expand?(data: unknown): string
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export interface TuiFieldsFace {
|
|
521
|
+
register(contribution: SpecialFieldContribution): () => void
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Create a special field instance rendered as an inline chip with its own
|
|
526
|
+
* background. The returned sentinel char behaves like a single grapheme:
|
|
527
|
+
* cursor movement and deletion treat it atomically and line wrapping never
|
|
528
|
+
* splits it. `kind` resolves the style from registered field kinds.
|
|
529
|
+
*/
|
|
530
|
+
export interface SpecialFieldCreateInput {
|
|
531
|
+
kind: string
|
|
532
|
+
label: string
|
|
533
|
+
/** Which reclaim scan owns the slot: 'composer' chips die with composer text, 'message' chips with the message list. */
|
|
534
|
+
owner?: 'composer' | 'message'
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
export interface SpecialFieldFactory {
|
|
538
|
+
create(input: SpecialFieldCreateInput): string | null
|
|
539
|
+
release(char: string): void
|
|
540
|
+
/** Protect a chip from the automatic reclaim scans until the disposer runs. */
|
|
541
|
+
pin(char: string): (() => void) | undefined
|
|
542
|
+
isFieldChar(char: string): boolean
|
|
543
|
+
labelOf(char: string): string | undefined
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export interface PasteContext {
|
|
547
|
+
/** Raw pasted text with normalized newlines. */
|
|
548
|
+
text: string
|
|
549
|
+
/** Insert at this char index in the composer value. */
|
|
550
|
+
cursor: number
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
export interface PasteResult {
|
|
554
|
+
/** Text to insert (may contain field sentinel chars created via the field factory). */
|
|
555
|
+
insert: string
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
export interface PasteHandlerContribution {
|
|
559
|
+
id: string
|
|
560
|
+
order?: number
|
|
561
|
+
/** Return a result to claim the paste; return undefined to fall through. */
|
|
562
|
+
handle(context: PasteContext): PasteResult | undefined
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
export interface ComposerInsertSpec {
|
|
566
|
+
/** Plain text to insert at the cursor. */
|
|
567
|
+
text?: string
|
|
568
|
+
/** A special field chip to insert at the cursor; `data` is passed to the kind's expand on send. */
|
|
569
|
+
field?: { kind: string; label: string; data?: unknown }
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export interface TuiComposerFace {
|
|
573
|
+
paste: { register(handler: PasteHandlerContribution): () => void }
|
|
574
|
+
/**
|
|
575
|
+
* Intercept a key before the builtin composer handling consumes it.
|
|
576
|
+
* Runs for every key routed to the composer (only while it is interactive);
|
|
577
|
+
* return true to consume the event.
|
|
578
|
+
*/
|
|
579
|
+
keys: { register(binding: { id: string; order?: number; handle(input: string, key: TuiKey): boolean }): () => void }
|
|
580
|
+
/** Insert text or a special field into the live composer at the cursor. False when the composer is not mounted. */
|
|
581
|
+
insert(spec: ComposerInsertSpec): boolean
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
export interface MarkdownInlineContext {
|
|
585
|
+
palette: MdPalette
|
|
586
|
+
base?: MarkStyle
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
export interface MarkdownBlockContext {
|
|
590
|
+
palette: MdPalette
|
|
591
|
+
thinking: boolean
|
|
592
|
+
width: number
|
|
593
|
+
streamId: string
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* A custom markdown block renderer. Keyed by the marked token `type` it
|
|
598
|
+
* claims (`code`, `heading`, `table`, ...). Registering over an existing
|
|
599
|
+
* type replaces that layer; disposing restores it (layered registry
|
|
600
|
+
* semantics).
|
|
601
|
+
*/
|
|
602
|
+
export interface MarkdownBlockContribution {
|
|
603
|
+
/** marked token type this renderer claims. */
|
|
604
|
+
type: string
|
|
605
|
+
order?: number
|
|
606
|
+
render(token: Token, context: MarkdownBlockContext): Segment[][]
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/** A custom inline (span-level) markdown token renderer, keyed by token `type`. */
|
|
610
|
+
export interface MarkdownInlineContribution {
|
|
611
|
+
type: string
|
|
612
|
+
order?: number
|
|
613
|
+
render(token: Token, context: MarkdownInlineContext): Segment
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
export interface PrismGrammarContribution {
|
|
617
|
+
/** Code fence language id (lowercase). */
|
|
618
|
+
id: string
|
|
619
|
+
/** Prism grammar object (from a loaded prism component or hand-built). */
|
|
620
|
+
grammar: unknown
|
|
621
|
+
/** Extra aliases accepted for the same grammar. */
|
|
622
|
+
aliases?: readonly string[]
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export interface TuiMarkdownFace {
|
|
626
|
+
blocks: { register(contribution: MarkdownBlockContribution): () => void }
|
|
627
|
+
inline: { register(contribution: MarkdownInlineContribution): () => void }
|
|
628
|
+
languages: { register(contribution: PrismGrammarContribution): () => void }
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export interface InteractionPanelComponentProps {
|
|
632
|
+
request: unknown
|
|
633
|
+
resolve(value: unknown): void
|
|
634
|
+
reject(cause: unknown): void
|
|
635
|
+
active: boolean
|
|
636
|
+
columns: number
|
|
637
|
+
rows: number
|
|
638
|
+
innerWidth: number
|
|
639
|
+
blockWidth: number
|
|
640
|
+
background: string
|
|
641
|
+
handleRef?: { current: unknown }
|
|
642
|
+
onResize(height: number): void
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
export interface InteractionPanelContribution {
|
|
646
|
+
kind: string
|
|
647
|
+
order?: number
|
|
648
|
+
component: ComponentType<InteractionPanelComponentProps>
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
export interface TuiInteractionPanelsFace {
|
|
652
|
+
register(contribution: InteractionPanelContribution): () => void
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
export interface TuiInteractionsFace {
|
|
656
|
+
panels: TuiInteractionPanelsFace
|
|
657
|
+
/** Queue a plugin interaction; resolves when the panel for `kind` settles it. */
|
|
658
|
+
push(kind: string, request: unknown, signal?: AbortSignal): Promise<unknown>
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
export interface TuiSessionSummary {
|
|
662
|
+
id: string
|
|
663
|
+
name: string
|
|
664
|
+
directory: string
|
|
665
|
+
ungrouped: boolean
|
|
666
|
+
updatedAt: number
|
|
667
|
+
modifiedAt?: number
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export interface TuiChatFace {
|
|
671
|
+
cwd(): string
|
|
672
|
+
activeSessionId(): string
|
|
673
|
+
onEvent(listener: (event: SessionEvent) => void): () => void
|
|
674
|
+
send(text: string, images?: ReadonlyArray<readonly PendingImage[]>): void
|
|
675
|
+
interrupt(): void
|
|
676
|
+
newSession(): Promise<void>
|
|
677
|
+
openSession(id: string): Promise<void>
|
|
678
|
+
listSessions(): Promise<TuiSessionSummary[]>
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
export interface TuiExtensionPoint {
|
|
682
|
+
windows: TuiWindowsFace
|
|
683
|
+
services: TuiServicesFace
|
|
684
|
+
chrome: TuiChromeFace
|
|
685
|
+
commands: TuiCommandsFace
|
|
686
|
+
tools: TuiToolsFace
|
|
687
|
+
content: TuiContentFace
|
|
688
|
+
startup: TuiStartupFace
|
|
689
|
+
fields: TuiFieldsFace & { factory: SpecialFieldFactory }
|
|
690
|
+
composer: TuiComposerFace
|
|
691
|
+
markdown: TuiMarkdownFace
|
|
692
|
+
hint: TuiHintFace
|
|
693
|
+
pointer: TuiPointerFace
|
|
694
|
+
selection: TuiSelectionFace
|
|
695
|
+
clipboard: TuiClipboardFace
|
|
696
|
+
interactions?: TuiInteractionsFace
|
|
697
|
+
chat?: TuiChatFace
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
declare module '@deepseek-ai/cordis' {
|
|
701
|
+
interface Context {
|
|
702
|
+
tui: TuiExtensionPoint
|
|
703
|
+
}
|
|
704
|
+
}
|