@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
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/** Model/provider selection command registered through dsh-commands. */
|
|
2
|
+
import { ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
3
|
+
import { registerCommands } from "./command-registration.js";
|
|
4
|
+
export const name = 'omdsh-command-model';
|
|
5
|
+
export const inject = ['commands', 'omdshSession', 'tui', 'llm'];
|
|
6
|
+
const FIXED_CHOICE = {
|
|
7
|
+
presentation: 'fullscreen-list',
|
|
8
|
+
filterable: true,
|
|
9
|
+
allowCustom: false,
|
|
10
|
+
};
|
|
11
|
+
function selected(raw, values) {
|
|
12
|
+
const index = /^\d+$/u.test(raw) ? Number(raw) - 1 : -1;
|
|
13
|
+
return index >= 0 ? values[index] : raw;
|
|
14
|
+
}
|
|
15
|
+
async function selectModel(ctx, invocation) {
|
|
16
|
+
if (invocation.rawInput.trim() !== '')
|
|
17
|
+
return { kind: 'error', text: 'Usage: /model' };
|
|
18
|
+
const providers = ctx.llm.listProviders();
|
|
19
|
+
if (providers.length === 0)
|
|
20
|
+
return { kind: 'error', text: 'No model providers are registered.' };
|
|
21
|
+
const current = ctx.omdshSession.selection(invocation.agent);
|
|
22
|
+
const providerRaw = await ctx.tui.prompt({
|
|
23
|
+
...FIXED_CHOICE,
|
|
24
|
+
title: 'Model provider',
|
|
25
|
+
question: 'Choose a provider',
|
|
26
|
+
options: providers.map(provider => ({ label: provider.id, description: provider.name })),
|
|
27
|
+
signal: invocation.signal,
|
|
28
|
+
});
|
|
29
|
+
if (providerRaw === null)
|
|
30
|
+
return { kind: 'success' };
|
|
31
|
+
const provider = selected(providerRaw, providers.map(entry => entry.id));
|
|
32
|
+
if (provider === undefined || !providers.some(entry => entry.id === provider)) {
|
|
33
|
+
return { kind: 'error', text: `Unknown provider: ${providerRaw}` };
|
|
34
|
+
}
|
|
35
|
+
const models = await ctx.llm.listModels(provider);
|
|
36
|
+
const modelRaw = await ctx.tui.prompt({
|
|
37
|
+
...FIXED_CHOICE,
|
|
38
|
+
title: 'Model',
|
|
39
|
+
question: `Choose a model for ${provider}`,
|
|
40
|
+
options: models.map(model => ({ label: model.id, description: model.description ?? model.name })),
|
|
41
|
+
signal: invocation.signal,
|
|
42
|
+
});
|
|
43
|
+
if (modelRaw === null)
|
|
44
|
+
return { kind: 'success' };
|
|
45
|
+
const model = selected(modelRaw, models.map(entry => entry.id));
|
|
46
|
+
if (model === undefined || !models.some(entry => entry.id === model)) {
|
|
47
|
+
return { kind: 'error', text: `Unknown model: ${modelRaw}` };
|
|
48
|
+
}
|
|
49
|
+
const info = await ctx.llm.resolveModelInfo(provider, model, invocation.signal);
|
|
50
|
+
let reasoningEffort = current.reasoningEffort;
|
|
51
|
+
if (info.reasoning === undefined) {
|
|
52
|
+
reasoningEffort = undefined;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const effortRaw = await ctx.tui.prompt({
|
|
56
|
+
...FIXED_CHOICE,
|
|
57
|
+
title: 'Reasoning effort',
|
|
58
|
+
question: 'Choose reasoning effort',
|
|
59
|
+
options: info.reasoning.efforts.map(effort => ({ label: String(effort.id), description: effort.description ?? effort.name })),
|
|
60
|
+
signal: invocation.signal,
|
|
61
|
+
});
|
|
62
|
+
if (effortRaw === null)
|
|
63
|
+
return { kind: 'success' };
|
|
64
|
+
const effortIds = info.reasoning.efforts.map(entry => String(entry.id));
|
|
65
|
+
const resolved = selected(effortRaw, effortIds);
|
|
66
|
+
if (resolved === undefined || !effortIds.includes(resolved)) {
|
|
67
|
+
return { kind: 'error', text: `Unknown reasoning effort: ${effortRaw}` };
|
|
68
|
+
}
|
|
69
|
+
reasoningEffort = ReasoningEffortId(resolved);
|
|
70
|
+
}
|
|
71
|
+
const selection = {
|
|
72
|
+
provider,
|
|
73
|
+
model,
|
|
74
|
+
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
75
|
+
};
|
|
76
|
+
await ctx.omdshSession.changeSelection(invocation.agent, selection, info);
|
|
77
|
+
return {
|
|
78
|
+
kind: 'success',
|
|
79
|
+
text: `Model: ${provider}/${model}${reasoningEffort === undefined ? '' : ` (${String(reasoningEffort)})`}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function apply(ctx) {
|
|
83
|
+
registerCommands(ctx, [
|
|
84
|
+
{ name: 'model', description: 'Select provider, model, and reasoning effort', handler: invocation => selectModel(ctx, invocation) },
|
|
85
|
+
], 'omdsh model command');
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=command-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-model.js","sourceRoot":"","sources":["../src/command-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Shared presentation for successful slash-command output. */
|
|
2
|
+
import { type Theme } from './theme.ts';
|
|
3
|
+
/** Render a command result without the generic notice frame. */
|
|
4
|
+
export declare function renderCommandOutput(command: string, text: string, theme: Theme, width: number): string[];
|
|
5
|
+
/** Subtle separator used only between adjacent, different command surfaces. */
|
|
6
|
+
export declare function renderCommandSeparator(theme: Theme, width: number): string;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Shared presentation for successful slash-command output. */
|
|
2
|
+
import { renderMarkdown } from "./markdown.js";
|
|
3
|
+
import { BOX } from "./theme.js";
|
|
4
|
+
import { truncateToWidth, visibleWidth, wrapText } from "./width.js";
|
|
5
|
+
/** Render a command result without the generic notice frame. */
|
|
6
|
+
export function renderCommandOutput(command, text, theme, width) {
|
|
7
|
+
const normalized = text.replaceAll('\r\n', '\n').replaceAll('\r', '\n').trimEnd();
|
|
8
|
+
const rows = normalized.split('\n');
|
|
9
|
+
if (rows.length <= 1) {
|
|
10
|
+
const prefix = width > 2 ? ' ' : '';
|
|
11
|
+
const continuation = ' '.repeat(visibleWidth(prefix));
|
|
12
|
+
return wrapText(normalized, Math.max(1, width - visibleWidth(prefix))).map((line, index) => truncateToWidth((index === 0 ? prefix : continuation) + theme.fg('dim', line), width));
|
|
13
|
+
}
|
|
14
|
+
const inset = width > 2 ? 1 : 0;
|
|
15
|
+
const contentWidth = Math.max(1, width - inset * 2);
|
|
16
|
+
const prefix = ' '.repeat(inset);
|
|
17
|
+
const first = rows.shift()?.trim() ?? '';
|
|
18
|
+
const title = first === '' ? `/${command}` : first;
|
|
19
|
+
const body = rows.join('\n').trim();
|
|
20
|
+
const heading = prefix + theme.bold(theme.fg('accent', truncateToWidth(title, contentWidth)));
|
|
21
|
+
if (body === '')
|
|
22
|
+
return [heading];
|
|
23
|
+
return [heading, '', ...renderMarkdown(body, theme, contentWidth).map(line => prefix + line)];
|
|
24
|
+
}
|
|
25
|
+
/** Subtle separator used only between adjacent, different command surfaces. */
|
|
26
|
+
export function renderCommandSeparator(theme, width) {
|
|
27
|
+
if (width <= 0)
|
|
28
|
+
return '';
|
|
29
|
+
if (width <= 2)
|
|
30
|
+
return theme.fg('border', BOX.horizontal.repeat(width));
|
|
31
|
+
return ' ' + theme.fg('border', BOX.horizontal.repeat(width - 2)) + ' ';
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=command-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-output.js","sourceRoot":"","sources":["../src/command-output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Follow-up and steering queue commands registered through dsh-commands. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
export declare const name = "omdsh-command-queue";
|
|
4
|
+
export declare const inject: string[];
|
|
5
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** Follow-up and steering queue commands registered through dsh-commands. */
|
|
2
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
3
|
+
import { registerCommands } from "./command-registration.js";
|
|
4
|
+
export const name = 'omdsh-command-queue';
|
|
5
|
+
export const inject = ['commands'];
|
|
6
|
+
function messageText(message) {
|
|
7
|
+
return message.content.map(block => block.type === 'text' ? block.text : `[${block.type}]`).join('');
|
|
8
|
+
}
|
|
9
|
+
function tableCell(value) {
|
|
10
|
+
return value.replace(/\|/gu, '\\|').replace(/\s+/gu, ' ').trim();
|
|
11
|
+
}
|
|
12
|
+
function messageTable(messages) {
|
|
13
|
+
if (messages.length === 0)
|
|
14
|
+
return ['_None queued._'];
|
|
15
|
+
return [
|
|
16
|
+
'| # | Message |',
|
|
17
|
+
'|---|---|',
|
|
18
|
+
...messages.map((message, index) => `| ${index + 1} | ${tableCell(messageText(message))} |`),
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
function steer(invocation) {
|
|
22
|
+
const input = invocation.rawInput.trim();
|
|
23
|
+
if (input === '')
|
|
24
|
+
return { kind: 'error', text: 'Usage: /steer <message>' };
|
|
25
|
+
invocation.agent.steer(createUserMessage({ content: [{ type: 'text', text: input }], source: { kind: 'user' } }));
|
|
26
|
+
return { kind: 'success', text: 'Steering queued for the next step.' };
|
|
27
|
+
}
|
|
28
|
+
function showQueue(invocation) {
|
|
29
|
+
if (invocation.rawInput.trim() !== '')
|
|
30
|
+
return { kind: 'error', text: 'Usage: /queue' };
|
|
31
|
+
const inbox = invocation.agent.inbox;
|
|
32
|
+
const total = inbox.nextTurn.length + inbox.nextStep.length;
|
|
33
|
+
return {
|
|
34
|
+
kind: 'success',
|
|
35
|
+
text: [
|
|
36
|
+
`Queued Messages · ${total}`,
|
|
37
|
+
'',
|
|
38
|
+
`**Follow-ups · ${inbox.nextTurn.length}**`,
|
|
39
|
+
...messageTable(inbox.nextTurn),
|
|
40
|
+
'',
|
|
41
|
+
`**Steering · ${inbox.nextStep.length}**`,
|
|
42
|
+
...messageTable(inbox.nextStep),
|
|
43
|
+
].join('\n'),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function dequeue(invocation) {
|
|
47
|
+
if (invocation.rawInput.trim() !== '')
|
|
48
|
+
return { kind: 'error', text: 'Usage: /dequeue' };
|
|
49
|
+
const inbox = invocation.agent.inbox;
|
|
50
|
+
const count = inbox.nextTurn.length + inbox.nextStep.length;
|
|
51
|
+
inbox.splice('next-turn', 0, inbox.nextTurn.length, []);
|
|
52
|
+
inbox.splice('next-step', 0, inbox.nextStep.length, []);
|
|
53
|
+
return { kind: 'success', text: `Removed ${count} queued message${count === 1 ? '' : 's'}.` };
|
|
54
|
+
}
|
|
55
|
+
export function apply(ctx) {
|
|
56
|
+
registerCommands(ctx, [
|
|
57
|
+
{ name: 'steer', description: 'Send guidance to the next model step', input: { hint: '<message>' }, handler: steer },
|
|
58
|
+
{ name: 'queue', description: 'Show queued follow-up and steering messages', handler: showQueue },
|
|
59
|
+
{ name: 'dequeue', description: 'Clear queued follow-up and steering messages', handler: dequeue },
|
|
60
|
+
], 'omdsh queue commands');
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=command-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-queue.js","sourceRoot":"","sources":["../src/command-queue.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAI7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAE5D,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAA;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,CAAA;AAElC,SAAS,WAAW,CAAC,OAAgE;IACnF,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACtG,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;AAClE,CAAC;AAED,SAAS,YAAY,CAAC,QAA4E;IAChG,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACpD,OAAO;QACL,iBAAiB;QACjB,WAAW;QACX,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,MAAM,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;KAC7F,CAAA;AACH,CAAC;AAED,SAAS,KAAK,CAAC,UAA6B;IAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;IACxC,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAA;IAC3E,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAA;IACjH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,oCAAoC,EAAE,CAAA;AACxE,CAAC;AAED,SAAS,SAAS,CAAC,UAA6B;IAC9C,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAA;IACtF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAA;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAA;IAC3D,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,qBAAqB,KAAK,EAAE;YAC5B,EAAE;YACF,kBAAkB,KAAK,CAAC,QAAQ,CAAC,MAAM,IAAI;YAC3C,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC/B,EAAE;YACF,gBAAgB,KAAK,CAAC,QAAQ,CAAC,MAAM,IAAI;YACzC,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;SAChC,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,UAA6B;IAC5C,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAA;IACxF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAA;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAA;IAC3D,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACvD,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACvD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,KAAK,kBAAkB,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAA;AAC/F,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,gBAAgB,CAAC,GAAG,EAAE;QACpB,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,sCAAsC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;QACpH,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,6CAA6C,EAAE,OAAO,EAAE,SAAS,EAAE;QACjG,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,8CAA8C,EAAE,OAAO,EAAE,OAAO,EAAE;KACnG,EAAE,sBAAsB,CAAC,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Shared lifecycle ownership for omdsh command plugins. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { CommandDefinition } from '@deepseek-ai/dsh-commands';
|
|
4
|
+
/** Register one command group, unregister before draining in-flight handlers. */
|
|
5
|
+
export declare function registerCommands(ctx: Context, definitions: readonly CommandDefinition[], label: string): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Shared lifecycle ownership for omdsh command plugins. */
|
|
2
|
+
/** Register one command group, unregister before draining in-flight handlers. */
|
|
3
|
+
export function registerCommands(ctx, definitions, label) {
|
|
4
|
+
const active = new Set();
|
|
5
|
+
ctx.effect(function* () {
|
|
6
|
+
yield async () => { await Promise.allSettled(active); };
|
|
7
|
+
for (const definition of definitions) {
|
|
8
|
+
yield ctx.commands.register({
|
|
9
|
+
...definition,
|
|
10
|
+
handler: (invocation) => {
|
|
11
|
+
const operation = Promise.resolve(definition.handler(invocation));
|
|
12
|
+
active.add(operation);
|
|
13
|
+
void operation.then(() => { active.delete(operation); }, () => { active.delete(operation); });
|
|
14
|
+
return operation;
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}, label);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=command-registration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-registration.js","sourceRoot":"","sources":["../src/command-registration.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAK5D,iFAAiF;AACjF,MAAM,UAAU,gBAAgB,CAAC,GAAY,EAAE,WAAyC,EAAE,KAAa;IACrG,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAA;IAChD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;QAClB,MAAM,KAAK,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAA;QACtD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC1B,GAAG,UAAU;gBACb,OAAO,EAAE,CAAC,UAAU,EAAE,EAAE;oBACtB,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAA;oBACjE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;oBACrB,KAAK,SAAS,CAAC,IAAI,CACjB,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA,CAAC,CAAC,EAClC,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA,CAAC,CAAC,CACnC,CAAA;oBACD,OAAO,SAAS,CAAA;gBAClB,CAAC;aACF,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,EAAE,KAAK,CAAC,CAAA;AACX,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Session lifecycle and inspection commands registered through dsh-commands. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
export declare const name = "omdsh-command-session";
|
|
4
|
+
export declare const inject: string[];
|
|
5
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/** Session lifecycle and inspection commands registered through dsh-commands. */
|
|
2
|
+
import { registerCommands } from "./command-registration.js";
|
|
3
|
+
import { formatRelativeAge } from "./relative-time.js";
|
|
4
|
+
export const name = 'omdsh-command-session';
|
|
5
|
+
export const inject = ['commands', 'omdshSession', 'tui'];
|
|
6
|
+
function humanText(event) {
|
|
7
|
+
if (event.type !== 'user/message' || event.data.source.kind !== 'user')
|
|
8
|
+
return undefined;
|
|
9
|
+
const text = event.data.content
|
|
10
|
+
.filter((block) => block.type === 'text')
|
|
11
|
+
.map(block => block.text)
|
|
12
|
+
.join('\n');
|
|
13
|
+
return text === '' ? undefined : text;
|
|
14
|
+
}
|
|
15
|
+
async function newSession(ctx, invocation) {
|
|
16
|
+
if (invocation.rawInput.trim() !== '')
|
|
17
|
+
return { kind: 'error', text: 'Usage: /new' };
|
|
18
|
+
if (invocation.agent.status === 'running') {
|
|
19
|
+
return { kind: 'error', text: 'Finish or interrupt the active turn before starting a new session.' };
|
|
20
|
+
}
|
|
21
|
+
await ctx.omdshSession.newSession(invocation.agent);
|
|
22
|
+
return { kind: 'success', text: 'Started a new session.' };
|
|
23
|
+
}
|
|
24
|
+
async function resumeSession(ctx, invocation) {
|
|
25
|
+
if (ctx.get('sessionPersistence') === undefined)
|
|
26
|
+
return { kind: 'error', text: 'Session persistence is not configured.' };
|
|
27
|
+
if (invocation.agent.status === 'running') {
|
|
28
|
+
return { kind: 'error', text: 'Finish or interrupt the active turn before resuming another session.' };
|
|
29
|
+
}
|
|
30
|
+
await ctx.omdshSession.refreshRecent();
|
|
31
|
+
let id = invocation.rawInput.trim();
|
|
32
|
+
if (id === '') {
|
|
33
|
+
const recent = ctx.omdshSession.recentSessions;
|
|
34
|
+
if (recent.length === 0)
|
|
35
|
+
return { kind: 'success', text: 'No durable sessions found.' };
|
|
36
|
+
const answer = await ctx.tui.prompt({
|
|
37
|
+
title: 'Resume Session',
|
|
38
|
+
question: '',
|
|
39
|
+
options: recent.map(row => ({
|
|
40
|
+
label: row.title,
|
|
41
|
+
value: row.id,
|
|
42
|
+
...(row.preview === undefined ? {} : { preview: row.preview }),
|
|
43
|
+
description: [
|
|
44
|
+
formatRelativeAge(row.updatedAt ?? row.createdAt),
|
|
45
|
+
...(row.eventCount === undefined ? [] : [`${row.eventCount} events`]),
|
|
46
|
+
].join(' · '),
|
|
47
|
+
...(row.status === undefined
|
|
48
|
+
? {}
|
|
49
|
+
: {
|
|
50
|
+
badge: {
|
|
51
|
+
label: row.status,
|
|
52
|
+
tone: row.status === 'done'
|
|
53
|
+
? 'success'
|
|
54
|
+
: row.status === 'failed'
|
|
55
|
+
? 'error'
|
|
56
|
+
: 'warning',
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
})),
|
|
60
|
+
presentation: 'fullscreen-list',
|
|
61
|
+
filterable: true,
|
|
62
|
+
allowCustom: false,
|
|
63
|
+
signal: invocation.signal,
|
|
64
|
+
});
|
|
65
|
+
if (answer === null)
|
|
66
|
+
return { kind: 'success' };
|
|
67
|
+
const index = /^\d+$/u.test(answer) ? Number(answer) - 1 : -1;
|
|
68
|
+
id = index >= 0 ? (recent[index]?.id ?? answer) : answer;
|
|
69
|
+
}
|
|
70
|
+
if (id === invocation.agent.id)
|
|
71
|
+
return { kind: 'success', text: 'That session is already active.' };
|
|
72
|
+
try {
|
|
73
|
+
await ctx.omdshSession.resumeSession(invocation.agent, id, invocation.signal);
|
|
74
|
+
return { kind: 'success', text: `Resumed ${id}.` };
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (invocation.signal.aborted)
|
|
78
|
+
return { kind: 'error', text: 'Resume cancelled.' };
|
|
79
|
+
return { kind: 'error', text: 'Resume failed: ' + (error instanceof Error ? error.message : String(error)) };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function showSession(ctx, invocation) {
|
|
83
|
+
const stats = ctx.omdshSession.stats(invocation.agent);
|
|
84
|
+
const selection = ctx.omdshSession.selection(invocation.agent);
|
|
85
|
+
const reasoningEffort = ctx.omdshSession.reasoningEffort(invocation.agent);
|
|
86
|
+
const controls = ctx.omdshSession.controls(invocation.agent);
|
|
87
|
+
const mode = controls.plan?.pending === true
|
|
88
|
+
? controls.plan.active ? 'Plan → Default (pending)' : 'Plan (pending)'
|
|
89
|
+
: controls.plan?.active === true ? 'Plan' : 'Default';
|
|
90
|
+
return {
|
|
91
|
+
kind: 'success',
|
|
92
|
+
text: [
|
|
93
|
+
'Session Details',
|
|
94
|
+
'',
|
|
95
|
+
'| Field | Value |',
|
|
96
|
+
'|---|---|',
|
|
97
|
+
`| Session | \`${invocation.agent.id}\` |`,
|
|
98
|
+
`| Model | \`${selection.provider}/${selection.model}\` |`,
|
|
99
|
+
`| Reasoning | \`${reasoningEffort ?? 'not available'}\` |`,
|
|
100
|
+
`| Mode | ${mode} |`,
|
|
101
|
+
...(controls.permission === undefined ? [] : [`| Access mode | \`${controls.permission}\` |`]),
|
|
102
|
+
`| Activity | ${stats.turns} turns · ${stats.steps} steps |`,
|
|
103
|
+
`| Tokens | ${stats.inputTokens} in · ${stats.outputTokens} out |`,
|
|
104
|
+
`| Queue | ${invocation.agent.inbox.nextTurn.length} follow-up · ${invocation.agent.inbox.nextStep.length} steering |`,
|
|
105
|
+
].join('\n'),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async function retry(ctx, invocation) {
|
|
109
|
+
if (invocation.rawInput.trim() !== '')
|
|
110
|
+
return { kind: 'error', text: 'Usage: /retry' };
|
|
111
|
+
for (let i = invocation.agent.session.events.length - 1; i >= 0; i -= 1) {
|
|
112
|
+
const text = humanText(invocation.agent.session.events[i]);
|
|
113
|
+
if (text === undefined)
|
|
114
|
+
continue;
|
|
115
|
+
await ctx.omdshSession.send(text, invocation.agent);
|
|
116
|
+
return { kind: 'success', text: 'Re-running the most recent human prompt as a new turn.' };
|
|
117
|
+
}
|
|
118
|
+
return { kind: 'success', text: 'No human prompt is available to retry.' };
|
|
119
|
+
}
|
|
120
|
+
function showTodo(invocation) {
|
|
121
|
+
if (invocation.rawInput.trim() !== '')
|
|
122
|
+
return { kind: 'error', text: 'Usage: /todo' };
|
|
123
|
+
const event = invocation.agent.session.events.findLast(item => item.type === 'todo/write');
|
|
124
|
+
if (event === undefined)
|
|
125
|
+
return { kind: 'success', text: 'No todo list has been recorded.' };
|
|
126
|
+
return {
|
|
127
|
+
kind: 'success',
|
|
128
|
+
text: [
|
|
129
|
+
`Todo · ${event.data.todos.length} item${event.data.todos.length === 1 ? '' : 's'}`,
|
|
130
|
+
'',
|
|
131
|
+
...event.data.todos.map((todo) => todo.status === 'completed'
|
|
132
|
+
? `- [x] ${todo.content}`
|
|
133
|
+
: todo.status === 'in_progress'
|
|
134
|
+
? `- [ ] **In progress** · ${todo.content}`
|
|
135
|
+
: `- [ ] ${todo.content}`),
|
|
136
|
+
].join('\n'),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export function apply(ctx) {
|
|
140
|
+
registerCommands(ctx, [
|
|
141
|
+
{ name: 'new', description: 'Start a new session', handler: invocation => newSession(ctx, invocation) },
|
|
142
|
+
{
|
|
143
|
+
name: 'resume',
|
|
144
|
+
description: 'Resume a durable session',
|
|
145
|
+
input: { hint: '[session-id]' },
|
|
146
|
+
handler: invocation => resumeSession(ctx, invocation),
|
|
147
|
+
},
|
|
148
|
+
{ name: 'session', description: 'Show current session details', handler: invocation => showSession(ctx, invocation) },
|
|
149
|
+
{ name: 'retry', description: 'Run the most recent human prompt again', handler: invocation => retry(ctx, invocation) },
|
|
150
|
+
{ name: 'todo', description: 'Show the current session todo list', handler: showTodo },
|
|
151
|
+
], 'omdsh session commands');
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=command-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-session.js","sourceRoot":"","sources":["../src/command-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Transcript search/export commands registered through dsh-commands. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
export declare const name = "omdsh-command-transcript";
|
|
4
|
+
export declare const inject: string[];
|
|
5
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** Transcript search/export commands registered through dsh-commands. */
|
|
2
|
+
import { writeFile } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import { registerCommands } from "./command-registration.js";
|
|
6
|
+
import { formatTranscriptMarkdown } from "./transcript-export.js";
|
|
7
|
+
export const name = 'omdsh-command-transcript';
|
|
8
|
+
export const inject = ['commands'];
|
|
9
|
+
function tableCell(value) {
|
|
10
|
+
return value.replace(/\|/gu, '\\|').replace(/\s+/gu, ' ').trim();
|
|
11
|
+
}
|
|
12
|
+
function sessionTitle(events, fallback) {
|
|
13
|
+
for (let i = events.length - 1; i >= 0; i -= 1) {
|
|
14
|
+
const event = events[i];
|
|
15
|
+
if (event?.type === 'session/title')
|
|
16
|
+
return event.data.title;
|
|
17
|
+
}
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
async function search(ctx, invocation) {
|
|
21
|
+
const input = invocation.rawInput.trim();
|
|
22
|
+
const all = input === '--all' || input.startsWith('--all ');
|
|
23
|
+
const query = (all ? input.slice('--all'.length) : input).trim();
|
|
24
|
+
if (query === '')
|
|
25
|
+
return { kind: 'error', text: 'Usage: /search [--all] <query>' };
|
|
26
|
+
const service = ctx.get('sessionQuery');
|
|
27
|
+
if (service === undefined)
|
|
28
|
+
return { kind: 'error', text: 'Session search is not configured.' };
|
|
29
|
+
try {
|
|
30
|
+
if (all) {
|
|
31
|
+
const page = await service.searchSessions({ query, limit: 20 }, { signal: invocation.signal });
|
|
32
|
+
const lines = page.items.map((hit) => `| \`${tableCell(hit.header.id)}\` · #${hit.bestMatch.seq} ${tableCell(hit.bestMatch.type)} | ${tableCell(hit.bestMatch.snippet)} |`);
|
|
33
|
+
return {
|
|
34
|
+
kind: 'success',
|
|
35
|
+
text: lines.length === 0
|
|
36
|
+
? `No sessions match “${query}”.`
|
|
37
|
+
: [`Session Matches · ${lines.length} · “${query}”`, '', '| Session / Event | Snippet |', '|---|---|', ...lines].join('\n'),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const page = await service.searchEvents({ sessionId: invocation.agent.session.id, query, limit: 30 }, { signal: invocation.signal });
|
|
41
|
+
const lines = page.items.map((hit) => `| #${hit.seq} ${tableCell(hit.type)} | ${tableCell(hit.snippet)} |`);
|
|
42
|
+
return {
|
|
43
|
+
kind: 'success',
|
|
44
|
+
text: lines.length === 0
|
|
45
|
+
? `No transcript matches “${query}”.`
|
|
46
|
+
: [`Transcript Matches · ${lines.length} · “${query}”`, '', '| Event | Snippet |', '|---|---|', ...lines].join('\n'),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (invocation.signal.aborted)
|
|
51
|
+
return { kind: 'error', text: 'Search cancelled.' };
|
|
52
|
+
return { kind: 'error', text: 'Search failed: ' + (error instanceof Error ? error.message : String(error)) };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function exportTranscript(invocation) {
|
|
56
|
+
const input = invocation.rawInput.trim();
|
|
57
|
+
const unquoted = input.replace(/^(?:"(.*)"|'(.*)')$/u, '$1$2');
|
|
58
|
+
const fallback = `omdsh-transcript-${invocation.agent.id}.md`;
|
|
59
|
+
const path = resolve(unquoted === '' ? fallback : (unquoted.startsWith('~/') ? homedir() + unquoted.slice(1) : unquoted));
|
|
60
|
+
const title = sessionTitle(invocation.agent.session.events, invocation.agent.id);
|
|
61
|
+
try {
|
|
62
|
+
await writeFile(path, formatTranscriptMarkdown(invocation.agent.id, title, invocation.agent.session.events), { encoding: 'utf8', mode: 0o600 });
|
|
63
|
+
return { kind: 'success', text: `Exported complete transcript to ${path}` };
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return { kind: 'error', text: 'Export failed: ' + (error instanceof Error ? error.message : String(error)) };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function apply(ctx) {
|
|
70
|
+
registerCommands(ctx, [
|
|
71
|
+
{
|
|
72
|
+
name: 'search',
|
|
73
|
+
description: 'Search this transcript, or all sessions with --all',
|
|
74
|
+
input: { hint: '[--all] <query>' },
|
|
75
|
+
handler: invocation => search(ctx, invocation),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'export',
|
|
79
|
+
description: 'Export the complete transcript as Markdown',
|
|
80
|
+
input: { hint: '[path]' },
|
|
81
|
+
handler: exportTranscript,
|
|
82
|
+
},
|
|
83
|
+
], 'omdsh transcript commands');
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=command-transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-transcript.js","sourceRoot":"","sources":["../src/command-transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/copy` picker overlay: OMP-style list of transcript copy targets.
|
|
3
|
+
* Pure — the provider owns the clipboard write.
|
|
4
|
+
* @module @agi-fans/dsh-tui
|
|
5
|
+
*/
|
|
6
|
+
import type { CopyPick } from './copy-targets.ts';
|
|
7
|
+
import type { KeyEvent } from './keys.ts';
|
|
8
|
+
import { type Theme } from './theme.ts';
|
|
9
|
+
/** Visible picker rows. */
|
|
10
|
+
export declare const COPY_SELECTOR_MAX_VISIBLE = 8;
|
|
11
|
+
/** Preview lines under the list. */
|
|
12
|
+
export declare const COPY_SELECTOR_PREVIEW_LINES = 4;
|
|
13
|
+
/** First overlay-local row that paints a target. */
|
|
14
|
+
export declare const COPY_SELECTOR_ITEM_ROW = 3;
|
|
15
|
+
/** Live overlay state. */
|
|
16
|
+
export interface CopySelectorState {
|
|
17
|
+
items: readonly CopyPick[];
|
|
18
|
+
selected: number;
|
|
19
|
+
}
|
|
20
|
+
/** Outcome of one key against the overlay. */
|
|
21
|
+
export type CopySelectorCommand = {
|
|
22
|
+
kind: 'update';
|
|
23
|
+
state: CopySelectorState;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'pick';
|
|
26
|
+
item: CopyPick;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'close';
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'ignore';
|
|
31
|
+
};
|
|
32
|
+
/** Open the picker on the assembled targets. */
|
|
33
|
+
export declare function createCopySelector(items: readonly CopyPick[], selected?: number): CopySelectorState;
|
|
34
|
+
/** Visible item-index window around `selected`. */
|
|
35
|
+
export declare function copySelectorVisibleRange(count: number, selected: number, maxVisible?: number): {
|
|
36
|
+
start: number;
|
|
37
|
+
end: number;
|
|
38
|
+
};
|
|
39
|
+
/** Item index under an overlay-local row, or undefined on chrome. */
|
|
40
|
+
export declare function hitTestCopySelector(count: number, selected: number, localRow: number, maxVisible?: number): number | undefined;
|
|
41
|
+
/** Move the highlight to `index` without copying. */
|
|
42
|
+
export declare function selectCopyTarget(state: CopySelectorState, index: number): CopySelectorState;
|
|
43
|
+
/** Apply one decoded event to the overlay. */
|
|
44
|
+
export declare function applyCopySelectorEvent(state: CopySelectorState, event: KeyEvent): CopySelectorCommand;
|
|
45
|
+
/** Overlay frame: title, windowed rows, preview, hints. */
|
|
46
|
+
export declare function renderCopySelector(state: CopySelectorState, theme: Theme, width: number, maxVisible?: number): {
|
|
47
|
+
lines: string[];
|
|
48
|
+
cursor: {
|
|
49
|
+
row: number;
|
|
50
|
+
column: number;
|
|
51
|
+
};
|
|
52
|
+
};
|