@aiwayds/dsh-tui-pi 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 +324 -0
- package/bin/dsh-tui-pi +5 -0
- package/cordis.patch.yml +9 -0
- package/lib/append-system.d.ts +66 -0
- package/lib/append-system.js +161 -0
- package/lib/append-system.js.map +1 -0
- package/lib/commands.d.ts +53 -0
- package/lib/commands.js +167 -0
- package/lib/commands.js.map +1 -0
- package/lib/dsh-events.d.ts +106 -0
- package/lib/dsh-events.js +30 -0
- package/lib/dsh-events.js.map +1 -0
- package/lib/editor.d.ts +28 -0
- package/lib/editor.js +70 -0
- package/lib/editor.js.map +1 -0
- package/lib/footer.d.ts +36 -0
- package/lib/footer.js +112 -0
- package/lib/footer.js.map +1 -0
- package/lib/frame.d.ts +35 -0
- package/lib/frame.js +75 -0
- package/lib/frame.js.map +1 -0
- package/lib/git.d.ts +17 -0
- package/lib/git.js +51 -0
- package/lib/git.js.map +1 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.js +781 -0
- package/lib/index.js.map +1 -0
- package/lib/instructions.d.ts +29 -0
- package/lib/instructions.js +67 -0
- package/lib/instructions.js.map +1 -0
- package/lib/live-widgets.d.ts +85 -0
- package/lib/live-widgets.js +218 -0
- package/lib/live-widgets.js.map +1 -0
- package/lib/messages.d.ts +277 -0
- package/lib/messages.js +734 -0
- package/lib/messages.js.map +1 -0
- package/lib/permission.d.ts +27 -0
- package/lib/permission.js +48 -0
- package/lib/permission.js.map +1 -0
- package/lib/provider-catalog.d.ts +114 -0
- package/lib/provider-catalog.js +124 -0
- package/lib/provider-catalog.js.map +1 -0
- package/lib/quotes.d.ts +28 -0
- package/lib/quotes.js +144 -0
- package/lib/quotes.js.map +1 -0
- package/lib/reload.d.ts +23 -0
- package/lib/reload.js +171 -0
- package/lib/reload.js.map +1 -0
- package/lib/selectors.d.ts +48 -0
- package/lib/selectors.js +261 -0
- package/lib/selectors.js.map +1 -0
- package/lib/session.d.ts +157 -0
- package/lib/session.js +555 -0
- package/lib/session.js.map +1 -0
- package/lib/sessions.d.ts +73 -0
- package/lib/sessions.js +253 -0
- package/lib/sessions.js.map +1 -0
- package/lib/settings.d.ts +180 -0
- package/lib/settings.js +1328 -0
- package/lib/settings.js.map +1 -0
- package/lib/text.d.ts +22 -0
- package/lib/text.js +45 -0
- package/lib/text.js.map +1 -0
- package/lib/theme/index.d.ts +79 -0
- package/lib/theme/index.js +121 -0
- package/lib/theme/index.js.map +1 -0
- package/lib/theme/palette.d.ts +56 -0
- package/lib/theme/palette.js +154 -0
- package/lib/theme/palette.js.map +1 -0
- package/lib/theme-settings.d.ts +68 -0
- package/lib/theme-settings.js +223 -0
- package/lib/theme-settings.js.map +1 -0
- package/lib/tui.d.ts +70 -0
- package/lib/tui.js +206 -0
- package/lib/tui.js.map +1 -0
- package/lib/welcome.d.ts +91 -0
- package/lib/welcome.js +281 -0
- package/lib/welcome.js.map +1 -0
- package/package.json +50 -0
- package/patches/@earendil-works__pi-tui.patch +72 -0
- package/pnpm-workspace.yaml +2 -0
- package/templates/APPEND_SYSTEM.md +34 -0
package/lib/welcome.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup welcome banner: a pixel-art whale (generated pixel-by-pixel from
|
|
3
|
+
* the user's image) with the "DSH" wordmark to its right, drawn in the same
|
|
4
|
+
* pixel language as the whale. Each letter is a hand-authored 20×20 pixel
|
|
5
|
+
* bitmap (PIXEL_FONT: 20 columns × 20 half-cell rows, '#' a pixel, '.'
|
|
6
|
+
* empty) — an upright glyph sheared into an arcade italic: every 4 pixel
|
|
7
|
+
* rows the stroke shifts 1 pixel right, so the top leans 4 pixels —
|
|
8
|
+
* rendered to the terminal with the whale's own half-block mapping
|
|
9
|
+
* (top and bottom pixel → '█', top only → '▀', bottom only → '▄', neither
|
|
10
|
+
* → ' '), so the letters show the same visible pixel grid: 3-pixel strokes,
|
|
11
|
+
* and D's bowl and S's spine step diagonally in 2-pixel staircase corners
|
|
12
|
+
* instead of meeting at square rectangle corners.
|
|
13
|
+
*
|
|
14
|
+
* The banner is a 94-column × 10-row grid: 28 columns of whale art, a
|
|
15
|
+
* 2-column gap, then the wordmark — D (20) + 2 + S (20) + 2 + H (20) =
|
|
16
|
+
* 64 columns of letters (each letter spans 20 columns — slimmer than the
|
|
17
|
+
* whale's body mass). Below 96 terminal columns the wordmark is
|
|
18
|
+
* dropped — the banner degrades to the 10 whale rows (28 columns each, no
|
|
19
|
+
* gap, no letters), so a narrow terminal never wraps the letter rows; the
|
|
20
|
+
* full banner comes back as soon as the terminal is 96 columns or wider
|
|
21
|
+
* again (the transcript rebuilds on resize). Everything is painted in the
|
|
22
|
+
* whale brand blue. Transparent cells stay unpainted — they show the
|
|
23
|
+
* terminal default background. This is deliberate: the transcript never
|
|
24
|
+
* paints a canvas background (the TUI startup already sets the terminal
|
|
25
|
+
* background to the theme canvas), so a half-block's transparent half must
|
|
26
|
+
* fall through to the terminal default, not to an explicit theme
|
|
27
|
+
* background. Painting it would mismatch on any terminal whose default
|
|
28
|
+
* background differs from the theme canvas.
|
|
29
|
+
*/
|
|
30
|
+
/** The whale color — the same brand blue as the powerline 'dsh' segment. */
|
|
31
|
+
export declare const WHALE_COLOR: "#4D6BFE";
|
|
32
|
+
/**
|
|
33
|
+
* Whale pixel art, 28 columns × 10 rows, generated pixel-by-pixel from the
|
|
34
|
+
* user's image (regenerate with `node assets/whale-gen.mjs`; see
|
|
35
|
+
* assets/whale-gen.mjs). Only ' ', '█', '▀' and '▄' appear (see the glyph
|
|
36
|
+
* semantics above). Every row carries at least one whale glyph, so the
|
|
37
|
+
* banner text as a whole is never blank — Text.render only skips an
|
|
38
|
+
* entirely blank text, and individual blank rows would render as empty
|
|
39
|
+
* lines either way.
|
|
40
|
+
*/
|
|
41
|
+
export declare const WHALE_ART: readonly string[];
|
|
42
|
+
/** The wordmark: D S H, each letter a 28-column glyph, spaced 2 columns apart. */
|
|
43
|
+
export declare const WORDMARK = "DSH";
|
|
44
|
+
/**
|
|
45
|
+
* Pixel font for the wordmark letters: '#' is a pixel, '.' is empty. Each
|
|
46
|
+
* glyph is a hand-authored 20×20 pixel bitmap: an upright body (16 pixels
|
|
47
|
+
* wide, 17 for D's bowl) with 3-pixel strokes and 2-pixel staircase
|
|
48
|
+
* corners, sheared italic — every 4 pixel rows shift 1 pixel right (the
|
|
49
|
+
* top block leans 4 pixels, ~14°) — so every stroke's edge is a pixel
|
|
50
|
+
* staircase and each letter spans exactly 20 columns, slimmer than the
|
|
51
|
+
* whale's body (21–24). renderPixelGlyph folds every two pixel
|
|
52
|
+
* rows into one terminal row of '█'/'▀'/'▄'/' ' — the exact mapping the
|
|
53
|
+
* whale generator uses — so the letters and the whale share one pixel
|
|
54
|
+
* grid. Strokes render in the whale brand blue; empties fall through to
|
|
55
|
+
* the terminal default background like the whale's spaces.
|
|
56
|
+
*/
|
|
57
|
+
export declare const PIXEL_FONT: Record<string, readonly string[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Full banner width: whale + gap + wordmark block — derived from the
|
|
60
|
+
* constants so a layout tweak (gap, glyph widths) cannot silently desync
|
|
61
|
+
* the degradation threshold in `buildWelcomeBanner` from the assembled
|
|
62
|
+
* rows: 28 + 2 + 20 + 2 + 20 + 2 + 20 = 94 columns.
|
|
63
|
+
*/
|
|
64
|
+
export declare const WELCOME_FULL_WIDTH: number;
|
|
65
|
+
/**
|
|
66
|
+
* Fold a 20×20 pixel bitmap into its 10 terminal rows with the whale's own
|
|
67
|
+
* half-block mapping: both pixel rows on → '█', top only → '▀', bottom
|
|
68
|
+
* only → '▄', neither → ' '. Two pixels vertically per cell is what makes
|
|
69
|
+
* the pixels square on screen — one column wide, one half-cell tall — the
|
|
70
|
+
* same grid the whale art lives on.
|
|
71
|
+
*/
|
|
72
|
+
export declare function renderPixelGlyph(px: readonly string[]): readonly string[];
|
|
73
|
+
/**
|
|
74
|
+
* Assemble the welcome banner text. Every row is the styled whale row, the
|
|
75
|
+
* 2-column gap, then the 88-column pixel-letter row (letters 2 columns
|
|
76
|
+
* apart) — all painted in the whale brand blue. The banner is
|
|
77
|
+
* theme-independent: no theme colors, no bold, nothing to repaint on a
|
|
78
|
+
* theme switch.
|
|
79
|
+
*
|
|
80
|
+
* Width floor: the full banner is 94 columns wide plus the transcript
|
|
81
|
+
* Text's 1-column left/right padding (the renderer passes its Text paddingX
|
|
82
|
+
* — currently 1 — so the threshold is 96). Below it the banner degrades
|
|
83
|
+
* to the whale alone: the 10 art rows, 28 columns each, no gap and no
|
|
84
|
+
* letters, which needs only 30 columns with the padding. A terminal
|
|
85
|
+
* narrower than that wraps the whale rows onto extra lines (accepted
|
|
86
|
+
* degradation, documented rather than clipped, because a terminal that
|
|
87
|
+
* narrow can't show the whale either way). `undefined` (non-TTY contexts,
|
|
88
|
+
* e.g. tests) counts as wide — the full banner, conservative like
|
|
89
|
+
* PANEL_LINE_CAP_FALLBACK.
|
|
90
|
+
*/
|
|
91
|
+
export declare function buildWelcomeBanner(columns: number | undefined): string;
|
package/lib/welcome.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup welcome banner: a pixel-art whale (generated pixel-by-pixel from
|
|
3
|
+
* the user's image) with the "DSH" wordmark to its right, drawn in the same
|
|
4
|
+
* pixel language as the whale. Each letter is a hand-authored 20×20 pixel
|
|
5
|
+
* bitmap (PIXEL_FONT: 20 columns × 20 half-cell rows, '#' a pixel, '.'
|
|
6
|
+
* empty) — an upright glyph sheared into an arcade italic: every 4 pixel
|
|
7
|
+
* rows the stroke shifts 1 pixel right, so the top leans 4 pixels —
|
|
8
|
+
* rendered to the terminal with the whale's own half-block mapping
|
|
9
|
+
* (top and bottom pixel → '█', top only → '▀', bottom only → '▄', neither
|
|
10
|
+
* → ' '), so the letters show the same visible pixel grid: 3-pixel strokes,
|
|
11
|
+
* and D's bowl and S's spine step diagonally in 2-pixel staircase corners
|
|
12
|
+
* instead of meeting at square rectangle corners.
|
|
13
|
+
*
|
|
14
|
+
* The banner is a 94-column × 10-row grid: 28 columns of whale art, a
|
|
15
|
+
* 2-column gap, then the wordmark — D (20) + 2 + S (20) + 2 + H (20) =
|
|
16
|
+
* 64 columns of letters (each letter spans 20 columns — slimmer than the
|
|
17
|
+
* whale's body mass). Below 96 terminal columns the wordmark is
|
|
18
|
+
* dropped — the banner degrades to the 10 whale rows (28 columns each, no
|
|
19
|
+
* gap, no letters), so a narrow terminal never wraps the letter rows; the
|
|
20
|
+
* full banner comes back as soon as the terminal is 96 columns or wider
|
|
21
|
+
* again (the transcript rebuilds on resize). Everything is painted in the
|
|
22
|
+
* whale brand blue. Transparent cells stay unpainted — they show the
|
|
23
|
+
* terminal default background. This is deliberate: the transcript never
|
|
24
|
+
* paints a canvas background (the TUI startup already sets the terminal
|
|
25
|
+
* background to the theme canvas), so a half-block's transparent half must
|
|
26
|
+
* fall through to the terminal default, not to an explicit theme
|
|
27
|
+
* background. Painting it would mismatch on any terminal whose default
|
|
28
|
+
* background differs from the theme canvas.
|
|
29
|
+
*/
|
|
30
|
+
import { ansiFg, POWERLINE, RESET } from "./theme/index.js";
|
|
31
|
+
/** The whale color — the same brand blue as the powerline 'dsh' segment. */
|
|
32
|
+
export const WHALE_COLOR = POWERLINE.brand;
|
|
33
|
+
/**
|
|
34
|
+
* Whale pixel art, 28 columns × 10 rows, generated pixel-by-pixel from the
|
|
35
|
+
* user's image (regenerate with `node assets/whale-gen.mjs`; see
|
|
36
|
+
* assets/whale-gen.mjs). Only ' ', '█', '▀' and '▄' appear (see the glyph
|
|
37
|
+
* semantics above). Every row carries at least one whale glyph, so the
|
|
38
|
+
* banner text as a whole is never blank — Text.render only skips an
|
|
39
|
+
* entirely blank text, and individual blank rows would render as empty
|
|
40
|
+
* lines either way.
|
|
41
|
+
*/
|
|
42
|
+
export const WHALE_ART = [
|
|
43
|
+
' ▄▄▄▄ █ ',
|
|
44
|
+
' ▄██████████▄ ████ ▄▄▄█▀',
|
|
45
|
+
' ▄██████████████▄ ████████ ',
|
|
46
|
+
' ██▀▀█████████████▄ ▄██▀▀ ',
|
|
47
|
+
'██ ▀▀█████▄▀██████ ',
|
|
48
|
+
'▀██ ▀████▄ ████▀ ',
|
|
49
|
+
' ███ ▀████████▀ ',
|
|
50
|
+
' ▀██▄ █▄▄ ▀█████▀ ',
|
|
51
|
+
' ▀▀███▄▄███▄▄▄█████▄ ',
|
|
52
|
+
' ▀▀▀████▀▀▀ ',
|
|
53
|
+
];
|
|
54
|
+
/** Blank columns between the whale and the wordmark column. */
|
|
55
|
+
const WHALE_TITLE_GAP = 2;
|
|
56
|
+
/** Blank columns between the wordmark's letters. */
|
|
57
|
+
const LETTER_GAP = 2;
|
|
58
|
+
/** The wordmark: D S H, each letter a 28-column glyph, spaced 2 columns apart. */
|
|
59
|
+
export const WORDMARK = 'DSH';
|
|
60
|
+
/** Whale art width in columns (every row is this wide). */
|
|
61
|
+
const WHALE_ART_WIDTH = Math.max(...WHALE_ART.map(row => row.length));
|
|
62
|
+
/**
|
|
63
|
+
* Pixel font for the wordmark letters: '#' is a pixel, '.' is empty. Each
|
|
64
|
+
* glyph is a hand-authored 20×20 pixel bitmap: an upright body (16 pixels
|
|
65
|
+
* wide, 17 for D's bowl) with 3-pixel strokes and 2-pixel staircase
|
|
66
|
+
* corners, sheared italic — every 4 pixel rows shift 1 pixel right (the
|
|
67
|
+
* top block leans 4 pixels, ~14°) — so every stroke's edge is a pixel
|
|
68
|
+
* staircase and each letter spans exactly 20 columns, slimmer than the
|
|
69
|
+
* whale's body (21–24). renderPixelGlyph folds every two pixel
|
|
70
|
+
* rows into one terminal row of '█'/'▀'/'▄'/' ' — the exact mapping the
|
|
71
|
+
* whale generator uses — so the letters and the whale share one pixel
|
|
72
|
+
* grid. Strokes render in the whale brand blue; empties fall through to
|
|
73
|
+
* the terminal default background like the whale's spaces.
|
|
74
|
+
*/
|
|
75
|
+
export const PIXEL_FONT = {
|
|
76
|
+
D: [
|
|
77
|
+
'....#############...',
|
|
78
|
+
'....#############...',
|
|
79
|
+
'....#############...',
|
|
80
|
+
'....###.........###.',
|
|
81
|
+
'...###.........###..',
|
|
82
|
+
'...###...........###',
|
|
83
|
+
'...###...........###',
|
|
84
|
+
'...###...........###',
|
|
85
|
+
'..###...........###.',
|
|
86
|
+
'..###...........###.',
|
|
87
|
+
'..###...........###.',
|
|
88
|
+
'..###...........###.',
|
|
89
|
+
'.###...........###..',
|
|
90
|
+
'.###...........###..',
|
|
91
|
+
'.###...........###..',
|
|
92
|
+
'.###.........###....',
|
|
93
|
+
'###.........###.....',
|
|
94
|
+
'#############.......',
|
|
95
|
+
'#############.......',
|
|
96
|
+
'#############.......',
|
|
97
|
+
],
|
|
98
|
+
S: [
|
|
99
|
+
'.......#############',
|
|
100
|
+
'.......#############',
|
|
101
|
+
'.......#############',
|
|
102
|
+
'....###.............',
|
|
103
|
+
'...###..............',
|
|
104
|
+
'...###..............',
|
|
105
|
+
'...###..............',
|
|
106
|
+
'...#############....',
|
|
107
|
+
'..#############.....',
|
|
108
|
+
'..#############.....',
|
|
109
|
+
'..#############.....',
|
|
110
|
+
'...............###..',
|
|
111
|
+
'..............###...',
|
|
112
|
+
'..............###...',
|
|
113
|
+
'..............###...',
|
|
114
|
+
'..............###...',
|
|
115
|
+
'.............###....',
|
|
116
|
+
'############........',
|
|
117
|
+
'############........',
|
|
118
|
+
'############........',
|
|
119
|
+
],
|
|
120
|
+
H: [
|
|
121
|
+
'....###..........###',
|
|
122
|
+
'....###..........###',
|
|
123
|
+
'....###..........###',
|
|
124
|
+
'....###..........###',
|
|
125
|
+
'...###..........###.',
|
|
126
|
+
'...###..........###.',
|
|
127
|
+
'...###..........###.',
|
|
128
|
+
'...###..........###.',
|
|
129
|
+
'..################..',
|
|
130
|
+
'..################..',
|
|
131
|
+
'..################..',
|
|
132
|
+
'..################..',
|
|
133
|
+
'.###..........###...',
|
|
134
|
+
'.###..........###...',
|
|
135
|
+
'.###..........###...',
|
|
136
|
+
'.###..........###...',
|
|
137
|
+
'###..........###....',
|
|
138
|
+
'###..........###....',
|
|
139
|
+
'###..........###....',
|
|
140
|
+
'###..........###....',
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
// Load-time validation: a wordmark letter without a font glyph, or a glyph
|
|
144
|
+
// that cannot fold into the whale's 10 terminal rows, is a programming
|
|
145
|
+
// error — fail at module load, not at some later resize when the full
|
|
146
|
+
// banner is first assembled (a narrow terminal would defer the crash into
|
|
147
|
+
// the resize handler).
|
|
148
|
+
for (const ch of WORDMARK) {
|
|
149
|
+
if (ch !== ' ' && PIXEL_FONT[ch] === undefined) {
|
|
150
|
+
throw new Error(`PIXEL_FONT lacks glyph for '${ch}' in WORDMARK`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
for (const [ch, glyph] of Object.entries(PIXEL_FONT)) {
|
|
154
|
+
if (glyph.length !== 2 * WHALE_ART.length) {
|
|
155
|
+
throw new Error(`PIXEL_FONT['${ch}'] has ${glyph.length} pixel rows — need ${2 * WHALE_ART.length} (two per banner row)`);
|
|
156
|
+
}
|
|
157
|
+
const widths = [...new Set(glyph.map(row => row.length))];
|
|
158
|
+
if (widths.length !== 1) {
|
|
159
|
+
throw new Error(`PIXEL_FONT['${ch}'] has ragged pixel rows: widths ${widths.join(', ')}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* The wordmark letters' total width in columns — the glyphs' widths
|
|
164
|
+
* summed: 20 (D) + 20 (S) + 20 (H) = 60. The 2-column gaps between
|
|
165
|
+
* letters are added separately in WELCOME_FULL_WIDTH (2 gaps × 2 columns
|
|
166
|
+
* → the wordmark block spans 64).
|
|
167
|
+
*/
|
|
168
|
+
const WORDMARK_WIDTH = [...WORDMARK].reduce((width, ch) => width + (ch === ' ' ? 1 : PIXEL_FONT[ch][0].length), 0);
|
|
169
|
+
/**
|
|
170
|
+
* Full banner width: whale + gap + wordmark block — derived from the
|
|
171
|
+
* constants so a layout tweak (gap, glyph widths) cannot silently desync
|
|
172
|
+
* the degradation threshold in `buildWelcomeBanner` from the assembled
|
|
173
|
+
* rows: 28 + 2 + 20 + 2 + 20 + 2 + 20 = 94 columns.
|
|
174
|
+
*/
|
|
175
|
+
export const WELCOME_FULL_WIDTH = WHALE_ART_WIDTH + WHALE_TITLE_GAP + WORDMARK_WIDTH + LETTER_GAP * (WORDMARK.length - 1);
|
|
176
|
+
/**
|
|
177
|
+
* Fold a 20×20 pixel bitmap into its 10 terminal rows with the whale's own
|
|
178
|
+
* half-block mapping: both pixel rows on → '█', top only → '▀', bottom
|
|
179
|
+
* only → '▄', neither → ' '. Two pixels vertically per cell is what makes
|
|
180
|
+
* the pixels square on screen — one column wide, one half-cell tall — the
|
|
181
|
+
* same grid the whale art lives on.
|
|
182
|
+
*/
|
|
183
|
+
export function renderPixelGlyph(px) {
|
|
184
|
+
const rows = [];
|
|
185
|
+
for (let i = 0; i < px.length / 2; i++) {
|
|
186
|
+
let row = '';
|
|
187
|
+
for (let c = 0; c < px[0].length; c++) {
|
|
188
|
+
const top = px[2 * i][c] === '#';
|
|
189
|
+
const bottom = px[2 * i + 1][c] === '#';
|
|
190
|
+
row += top && bottom ? '█' : top ? '▀' : bottom ? '▄' : ' ';
|
|
191
|
+
}
|
|
192
|
+
rows.push(row);
|
|
193
|
+
}
|
|
194
|
+
return rows;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Lay out the wordmark's 10 letter rows, 64 columns each: the D, S and H
|
|
198
|
+
* glyphs with a 2-column gap between letters (20 + 2 + 20 + 2 + 20
|
|
199
|
+
* columns). The pixel bitmaps are folded by renderPixelGlyph into the same
|
|
200
|
+
* '█'/'▀'/'▄'/' ' glyphs the whale uses, so the rows paint exactly like
|
|
201
|
+
* whale rows (see the header note). Wordmark glyph coverage and shape are
|
|
202
|
+
* validated at module load.
|
|
203
|
+
*/
|
|
204
|
+
function wordmarkRows() {
|
|
205
|
+
const glyphRows = [...WORDMARK].map(ch => renderPixelGlyph(PIXEL_FONT[ch]));
|
|
206
|
+
const rows = Array.from({ length: WHALE_ART.length }, () => '');
|
|
207
|
+
for (let i = 0; i < glyphRows.length; i++) {
|
|
208
|
+
for (let r = 0; r < rows.length; r++) {
|
|
209
|
+
rows[r] += glyphRows[i][r];
|
|
210
|
+
if (i < glyphRows.length - 1)
|
|
211
|
+
rows[r] += ' '.repeat(LETTER_GAP);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return rows;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Paint one consecutive run of brand-blue glyphs as a single SGR span,
|
|
218
|
+
* RESET at the end. Runs are painted in the whale blue only — half-block
|
|
219
|
+
* glyphs ('▀'/'▄') are never given a background, so their transparent half
|
|
220
|
+
* shows the terminal default background (see the header note).
|
|
221
|
+
*/
|
|
222
|
+
function paintWhaleRun(run) {
|
|
223
|
+
return ansiFg(WHALE_COLOR) + run + RESET;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Paint one row's consecutive runs of non-space glyphs as whale-blue spans,
|
|
227
|
+
* RESET after each. The spaces between runs stay unstyled (transparent,
|
|
228
|
+
* terminal background). Used for whale rows and the wordmark's letter rows
|
|
229
|
+
* alike.
|
|
230
|
+
*/
|
|
231
|
+
function paintRowRuns(row) {
|
|
232
|
+
let styled = '';
|
|
233
|
+
let run = '';
|
|
234
|
+
for (const ch of row) {
|
|
235
|
+
if (ch === ' ') {
|
|
236
|
+
if (run !== '') {
|
|
237
|
+
styled += paintWhaleRun(run);
|
|
238
|
+
run = '';
|
|
239
|
+
}
|
|
240
|
+
styled += ' ';
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
run += ch;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (run !== '')
|
|
247
|
+
styled += paintWhaleRun(run);
|
|
248
|
+
return styled;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Assemble the welcome banner text. Every row is the styled whale row, the
|
|
252
|
+
* 2-column gap, then the 88-column pixel-letter row (letters 2 columns
|
|
253
|
+
* apart) — all painted in the whale brand blue. The banner is
|
|
254
|
+
* theme-independent: no theme colors, no bold, nothing to repaint on a
|
|
255
|
+
* theme switch.
|
|
256
|
+
*
|
|
257
|
+
* Width floor: the full banner is 94 columns wide plus the transcript
|
|
258
|
+
* Text's 1-column left/right padding (the renderer passes its Text paddingX
|
|
259
|
+
* — currently 1 — so the threshold is 96). Below it the banner degrades
|
|
260
|
+
* to the whale alone: the 10 art rows, 28 columns each, no gap and no
|
|
261
|
+
* letters, which needs only 30 columns with the padding. A terminal
|
|
262
|
+
* narrower than that wraps the whale rows onto extra lines (accepted
|
|
263
|
+
* degradation, documented rather than clipped, because a terminal that
|
|
264
|
+
* narrow can't show the whale either way). `undefined` (non-TTY contexts,
|
|
265
|
+
* e.g. tests) counts as wide — the full banner, conservative like
|
|
266
|
+
* PANEL_LINE_CAP_FALLBACK.
|
|
267
|
+
*/
|
|
268
|
+
export function buildWelcomeBanner(columns) {
|
|
269
|
+
// 2 = the transcript Text's paddingX on each side (messages.ts renders the
|
|
270
|
+
// banner with `new Text(..., 1, 0)`).
|
|
271
|
+
if (columns !== undefined && columns < WELCOME_FULL_WIDTH + 2) {
|
|
272
|
+
// Narrow terminal: whale-only, the 10 art rows (28 columns each) — no
|
|
273
|
+
// gap, no letters. Wraps only below the 30-column floor.
|
|
274
|
+
return WHALE_ART.map(row => paintRowRuns(row)).join('\n');
|
|
275
|
+
}
|
|
276
|
+
const letters = wordmarkRows();
|
|
277
|
+
return WHALE_ART.map((row, r) => {
|
|
278
|
+
return paintRowRuns(row) + ' '.repeat(WHALE_TITLE_GAP + WHALE_ART_WIDTH - row.length) + paintRowRuns(letters[r]);
|
|
279
|
+
}).join('\n');
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=welcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../src/welcome.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aiwayds/dsh-tui-pi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "pi-style terminal UI for DeepSeek Harness (dsh) — pi-tui look & feel, dsh slash commands, GitHub light/dark themes, powerline footer",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"dsh-tui-pi": "bin/dsh-tui-pi"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=22.19.0"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"lib",
|
|
17
|
+
"bin",
|
|
18
|
+
"cordis.patch.yml",
|
|
19
|
+
"patches",
|
|
20
|
+
"pnpm-workspace.yaml",
|
|
21
|
+
"templates",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"check": "tsc --noEmit -p tsconfig.json",
|
|
28
|
+
"pretest": "npm run build",
|
|
29
|
+
"test": "node --test test/*.test.mjs"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@deepseek-ai/dsh-client-schema-form": "0.1.0-rc.6",
|
|
33
|
+
"@earendil-works/pi-tui": "0.84.2"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@deepseek-ai/dsh-settings": "0.1.0-rc.6",
|
|
37
|
+
"@deepseek-ai/schemastery": "3.18.1",
|
|
38
|
+
"@types/node": "^24.0.0",
|
|
39
|
+
"typescript": "~5.9.0"
|
|
40
|
+
},
|
|
41
|
+
"dsh": {
|
|
42
|
+
"bundle": {
|
|
43
|
+
"patch": "./cordis.patch.yml"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"author": "fan56",
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
diff --git a/dist/components/editor.js b/dist/components/editor.js
|
|
2
|
+
index 4786b46932b65785cfbd2304610ca77ccead910a..e0e4e39c3be8e5d4d828621ad2d3d8768984add8 100644
|
|
3
|
+
--- a/dist/components/editor.js
|
|
4
|
+
+++ b/dist/components/editor.js
|
|
5
|
+
@@ -463,14 +463,20 @@ export class Editor {
|
|
6
|
+
else {
|
|
7
|
+
result.push(horizontal.repeat(width));
|
|
8
|
+
}
|
|
9
|
+
- // Add autocomplete list if active
|
|
10
|
+
+ // Add autocomplete list if active — inside a full box (┌─┐ rows)
|
|
11
|
+
if (this.autocompleteState && this.autocompleteList) {
|
|
12
|
+
- const autocompleteResult = this.autocompleteList.render(contentWidth);
|
|
13
|
+
+ const boxInnerWidth = Math.max(1, contentWidth - 2);
|
|
14
|
+
+ const autocompleteResult = this.autocompleteList.render(boxInnerWidth);
|
|
15
|
+
+ result.push(`${leftPadding}${this.borderColor(`┌${"─".repeat(boxInnerWidth)}┐`)}${rightPadding}`);
|
|
16
|
+
for (const line of autocompleteResult) {
|
|
17
|
+
const lineWidth = visibleWidth(line);
|
|
18
|
+
- const linePadding = " ".repeat(Math.max(0, contentWidth - lineWidth));
|
|
19
|
+
- result.push(`${leftPadding}${line}${linePadding}${rightPadding}`);
|
|
20
|
+
+ const linePadding = " ".repeat(Math.max(0, boxInnerWidth - lineWidth));
|
|
21
|
+
+ // Strip trailing RESETs so the row's own backdrop SGR bleeds
|
|
22
|
+
+ // into the padding and the right side border (solid interior);
|
|
23
|
+
+ // the reset before rightPadding keeps the editor margin clear.
|
|
24
|
+
+ result.push(`${leftPadding}│${line.replace(/(?:\x1b\[0m)+$/, "")}${linePadding}│\x1b[0m${rightPadding}`);
|
|
25
|
+
}
|
|
26
|
+
+ result.push(`${leftPadding}${this.borderColor(`└${"─".repeat(boxInnerWidth)}┘`)}${rightPadding}`);
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
diff --git a/dist/components/select-list.d.ts b/dist/components/select-list.d.ts
|
|
31
|
+
index d507de4ebff8e7fbaacd089677099c63b4dfff6c..4b8a374cd1db0544a11082f8008f73f8eb8d7ede 100644
|
|
32
|
+
--- a/dist/components/select-list.d.ts
|
|
33
|
+
+++ b/dist/components/select-list.d.ts
|
|
34
|
+
@@ -10,6 +10,8 @@ export interface SelectListTheme {
|
|
35
|
+
description: (text: string) => string;
|
|
36
|
+
scrollInfo: (text: string) => string;
|
|
37
|
+
noMatch: (text: string) => string;
|
|
38
|
+
+ /** Style hook for unselected rows (plain rows render without any theme call upstream). */
|
|
39
|
+
+ unselectedText?: (text: string) => string;
|
|
40
|
+
}
|
|
41
|
+
export interface SelectListTruncatePrimaryContext {
|
|
42
|
+
text: string;
|
|
43
|
+
diff --git a/dist/components/select-list.js b/dist/components/select-list.js
|
|
44
|
+
index 2e9231150951c3d3f3e13ac8ae8d623f06d38d5d..d5c8859ecd08fe4eccdc3cfca8ac7a3226f8fcb5 100644
|
|
45
|
+
--- a/dist/components/select-list.js
|
|
46
|
+
+++ b/dist/components/select-list.js
|
|
47
|
+
@@ -101,18 +101,21 @@ export class SelectList {
|
|
48
|
+
if (remainingWidth > MIN_DESCRIPTION_WIDTH) {
|
|
49
|
+
const truncatedDesc = truncateToWidth(descriptionSingleLine, remainingWidth, "");
|
|
50
|
+
if (isSelected) {
|
|
51
|
+
- return this.theme.selectedText(`${prefix}${truncatedValue}${spacing}${truncatedDesc}`);
|
|
52
|
+
+ // selectedPrefix is otherwise dead in renderItem: style the
|
|
53
|
+
+ // arrow accent, then the row text (concatenated, not nested —
|
|
54
|
+
+ // nesting would let the prefix's RESETs clear the row style).
|
|
55
|
+
+ return this.theme.selectedPrefix("") + this.theme.selectedText(`${truncatedValue}${spacing}${truncatedDesc}`);
|
|
56
|
+
}
|
|
57
|
+
const descText = this.theme.description(spacing + truncatedDesc);
|
|
58
|
+
- return prefix + truncatedValue + descText;
|
|
59
|
+
+ return (this.theme.unselectedText ?? ((t) => t))(prefix + truncatedValue) + descText;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const maxWidth = width - prefixWidth - 2;
|
|
63
|
+
const truncatedValue = this.truncatePrimary(item, isSelected, maxWidth, maxWidth);
|
|
64
|
+
if (isSelected) {
|
|
65
|
+
- return this.theme.selectedText(`${prefix}${truncatedValue}`);
|
|
66
|
+
+ return this.theme.selectedPrefix("") + this.theme.selectedText(`${truncatedValue}`);
|
|
67
|
+
}
|
|
68
|
+
- return prefix + truncatedValue;
|
|
69
|
+
+ return (this.theme.unselectedText ?? ((t) => t))(prefix + truncatedValue);
|
|
70
|
+
}
|
|
71
|
+
getPrimaryColumnWidth() {
|
|
72
|
+
const { min, max } = this.getPrimaryColumnBounds();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# APPEND_SYSTEM.md — Orchestrator identity
|
|
2
|
+
|
|
3
|
+
## Identity: I am an orchestrator, not an executor
|
|
4
|
+
The user defines my core identity as an **orchestrator**: I analyze tasks,
|
|
5
|
+
break them into plans, dispatch sub-agents and consolidate results — I do
|
|
6
|
+
not perform concrete operations myself.
|
|
7
|
+
|
|
8
|
+
## Core rules
|
|
9
|
+
|
|
10
|
+
1. All research work must be done through sub-agents.
|
|
11
|
+
2. Forbidden:
|
|
12
|
+
- Running tests sequentially in the conversation, silently reading files,
|
|
13
|
+
or analyzing code on my own.
|
|
14
|
+
- Using execution tools directly (read/write/search/bash/edit), unless a
|
|
15
|
+
sub-agent cannot do the job.
|
|
16
|
+
- Suggesting the user do things manually.
|
|
17
|
+
3. Tasks must pass through verify/review agents. Without review, a task must
|
|
18
|
+
not be marked "completed".
|
|
19
|
+
4. Never assume "the problem is known".
|
|
20
|
+
5. Never guess — every claim must be backed by evidence.
|
|
21
|
+
|
|
22
|
+
## Execution workflow
|
|
23
|
+
|
|
24
|
+
1. **Analyze**: understand the request, identify the task boundaries.
|
|
25
|
+
2. **Create todos**: break the task into executable subtasks.
|
|
26
|
+
3. **Dispatch sub-agents**: dispatch sub-agents in parallel.
|
|
27
|
+
4. **Verify**: check the results returned by the sub-agents.
|
|
28
|
+
5. **Consolidate**: integrate the results and report to the user.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
> **Remember**: my value lies in orchestration and decisions, not execution.
|
|
33
|
+
> Let sub-agents do the concrete work; I focus on analysis, planning and
|
|
34
|
+
> quality control.
|