@hncode/hncode 0.1.4 → 0.1.5
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/package.json +1 -1
- package/src/colors.js +53 -4
- package/src/tui.js +19 -6
package/package.json
CHANGED
package/src/colors.js
CHANGED
|
@@ -33,9 +33,23 @@ export const BORDER = rgb(70, 130, 180);
|
|
|
33
33
|
// terminal's own palette show through for everything else; `dark`/`light` pick
|
|
34
34
|
// accent triples that stay readable on that background.
|
|
35
35
|
const THEMES = {
|
|
36
|
-
auto: {
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
auto: {
|
|
37
|
+
fg: [0, 184, 219], bg: [0, 18, 26],
|
|
38
|
+
teal: [0, 184, 219], cyan: [0, 215, 255], blue: [66, 135, 245], border: [70, 130, 180],
|
|
39
|
+
hover: [190, 245, 255], selBg: [0, 70, 84]
|
|
40
|
+
},
|
|
41
|
+
dark: {
|
|
42
|
+
fg: [0, 200, 230], bg: [0, 18, 26],
|
|
43
|
+
teal: [0, 200, 230], cyan: [90, 225, 255], blue: [90, 150, 255], border: [80, 140, 190],
|
|
44
|
+
hover: [190, 245, 255], selBg: [0, 70, 84]
|
|
45
|
+
},
|
|
46
|
+
light: {
|
|
47
|
+
fg: [26, 26, 26], bg: [255, 255, 255],
|
|
48
|
+
teal: [0, 102, 128], cyan: [0, 122, 153], blue: [10, 77, 158], border: [138, 155, 176],
|
|
49
|
+
hover: [0, 78, 102], selBg: [200, 230, 239],
|
|
50
|
+
red: [179, 38, 30], green: [30, 122, 60], yellow: [160, 120, 0], orange: [178, 90, 0],
|
|
51
|
+
white: [26, 26, 26], gray: [85, 85, 85],
|
|
52
|
+
},
|
|
39
53
|
};
|
|
40
54
|
export const THEME_NAMES = Object.keys(THEMES);
|
|
41
55
|
|
|
@@ -101,20 +115,55 @@ export function lerpColor(r1, g1, b1, r2, g2, b2, t) {
|
|
|
101
115
|
export function setTheme(name) {
|
|
102
116
|
const t = THEMES[name];
|
|
103
117
|
if (!t) return false;
|
|
118
|
+
|
|
119
|
+
// Update foreground colors
|
|
104
120
|
C.teal = rgb(...t.teal);
|
|
105
|
-
C.fg =
|
|
121
|
+
C.fg = rgb(...t.fg);
|
|
106
122
|
C.cyan = rgb(...t.cyan);
|
|
107
123
|
C.blue = rgb(...t.blue);
|
|
108
124
|
C.border = rgb(...t.border);
|
|
125
|
+
|
|
126
|
+
// Update background colors
|
|
127
|
+
C.bg = brgb(...t.bg);
|
|
109
128
|
C.bgTeal = brgb(...t.teal);
|
|
129
|
+
C.bgPanel = brgb(...t.bg);
|
|
130
|
+
C.selBg = brgb(...t.selBg);
|
|
131
|
+
|
|
132
|
+
// Scrollbar colors - adjust based on theme brightness
|
|
133
|
+
const isLight = t.bg[0] > 128; // Simple brightness check
|
|
134
|
+
C.scrollTrack = isLight ? '\x1b[90m' : '\x1b[90m'; // dim gutter (works for both)
|
|
135
|
+
C.scrollThumb = rgb(...t.teal);
|
|
136
|
+
C.scrollThumbHover = rgb(...t.hover);
|
|
137
|
+
C.scrollThumbActive = rgb(t.teal[0] * 0.7, t.teal[1] * 0.7, t.teal[2] * 0.7);
|
|
138
|
+
|
|
110
139
|
// Hover stays visible on this theme's background (bright on dark, dark on light).
|
|
111
140
|
C.hover = '\x1b[1m' + rgb(...(t.hover || [190, 245, 255]));
|
|
141
|
+
|
|
142
|
+
// Semantic colors — swap to deep versions on light backgrounds.
|
|
143
|
+
if (t.white) C.white = rgb(...t.white);
|
|
144
|
+
if (t.gray) C.gray = rgb(...t.gray);
|
|
145
|
+
if (t.red) C.red = rgb(...t.red);
|
|
146
|
+
if (t.green) C.green = rgb(...t.green);
|
|
147
|
+
if (t.yellow) C.yellow = rgb(...t.yellow);
|
|
148
|
+
if (t.orange) C.orange = rgb(...t.orange);
|
|
149
|
+
|
|
112
150
|
return true;
|
|
113
151
|
}
|
|
114
152
|
|
|
115
153
|
export function clearScreen() {
|
|
116
154
|
return '\x1b[3J\x1b[H\x1b[2J';
|
|
117
155
|
}
|
|
156
|
+
|
|
157
|
+
// Clear screen and set background color based on current theme
|
|
158
|
+
export function clearAndSetBg() {
|
|
159
|
+
// Reset all attributes first
|
|
160
|
+
const reset = '\x1b[0m';
|
|
161
|
+
// Clear screen
|
|
162
|
+
const clear = '\x1b[3J\x1b[H\x1b[2J';
|
|
163
|
+
// Set background color using current C.bg value
|
|
164
|
+
const bg = C.bg || '\x1b[48;2;0;18;26m'; // Default dark background
|
|
165
|
+
return reset + clear + bg;
|
|
166
|
+
}
|
|
118
167
|
export function eraseLine() {
|
|
119
168
|
return '\x1b[2K';
|
|
120
169
|
}
|
package/src/tui.js
CHANGED
|
@@ -18,7 +18,7 @@ import fs from 'node:fs';
|
|
|
18
18
|
import os from 'node:os';
|
|
19
19
|
import cp from 'node:child_process';
|
|
20
20
|
import {
|
|
21
|
-
C, blockCursor, showCursor, hideCursor, alternateScreen, clearScreen, setTheme, THEME_NAMES, lerpColor,
|
|
21
|
+
C, blockCursor, showCursor, hideCursor, alternateScreen, clearScreen, clearAndSetBg, setTheme, THEME_NAMES, lerpColor,
|
|
22
22
|
} from './colors.js';
|
|
23
23
|
import { copyText, readText, warmClipboard, readImage } from './clipboard.js';
|
|
24
24
|
import { visualWidth, estimateTokens, estimateMessagesTokens, expandTabs } from './term.js';
|
|
@@ -707,14 +707,15 @@ export function isFailureResult(text) {
|
|
|
707
707
|
|
|
708
708
|
function msgColorFor(role, text) {
|
|
709
709
|
if (role === 'system' && typeof text === 'string' && text.startsWith('[turn took')) return C.gray;
|
|
710
|
-
if (role === 'system') return C.
|
|
710
|
+
if (role === 'system') return C.teal;
|
|
711
711
|
if (role === 'user') return C.cyan;
|
|
712
712
|
if (role === 'warn') return C.orange; // unfinished-turn warning
|
|
713
713
|
if (role === 'queued') return C.gray; // pending, not yet sent
|
|
714
714
|
if (role === 'steer') return C.yellow; // injected into the running turn
|
|
715
|
-
if (role === 'tool') return C.
|
|
715
|
+
if (role === 'tool') return C.blue;
|
|
716
716
|
if (role === 'tool_result') return C.gray;
|
|
717
|
-
|
|
717
|
+
// Default foreground color based on theme
|
|
718
|
+
return C.fg;
|
|
718
719
|
}
|
|
719
720
|
|
|
720
721
|
// ---- tool call display: "Using Name (keyArg)" / "Used Name (keyArg) ----
|
|
@@ -2400,7 +2401,7 @@ export function makeState({ cfg, session, opts }) {
|
|
|
2400
2401
|
planPath: (session && session.planPath) || null,
|
|
2401
2402
|
focus: !!(session && session.focus),
|
|
2402
2403
|
effort: (session && session.effort) || cfg.effort || (cfg.reasoning ? 'on' : 'off'),
|
|
2403
|
-
|
|
2404
|
+
// Theme removed - forced dark only
|
|
2404
2405
|
addDirs: [],
|
|
2405
2406
|
tasks: {},
|
|
2406
2407
|
slMode: true, slModel: true, slEffort: true, slCwd: true, slTasks: true, slTips: true,
|
|
@@ -3161,6 +3162,18 @@ async function dispatch(cmdRaw, arg, state, cfg, session, h) {
|
|
|
3161
3162
|
: `theme = "${name}"\n` + txt;
|
|
3162
3163
|
fs.writeFileSync(f, next, 'utf8');
|
|
3163
3164
|
} catch { }
|
|
3165
|
+
|
|
3166
|
+
// Force a complete screen refresh with new theme colors
|
|
3167
|
+
// We need to access stdout from the host context
|
|
3168
|
+
if (host && typeof host.renderFrame === 'function') {
|
|
3169
|
+
// Trigger immediate re-render which will use new theme colors
|
|
3170
|
+
host.renderFrame();
|
|
3171
|
+
} else {
|
|
3172
|
+
// Fallback: just show message and let normal flow handle it
|
|
3173
|
+
app(`Theme set to "${name}".`);
|
|
3174
|
+
return true;
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3164
3177
|
app(`Theme set to "${name}".`);
|
|
3165
3178
|
return true;
|
|
3166
3179
|
};
|
|
@@ -5422,7 +5435,7 @@ export async function startTUI(opts) {
|
|
|
5422
5435
|
session.planPath = state.planPath || null;
|
|
5423
5436
|
session.focus = !!state.focus;
|
|
5424
5437
|
session.effort = state.effort || '';
|
|
5425
|
-
|
|
5438
|
+
// Theme removed - forced dark only
|
|
5426
5439
|
session.steps = state.steps || 0;
|
|
5427
5440
|
session.rounds = state.rounds || 0;
|
|
5428
5441
|
if (state.lastTurnMs) session.lastTurnMs = state.lastTurnMs;
|