dsh-code 1.0.1 → 1.0.2
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/README.en.md +4 -4
- package/README.md +4 -4
- package/lib/index.mjs +754 -380
- package/lib/types/app.d.ts +2 -13
- package/lib/types/attachments.d.ts +1 -1
- package/lib/types/keyboard.d.ts +31 -0
- package/lib/types/mentions.d.ts +2 -0
- package/lib/types/render/animations.d.ts +27 -11
- package/lib/types/render/editor.d.ts +32 -7
- package/lib/types/render/lines.d.ts +1 -1
- package/package.json +1 -1
- package/src/app.ts +596 -503
- package/src/attachments.ts +7 -0
- package/src/index.ts +1 -1
- package/src/internals.ts +26 -9
- package/src/keyboard.ts +131 -7
- package/src/mentions.ts +6 -1
- package/src/render/animations.ts +64 -17
- package/src/render/editor.ts +125 -25
- package/src/render/lines.ts +16 -2
package/lib/types/app.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ import type { ModelDirectory, ModelRow } from './models.ts';
|
|
|
26
26
|
import type { ProviderConfiguration, ProviderSettingsDirectory, ProviderTargetView } from './provider-settings.ts';
|
|
27
27
|
import type { QuestionStore } from './questions.ts';
|
|
28
28
|
import type { SkillsView, SkillRow } from './skills.ts';
|
|
29
|
-
import type
|
|
29
|
+
import { type MentionCandidate } from './mentions.ts';
|
|
30
30
|
import type { SubagentFeedView } from './subagents.ts';
|
|
31
31
|
import { type JobRow } from './kernel-panels.ts';
|
|
32
32
|
import type { PresetRow } from './presets.ts';
|
|
@@ -85,7 +85,7 @@ export interface AppProps {
|
|
|
85
85
|
/** Validate draft image paths without committing attachment objects. */
|
|
86
86
|
inspectImages(paths: readonly string[]): Promise<readonly ImagePathInspection[]>;
|
|
87
87
|
/** Validate, normalize and persist images immediately before submission. */
|
|
88
|
-
prepareImages(paths: readonly string[]): Promise<readonly ImageBlock[]>;
|
|
88
|
+
prepareImages(paths: readonly string[], signal?: AbortSignal): Promise<readonly ImageBlock[]>;
|
|
89
89
|
/** Apply one /model selection (with an advertised reasoning effort, when picked); returns the display label. */
|
|
90
90
|
selectModel(row: ModelRow, effortId?: string): string;
|
|
91
91
|
/** The /subagent override label, '' when delegated agents follow the current model. */
|
|
@@ -164,17 +164,6 @@ export interface AppProps {
|
|
|
164
164
|
/** Cancel one queued inbox message by identity (Delete on the empty composer). */
|
|
165
165
|
cancelQueued(messageId: string): void;
|
|
166
166
|
}
|
|
167
|
-
/**
|
|
168
|
-
* One-row editor window keeping the logical cursor visible in long drafts.
|
|
169
|
-
* The caret and its surroundings slice at grapheme boundaries: splitting a
|
|
170
|
-
* star-plane surrogate pair would render an isolated half under the block
|
|
171
|
-
* caret with a width the terminal never draws.
|
|
172
|
-
*/
|
|
173
|
-
export declare function editorWindow(value: string, cursor: number, columns: number): {
|
|
174
|
-
before: string;
|
|
175
|
-
caret: string;
|
|
176
|
-
after: string;
|
|
177
|
-
};
|
|
178
167
|
/** One completion candidate row. */
|
|
179
168
|
interface CompletionCandidate {
|
|
180
169
|
/** Insertion text for the command name (with leading slash). */
|
|
@@ -17,4 +17,4 @@ export declare function parsePastedImagePaths(input: string): readonly string[];
|
|
|
17
17
|
/** Validate path, byte size and encoded signature without writing an attachment object. */
|
|
18
18
|
export declare function inspectImagePaths(paths: readonly string[], attachments: AttachmentStore | undefined, cwd?: string): Promise<readonly ImagePathInspection[]>;
|
|
19
19
|
/** Read, validate, and persist an ordered image path list as model content blocks. */
|
|
20
|
-
export declare function saveImagePaths(paths: readonly string[], attachments: AttachmentStore | undefined): Promise<readonly ImageBlock[]>;
|
|
20
|
+
export declare function saveImagePaths(paths: readonly string[], attachments: AttachmentStore | undefined, signal?: AbortSignal): Promise<readonly ImageBlock[]>;
|
package/lib/types/keyboard.d.ts
CHANGED
|
@@ -19,10 +19,26 @@
|
|
|
19
19
|
export declare const KEYBOARD_ENHANCE_ENABLE = "\u001B[>4;0m\u001B[>5u";
|
|
20
20
|
/** Pop the enhancement stack and reset modifyOtherKeys (exit path). */
|
|
21
21
|
export declare const KEYBOARD_ENHANCE_DISABLE = "\u001B[<u\u001B[>4;0m";
|
|
22
|
+
/** Explicit environment overrides for terminal keyboard enhancement. */
|
|
23
|
+
export declare const DSH_DISABLE_KEYBOARD_ENHANCEMENT = "DSH_DISABLE_KEYBOARD_ENHANCEMENT";
|
|
24
|
+
export declare const DSH_ENABLE_KEYBOARD_ENHANCEMENT = "DSH_ENABLE_KEYBOARD_ENHANCEMENT";
|
|
25
|
+
/** True when the process is running inside the VS Code integrated terminal. */
|
|
26
|
+
export declare function isVsCodeTerminalEnv(env?: NodeJS.ProcessEnv): boolean;
|
|
27
|
+
/** Whether to push Kitty keyboard enhancement for the current terminal. */
|
|
28
|
+
export declare function shouldEnableKeyboardEnhancement(env?: NodeJS.ProcessEnv): boolean;
|
|
22
29
|
/** Enable bracketed paste reporting. */
|
|
23
30
|
export declare const BRACKETED_PASTE_ENABLE = "\u001B[?2004h";
|
|
24
31
|
/** Disable bracketed paste reporting. */
|
|
25
32
|
export declare const BRACKETED_PASTE_DISABLE = "\u001B[?2004l";
|
|
33
|
+
/** Enable terminal focus-in/focus-out reporting (xterm focus protocol). */
|
|
34
|
+
export declare const TERMINAL_FOCUS_REPORT_ENABLE = "\u001B[?1004h";
|
|
35
|
+
/** Disable terminal focus-in/focus-out reporting. */
|
|
36
|
+
export declare const TERMINAL_FOCUS_REPORT_DISABLE = "\u001B[?1004l";
|
|
37
|
+
/**
|
|
38
|
+
* Remove xterm focus reports from one input chunk and update the caller's
|
|
39
|
+
* focus state. Focus reports are terminal protocol, not composer text.
|
|
40
|
+
*/
|
|
41
|
+
export declare function stripTerminalFocusEvents(chunk: string, onFocus: (focused: boolean) => void): string;
|
|
26
42
|
/** Bracketed paste markers as Ink delivers them (it strips the leading ESC). */
|
|
27
43
|
export declare const PASTE_START_MARKER = "[200~";
|
|
28
44
|
export declare const PASTE_END_MARKER = "[201~";
|
|
@@ -39,3 +55,18 @@ export declare function stripPasteMarkers(text: string): string;
|
|
|
39
55
|
* unaffected.
|
|
40
56
|
*/
|
|
41
57
|
export declare function normalizeKeyboardChunk(chunk: string): string;
|
|
58
|
+
/** Editor actions Ink cannot distinguish reliably when terminal bytes batch. */
|
|
59
|
+
export type RawEditorToken = {
|
|
60
|
+
readonly kind: 'text';
|
|
61
|
+
readonly text: string;
|
|
62
|
+
} | {
|
|
63
|
+
readonly kind: 'home' | 'end' | 'delete-backward' | 'delete-word-backward' | 'delete-forward' | 'delete-word-forward';
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Tokenize a stdin chunk containing at least one editor-only key. Ink calls
|
|
67
|
+
* `useInput` once for a pasted/batched chunk, so preserving each action here
|
|
68
|
+
* prevents repeated Backspace/Home/End/Delete presses from collapsing into
|
|
69
|
+
* one blurred key event. Unknown escape sequences return undefined and stay
|
|
70
|
+
* under Ink's ownership.
|
|
71
|
+
*/
|
|
72
|
+
export declare function tokenizeRawEditorChunk(chunk: string): readonly RawEditorToken[] | undefined;
|
package/lib/types/mentions.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export interface PreparedMention {
|
|
|
44
44
|
/** Aggregated snapshot for `agent.inject()`, undefined without references. */
|
|
45
45
|
additionalContext?: import('@deepseek-ai/dsh-session').UserMessage;
|
|
46
46
|
}
|
|
47
|
+
/** Whether a mention token is already navigating a filesystem path. */
|
|
48
|
+
export declare function isPathLikeMentionQuery(query: string): boolean;
|
|
47
49
|
/** The mention API the input editor and the runner share. */
|
|
48
50
|
export interface MentionsApi {
|
|
49
51
|
/** Ranked menu candidates for the typed `@` query. */
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Terminal animation
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Claude-Code convention.
|
|
2
|
+
* Terminal animation helpers derived from the web design language:
|
|
3
|
+
* thinking uses Codex's slow shimmer sweep, the busy composer marker uses the
|
|
4
|
+
* original braille chase, and the streaming caret blink is the Claude-Code
|
|
5
|
+
* convention.
|
|
7
6
|
*
|
|
8
7
|
* The DeepSeek model-switch easter egg ports Codex's effort-ignition "Wave"
|
|
9
8
|
* style (`codex-rs/tui/src/bottom_pane/effort_ignition_styles.rs`): switching
|
|
@@ -17,14 +16,31 @@
|
|
|
17
16
|
* @module @deepseek-ai/dsh-code/render/animations
|
|
18
17
|
*/
|
|
19
18
|
import type { RgbTriple } from '../theme.ts';
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* per step — 8 frames × 125ms = the web's 1s cycle.
|
|
24
|
-
*/
|
|
19
|
+
/** Cadence for the original busy braille chase (8 frames × 125ms = 1s). */
|
|
20
|
+
export declare const BUSY_CHASE_TICK_MS = 125;
|
|
21
|
+
/** Original terminal StateDot chase frames. */
|
|
25
22
|
export declare const BUSY_CHASE_FRAMES: readonly ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
|
|
26
|
-
/** Chase frame for a monotonic tick
|
|
23
|
+
/** Chase frame for a monotonic tick. */
|
|
27
24
|
export declare function busyChaseFrame(tick: number): string;
|
|
25
|
+
/** Clock cadence for the Codex-style Deep diving shimmer. */
|
|
26
|
+
export declare const DEEP_DIVING_SHIMMER_TICK_MS = 33;
|
|
27
|
+
/** Codex shimmer timing and geometry. */
|
|
28
|
+
export declare const DEEP_DIVING_SHIMMER_DURATION_MS = 2000;
|
|
29
|
+
export declare const DEEP_DIVING_SHIMMER_PADDING = 10;
|
|
30
|
+
export declare const DEEP_DIVING_SHIMMER_HALF_WIDTH = 5;
|
|
31
|
+
export declare const DEEP_DIVING_SPARK_BREATH_DURATION_MS = 2000;
|
|
32
|
+
/**
|
|
33
|
+
* Codex's 2-second shimmer sweep, expressed in terminal ticks. The sweep has
|
|
34
|
+
* ten virtual columns of padding on either side and a five-column cosine
|
|
35
|
+
* highlight band, so the text changes gently rather than cycling rapidly.
|
|
36
|
+
*/
|
|
37
|
+
export declare function deepDivingShimmerIntensity(index: number, tick: number, graphemeCount: number): number;
|
|
38
|
+
/** Blue RGB color for one grapheme in the Codex-style shimmer. */
|
|
39
|
+
export declare function deepDivingGradientColor(index: number, tick: number, graphemeCount: number, base: RgbTriple, highlight: RgbTriple): RgbTriple;
|
|
40
|
+
/** Smooth breathing intensity for the always-visible Deep diving sparkle. */
|
|
41
|
+
export declare function deepDivingSparkIntensity(tick: number): number;
|
|
42
|
+
/** Blue RGB color for the breathing Deep diving sparkle. */
|
|
43
|
+
export declare function deepDivingSparkColor(tick: number, base: RgbTriple, highlight: RgbTriple): RgbTriple;
|
|
28
44
|
/** Caret visibility: half the ticks on, half off (530ms blink). */
|
|
29
45
|
export declare function caretVisible(tick: number): boolean;
|
|
30
46
|
/**
|
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
* grapheme boundaries) so the React state stays two primitives
|
|
9
9
|
* (value, cursor) and every operation here stays pure and testable.
|
|
10
10
|
*
|
|
11
|
-
* Word motion
|
|
12
|
-
*
|
|
13
|
-
* single word (two hanzi are one Alt+B step, not two).
|
|
11
|
+
* Word motion follows Codex's piece semantics: whitespace separates runs,
|
|
12
|
+
* punctuation runs stay atomic, and each Han grapheme is its own boundary.
|
|
14
13
|
*
|
|
15
14
|
* @module @deepseek-ai/dsh-code/render/editor
|
|
16
15
|
*/
|
|
@@ -79,6 +78,15 @@ export interface CaretSite {
|
|
|
79
78
|
row: number;
|
|
80
79
|
column: number;
|
|
81
80
|
}
|
|
81
|
+
/** Text slices for rendering one physical row with at most one caret. */
|
|
82
|
+
export interface EditorRowParts {
|
|
83
|
+
readonly before: string;
|
|
84
|
+
readonly caret: string;
|
|
85
|
+
readonly after: string;
|
|
86
|
+
readonly hasCaret: boolean;
|
|
87
|
+
}
|
|
88
|
+
/** Split one row around the authoritative caret; every other row stays whole. */
|
|
89
|
+
export declare function editorRowParts(row: EditorRowModel, rowIndex: number, caretRow: number, cursor: number, caretEnabled?: boolean): EditorRowParts;
|
|
82
90
|
/** Map a cursor offset to its caret site on the wrapped rows. */
|
|
83
91
|
export declare function caretSite(model: EditorModel, offset: number): CaretSite;
|
|
84
92
|
/**
|
|
@@ -123,6 +131,23 @@ export declare function killToLineStart(value: string, cursor: number): EditResu
|
|
|
123
131
|
export declare function killToLineEnd(value: string, cursor: number): EditResult;
|
|
124
132
|
/** Insert sanitized text at the cursor. */
|
|
125
133
|
export declare function insertText(value: string, cursor: number, text: string): EditResult;
|
|
134
|
+
/** Ctrl+A: current logical line start, then the previous line start on repeat. */
|
|
135
|
+
export declare function moveToLineStart(value: string, cursor: number, crossOnRepeat: boolean): number;
|
|
136
|
+
/** Ctrl+E: current logical line end, then the next line end on repeat. */
|
|
137
|
+
export declare function moveToLineEnd(value: string, cursor: number, crossOnRepeat: boolean): number;
|
|
138
|
+
/** One stable text range captured before an asynchronous draft operation. */
|
|
139
|
+
export interface DraftRange {
|
|
140
|
+
readonly start: number;
|
|
141
|
+
readonly end: number;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Remap a captured range when all intervening edits are wholly before or
|
|
145
|
+
* wholly after it. An edit overlapping either boundary invalidates the
|
|
146
|
+
* anchor instead of guessing and inserting content at a surprising place.
|
|
147
|
+
*/
|
|
148
|
+
export declare function remapStableRange(original: string, current: string, range: DraftRange): DraftRange | undefined;
|
|
149
|
+
/** Replace a current range while preserving a cursor moved after capture. */
|
|
150
|
+
export declare function replaceRangePreservingCursor(value: string, cursor: number, range: DraftRange, replacement: string): EditResult;
|
|
126
151
|
/**
|
|
127
152
|
* Composer editor row budget: the editor itself never grows past this many
|
|
128
153
|
* physical rows; deeper drafts scroll internally to keep the caret visible.
|
|
@@ -130,8 +155,8 @@ export declare function insertText(value: string, cursor: number, text: string):
|
|
|
130
155
|
*/
|
|
131
156
|
export declare function composerMaxRows(terminalRows: number): number;
|
|
132
157
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
158
|
+
* History navigation starts with Up on an empty draft, or after visual
|
|
159
|
+
* movement has reached the directional text edge of an unchanged recalled
|
|
160
|
+
* entry. Every other position remains under textarea movement.
|
|
136
161
|
*/
|
|
137
|
-
export declare function shouldRecallNavigate(value: string, cursor: number, lastRecalled: string | null): boolean;
|
|
162
|
+
export declare function shouldRecallNavigate(value: string, cursor: number, lastRecalled: string | null, direction: -1 | 1): boolean;
|
|
@@ -36,6 +36,6 @@ export declare function reasoningLines(text: string, columns: number): readonly
|
|
|
36
36
|
* Wrapped continuations keep a hanging indent aligned under each row's
|
|
37
37
|
* content (Codex history-cell alignment) instead of resetting to column 0.
|
|
38
38
|
*/
|
|
39
|
-
export declare function transcriptEntryLines(entry: TranscriptEntry, columns: number, showReasoning?: boolean, reasoningToggleHint?: boolean): readonly StyledLine[];
|
|
39
|
+
export declare function transcriptEntryLines(entry: TranscriptEntry, columns: number, showReasoning?: boolean, reasoningToggleHint?: boolean, showToolDetails?: boolean): readonly StyledLine[];
|
|
40
40
|
/** Settled-history variant carrying the Ctrl+R reasoning fold. */
|
|
41
41
|
export declare function settledEntryLines(entry: TranscriptEntry, columns: number, showReasoning: boolean): readonly StyledLine[];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-code",
|
|
3
3
|
"description": "DeepSeek Harness CLI core bundle: interactive coding terminal, durable sessions, and model management for dsh --profile cli",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"deepseek": "./bin/deepseek.mjs",
|