dsh-code 0.6.0 → 0.7.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.
@@ -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 publishes
4
- * {@link TUI_STARTUP_SERVICE} for the runner to consume lazily. Follows the
5
- * headless bundle's startup shape (a commander action publishing a service
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;
@@ -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;
@@ -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
- * RGB triples for the TUI, one entry per design-platform token in use.
11
- * Keep names and values in sync with the CSS custom properties cited inline.
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. */
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.6.0",
4
+ "version": "0.7.0",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "deepseek": "./bin/deepseek.mjs",