dsh-code 0.6.1 → 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 +3952 -1315
- package/lib/startup.mjs +21 -9
- package/lib/theme-BEi4i_aN.mjs +624 -0
- package/lib/types/app.d.ts +108 -4
- package/lib/types/history.d.ts +15 -4
- package/lib/types/index.d.ts +49 -0
- package/lib/types/kernel-panels.d.ts +28 -0
- package/lib/types/mentions.d.ts +29 -12
- package/lib/types/models.d.ts +66 -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 +177 -2
- 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 +123 -3
- package/lib/types/render/status.d.ts +35 -24
- 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/startup.d.ts +12 -4
- package/lib/types/store.d.ts +13 -2
- package/lib/types/theme-panel.d.ts +24 -0
- package/lib/types/theme.d.ts +158 -2
- package/lib/types/version.d.ts +5 -0
- package/package.json +1 -1
- package/src/app.ts +1283 -206
- package/src/approval.ts +11 -2
- package/src/history.ts +20 -5
- package/src/index.ts +1207 -905
- package/src/kernel-panels.ts +518 -419
- package/src/mentions.ts +57 -27
- package/src/models.ts +200 -66
- 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 +373 -2
- package/src/render/lines.ts +21 -6
- package/src/render/markdown.ts +302 -4
- package/src/render/projection.ts +1419 -659
- package/src/render/status.ts +650 -603
- 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/startup.ts +119 -109
- package/src/store.ts +26 -8
- package/src/theme-panel.ts +72 -0
- package/src/theme.ts +206 -70
- package/src/version.ts +16 -0
|
@@ -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;
|
|
@@ -80,21 +78,30 @@ export declare const STATUS_GROUP_SEPARATOR = " | ";
|
|
|
80
78
|
export declare const STATUS_ITEM_SEPARATOR = " \u00B7 ";
|
|
81
79
|
/** The Codex-style mode cycle hint appended to the permission badge. */
|
|
82
80
|
export declare const STATUS_CYCLE_HINT = " (shift+tab to cycle)";
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Interior columns of the segmented context bar (content-type segments plus
|
|
83
|
+
* the free tail whose right edge carries the usage readout). Fixed so the
|
|
84
|
+
* row-2 drop ladder can pre-measure the group; the bar shrinks its labels and
|
|
85
|
+
* readout inside this budget rather than asking the layout for more room.
|
|
86
|
+
*/
|
|
87
|
+
export declare const CONTEXT_BAR_WIDTH = 24;
|
|
88
|
+
/** Occupancy at which the usage readout flips from brand blue to amber. */
|
|
86
89
|
export declare const CONTEXT_WARN_PERCENT = 90;
|
|
87
90
|
/**
|
|
88
|
-
* Render
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
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.
|
|
99
|
+
* @param usedTokens - reported used tokens (drives the readout and percent).
|
|
100
|
+
* @param contextWindow - route capacity.
|
|
101
|
+
* @param width - total bar interior columns.
|
|
95
102
|
* @returns tone-split spans for the footer to paint.
|
|
96
103
|
*/
|
|
97
|
-
export declare function contextBar(
|
|
104
|
+
export declare function contextBar(usedTokens: number, contextWindow: number, width: number): readonly StatusSpan[];
|
|
98
105
|
/**
|
|
99
106
|
* One customizable status item (the Codex /statusline picker contract).
|
|
100
107
|
* 'left' items render as pipe-separated clusters after the identity dot;
|
|
@@ -128,6 +135,12 @@ export declare const DEFAULT_STATUSLINE_ITEMS: readonly StatusItemId[];
|
|
|
128
135
|
* @returns the normalized ordered item list.
|
|
129
136
|
*/
|
|
130
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;
|
|
131
144
|
/** Identity facts the runner resolves once at mount; empty strings drop out. */
|
|
132
145
|
export interface StatusFacts {
|
|
133
146
|
/** 'provider/model' selection serving this session. */
|
|
@@ -152,7 +165,7 @@ export interface StatusFacts {
|
|
|
152
165
|
} | undefined;
|
|
153
166
|
/** Whether plan mode is active (folded from 'plan/mode'). */
|
|
154
167
|
plan: boolean;
|
|
155
|
-
/** Active
|
|
168
|
+
/** Active or pending permission preset; empty only when the service is unavailable. */
|
|
156
169
|
permission: string;
|
|
157
170
|
}
|
|
158
171
|
/**
|
|
@@ -164,12 +177,10 @@ export interface StatusFacts {
|
|
|
164
177
|
*/
|
|
165
178
|
export declare function permissionTone(permission: string): StatusTone;
|
|
166
179
|
/**
|
|
167
|
-
* Compose the two-row footer layout under a column budget. Row 1
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* (mode, context bar, cache, duration figures) fits its own budget and
|
|
172
|
-
* 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.
|
|
173
184
|
* @param facts - identity facts resolved by the runner.
|
|
174
185
|
* @param stats - session figures folded from the durable log.
|
|
175
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/startup.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The interactive terminal app's command-line provider: parses `--resume`,
|
|
3
|
-
* `--continue`, `--session`, `--mode`, and `--help`, then
|
|
4
|
-
* {@link TUI_STARTUP_SERVICE} for the runner to consume lazily.
|
|
5
|
-
* headless bundle's startup shape (a commander action publishing
|
|
6
|
-
* through {@link parseCmdline}).
|
|
3
|
+
* `--continue`, `--session`, `--mode`, `--theme`, and `--help`, then
|
|
4
|
+
* publishes {@link TUI_STARTUP_SERVICE} for the runner to consume lazily.
|
|
5
|
+
* Follows the headless bundle's startup shape (a commander action publishing
|
|
6
|
+
* a service through {@link parseCmdline}).
|
|
7
7
|
*
|
|
8
8
|
* Semantics:
|
|
9
9
|
* - `--resume <id|prefix>` — continue the persisted session whose id or unique
|
|
@@ -13,11 +13,14 @@
|
|
|
13
13
|
* whose project directory matches the current working directory.
|
|
14
14
|
* - `--session <id>` — create a new session under an explicit identity (the
|
|
15
15
|
* id must not exist yet).
|
|
16
|
+
* - `--theme <dark|light|auto>` — the color palette; auto follows the
|
|
17
|
+
* terminal (dark fallback until OSC-11 detection lands).
|
|
16
18
|
* - no flags — a fresh session with a minted id.
|
|
17
19
|
*
|
|
18
20
|
* @module @deepseek-ai/dsh-tui/startup
|
|
19
21
|
*/
|
|
20
22
|
import type { Context } from '@deepseek-ai/cordis';
|
|
23
|
+
import { type ThemeName } from './theme.ts';
|
|
21
24
|
/** Stable Cordis plugin name. */
|
|
22
25
|
export declare const name = "tui-startup";
|
|
23
26
|
/** Services required before the invocation can be resolved. */
|
|
@@ -28,21 +31,26 @@ export declare const TUI_STARTUP_SERVICE = "tuiStartup";
|
|
|
28
31
|
export type TuiStartup = {
|
|
29
32
|
readonly kind: 'fresh';
|
|
30
33
|
readonly mode?: string;
|
|
34
|
+
readonly theme?: ThemeName;
|
|
31
35
|
} | {
|
|
32
36
|
readonly kind: 'named';
|
|
33
37
|
readonly sessionId: string;
|
|
34
38
|
readonly mode?: string;
|
|
39
|
+
readonly theme?: ThemeName;
|
|
35
40
|
} | {
|
|
36
41
|
readonly kind: 'resume';
|
|
37
42
|
readonly sessionId: string;
|
|
43
|
+
readonly theme?: ThemeName;
|
|
38
44
|
} | {
|
|
39
45
|
readonly kind: 'latest';
|
|
46
|
+
readonly theme?: ThemeName;
|
|
40
47
|
};
|
|
41
48
|
export interface TuiStartupOptions {
|
|
42
49
|
readonly resume?: string;
|
|
43
50
|
readonly continue?: boolean;
|
|
44
51
|
readonly session?: string;
|
|
45
52
|
readonly mode?: string;
|
|
53
|
+
readonly theme?: ThemeName;
|
|
46
54
|
}
|
|
47
55
|
/** Pure option policy shared by Commander and tests. */
|
|
48
56
|
export declare function resolveTuiStartup(options: TuiStartupOptions): TuiStartup;
|
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,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/theme` picker (the Codex `/theme` contract): one bounded list over
|
|
3
|
+
* the three color themes — dark, light, and auto (terminal-sensed; auto
|
|
4
|
+
* falls back to dark until OSC-11 detection lands). Enter applies the row
|
|
5
|
+
* and the runner persists it; Esc closes without changing the theme.
|
|
6
|
+
*
|
|
7
|
+
* @module @deepseek-ai/dsh-tui/theme-panel
|
|
8
|
+
*/
|
|
9
|
+
import { type ReactElement } from 'react';
|
|
10
|
+
import { type ThemeName } from './theme.ts';
|
|
11
|
+
/**
|
|
12
|
+
* The /theme list: one row per theme, the current one marked with ●, the
|
|
13
|
+
* focused one with ›. Enter applies the focused theme (the runner persists
|
|
14
|
+
* it), Esc/q closes without changing anything. Colors read the ACTIVE
|
|
15
|
+
* palette, so the panel itself adapts to a light theme once applied.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ThemePanel({ current, select, close }: {
|
|
18
|
+
/** Theme name in force (the requested name; 'auto' included). */
|
|
19
|
+
current: ThemeName;
|
|
20
|
+
/** Accept one theme name: applied immediately and persisted by the runner. */
|
|
21
|
+
select(name: ThemeName): void;
|
|
22
|
+
/** Close without changing the theme. */
|
|
23
|
+
close(): void;
|
|
24
|
+
}): ReactElement;
|
package/lib/types/theme.d.ts
CHANGED
|
@@ -4,17 +4,141 @@
|
|
|
4
4
|
* (`packages/client/ui-theme/src/styles/design-platform.css`). Truecolor RGB
|
|
5
5
|
* rides chalk, which degrades automatically on terminals without truecolor.
|
|
6
6
|
*
|
|
7
|
+
* Two palettes — `dark` (the default) and `light` — share the same token keys
|
|
8
|
+
* with different values. Painters and the palette accessor read the ACTIVE
|
|
9
|
+
* palette selected through {@link setTheme}, so a theme switch recolors every
|
|
10
|
+
* painted surface on the next render without touching call sites. Raw token
|
|
11
|
+
* consumers keep reading {@link TUI_RGB} (the dark values) until the
|
|
12
|
+
* theme-aware integration replaces those call sites with
|
|
13
|
+
* `inkColor(getPalette().token)`.
|
|
14
|
+
*
|
|
7
15
|
* @module @deepseek-ai/dsh-tui/theme
|
|
8
16
|
*/
|
|
17
|
+
/** One RGB triple for a palette token. */
|
|
18
|
+
export type RgbTriple = readonly [number, number, number];
|
|
19
|
+
/** Palette token keys shared by every theme. */
|
|
20
|
+
export type ThemeToken = 'brand' | 'brandBright' | 'brandMid' | 'brandDeep' | 'dim' | 'success' | 'error' | 'warn' | 'text' | 'code';
|
|
21
|
+
/** One full color palette: every token key mapped to an RGB triple. */
|
|
22
|
+
export type ThemePalette = Readonly<Record<ThemeToken, RgbTriple>>;
|
|
23
|
+
/** Selectable theme names: dark, light, or auto (terminal-sensed). */
|
|
24
|
+
export type ThemeName = 'dark' | 'light' | 'auto';
|
|
25
|
+
/** Valid theme names in canonical picker order. */
|
|
26
|
+
export declare const THEME_NAMES: readonly ThemeName[];
|
|
9
27
|
/**
|
|
10
|
-
*
|
|
11
|
-
* Keep names and values in sync with the CSS
|
|
28
|
+
* DeepSeek dark palette: the original TUI colors, one entry per
|
|
29
|
+
* design-platform token in use. Keep names and values in sync with the CSS
|
|
30
|
+
* custom properties cited inline.
|
|
31
|
+
*/
|
|
32
|
+
export declare const DARK_PALETTE: {
|
|
33
|
+
/** Primary brand blue — `--dsw-static-deepseek-500`. */
|
|
34
|
+
readonly brand: readonly [65, 118, 230];
|
|
35
|
+
/** Brighter brand blue for live/streaming emphasis — `--dsw-static-deepseek-400`. */
|
|
36
|
+
readonly brandBright: readonly [103, 158, 254];
|
|
37
|
+
/** Intermediate brand blue between brand and brandBright — `--dsw-static-deepseek-450`. */
|
|
38
|
+
readonly brandMid: readonly [86, 134, 254];
|
|
39
|
+
/** Deep brand blue for secondary chrome — `--dsw-static-deepseek-600`. */
|
|
40
|
+
readonly brandDeep: readonly [72, 104, 178];
|
|
41
|
+
/** Muted caption gray — `--dsw-static-neutral-bluish-600`. */
|
|
42
|
+
readonly dim: readonly [129, 133, 140];
|
|
43
|
+
/** Success green — `--dsw-static-green-500`. */
|
|
44
|
+
readonly success: readonly [34, 197, 94];
|
|
45
|
+
/** Error red — `--dsw-static-red-500`. */
|
|
46
|
+
readonly error: readonly [239, 68, 68];
|
|
47
|
+
/** Warning amber — `--dsw-static-amber-500`. */
|
|
48
|
+
readonly warn: readonly [245, 158, 11];
|
|
49
|
+
/** Default foreground text — `--dsw-static-neutral-50`. */
|
|
50
|
+
readonly text: readonly [236, 240, 246];
|
|
51
|
+
/** Inline/fenced code — soft sky blue, distinct from brand accents. */
|
|
52
|
+
readonly code: readonly [125, 211, 252];
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Light palette tuned for white terminals: the same token keys as dark with
|
|
56
|
+
* contrast-driven values (AA on a white background). Brand keeps its dark
|
|
57
|
+
* value (≈4.9:1); the bright/mid/deep blues, muted grays, and status colors
|
|
58
|
+
* deepen so they stay legible on bright backgrounds.
|
|
59
|
+
*/
|
|
60
|
+
export declare const LIGHT_PALETTE: {
|
|
61
|
+
/** Primary brand blue — unchanged, ≈4.9:1 AA on white. */
|
|
62
|
+
readonly brand: readonly [65, 118, 230];
|
|
63
|
+
/** Brighter brand blue deepened for white backgrounds (was 2.7:1). */
|
|
64
|
+
readonly brandBright: readonly [72, 104, 178];
|
|
65
|
+
/** Intermediate brand blue — Tailwind blue-500. */
|
|
66
|
+
readonly brandMid: readonly [59, 130, 246];
|
|
67
|
+
/** Deep brand blue for secondary chrome — `--dsw-static-deepseek-700`. */
|
|
68
|
+
readonly brandDeep: readonly [47, 76, 143];
|
|
69
|
+
/** Muted caption gray deepened for white backgrounds. */
|
|
70
|
+
readonly dim: readonly [101, 103, 107];
|
|
71
|
+
/** Success green — Tailwind green-700. */
|
|
72
|
+
readonly success: readonly [21, 128, 61];
|
|
73
|
+
/** Error red — Tailwind red-600. */
|
|
74
|
+
readonly error: readonly [236, 19, 19];
|
|
75
|
+
/** Warning amber — Tailwind amber-700. */
|
|
76
|
+
readonly warn: readonly [180, 83, 9];
|
|
77
|
+
/** Default foreground text — near-black. */
|
|
78
|
+
readonly text: readonly [21, 21, 23];
|
|
79
|
+
/** Inline/fenced code — Tailwind cyan-700, distinct from brand accents. */
|
|
80
|
+
readonly code: readonly [14, 116, 144];
|
|
81
|
+
};
|
|
82
|
+
/** Every palette by theme name; auto resolves through {@link resolveTheme}. */
|
|
83
|
+
export declare const PALETTES: {
|
|
84
|
+
readonly dark: {
|
|
85
|
+
/** Primary brand blue — `--dsw-static-deepseek-500`. */
|
|
86
|
+
readonly brand: readonly [65, 118, 230];
|
|
87
|
+
/** Brighter brand blue for live/streaming emphasis — `--dsw-static-deepseek-400`. */
|
|
88
|
+
readonly brandBright: readonly [103, 158, 254];
|
|
89
|
+
/** Intermediate brand blue between brand and brandBright — `--dsw-static-deepseek-450`. */
|
|
90
|
+
readonly brandMid: readonly [86, 134, 254];
|
|
91
|
+
/** Deep brand blue for secondary chrome — `--dsw-static-deepseek-600`. */
|
|
92
|
+
readonly brandDeep: readonly [72, 104, 178];
|
|
93
|
+
/** Muted caption gray — `--dsw-static-neutral-bluish-600`. */
|
|
94
|
+
readonly dim: readonly [129, 133, 140];
|
|
95
|
+
/** Success green — `--dsw-static-green-500`. */
|
|
96
|
+
readonly success: readonly [34, 197, 94];
|
|
97
|
+
/** Error red — `--dsw-static-red-500`. */
|
|
98
|
+
readonly error: readonly [239, 68, 68];
|
|
99
|
+
/** Warning amber — `--dsw-static-amber-500`. */
|
|
100
|
+
readonly warn: readonly [245, 158, 11];
|
|
101
|
+
/** Default foreground text — `--dsw-static-neutral-50`. */
|
|
102
|
+
readonly text: readonly [236, 240, 246];
|
|
103
|
+
/** Inline/fenced code — soft sky blue, distinct from brand accents. */
|
|
104
|
+
readonly code: readonly [125, 211, 252];
|
|
105
|
+
};
|
|
106
|
+
readonly light: {
|
|
107
|
+
/** Primary brand blue — unchanged, ≈4.9:1 AA on white. */
|
|
108
|
+
readonly brand: readonly [65, 118, 230];
|
|
109
|
+
/** Brighter brand blue deepened for white backgrounds (was 2.7:1). */
|
|
110
|
+
readonly brandBright: readonly [72, 104, 178];
|
|
111
|
+
/** Intermediate brand blue — Tailwind blue-500. */
|
|
112
|
+
readonly brandMid: readonly [59, 130, 246];
|
|
113
|
+
/** Deep brand blue for secondary chrome — `--dsw-static-deepseek-700`. */
|
|
114
|
+
readonly brandDeep: readonly [47, 76, 143];
|
|
115
|
+
/** Muted caption gray deepened for white backgrounds. */
|
|
116
|
+
readonly dim: readonly [101, 103, 107];
|
|
117
|
+
/** Success green — Tailwind green-700. */
|
|
118
|
+
readonly success: readonly [21, 128, 61];
|
|
119
|
+
/** Error red — Tailwind red-600. */
|
|
120
|
+
readonly error: readonly [236, 19, 19];
|
|
121
|
+
/** Warning amber — Tailwind amber-700. */
|
|
122
|
+
readonly warn: readonly [180, 83, 9];
|
|
123
|
+
/** Default foreground text — near-black. */
|
|
124
|
+
readonly text: readonly [21, 21, 23];
|
|
125
|
+
/** Inline/fenced code — Tailwind cyan-700, distinct from brand accents. */
|
|
126
|
+
readonly code: readonly [14, 116, 144];
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* The dark palette under its original name: call sites that predate the
|
|
131
|
+
* two-palette switch keep compiling and painting identically (the default
|
|
132
|
+
* theme IS dark). New code should read the active palette through
|
|
133
|
+
* {@link getPalette} so a theme switch reaches it.
|
|
12
134
|
*/
|
|
13
135
|
export declare const TUI_RGB: {
|
|
14
136
|
/** Primary brand blue — `--dsw-static-deepseek-500`. */
|
|
15
137
|
readonly brand: readonly [65, 118, 230];
|
|
16
138
|
/** Brighter brand blue for live/streaming emphasis — `--dsw-static-deepseek-400`. */
|
|
17
139
|
readonly brandBright: readonly [103, 158, 254];
|
|
140
|
+
/** Intermediate brand blue between brand and brandBright — `--dsw-static-deepseek-450`. */
|
|
141
|
+
readonly brandMid: readonly [86, 134, 254];
|
|
18
142
|
/** Deep brand blue for secondary chrome — `--dsw-static-deepseek-600`. */
|
|
19
143
|
readonly brandDeep: readonly [72, 104, 178];
|
|
20
144
|
/** Muted caption gray — `--dsw-static-neutral-bluish-600`. */
|
|
@@ -30,6 +154,38 @@ export declare const TUI_RGB: {
|
|
|
30
154
|
/** Inline/fenced code — soft sky blue, distinct from brand accents. */
|
|
31
155
|
readonly code: readonly [125, 211, 252];
|
|
32
156
|
};
|
|
157
|
+
/**
|
|
158
|
+
* Resolve a theme name to the palette actually in use. `auto` detection
|
|
159
|
+
* (OSC 11 terminal background query) is a later enhancement; until it lands,
|
|
160
|
+
* auto falls back to the dark palette.
|
|
161
|
+
* @param name - the requested theme name.
|
|
162
|
+
* @returns 'dark' or 'light' — the palette key to paint with.
|
|
163
|
+
*/
|
|
164
|
+
export declare function resolveTheme(name: ThemeName): 'dark' | 'light';
|
|
165
|
+
/**
|
|
166
|
+
* Switch the active theme: painters and {@link getPalette} reflect the new
|
|
167
|
+
* palette from the next render onward. The default is dark, so a process
|
|
168
|
+
* that never calls this paints exactly as before.
|
|
169
|
+
* @param name - the theme to activate ('auto' resolves to dark for now).
|
|
170
|
+
*/
|
|
171
|
+
export declare function setTheme(name: ThemeName): void;
|
|
172
|
+
/**
|
|
173
|
+
* The theme name in force. Returns the requested name ('auto' included) so
|
|
174
|
+
* the /theme picker and persistence can round-trip the user's choice; the
|
|
175
|
+
* palette actually used is {@link getPalette}.
|
|
176
|
+
*/
|
|
177
|
+
export declare function getTheme(): ThemeName;
|
|
178
|
+
/** The palette in force; theme-aware call sites read colors through it. */
|
|
179
|
+
export declare function getPalette(): ThemePalette;
|
|
180
|
+
/**
|
|
181
|
+
* Parse a persisted theme name: only 'light' and 'auto' survive; anything
|
|
182
|
+
* else (missing, corrupt, or unknown) falls back to the dark default.
|
|
183
|
+
* @param value - the raw parsed JSON value (expected string).
|
|
184
|
+
* @returns a valid theme name.
|
|
185
|
+
*/
|
|
186
|
+
export declare function parseThemeName(value: unknown): ThemeName;
|
|
187
|
+
/** Ink `color` string for one RGB triple. */
|
|
188
|
+
export declare function inkColor(triple: RgbTriple): string;
|
|
33
189
|
/** Paint with the primary brand blue: whale, wordmark, tool names, accents. */
|
|
34
190
|
export declare function brand(text: string): string;
|
|
35
191
|
/** Paint with the bright brand blue: streaming output and active spinners. */
|
|
@@ -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",
|