dsh-code 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +20 -6
- package/README.md +20 -6
- package/lib/index.mjs +2685 -622
- package/lib/types/app.d.ts +77 -1
- package/lib/types/history.d.ts +15 -4
- package/lib/types/index.d.ts +48 -0
- package/lib/types/kernel-panels.d.ts +7 -0
- package/lib/types/permissions.d.ts +37 -0
- package/lib/types/presets.d.ts +2 -0
- package/lib/types/provider-settings.d.ts +144 -0
- package/lib/types/questions.d.ts +2 -0
- package/lib/types/render/animations.d.ts +8 -6
- package/lib/types/render/lines.d.ts +6 -0
- package/lib/types/render/markdown.d.ts +3 -3
- package/lib/types/render/projection.d.ts +95 -3
- package/lib/types/render/status.d.ts +26 -36
- package/lib/types/render/text.d.ts +14 -7
- package/lib/types/render/tool-detail.d.ts +3 -1
- package/lib/types/render/tool-preview.d.ts +4 -1
- package/lib/types/session-directory.d.ts +15 -0
- package/lib/types/store.d.ts +13 -2
- package/lib/types/version.d.ts +5 -0
- package/package.json +1 -1
- package/src/app.ts +847 -150
- package/src/approval.ts +11 -2
- package/src/history.ts +20 -5
- package/src/index.ts +402 -159
- package/src/kernel-panels.ts +45 -8
- package/src/permissions.ts +85 -0
- package/src/presets.ts +12 -0
- package/src/provider-settings.ts +520 -0
- package/src/questions.ts +15 -5
- package/src/render/animations.ts +32 -18
- package/src/render/lines.ts +21 -6
- package/src/render/markdown.ts +302 -4
- package/src/render/projection.ts +665 -10
- package/src/render/status.ts +68 -162
- package/src/render/text.ts +28 -9
- package/src/render/tool-detail.ts +81 -40
- package/src/render/tool-preview.ts +18 -2
- package/src/session-directory.ts +44 -5
- package/src/skills.ts +8 -4
- package/src/store.ts +26 -8
- package/src/version.ts +16 -0
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @module @deepseek-ai/dsh-tui/render/status
|
|
11
11
|
*/
|
|
12
|
-
import type {
|
|
12
|
+
import type { TranscriptStats } from './projection.ts';
|
|
13
13
|
/**
|
|
14
14
|
* Compact token count: 517 / 12.2K / 517K / 1.2M (one decimal under three
|
|
15
15
|
* digits), mirroring the web composer's StatsLine format.
|
|
@@ -40,7 +40,7 @@ export declare function cacheHitPercent(usage: TranscriptStats['usage']): number
|
|
|
40
40
|
* Presentation tones for status spans; the footer maps each to a theme color
|
|
41
41
|
* (Codex status-line accents: model/path/branch/state/usage categories).
|
|
42
42
|
*/
|
|
43
|
-
export type StatusTone = 'model' | 'live' | 'path' | 'branch' | 'value' | 'label' | 'meta' | 'accent' | 'success' | 'warn' | 'error' | '
|
|
43
|
+
export type StatusTone = 'model' | 'live' | 'path' | 'branch' | 'value' | 'label' | 'meta' | 'accent' | 'success' | 'warn' | 'error' | 'ctxFill';
|
|
44
44
|
/** One colored run inside the status bar. */
|
|
45
45
|
export interface StatusSpan {
|
|
46
46
|
text: string;
|
|
@@ -64,11 +64,9 @@ export interface StatusRow {
|
|
|
64
64
|
hint: boolean;
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
|
-
* The footer layout: two stacked physical rows. Row 1
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* context progress bar, cache, and duration figures) and degrades to empty
|
|
71
|
-
* before any row-1 content is touched.
|
|
67
|
+
* The footer layout: two stacked physical rows. Row 1 keeps the primary
|
|
68
|
+
* controls in model, cwd, mode, branch, context, permission order. Row 2
|
|
69
|
+
* carries every secondary session/run figure and degrades independently.
|
|
72
70
|
*/
|
|
73
71
|
export interface StatusLayout {
|
|
74
72
|
row1: StatusRow;
|
|
@@ -89,33 +87,21 @@ export declare const STATUS_CYCLE_HINT = " (shift+tab to cycle)";
|
|
|
89
87
|
export declare const CONTEXT_BAR_WIDTH = 24;
|
|
90
88
|
/** Occupancy at which the usage readout flips from brand blue to amber. */
|
|
91
89
|
export declare const CONTEXT_WARN_PERCENT = 90;
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
export declare const CONTEXT_SEGMENTS: readonly ContextSegmentSpec[];
|
|
102
|
-
/**
|
|
103
|
-
* Render context occupancy as a segmented bar: one DeepSeek-blue run per
|
|
104
|
-
* content type (system/prompt/assistant/thinking/tools), column widths
|
|
105
|
-
* proportional to their estimated token share, each with a centered label
|
|
106
|
-
* that shortens to fit (system→sys→s). The remaining free tail is a dim
|
|
107
|
-
* track whose right edge carries the usage readout (`12.3K/1.0M 25%`,
|
|
108
|
-
* shrinking to the bare percent as the tail narrows). The readout flips to
|
|
109
|
-
* amber once occupancy reaches the warning threshold; the segment blues stay
|
|
110
|
-
* untouched so the composition remains readable at full context. The used
|
|
111
|
-
* total comes from the reported `lastPromptTokens`, never from the estimates.
|
|
112
|
-
* @param segments - estimated used tokens per content type.
|
|
90
|
+
/**
|
|
91
|
+
* Render context occupancy as ONE stepless bar: a solid DeepSeek-blue fill
|
|
92
|
+
* run, a dim dotted free track, and the usage readout riding the track's
|
|
93
|
+
* right edge (`12.3K/1.0M 25%`, shrinking to the bare percent as the track
|
|
94
|
+
* narrows). No per-content-type segmentation. Column split is deterministic:
|
|
95
|
+
* the free share is `Math.round(free/window*width)` clamped to at least
|
|
96
|
+
* CONTEXT_MIN_FREE columns and at most the full width; the fill takes every
|
|
97
|
+
* remaining column, so a given occupancy always renders the identical bar.
|
|
98
|
+
* The readout flips to amber once occupancy reaches the warning threshold.
|
|
113
99
|
* @param usedTokens - reported used tokens (drives the readout and percent).
|
|
114
100
|
* @param contextWindow - route capacity.
|
|
115
101
|
* @param width - total bar interior columns.
|
|
116
102
|
* @returns tone-split spans for the footer to paint.
|
|
117
103
|
*/
|
|
118
|
-
export declare function contextBar(
|
|
104
|
+
export declare function contextBar(usedTokens: number, contextWindow: number, width: number): readonly StatusSpan[];
|
|
119
105
|
/**
|
|
120
106
|
* One customizable status item (the Codex /statusline picker contract).
|
|
121
107
|
* 'left' items render as pipe-separated clusters after the identity dot;
|
|
@@ -149,6 +135,12 @@ export declare const DEFAULT_STATUSLINE_ITEMS: readonly StatusItemId[];
|
|
|
149
135
|
* @returns the normalized ordered item list.
|
|
150
136
|
*/
|
|
151
137
|
export declare function parseStatuslineItems(value: unknown): readonly StatusItemId[];
|
|
138
|
+
/**
|
|
139
|
+
* Extra left padding on the secondary row so its content aligns with the
|
|
140
|
+
* model name's left edge on the primary row (padding 2 + busy dot 2). The
|
|
141
|
+
* layout subtracts it from row 2's budget so the indent can never wrap it.
|
|
142
|
+
*/
|
|
143
|
+
export declare const STATUS_ROW2_INDENT = 2;
|
|
152
144
|
/** Identity facts the runner resolves once at mount; empty strings drop out. */
|
|
153
145
|
export interface StatusFacts {
|
|
154
146
|
/** 'provider/model' selection serving this session. */
|
|
@@ -173,7 +165,7 @@ export interface StatusFacts {
|
|
|
173
165
|
} | undefined;
|
|
174
166
|
/** Whether plan mode is active (folded from 'plan/mode'). */
|
|
175
167
|
plan: boolean;
|
|
176
|
-
/** Active
|
|
168
|
+
/** Active or pending permission preset; empty only when the service is unavailable. */
|
|
177
169
|
permission: string;
|
|
178
170
|
}
|
|
179
171
|
/**
|
|
@@ -185,12 +177,10 @@ export interface StatusFacts {
|
|
|
185
177
|
*/
|
|
186
178
|
export declare function permissionTone(permission: string): StatusTone;
|
|
187
179
|
/**
|
|
188
|
-
* Compose the two-row footer layout under a column budget. Row 1
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* (mode, context bar, cache, duration figures) fits its own budget and
|
|
193
|
-
* degrades to empty before any row-1 content is touched.
|
|
180
|
+
* Compose the two-row footer layout under a column budget. Row 1 keeps model,
|
|
181
|
+
* cwd, mode, branch, context, then the right-pinned permission badge and cycle
|
|
182
|
+
* hint. It drops hint, context, and permission before ellipsizing identity.
|
|
183
|
+
* Row 2 fits all secondary figures and state within its own budget.
|
|
194
184
|
* @param facts - identity facts resolved by the runner.
|
|
195
185
|
* @param stats - session figures folded from the durable log.
|
|
196
186
|
* @param columns - usable columns for each row (before their left padding).
|
|
@@ -3,17 +3,21 @@
|
|
|
3
3
|
* tool payloads, skill descriptions). Control characters — including ANSI
|
|
4
4
|
* CSI/OSC escape sequences — would otherwise pass through Ink into the
|
|
5
5
|
* terminal, letting output rewrite the screen or inject prompts. Newlines
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* survive; everything else in C0/C1 plus DEL becomes a visible `\xNN`
|
|
7
|
+
* escape, and bidi overrides / invisible format controls / Unicode line and
|
|
8
|
+
* paragraph separators become a visible `\uXXXX` escape (terminal emulators
|
|
9
|
+
* that render bidirectional text would otherwise reorder the displayed
|
|
10
|
+
* glyphs and let a command read as something it is not).
|
|
8
11
|
*
|
|
9
12
|
* @module @deepseek-ai/dsh-code/render/text
|
|
10
13
|
*/
|
|
11
14
|
/**
|
|
12
|
-
* Escape control characters so externally sourced text cannot
|
|
13
|
-
* terminal.
|
|
15
|
+
* Escape control and deceptive characters so externally sourced text cannot
|
|
16
|
+
* drive the terminal. C0/C1/DEL render as a literal `\xNN` escape; bidi,
|
|
17
|
+
* invisible-format, and separator controls render as a literal `\uXXXX`
|
|
18
|
+
* escape. Newlines and tabs survive (budgeted callers normalize tabs).
|
|
14
19
|
* @param text - raw text from a session event, tool payload, or catalog.
|
|
15
|
-
* @returns text with every
|
|
16
|
-
* as a literal `\xNN` escape.
|
|
20
|
+
* @returns display-safe text with every injectable character made visible.
|
|
17
21
|
*/
|
|
18
22
|
export declare function displayText(text: string): string;
|
|
19
23
|
/** Collapse external text to one terminal-safe logical row. */
|
|
@@ -36,7 +40,10 @@ export interface DisplayTail {
|
|
|
36
40
|
* Keep only the newest display-safe text that fits a terminal rectangle.
|
|
37
41
|
* The scan walks backward and stops as soon as the suffix is full, so a long
|
|
38
42
|
* reasoning stream does not rescan its entire accumulated prefix per chunk.
|
|
39
|
-
* Explicit newlines and terminal wrapping both consume rows
|
|
43
|
+
* Explicit newlines and terminal wrapping both consume rows; tabs expand to
|
|
44
|
+
* two spaces so terminal tab stops (which render at contextual column 8
|
|
45
|
+
* boundaries, not at the budgeted cell count) cannot inflate the physical
|
|
46
|
+
* row count of the live region.
|
|
40
47
|
* @param text - raw externally sourced text.
|
|
41
48
|
* @param columns - available terminal columns.
|
|
42
49
|
* @param rows - available terminal rows.
|
|
@@ -70,7 +70,9 @@ export type ToolDetail = {
|
|
|
70
70
|
* Render one change as removed-then-added rows, hunked by common prefix and
|
|
71
71
|
* suffix. A null before-image (file create) renders as pure additions. The
|
|
72
72
|
* budget caps emitted rows and reports the cut, so a whole-file overwrite
|
|
73
|
-
* never floods the transcript.
|
|
73
|
+
* never floods the transcript. Inputs are hard-capped before line splitting
|
|
74
|
+
* and the row list is built incrementally up to the budget — a crafted or
|
|
75
|
+
* replayed giant diff cannot force a full intermediate rows array.
|
|
74
76
|
* @param oldText - prior content, or null for a create.
|
|
75
77
|
* @param newText - content after the change.
|
|
76
78
|
* @param budget - maximum rows to emit.
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Bounded preview line for a tool invocation's raw JSON arguments: the first
|
|
3
3
|
* human-meaningful string among the well-known keys (command, path, query, …)
|
|
4
4
|
* with a fallback to the bounded raw JSON. Shared by the tool card in the
|
|
5
|
-
* transcript and the approval bar's command preview.
|
|
5
|
+
* transcript and the approval bar's command preview. Arguments longer than
|
|
6
|
+
* {@link MAX_PARSE_CHARS} are never parsed: the preview is a display concern,
|
|
7
|
+
* and a synchronous `JSON.parse` plus string copies of an unbounded model
|
|
8
|
+
* payload must not run on the approval or projection paths.
|
|
6
9
|
*
|
|
7
10
|
* @module @deepseek-ai/dsh-code/render/tool-preview
|
|
8
11
|
*/
|
|
@@ -48,6 +48,21 @@ export interface SessionRow {
|
|
|
48
48
|
readonly preset: string;
|
|
49
49
|
readonly title?: string;
|
|
50
50
|
}
|
|
51
|
+
/** True when the header describes a subagent conversation (durable lineage). */
|
|
52
|
+
export declare function isSubagentSession(header: SessionHeader): boolean;
|
|
53
|
+
/** Platform-consistent path equality for session cwd comparisons. */
|
|
54
|
+
export declare function samePath(left: string | undefined, right: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Unique header match by exact id or unique id prefix (root and subagent
|
|
57
|
+
* headers alike); the caller applies any lineage gate.
|
|
58
|
+
* @param headers - the persisted headers.
|
|
59
|
+
* @param wanted - the id or id prefix.
|
|
60
|
+
* @returns the uniquely matched header.
|
|
61
|
+
* @throws when nothing matches or the prefix is ambiguous.
|
|
62
|
+
*/
|
|
63
|
+
export declare function matchSessionId(headers: readonly SessionHeader[], wanted: string): SessionHeader;
|
|
64
|
+
/** The newest persisted ROOT session pinned to this cwd, or undefined. */
|
|
65
|
+
export declare function newestRootForCwd(headers: readonly SessionHeader[], cwd: string): SessionHeader | undefined;
|
|
51
66
|
/** Filter/sort header-only records. No session log is loaded here. */
|
|
52
67
|
export declare function projectSessionRows(records: readonly SessionRecord[], options: SessionDirectoryOptions): SessionRow[];
|
|
53
68
|
/** Merge page-local title observations without disturbing directory order. */
|
package/lib/types/store.d.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Observable transcript store: folds session events into the projection view
|
|
3
3
|
* and notifies subscribers. The renderer subscribes through
|
|
4
|
-
* `useSyncExternalStore`; the runner owns event feeding.
|
|
5
|
-
*
|
|
4
|
+
* `useSyncExternalStore`; the runner owns event feeding.
|
|
5
|
+
*
|
|
6
|
+
* Notification coalescing: the fold stays synchronous — `getView()` always
|
|
7
|
+
* returns the latest state the moment `apply` returns — but listener
|
|
8
|
+
* notification is scheduled on a microtask and deduplicated, so N events
|
|
9
|
+
* delivered inside one synchronous drain (the zai/GLM adapter drains its
|
|
10
|
+
* token buffer in sub-millisecond bursts) produce ONE React re-render.
|
|
11
|
+
* Synchronous per-event notification instead cascades one
|
|
12
|
+
* `useSyncExternalStore` force-update per token inside a single flush; the
|
|
13
|
+
* reconciler counts those as nested passive updates and floods React's
|
|
14
|
+
* "Maximum update depth exceeded" warning past 50 events, besides rendering
|
|
15
|
+
* the whole live tree once per token. A microtask keeps latency within the
|
|
16
|
+
* same macrotask, before Ink's throttled paint.
|
|
6
17
|
*
|
|
7
18
|
* @module @deepseek-ai/dsh-tui/store
|
|
8
19
|
*/
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Installed dsh-code version exposed by the terminal header. */
|
|
2
|
+
/** Read one package manifest version without making terminal startup depend on it. */
|
|
3
|
+
export declare function readPackageVersion(manifest?: import("url").URL): string;
|
|
4
|
+
/** Version of the installed dsh-code package. */
|
|
5
|
+
export declare const DSH_CODE_VERSION: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-code",
|
|
3
3
|
"description": "Claude-Code-style interactive TUI bundle for DeepSeek Harness (dsh): DeepSeek-blue whale banner, live session transcript, and a blended status line",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"deepseek": "./bin/deepseek.mjs",
|