@agi-fans/dsh-tui 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/LICENSE +21 -0
- package/README.md +13 -0
- package/lib/autocomplete.d.ts +80 -0
- package/lib/autocomplete.js +320 -0
- package/lib/autocomplete.js.map +1 -0
- package/lib/box.d.ts +79 -0
- package/lib/box.js +276 -0
- package/lib/box.js.map +1 -0
- package/lib/clipboard.d.ts +19 -0
- package/lib/clipboard.js +77 -0
- package/lib/clipboard.js.map +1 -0
- package/lib/command-integrations.d.ts +10 -0
- package/lib/command-integrations.js +49 -0
- package/lib/command-integrations.js.map +1 -0
- package/lib/command-mode.d.ts +5 -0
- package/lib/command-mode.js +73 -0
- package/lib/command-mode.js.map +1 -0
- package/lib/command-model.d.ts +5 -0
- package/lib/command-model.js +87 -0
- package/lib/command-model.js.map +1 -0
- package/lib/command-output.d.ts +6 -0
- package/lib/command-output.js +33 -0
- package/lib/command-output.js.map +1 -0
- package/lib/command-queue.d.ts +5 -0
- package/lib/command-queue.js +62 -0
- package/lib/command-queue.js.map +1 -0
- package/lib/command-registration.d.ts +5 -0
- package/lib/command-registration.js +20 -0
- package/lib/command-registration.js.map +1 -0
- package/lib/command-session.d.ts +5 -0
- package/lib/command-session.js +153 -0
- package/lib/command-session.js.map +1 -0
- package/lib/command-transcript.d.ts +5 -0
- package/lib/command-transcript.js +85 -0
- package/lib/command-transcript.js.map +1 -0
- package/lib/copy-selector.d.ts +52 -0
- package/lib/copy-selector.js +136 -0
- package/lib/copy-selector.js.map +1 -0
- package/lib/copy-targets.d.ts +34 -0
- package/lib/copy-targets.js +170 -0
- package/lib/copy-targets.js.map +1 -0
- package/lib/definition.d.ts +171 -0
- package/lib/definition.js +14 -0
- package/lib/definition.js.map +1 -0
- package/lib/editor.d.ts +66 -0
- package/lib/editor.js +365 -0
- package/lib/editor.js.map +1 -0
- package/lib/event-views.d.ts +188 -0
- package/lib/event-views.js +678 -0
- package/lib/event-views.js.map +1 -0
- package/lib/external-editor.d.ts +2 -0
- package/lib/external-editor.js +31 -0
- package/lib/external-editor.js.map +1 -0
- package/lib/history-search.d.ts +61 -0
- package/lib/history-search.js +239 -0
- package/lib/history-search.js.map +1 -0
- package/lib/history-store.d.ts +8 -0
- package/lib/history-store.js +36 -0
- package/lib/history-store.js.map +1 -0
- package/lib/hotkeys.d.ts +14 -0
- package/lib/hotkeys.js +115 -0
- package/lib/hotkeys.js.map +1 -0
- package/lib/human-interaction.d.ts +5 -0
- package/lib/human-interaction.js +8 -0
- package/lib/human-interaction.js.map +1 -0
- package/lib/image-paste.d.ts +21 -0
- package/lib/image-paste.js +277 -0
- package/lib/image-paste.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/interaction-adapter.d.ts +18 -0
- package/lib/interaction-adapter.js +93 -0
- package/lib/interaction-adapter.js.map +1 -0
- package/lib/keybindings-config.d.ts +5 -0
- package/lib/keybindings-config.js +28 -0
- package/lib/keybindings-config.js.map +1 -0
- package/lib/keys.d.ts +59 -0
- package/lib/keys.js +263 -0
- package/lib/keys.js.map +1 -0
- package/lib/markdown.d.ts +13 -0
- package/lib/markdown.js +453 -0
- package/lib/markdown.js.map +1 -0
- package/lib/path-complete.d.ts +85 -0
- package/lib/path-complete.js +231 -0
- package/lib/path-complete.js.map +1 -0
- package/lib/path-mentions.d.ts +4 -0
- package/lib/path-mentions.js +50 -0
- package/lib/path-mentions.js.map +1 -0
- package/lib/project-context.d.ts +13 -0
- package/lib/project-context.js +52 -0
- package/lib/project-context.js.map +1 -0
- package/lib/project-file-search.d.ts +25 -0
- package/lib/project-file-search.js +207 -0
- package/lib/project-file-search.js.map +1 -0
- package/lib/prompt-selector.d.ts +56 -0
- package/lib/prompt-selector.js +297 -0
- package/lib/prompt-selector.js.map +1 -0
- package/lib/provider-local.d.ts +115 -0
- package/lib/provider-local.js +1760 -0
- package/lib/provider-local.js.map +1 -0
- package/lib/pwd.d.ts +13 -0
- package/lib/pwd.js +14 -0
- package/lib/pwd.js.map +1 -0
- package/lib/relative-time.d.ts +2 -0
- package/lib/relative-time.js +11 -0
- package/lib/relative-time.js.map +1 -0
- package/lib/renderer.d.ts +112 -0
- package/lib/renderer.js +181 -0
- package/lib/renderer.js.map +1 -0
- package/lib/runner.d.ts +9 -0
- package/lib/runner.js +94 -0
- package/lib/runner.js.map +1 -0
- package/lib/session-controller.d.ts +92 -0
- package/lib/session-controller.js +571 -0
- package/lib/session-controller.js.map +1 -0
- package/lib/session-runtime.d.ts +16 -0
- package/lib/session-runtime.js +17 -0
- package/lib/session-runtime.js.map +1 -0
- package/lib/settings-list.d.ts +67 -0
- package/lib/settings-list.js +380 -0
- package/lib/settings-list.js.map +1 -0
- package/lib/status-config.d.ts +32 -0
- package/lib/status-config.js +52 -0
- package/lib/status-config.js.map +1 -0
- package/lib/status-line.d.ts +41 -0
- package/lib/status-line.js +351 -0
- package/lib/status-line.js.map +1 -0
- package/lib/style.d.ts +22 -0
- package/lib/style.js +23 -0
- package/lib/style.js.map +1 -0
- package/lib/theme.d.ts +83 -0
- package/lib/theme.js +317 -0
- package/lib/theme.js.map +1 -0
- package/lib/tool-presentation.d.ts +20 -0
- package/lib/tool-presentation.js +79 -0
- package/lib/tool-presentation.js.map +1 -0
- package/lib/tool-renderers.d.ts +21 -0
- package/lib/tool-renderers.js +133 -0
- package/lib/tool-renderers.js.map +1 -0
- package/lib/tools-list.d.ts +14 -0
- package/lib/tools-list.js +61 -0
- package/lib/tools-list.js.map +1 -0
- package/lib/transcript-export.d.ts +4 -0
- package/lib/transcript-export.js +66 -0
- package/lib/transcript-export.js.map +1 -0
- package/lib/tui-settings.d.ts +20 -0
- package/lib/tui-settings.js +23 -0
- package/lib/tui-settings.js.map +1 -0
- package/lib/welcome-tips.d.ts +10 -0
- package/lib/welcome-tips.js +36 -0
- package/lib/welcome-tips.js.map +1 -0
- package/lib/width.d.ts +54 -0
- package/lib/width.js +323 -0
- package/lib/width.js.map +1 -0
- package/package.json +119 -0
package/lib/box.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rounded-box chrome ported from oh-my-pi: framed tool output, the welcome
|
|
3
|
+
* card and the framed editor whose top border carries its compact label.
|
|
4
|
+
* @module @agi-fans/dsh-tui
|
|
5
|
+
*/
|
|
6
|
+
import { BOX, DEEPSEEK_LOGO, gradientLogo } from "./theme.js";
|
|
7
|
+
import { expandTabs, padToWidth, padding, truncateToWidth, visibleWidth, wrapIndexed, wrapText, cursorOnWrapped, indexOnWrapped } from "./width.js";
|
|
8
|
+
import { formatRelativeAge } from "./relative-time.js";
|
|
9
|
+
import { WELCOME_TIPS } from "./welcome-tips.js";
|
|
10
|
+
function borderColorFor(state) {
|
|
11
|
+
if (state === 'info')
|
|
12
|
+
return 'border';
|
|
13
|
+
if (state === 'error')
|
|
14
|
+
return 'error';
|
|
15
|
+
if (state === 'warning')
|
|
16
|
+
return 'warning';
|
|
17
|
+
if (state === 'running')
|
|
18
|
+
return 'accent';
|
|
19
|
+
return 'dim';
|
|
20
|
+
}
|
|
21
|
+
function bgColorFor(state) {
|
|
22
|
+
if (state === 'error')
|
|
23
|
+
return 'toolErrorBg';
|
|
24
|
+
if (state === 'running')
|
|
25
|
+
return 'toolPendingBg';
|
|
26
|
+
if (state === 'ok')
|
|
27
|
+
return 'toolSuccessBg';
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
function applyBg(line, theme, color, width) {
|
|
31
|
+
const ansi = theme.getBgAnsi(color);
|
|
32
|
+
if (ansi === '')
|
|
33
|
+
return padToWidth(line, width);
|
|
34
|
+
const padded = padToWidth(line, width);
|
|
35
|
+
const restabilized = padded
|
|
36
|
+
.replace(/\x1b\[(?:0)?m/g, (match) => match + ansi)
|
|
37
|
+
.replace(/\x1b\[49m/g, (match) => match + ansi);
|
|
38
|
+
return ansi + restabilized + '\x1b[49m';
|
|
39
|
+
}
|
|
40
|
+
function centerText(text, width) {
|
|
41
|
+
const vis = visibleWidth(text);
|
|
42
|
+
if (vis >= width)
|
|
43
|
+
return truncateToWidth(text, width);
|
|
44
|
+
const left = Math.floor((width - vis) / 2);
|
|
45
|
+
return padding(left) + text + padding(width - vis - left);
|
|
46
|
+
}
|
|
47
|
+
function fitToWidth(text, width) {
|
|
48
|
+
const vis = visibleWidth(text);
|
|
49
|
+
if (vis > width)
|
|
50
|
+
return truncateToWidth(text, width);
|
|
51
|
+
return text + padding(width - vis);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* OMP `renderOutputBlock`: `╭─── header ────╮` / padded body / `╰────╯`.
|
|
55
|
+
*/
|
|
56
|
+
export function renderFramedBlock(options, theme) {
|
|
57
|
+
const width = Math.max(0, options.width);
|
|
58
|
+
const h = BOX.horizontal;
|
|
59
|
+
const v = BOX.vertical;
|
|
60
|
+
const color = borderColorFor(options.state);
|
|
61
|
+
const border = (text) => theme.fg(color, text);
|
|
62
|
+
const bg = options.applyBg === false ? undefined : bgColorFor(options.state);
|
|
63
|
+
const paint = (line) => (bg ? applyBg(line, theme, bg, width) : padToWidth(line, width));
|
|
64
|
+
const cap = h.repeat(3);
|
|
65
|
+
const labelParts = [options.header, options.headerMeta].filter((part) => Boolean(part));
|
|
66
|
+
const labelChromeWidth = visibleWidth(BOX.topLeft + cap + ' ' + cap + BOX.topRight);
|
|
67
|
+
const top = labelParts.length === 0 || width < labelChromeWidth
|
|
68
|
+
? border(BOX.topLeft + h.repeat(Math.max(0, width - 2)) + BOX.topRight)
|
|
69
|
+
: (() => {
|
|
70
|
+
// The spaces and three-glyph caps belong to the frame, not the label's
|
|
71
|
+
// truncation budget. A long command can consume only the middle span.
|
|
72
|
+
const maxLabel = Math.max(0, width - labelChromeWidth);
|
|
73
|
+
const label = truncateToWidth(labelParts.join(' · '), maxLabel);
|
|
74
|
+
const fill = Math.max(0, maxLabel - visibleWidth(label));
|
|
75
|
+
return border(BOX.topLeft + cap) + ' ' + label + ' ' + border(h.repeat(fill) + cap + BOX.topRight);
|
|
76
|
+
})();
|
|
77
|
+
const contentWidth = Math.max(1, width - 4);
|
|
78
|
+
const body = [];
|
|
79
|
+
for (const raw of options.lines ?? []) {
|
|
80
|
+
for (const wrapped of wrapText(expandTabs(raw, 8, 2), contentWidth)) {
|
|
81
|
+
body.push(border(v) + ' ' + padToWidth(wrapped, contentWidth) + ' ' + border(v));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const bottomFill = Math.max(0, width - 2);
|
|
85
|
+
const bottom = border(BOX.bottomLeft + h.repeat(bottomFill) + BOX.bottomRight);
|
|
86
|
+
return [paint(top), ...body.map(paint), paint(bottom)];
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Two-column welcome card: gradient DeepSeek logo + tips, titled `app vversion`.
|
|
90
|
+
*/
|
|
91
|
+
export function renderWelcome(options, theme) {
|
|
92
|
+
const boxWidth = Math.max(0, options.width);
|
|
93
|
+
if (boxWidth < 8)
|
|
94
|
+
return [];
|
|
95
|
+
const dualContentWidth = boxWidth - 3;
|
|
96
|
+
const minLeft = visibleWidth(DEEPSEEK_LOGO[0]) + 2;
|
|
97
|
+
const minRight = 20;
|
|
98
|
+
const desiredLeft = Math.min(26, Math.max(minLeft, Math.floor(dualContentWidth * 0.35)));
|
|
99
|
+
const showRight = dualContentWidth >= minRight + minLeft;
|
|
100
|
+
const leftCol = showRight ? Math.min(desiredLeft, dualContentWidth - minRight) : boxWidth - 2;
|
|
101
|
+
const rightCol = showRight ? Math.max(1, dualContentWidth - leftCol) : 0;
|
|
102
|
+
const logo = gradientLogo(theme, DEEPSEEK_LOGO);
|
|
103
|
+
const effort = options.reasoningEffort ?? '';
|
|
104
|
+
const leftLines = [
|
|
105
|
+
centerText(theme.bold('Into the Unknown'), leftCol),
|
|
106
|
+
'',
|
|
107
|
+
...logo.map((line) => centerText(line, leftCol)),
|
|
108
|
+
'',
|
|
109
|
+
centerText(theme.fg('muted', options.model), leftCol),
|
|
110
|
+
...(effort === '' ? [] : [centerText(theme.fg('dim', effort), leftCol)]),
|
|
111
|
+
];
|
|
112
|
+
const tips = options.tips ?? WELCOME_TIPS.slice(0, 4);
|
|
113
|
+
const tipKeyWidth = tips.reduce((width, tip) => Math.max(width, visibleWidth(tip.key)), 0);
|
|
114
|
+
const tipLines = tips.map((tip) => {
|
|
115
|
+
const key = fitToWidth(tip.key, tipKeyWidth);
|
|
116
|
+
return ` ${theme.fg('dim', key)}${theme.fg('muted', ' ' + tip.text)}`;
|
|
117
|
+
});
|
|
118
|
+
const rightLines = showRight
|
|
119
|
+
? [
|
|
120
|
+
` ${theme.bold(theme.fg('accent', 'Tips'))}`,
|
|
121
|
+
...tipLines,
|
|
122
|
+
'',
|
|
123
|
+
` ${theme.bold(theme.fg('accent', 'Recent sessions'))}`,
|
|
124
|
+
...(options.recentSessions === undefined || options.recentSessions.length === 0
|
|
125
|
+
? [` ${theme.fg('dim', 'No recent sessions')}`]
|
|
126
|
+
: options.recentSessions.slice(0, 3).map((session) => {
|
|
127
|
+
const age = ` (${formatRelativeAge(session.updatedAt ?? session.createdAt)})`;
|
|
128
|
+
const labelWidth = Math.max(1, rightCol - 2 - visibleWidth(age));
|
|
129
|
+
const label = truncateToWidth(session.title || session.id, labelWidth);
|
|
130
|
+
return ` ${theme.fg('muted', label)}${theme.fg('dim', age)}`;
|
|
131
|
+
})),
|
|
132
|
+
]
|
|
133
|
+
: [];
|
|
134
|
+
const h = theme.fg('dim', BOX.horizontal);
|
|
135
|
+
const v = theme.fg('dim', BOX.vertical);
|
|
136
|
+
const tl = theme.fg('dim', BOX.topLeft);
|
|
137
|
+
const tr = theme.fg('dim', BOX.topRight);
|
|
138
|
+
const bl = theme.fg('dim', BOX.bottomLeft);
|
|
139
|
+
const br = theme.fg('dim', BOX.bottomRight);
|
|
140
|
+
const teeUp = theme.fg('dim', BOX.teeUp);
|
|
141
|
+
const teeDown = theme.fg('dim', BOX.teeDown);
|
|
142
|
+
const teeLeft = theme.fg('dim', BOX.teeLeft);
|
|
143
|
+
const teeRight = theme.fg('dim', BOX.teeRight);
|
|
144
|
+
const title = ` ${options.appName} v${options.version} `;
|
|
145
|
+
const titlePrefix = BOX.horizontal.repeat(3);
|
|
146
|
+
const titleStyled = theme.fg('dim', titlePrefix) + theme.fg('muted', title);
|
|
147
|
+
const titleWidth = showRight ? leftCol : boxWidth - 2;
|
|
148
|
+
const afterTitle = Math.max(0, titleWidth - visibleWidth(titlePrefix) - visibleWidth(title));
|
|
149
|
+
const titleSegment = visibleWidth(titleStyled) >= titleWidth
|
|
150
|
+
? truncateToWidth(titleStyled, titleWidth)
|
|
151
|
+
: titleStyled + theme.fg('dim', BOX.horizontal.repeat(afterTitle));
|
|
152
|
+
const lines = [showRight
|
|
153
|
+
? tl + titleSegment + teeDown + h.repeat(rightCol) + tr
|
|
154
|
+
: tl + titleSegment + tr];
|
|
155
|
+
const rows = showRight ? Math.max(leftLines.length, rightLines.length) : leftLines.length;
|
|
156
|
+
const separatorRow = 1 + tipLines.length;
|
|
157
|
+
for (let i = 0; i < rows; i += 1) {
|
|
158
|
+
const left = fitToWidth(leftLines[i] ?? '', leftCol);
|
|
159
|
+
if (showRight) {
|
|
160
|
+
lines.push(i === separatorRow
|
|
161
|
+
? v + left + teeRight + h.repeat(rightCol) + teeLeft
|
|
162
|
+
: v + left + v + fitToWidth(rightLines[i] ?? '', rightCol) + v);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
lines.push(v + left + v);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (showRight) {
|
|
169
|
+
lines.push(bl + h.repeat(leftCol) + teeUp + h.repeat(rightCol) + br);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
lines.push(bl + h.repeat(leftCol) + br);
|
|
173
|
+
}
|
|
174
|
+
return lines;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Rounded editor: its label lives in the top border, input occupies one or more
|
|
178
|
+
* body rows, and a dedicated bottom border keeps the cursor off the chrome.
|
|
179
|
+
*/
|
|
180
|
+
export function renderEditor(options, theme) {
|
|
181
|
+
const width = Math.max(4, options.width);
|
|
182
|
+
const padX = 1;
|
|
183
|
+
const contentWidth = Math.max(1, width - 2 - padX * 2);
|
|
184
|
+
const h = BOX.horizontal;
|
|
185
|
+
const border = (text) => theme.fg(options.border, text);
|
|
186
|
+
const topLeft = border(BOX.topLeft + h.repeat(padX));
|
|
187
|
+
const topRight = border(h.repeat(padX) + BOX.topRight);
|
|
188
|
+
const fillWidth = Math.max(0, width - visibleWidth(BOX.topLeft + h.repeat(padX)) - visibleWidth(h.repeat(padX) + BOX.topRight));
|
|
189
|
+
const status = truncateToWidth(options.status, fillWidth);
|
|
190
|
+
const statusFill = Math.max(0, fillWidth - visibleWidth(status));
|
|
191
|
+
const top = topLeft + status + border(h.repeat(statusFill)) + topRight;
|
|
192
|
+
const layout = wrapIndexed(options.input, contentWidth);
|
|
193
|
+
const caret = cursorOnWrapped(layout, options.inputCursor, options.input);
|
|
194
|
+
const rows = layout.length > 0 ? layout : [{ text: '', start: 0, end: 0 }];
|
|
195
|
+
const lines = [top];
|
|
196
|
+
for (let i = 0; i < rows.length; i += 1) {
|
|
197
|
+
const text = rows[i]?.text ?? '';
|
|
198
|
+
const hint = options.inlineHint;
|
|
199
|
+
const atCaretEnd = i === caret.row && caret.column >= visibleWidth(text);
|
|
200
|
+
let body = options.paintInput?.(text, rows[i]?.start ?? 0) ?? text;
|
|
201
|
+
if (atCaretEnd && hint !== undefined && hint !== '') {
|
|
202
|
+
const budget = Math.max(0, contentWidth - visibleWidth(text));
|
|
203
|
+
if (budget > 0)
|
|
204
|
+
body += theme.fg('dim', truncateToWidth(hint, budget));
|
|
205
|
+
}
|
|
206
|
+
const linePad = padding(Math.max(0, contentWidth - visibleWidth(body)));
|
|
207
|
+
const left = border(BOX.vertical) + padding(padX);
|
|
208
|
+
const right = padding(padX) + border(BOX.vertical);
|
|
209
|
+
lines.push(left + body + linePad + right);
|
|
210
|
+
}
|
|
211
|
+
const bottomLeft = border(BOX.bottomLeft + h.repeat(padX));
|
|
212
|
+
const bottomRight = border(h.repeat(padX) + BOX.bottomRight);
|
|
213
|
+
lines.push(bottomLeft + border(h.repeat(fillWidth)) + bottomRight);
|
|
214
|
+
return {
|
|
215
|
+
lines,
|
|
216
|
+
cursor: { row: 1 + caret.row, column: 2 + caret.column },
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/** Columns of left chrome before input text (`│ `). */
|
|
220
|
+
export const EDITOR_CONTENT_COL = 2;
|
|
221
|
+
/**
|
|
222
|
+
* Map a click in editor-local coordinates to a buffer index.
|
|
223
|
+
* Row 0 is the status cap (no hit). Undefined when the click is outside.
|
|
224
|
+
*/
|
|
225
|
+
export function hitTestEditor(input, width, localRow, col) {
|
|
226
|
+
if (localRow < 1)
|
|
227
|
+
return undefined;
|
|
228
|
+
const contentWidth = Math.max(1, Math.max(4, width) - 2 - 2);
|
|
229
|
+
const layout = wrapIndexed(input, contentWidth);
|
|
230
|
+
const rows = layout.length > 0 ? layout : [{ text: '', start: 0, end: 0 }];
|
|
231
|
+
if (localRow > rows.length)
|
|
232
|
+
return undefined;
|
|
233
|
+
const row = localRow - 1;
|
|
234
|
+
const line = rows[row];
|
|
235
|
+
if (line === undefined)
|
|
236
|
+
return 0;
|
|
237
|
+
return indexOnWrapped(line, col - EDITOR_CONTENT_COL, input);
|
|
238
|
+
}
|
|
239
|
+
/** DeepSeek Harness-aligned label shown while the model is driving a turn. */
|
|
240
|
+
export const DEEP_DRIVING_LABEL = 'Deep Driving';
|
|
241
|
+
/** Paint a restrained highlight that travels across the active driving label. */
|
|
242
|
+
function renderDrivingShimmer(theme, text, spinnerFrame) {
|
|
243
|
+
if (!theme.colors)
|
|
244
|
+
return text;
|
|
245
|
+
const characters = [...text];
|
|
246
|
+
const runway = 3;
|
|
247
|
+
const highlight = (spinnerFrame % (characters.length + runway * 2)) - runway;
|
|
248
|
+
return characters.map((character, index) => {
|
|
249
|
+
if (character === ' ')
|
|
250
|
+
return character;
|
|
251
|
+
const distance = Math.abs(index - highlight);
|
|
252
|
+
if (distance === 0)
|
|
253
|
+
return theme.bold(theme.fg('accent', character));
|
|
254
|
+
if (distance === 1)
|
|
255
|
+
return theme.fg('accent', character);
|
|
256
|
+
if (distance === 2)
|
|
257
|
+
return theme.fg('text', character);
|
|
258
|
+
return theme.fg('muted', character);
|
|
259
|
+
}).join('');
|
|
260
|
+
}
|
|
261
|
+
/** Activity row that sits above the editor while a turn is in flight. */
|
|
262
|
+
export function renderWorking(theme, spinnerFrame, action = DEEP_DRIVING_LABEL, width) {
|
|
263
|
+
const frame = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'][spinnerFrame % 10] ?? '⠋';
|
|
264
|
+
const prefix = ' ' + theme.fg('accent', frame) + ' ';
|
|
265
|
+
const hint = ' ' + theme.fg('dim', '⟨Ctrl+C: Interrupt⟩');
|
|
266
|
+
const paintAction = (text) => action === DEEP_DRIVING_LABEL
|
|
267
|
+
? renderDrivingShimmer(theme, text, spinnerFrame)
|
|
268
|
+
: theme.fg('muted', text);
|
|
269
|
+
if (width === undefined)
|
|
270
|
+
return [prefix + paintAction(action) + hint];
|
|
271
|
+
const actionWidth = Math.max(1, width - visibleWidth(prefix) - visibleWidth(hint));
|
|
272
|
+
if (actionWidth < 8)
|
|
273
|
+
return [truncateToWidth(prefix + paintAction(action), width)];
|
|
274
|
+
return [prefix + paintAction(truncateToWidth(action, actionWidth)) + hint];
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=box.js.map
|
package/lib/box.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../src/box.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort system clipboard write for `/copy`.
|
|
3
|
+
* @module @agi-fans/dsh-tui
|
|
4
|
+
*/
|
|
5
|
+
import { spawn } from 'node:child_process';
|
|
6
|
+
/** Writer used by `/copy`; injectable in tests. */
|
|
7
|
+
export type ClipboardWriter = (text: string) => Promise<void>;
|
|
8
|
+
/** Reader used by raw-paste bindings; injectable in tests. */
|
|
9
|
+
export type ClipboardReader = () => Promise<string>;
|
|
10
|
+
/** Platform clipboard argv, or undefined when no tool is available. */
|
|
11
|
+
export declare function clipboardCommand(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): readonly string[] | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Pipe `text` to the platform clipboard tool.
|
|
14
|
+
* @param text - payload to copy.
|
|
15
|
+
* @param spawnCmd - override for tests.
|
|
16
|
+
*/
|
|
17
|
+
export declare function copyToClipboard(text: string, spawnCmd?: typeof spawn): Promise<void>;
|
|
18
|
+
/** Read raw UTF-8 text from the platform clipboard. */
|
|
19
|
+
export declare function readFromClipboard(spawnCmd?: typeof spawn): Promise<string>;
|
package/lib/clipboard.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort system clipboard write for `/copy`.
|
|
3
|
+
* @module @agi-fans/dsh-tui
|
|
4
|
+
*/
|
|
5
|
+
import { spawn } from 'node:child_process';
|
|
6
|
+
/** Platform clipboard argv, or undefined when no tool is available. */
|
|
7
|
+
export function clipboardCommand(platform = process.platform, env = process.env) {
|
|
8
|
+
if (platform === 'darwin')
|
|
9
|
+
return ['pbcopy'];
|
|
10
|
+
if (platform === 'win32')
|
|
11
|
+
return ['clip'];
|
|
12
|
+
if (env.WAYLAND_DISPLAY)
|
|
13
|
+
return ['wl-copy'];
|
|
14
|
+
if (env.DISPLAY)
|
|
15
|
+
return ['xclip', '-selection', 'clipboard'];
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pipe `text` to the platform clipboard tool.
|
|
20
|
+
* @param text - payload to copy.
|
|
21
|
+
* @param spawnCmd - override for tests.
|
|
22
|
+
*/
|
|
23
|
+
export function copyToClipboard(text, spawnCmd = spawn) {
|
|
24
|
+
const cmd = clipboardCommand();
|
|
25
|
+
if (cmd === undefined)
|
|
26
|
+
return Promise.reject(new Error('no clipboard tool'));
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
const child = spawnCmd(cmd[0] ?? '', cmd.slice(1), { stdio: ['pipe', 'ignore', 'ignore'] });
|
|
29
|
+
const timer = setTimeout(() => {
|
|
30
|
+
child.kill();
|
|
31
|
+
reject(new Error('clipboard timed out'));
|
|
32
|
+
}, 2000);
|
|
33
|
+
child.on('error', (error) => {
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
reject(error);
|
|
36
|
+
});
|
|
37
|
+
child.on('close', (code) => {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
if (code === 0)
|
|
40
|
+
resolve();
|
|
41
|
+
else
|
|
42
|
+
reject(new Error('clipboard exited ' + String(code)));
|
|
43
|
+
});
|
|
44
|
+
child.stdin?.end(text);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/** Read raw UTF-8 text from the platform clipboard. */
|
|
48
|
+
export function readFromClipboard(spawnCmd = spawn) {
|
|
49
|
+
const cmd = process.platform === 'darwin'
|
|
50
|
+
? ['pbpaste']
|
|
51
|
+
: process.platform === 'win32'
|
|
52
|
+
? ['powershell.exe', '-NoProfile', '-Command', 'Get-Clipboard -Raw']
|
|
53
|
+
: process.env.WAYLAND_DISPLAY
|
|
54
|
+
? ['wl-paste', '-n']
|
|
55
|
+
: process.env.DISPLAY ? ['xclip', '-selection', 'clipboard', '-o'] : undefined;
|
|
56
|
+
if (cmd === undefined)
|
|
57
|
+
return Promise.reject(new Error('no clipboard tool'));
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const child = spawnCmd(cmd[0] ?? '', cmd.slice(1), { stdio: ['ignore', 'pipe', 'ignore'] });
|
|
60
|
+
let output = '';
|
|
61
|
+
const timer = setTimeout(() => {
|
|
62
|
+
child.kill();
|
|
63
|
+
reject(new Error('clipboard timed out'));
|
|
64
|
+
}, 2000);
|
|
65
|
+
child.stdout?.setEncoding('utf8');
|
|
66
|
+
child.stdout?.on('data', (chunk) => { output += chunk; });
|
|
67
|
+
child.on('error', (error) => { clearTimeout(timer); reject(error); });
|
|
68
|
+
child.on('close', (code) => {
|
|
69
|
+
clearTimeout(timer);
|
|
70
|
+
if (code === 0)
|
|
71
|
+
resolve(output);
|
|
72
|
+
else
|
|
73
|
+
reject(new Error('clipboard exited ' + String(code)));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=clipboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../src/clipboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Integration discovery commands registered through dsh-commands. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
export declare const name = "omdsh-command-integrations";
|
|
4
|
+
export declare const inject: string[];
|
|
5
|
+
/** Render the MCP subset of the unified Harness tool catalog. */
|
|
6
|
+
export declare function mcpCatalogText(tools: readonly {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
}[]): string;
|
|
10
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Integration discovery commands registered through dsh-commands. */
|
|
2
|
+
import { registerCommands } from "./command-registration.js";
|
|
3
|
+
export const name = 'omdsh-command-integrations';
|
|
4
|
+
export const inject = ['commands'];
|
|
5
|
+
function compactDescription(value, maxLength = 140) {
|
|
6
|
+
const normalized = value.replace(/\s+/gu, ' ').trim();
|
|
7
|
+
return normalized.length <= maxLength ? normalized : normalized.slice(0, maxLength - 1).trimEnd() + '…';
|
|
8
|
+
}
|
|
9
|
+
/** Render the MCP subset of the unified Harness tool catalog. */
|
|
10
|
+
export function mcpCatalogText(tools) {
|
|
11
|
+
const servers = new Map();
|
|
12
|
+
for (const tool of tools) {
|
|
13
|
+
const match = /^mcp__(.+?)__(.+)$/u.exec(tool.name);
|
|
14
|
+
if (match?.[1] === undefined || match[2] === undefined)
|
|
15
|
+
continue;
|
|
16
|
+
const rows = servers.get(match[1]) ?? [];
|
|
17
|
+
rows.push({ name: match[2], description: compactDescription(tool.description) });
|
|
18
|
+
servers.set(match[1], rows);
|
|
19
|
+
}
|
|
20
|
+
if (servers.size === 0) {
|
|
21
|
+
return 'No MCP tools are connected. Configure .dsh/mcp.json or ~/.dsh/mcp.json, then restart omdsh.';
|
|
22
|
+
}
|
|
23
|
+
const total = [...servers.values()].reduce((count, rows) => count + rows.length, 0);
|
|
24
|
+
return [
|
|
25
|
+
`MCP Servers · ${servers.size} connected · ${total} tool${total === 1 ? '' : 's'}`,
|
|
26
|
+
...[...servers].flatMap(([server, rows]) => [
|
|
27
|
+
'',
|
|
28
|
+
`**${server} · ${rows.length} tool${rows.length === 1 ? '' : 's'}**`,
|
|
29
|
+
'| Tool | Description |',
|
|
30
|
+
'|---|---|',
|
|
31
|
+
...rows.map(row => `| \`${row.name.replace(/\|/gu, '\\|')}\` | ${(row.description || 'No description provided.').replace(/\|/gu, '\\|')} |`),
|
|
32
|
+
]),
|
|
33
|
+
].join('\n');
|
|
34
|
+
}
|
|
35
|
+
function showMcp(ctx, invocation) {
|
|
36
|
+
if (invocation.rawInput.trim() !== '')
|
|
37
|
+
return { kind: 'error', text: 'Usage: /mcp' };
|
|
38
|
+
const tools = ctx.get('tools')?.schemas(invocation.agent).map(schema => ({
|
|
39
|
+
name: schema.name,
|
|
40
|
+
description: schema.description,
|
|
41
|
+
})) ?? [];
|
|
42
|
+
return { kind: 'success', text: mcpCatalogText(tools) };
|
|
43
|
+
}
|
|
44
|
+
export function apply(ctx) {
|
|
45
|
+
registerCommands(ctx, [
|
|
46
|
+
{ name: 'mcp', description: 'Show connected MCP servers and tools', handler: invocation => showMcp(ctx, invocation) },
|
|
47
|
+
], 'omdsh integration commands');
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=command-integrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-integrations.js","sourceRoot":"","sources":["../src/command-integrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Interactive access-mode command over the Harness permission preset seam. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
export declare const name = "omdsh-command-mode";
|
|
4
|
+
export declare const inject: string[];
|
|
5
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** Interactive access-mode command over the Harness permission preset seam. */
|
|
2
|
+
import { registerCommands } from "./command-registration.js";
|
|
3
|
+
export const name = 'omdsh-command-mode';
|
|
4
|
+
export const inject = ['commands', 'permissionPresets', 'tui'];
|
|
5
|
+
function titleCase(value) {
|
|
6
|
+
return value.split(/[-_]/u).filter(Boolean)
|
|
7
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
8
|
+
.join(' ');
|
|
9
|
+
}
|
|
10
|
+
async function confirmFullAccess(ctx, invocation) {
|
|
11
|
+
const answer = await ctx.tui.prompt({
|
|
12
|
+
title: 'Full access',
|
|
13
|
+
question: 'Allow unrestricted filesystem access without approval prompts?',
|
|
14
|
+
detail: 'Only enable this mode for a workspace and task you trust.',
|
|
15
|
+
options: [
|
|
16
|
+
{ label: 'Cancel', value: 'cancel', description: 'Keep the current access mode.' },
|
|
17
|
+
{ label: 'Enable full access', value: 'confirm', description: 'Disable sandbox and approval protection.' },
|
|
18
|
+
],
|
|
19
|
+
initialValue: 'cancel',
|
|
20
|
+
allowCustom: false,
|
|
21
|
+
submitLabel: 'choose',
|
|
22
|
+
signal: invocation.signal,
|
|
23
|
+
});
|
|
24
|
+
return answer === 'confirm';
|
|
25
|
+
}
|
|
26
|
+
async function selectMode(ctx, invocation) {
|
|
27
|
+
if (invocation.rawInput.trim() !== '')
|
|
28
|
+
return { kind: 'error', text: 'Usage: /mode' };
|
|
29
|
+
const current = ctx.permissionPresets.current(invocation.agent.session.events);
|
|
30
|
+
const options = ctx.permissionPresets.names.map((value) => {
|
|
31
|
+
const option = ctx.permissionPresets.optionOf(value);
|
|
32
|
+
return {
|
|
33
|
+
label: option.name,
|
|
34
|
+
value,
|
|
35
|
+
description: `${value === current ? 'Current · ' : ''}${option.description ?? titleCase(value)}`,
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
if (options.length === 0)
|
|
39
|
+
return { kind: 'error', text: 'No access modes are configured.' };
|
|
40
|
+
const selected = await ctx.tui.prompt({
|
|
41
|
+
title: 'Access mode',
|
|
42
|
+
question: 'Choose how omdsh may access your workspace',
|
|
43
|
+
options,
|
|
44
|
+
initialValue: current,
|
|
45
|
+
allowCustom: false,
|
|
46
|
+
submitLabel: 'apply',
|
|
47
|
+
signal: invocation.signal,
|
|
48
|
+
});
|
|
49
|
+
if (selected === null || selected === current)
|
|
50
|
+
return { kind: 'success' };
|
|
51
|
+
if (!ctx.permissionPresets.names.includes(selected)) {
|
|
52
|
+
return { kind: 'error', text: `Unknown access mode: ${selected}` };
|
|
53
|
+
}
|
|
54
|
+
if (selected === 'danger-full-access' && !await confirmFullAccess(ctx, invocation)) {
|
|
55
|
+
return { kind: 'success' };
|
|
56
|
+
}
|
|
57
|
+
// Keep the Harness command as the single mutation path. omdsh owns only
|
|
58
|
+
// this fixed-choice presentation; policy events and model notifications
|
|
59
|
+
// remain inside the permission plugin.
|
|
60
|
+
const switched = await ctx.commands.execute(invocation.agent, `/permission ${selected}`, invocation.signal);
|
|
61
|
+
if (switched === undefined)
|
|
62
|
+
return { kind: 'error', text: 'Access modes are unavailable.' };
|
|
63
|
+
if (switched.result.kind === 'error')
|
|
64
|
+
return switched.result;
|
|
65
|
+
const option = ctx.permissionPresets.optionOf(selected);
|
|
66
|
+
return { kind: 'success', text: `Access mode: ${option.name}` };
|
|
67
|
+
}
|
|
68
|
+
export function apply(ctx) {
|
|
69
|
+
registerCommands(ctx, [
|
|
70
|
+
{ name: 'mode', description: 'Choose the session access mode', handler: invocation => selectMode(ctx, invocation) },
|
|
71
|
+
], 'omdsh access-mode command');
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=command-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-mode.js","sourceRoot":"","sources":["../src/command-mode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Model/provider selection command registered through dsh-commands. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
export declare const name = "omdsh-command-model";
|
|
4
|
+
export declare const inject: string[];
|
|
5
|
+
export declare function apply(ctx: Context): void;
|