@aiwayds/dsh-tui-pi 0.8.3 → 0.9.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.
Files changed (55) hide show
  1. package/README.md +44 -3
  2. package/README.zh.md +36 -3
  3. package/assets/fonts/LICENSE-Hack.txt +45 -0
  4. package/assets/fonts/LICENSE-NerdFonts.txt +126 -0
  5. package/assets/fonts/LICENSE-NotoSansSymbols.txt +93 -0
  6. package/assets/fonts/LICENSE-NotoSansSymbols2.txt +93 -0
  7. package/assets/fonts/dsh-tui-pi-nerd.ttf +0 -0
  8. package/assets/fonts-gen.mjs +219 -0
  9. package/assets/whale-gen.mjs +169 -0
  10. package/assets/whale-source.png +0 -0
  11. package/lib/agents.js +1 -1
  12. package/lib/agents.js.map +1 -1
  13. package/lib/dsh-events.d.ts +32 -3
  14. package/lib/dsh-events.js +14 -0
  15. package/lib/dsh-events.js.map +1 -1
  16. package/lib/font-detect.d.ts +66 -0
  17. package/lib/font-detect.js +124 -0
  18. package/lib/font-detect.js.map +1 -0
  19. package/lib/footer.d.ts +3 -2
  20. package/lib/footer.js +16 -8
  21. package/lib/footer.js.map +1 -1
  22. package/lib/icons.d.ts +53 -0
  23. package/lib/icons.js +78 -0
  24. package/lib/icons.js.map +1 -0
  25. package/lib/index.js +44 -13
  26. package/lib/index.js.map +1 -1
  27. package/lib/live-widgets.d.ts +16 -5
  28. package/lib/live-widgets.js +29 -8
  29. package/lib/live-widgets.js.map +1 -1
  30. package/lib/messages.js +2 -1
  31. package/lib/messages.js.map +1 -1
  32. package/lib/session.d.ts +99 -16
  33. package/lib/session.js +322 -64
  34. package/lib/session.js.map +1 -1
  35. package/lib/sessions.d.ts +15 -0
  36. package/lib/sessions.js +18 -3
  37. package/lib/sessions.js.map +1 -1
  38. package/lib/settings.js +2 -2
  39. package/lib/skills.d.ts +19 -3
  40. package/lib/skills.js +43 -10
  41. package/lib/skills.js.map +1 -1
  42. package/lib/subagent-policy.d.ts +11 -11
  43. package/lib/subagent-policy.js +17 -15
  44. package/lib/subagent-policy.js.map +1 -1
  45. package/lib/subagent-viewer.d.ts +20 -5
  46. package/lib/subagent-viewer.js +29 -15
  47. package/lib/subagent-viewer.js.map +1 -1
  48. package/lib/theme-settings.d.ts +25 -10
  49. package/lib/theme-settings.js +40 -14
  50. package/lib/theme-settings.js.map +1 -1
  51. package/lib/tokens.d.ts +38 -0
  52. package/lib/tokens.js +68 -0
  53. package/lib/tokens.js.map +1 -0
  54. package/package.json +2 -1
  55. package/scripts/install-font.mjs +329 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Nerd Font detection for the icon-set self-adaptation — a
3
+ * zero-dependency probe that tells `src/icons.ts` whether the terminal can
4
+ * render the powerline PUA glyph U+E0B0 (and the other weak-terminal glyphs)
5
+ * before the `auto` icon-set mode picks between 'nerdfont' and 'plain'.
6
+ *
7
+ * Detection is per-platform and deliberately approximate:
8
+ *
9
+ * - Linux: `fc-list -q <name>` for each candidate family. fc-list exits 0
10
+ * when the family is installed (quiet mode prints nothing either way).
11
+ * When `fc-list` itself is missing (ENOENT — a fontconfig-less system),
12
+ * every probe fails and the probe reports "no Nerd Font".
13
+ * - macOS: scan `~/Library/Fonts` and `/Library/Fonts` and match file names
14
+ * against a Nerd/Powerline heuristic (the real Core Text registry is not
15
+ * reachable without Objective-C bindings — a file-name scan is the
16
+ * reasonable zero-dependency approximation; it also recognises the TUI's
17
+ * own bundled font `dsh-tui-pi-nerd.ttf`, so `node scripts/install-font.mjs`
18
+ * flipping the terminal to it is enough to flip `auto` → nerdfont).
19
+ * - Windows / anything else: false (no free probe; the conservative answer
20
+ * is the plain glyphs).
21
+ *
22
+ * The result is memoised at module level — the TUI probes once at startup and
23
+ * hot-applied 'auto' settings changes resolve against that same snapshot. All
24
+ * failure paths return `false`; the probe never throws.
25
+ */
26
+ import { execFile as execFileCb } from 'node:child_process';
27
+ import { readdir as readdirCb } from 'node:fs';
28
+ import { homedir } from 'node:os';
29
+ import { join } from 'node:path';
30
+ import { promisify } from 'node:util';
31
+ const execFile = promisify(execFileCb);
32
+ const readdir = promisify(readdirCb);
33
+ /** Candidate font families probed with `fc-list -q` on Linux. */
34
+ export const NERD_FONT_CANDIDATES = [
35
+ 'JetBrainsMono Nerd Font',
36
+ 'Hack Nerd Font',
37
+ 'MesloLGS NF',
38
+ 'Cascadia Mono PL',
39
+ 'PowerlineSymbols',
40
+ '0xProto Nerd Font',
41
+ ];
42
+ /**
43
+ * macOS font-file-name heuristic for a Nerd/Powerline-capable font, incl. the
44
+ * TUI's own bundled subset (`dsh-tui-pi-nerd.ttf`). `MesloLGS` mirrors the
45
+ * Linux candidate list (MesloLGS NF ships as `MesloLGS NF Regular.ttf`).
46
+ */
47
+ export const NERD_FONT_FILE_RE = /Nerd|Powerline|Cascadia.*PL|MesloLGS|dsh-tui-pi-nerd/i;
48
+ /** The real environment: this process's platform, home and filesystem. */
49
+ const realEnv = {
50
+ platform: process.platform,
51
+ home: homedir(),
52
+ readdir: (dir) => readdir(dir),
53
+ execFile: (file, args, options) => execFile(file, args, options),
54
+ };
55
+ /** Probe one platform with `fc-list -q`; `false` when fc-list is absent. */
56
+ async function probeLinux(env) {
57
+ for (const candidate of NERD_FONT_CANDIDATES) {
58
+ try {
59
+ // 2s cap: a broken fontconfig / stale NFS font dir must fall through to
60
+ // the plain glyphs instead of hanging the TUI startup.
61
+ await env.execFile('fc-list', ['-q', candidate], { timeout: 2000 });
62
+ return true;
63
+ }
64
+ catch {
65
+ // fc-list missing (ENOENT), timed out, or the family not installed —
66
+ // try the next.
67
+ }
68
+ }
69
+ return false;
70
+ }
71
+ /** Probe macOS by scanning the two font directories for matching file names. */
72
+ async function probeDarwin(env) {
73
+ for (const dir of [join(env.home, 'Library', 'Fonts'), '/Library/Fonts']) {
74
+ let names;
75
+ try {
76
+ names = await env.readdir(dir);
77
+ }
78
+ catch {
79
+ continue; // missing/unreadable directory — try the next
80
+ }
81
+ for (const name of names) {
82
+ if (NERD_FONT_FILE_RE.test(name))
83
+ return true;
84
+ }
85
+ }
86
+ return false;
87
+ }
88
+ /**
89
+ * The full probe against an injected environment: Linux uses fc-list, macOS
90
+ * uses the font-directory scan, every other platform reports `false`. Never
91
+ * throws — every platform path is wrapped or falls through to `false`.
92
+ */
93
+ export async function probeNerdFont(env) {
94
+ switch (env.platform) {
95
+ case 'linux':
96
+ return probeLinux(env);
97
+ case 'darwin':
98
+ return probeDarwin(env);
99
+ default:
100
+ // Windows and the rest: no free probe, conservative plain answer.
101
+ return false;
102
+ }
103
+ }
104
+ /** Module-level memo: the TUI probes once per process, never again. */
105
+ let cachedNerdFont;
106
+ /**
107
+ * Detect whether a Nerd/Powerline font is available, memoised. The first call
108
+ * (TUI startup, src/index.ts) runs the platform probe and caches the result;
109
+ * every later call — including a hot-applied 'auto' iconSet change — resolves
110
+ * against the same startup snapshot. Never throws.
111
+ */
112
+ export function detectNerdFontAvailable(env = realEnv) {
113
+ if (cachedNerdFont !== undefined)
114
+ return Promise.resolve(cachedNerdFont);
115
+ return probeNerdFont(env).then((value) => {
116
+ cachedNerdFont = value;
117
+ return value;
118
+ });
119
+ }
120
+ /** Drop the memoised result — a test seam (deterministic probe tests). */
121
+ export function resetNerdFontCache() {
122
+ cachedNerdFont = undefined;
123
+ }
124
+ //# sourceMappingURL=font-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-detect.js","sourceRoot":"","sources":["../src/font-detect.ts"],"names":[],"mappings":"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"}
package/lib/footer.d.ts CHANGED
@@ -4,8 +4,9 @@
4
4
  * Segments (left → right): fixed brand "dsh" · provider · model+thinking ·
5
5
  * context usage · cache-hit rate · message count · tool count, then a
6
6
  * right-aligned 24h clock. Segment backgrounds are the pi-powerline-footer
7
- * palette; separators are U+E0B0 powerline arrows tinted by the neighbouring
8
- * segment colours.
7
+ * palette; separators are the powerline arrow from src/icons.ts (U+E0B0 in
8
+ * nerdfont/auto-with-font, ▸ in the plain icon set), tinted by the
9
+ * neighbouring segment colours.
9
10
  *
10
11
  * Render cost is O(segments): every statistic is read from the bridge's
11
12
  * incrementally maintained counters (never a session-log scan). The 1s clock
package/lib/footer.js CHANGED
@@ -4,8 +4,9 @@
4
4
  * Segments (left → right): fixed brand "dsh" · provider · model+thinking ·
5
5
  * context usage · cache-hit rate · message count · tool count, then a
6
6
  * right-aligned 24h clock. Segment backgrounds are the pi-powerline-footer
7
- * palette; separators are U+E0B0 powerline arrows tinted by the neighbouring
8
- * segment colours.
7
+ * palette; separators are the powerline arrow from src/icons.ts (U+E0B0 in
8
+ * nerdfont/auto-with-font, ▸ in the plain icon set), tinted by the
9
+ * neighbouring segment colours.
9
10
  *
10
11
  * Render cost is O(segments): every statistic is read from the bridge's
11
12
  * incrementally maintained counters (never a session-log scan). The 1s clock
@@ -15,6 +16,7 @@ import { truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';
15
16
  import { ansiBg, ansiFg, BOLD, POWERLINE, RESET } from "./theme/index.js";
16
17
  import { hexIsLight } from "./theme/palette.js";
17
18
  import { clipToWidth } from "./text.js";
19
+ import { arrowRight } from "./icons.js";
18
20
  /**
19
21
  * The footer keybinding hint, assembled from the user's `dsh-tui.footerHints`
20
22
  * selection (see buildFooterHint) - the pre-feature full string is what the
@@ -80,7 +82,6 @@ export class FooterHint {
80
82
  return [` ${styled}${pad} `];
81
83
  }
82
84
  }
83
- const ARROW_RIGHT = '\uE0B0';
84
85
  const WHITE = ansiFg('#FFFFFF');
85
86
  /** Segment text on bright fills (e.g. amber #FFC107): white is unreadable there. */
86
87
  const DARK_TEXT = ansiFg('#1f2328');
@@ -103,10 +104,10 @@ function buildSegments(segs) {
103
104
  const s = segs[i];
104
105
  out += `${ansiBg(s.bgHex)}${BOLD}${segmentText(s.bgHex)} ${s.label} `;
105
106
  if (i + 1 < segs.length) {
106
- out += `${ansiBg(segs[i + 1].bgHex)}${ansiFg(s.bgHex)}${ARROW_RIGHT}`;
107
+ out += `${ansiBg(segs[i + 1].bgHex)}${ansiFg(s.bgHex)}${arrowRight()}`;
107
108
  }
108
109
  else {
109
- out += RESET + ansiFg(s.bgHex) + ARROW_RIGHT + RESET;
110
+ out += RESET + ansiFg(s.bgHex) + arrowRight() + RESET;
110
111
  }
111
112
  }
112
113
  return out;
@@ -157,11 +158,18 @@ export class PowerlineFooter {
157
158
  bgHex: thinkingBg(effort),
158
159
  });
159
160
  }
160
- // Context usage: latest request's input tokens vs. the model's window.
161
+ // Context usage: the current occupancy estimate (latest request's billed
162
+ // input + output + a CJK estimate of messages after it) vs. the model's
163
+ // window — NOT the cumulative inputTokens, which only grows. Percent is
164
+ // capped at 100 (the window is a hard ceiling; the estimate can overshoot
165
+ // while it prices pending messages that a compaction will drop).
161
166
  const window = this.source.getContextWindow();
162
- const used = stats.inputTokens;
167
+ // Defensive `?? 0`: a stats source without the field (any object missing
168
+ // contextTokens) degrades to an empty context instead of rendering
169
+ // `undefined`/`NaN` in the segment.
170
+ const used = stats.contextTokens ?? 0;
163
171
  if (window !== undefined && window > 0) {
164
- const percent = (used / window) * 100;
172
+ const percent = Math.min(100, (used / window) * 100);
165
173
  segs.push({
166
174
  label: `🧠 ${fmtNum(used)}/${fmtNum(window)}(${percent.toFixed(1)}%)`,
167
175
  bgHex: contextBg(percent),
package/lib/footer.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"footer.js","sourceRoot":"","sources":["../src/footer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"footer.js","sourceRoot":"","sources":["../src/footer.ts"],"names":[],"mappings":"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"}
package/lib/icons.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Icon handling for dsh-tui-pi (icon-set self-adaptation).
3
+ *
4
+ * Glyph-risk classification for every symbol this TUI renders:
5
+ *
6
+ * - PUA, must fall back — the ONLY Private Use Area codepoint in the whole
7
+ * project is the powerline separator U+E0B0 (footer's arrow between
8
+ * segments). No default terminal font ships it, so a terminal without a
9
+ * Nerd Font shows a tofu box. `auto`/`plain` swap it for `▸` U+25B8.
10
+ *
11
+ * - Standard Unicode, weak-terminal-risky — U+23F9 `⏹` (stop) and U+2B58
12
+ * `⭘` (heavy circle) are standard codepoints, but weak terminals /
13
+ * emoji-less fonts still render them as boxes. `auto`/`plain` swap them
14
+ * for `■` U+25A0 and `●` U+25CF.
15
+ *
16
+ * - Standard Unicode, rely on system fallback — everything else
17
+ * (⚙ ⚠ ⚡ ✓ ✔ ✗ ✘ ⌘ ⎇ ⓘ ◐ ☑ ☐ ◔ ◑ ◕ ◉ ○ ★ ☁ 🤖 🧠 💬 🔧 ● …). Modern
18
+ * terminals resolve these via font fallback and they are left untouched
19
+ * in every mode.
20
+ *
21
+ * Modes (`dsh-tui.iconSet`, persisted in the settings namespace):
22
+ * - 'nerdfont': use the PUA powerline glyph (assumes a Nerd Font is the
23
+ * terminal's font).
24
+ * - 'plain': use the safe standard-Unicode stand-ins for every risky glyph.
25
+ * - 'auto' (default): nerdfont when a Nerd Font is detected at startup,
26
+ * plain otherwise (see src/font-detect.ts).
27
+ *
28
+ * The resolved mode lives in module state: `applyIconSet` is called once at
29
+ * TUI startup and again on every hot-applied `iconSet` settings change, so
30
+ * footer/notice/panel accessors return the right glyph at render time. The
31
+ * module defaults to 'nerdfont' — the pre-feature output (`\uE0B0`) is
32
+ * preserved unless the resolution lands on 'plain'.
33
+ */
34
+ /** The persisted/`auto` icon-set mode; 'auto' resolves at startup. */
35
+ export type IconSet = 'auto' | 'nerdfont' | 'plain';
36
+ /** A resolved (non-auto) icon set — the value that drives glyph selection. */
37
+ export type ResolvedIconSet = Exclude<IconSet, 'auto'>;
38
+ /**
39
+ * Resolve an icon-set mode against the startup font detection: `auto` picks
40
+ * the nerdfont glyphs when a Nerd Font is available and the plain fallbacks
41
+ * otherwise; an explicit `nerdfont`/`plain` pin returns itself unchanged.
42
+ */
43
+ export declare function resolveIconSet(mode: IconSet, nerdfontAvailable: boolean): IconSet;
44
+ /** Set the live resolved icon set (startup + hot-apply, src/index.ts). */
45
+ export declare function applyIconSet(set: IconSet): void;
46
+ /** The live resolved icon set (exposed for tests and the /settings UI). */
47
+ export declare function getResolvedIconSet(): ResolvedIconSet;
48
+ /** The powerline segment separator: `\uE0B0` (nerdfont) / `▸` (plain). */
49
+ export declare function arrowRight(set?: IconSet): string;
50
+ /** The stop glyph: `⏹` (nerdfont) / `■` (plain). */
51
+ export declare function stopIcon(set?: IconSet): string;
52
+ /** The subagent glyph: `⭘` (nerdfont) / `●` (plain). */
53
+ export declare function sunglassesIcon(set?: IconSet): string;
package/lib/icons.js ADDED
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Icon handling for dsh-tui-pi (icon-set self-adaptation).
3
+ *
4
+ * Glyph-risk classification for every symbol this TUI renders:
5
+ *
6
+ * - PUA, must fall back — the ONLY Private Use Area codepoint in the whole
7
+ * project is the powerline separator U+E0B0 (footer's arrow between
8
+ * segments). No default terminal font ships it, so a terminal without a
9
+ * Nerd Font shows a tofu box. `auto`/`plain` swap it for `▸` U+25B8.
10
+ *
11
+ * - Standard Unicode, weak-terminal-risky — U+23F9 `⏹` (stop) and U+2B58
12
+ * `⭘` (heavy circle) are standard codepoints, but weak terminals /
13
+ * emoji-less fonts still render them as boxes. `auto`/`plain` swap them
14
+ * for `■` U+25A0 and `●` U+25CF.
15
+ *
16
+ * - Standard Unicode, rely on system fallback — everything else
17
+ * (⚙ ⚠ ⚡ ✓ ✔ ✗ ✘ ⌘ ⎇ ⓘ ◐ ☑ ☐ ◔ ◑ ◕ ◉ ○ ★ ☁ 🤖 🧠 💬 🔧 ● …). Modern
18
+ * terminals resolve these via font fallback and they are left untouched
19
+ * in every mode.
20
+ *
21
+ * Modes (`dsh-tui.iconSet`, persisted in the settings namespace):
22
+ * - 'nerdfont': use the PUA powerline glyph (assumes a Nerd Font is the
23
+ * terminal's font).
24
+ * - 'plain': use the safe standard-Unicode stand-ins for every risky glyph.
25
+ * - 'auto' (default): nerdfont when a Nerd Font is detected at startup,
26
+ * plain otherwise (see src/font-detect.ts).
27
+ *
28
+ * The resolved mode lives in module state: `applyIconSet` is called once at
29
+ * TUI startup and again on every hot-applied `iconSet` settings change, so
30
+ * footer/notice/panel accessors return the right glyph at render time. The
31
+ * module defaults to 'nerdfont' — the pre-feature output (`\uE0B0`) is
32
+ * preserved unless the resolution lands on 'plain'.
33
+ */
34
+ /** PUA — must fall back (see the classification above). */
35
+ const ARROW_RIGHT_GLYPHS = { nerdfont: '\uE0B0', plain: '\u25B8' };
36
+ /** Standard Unicode, weak-terminal-risky: `⏹` → `■`. */
37
+ const STOP_GLYPHS = { nerdfont: '\u23F9', plain: '\u25A0' };
38
+ /** Standard Unicode, weak-terminal-risky: `⭘` → `●`. */
39
+ const SUNGLASSES_GLYPHS = { nerdfont: '\u2B58', plain: '\u25CF' };
40
+ /**
41
+ * Resolve an icon-set mode against the startup font detection: `auto` picks
42
+ * the nerdfont glyphs when a Nerd Font is available and the plain fallbacks
43
+ * otherwise; an explicit `nerdfont`/`plain` pin returns itself unchanged.
44
+ */
45
+ export function resolveIconSet(mode, nerdfontAvailable) {
46
+ if (mode === 'auto')
47
+ return nerdfontAvailable ? 'nerdfont' : 'plain';
48
+ return mode;
49
+ }
50
+ /**
51
+ * The live resolved icon set. Defaults to 'nerdfont' — the legacy output —
52
+ * so a TUI that renders before the async font detection lands never flickers
53
+ * from a plain glyph to the powerline arrow; only a resolved 'plain' flips it.
54
+ */
55
+ let resolvedIconSet = 'nerdfont';
56
+ /** Set the live resolved icon set (startup + hot-apply, src/index.ts). */
57
+ export function applyIconSet(set) {
58
+ // 'auto' is resolved at startup (font detection, index.ts); a hot-applied
59
+ // settings 'auto' keeps the current resolved set — never flickers.
60
+ resolvedIconSet = set === 'auto' ? resolvedIconSet : set;
61
+ }
62
+ /** The live resolved icon set (exposed for tests and the /settings UI). */
63
+ export function getResolvedIconSet() {
64
+ return resolvedIconSet;
65
+ }
66
+ /** The powerline segment separator: `\uE0B0` (nerdfont) / `▸` (plain). */
67
+ export function arrowRight(set = resolvedIconSet) {
68
+ return ARROW_RIGHT_GLYPHS[set === 'auto' ? resolvedIconSet : set];
69
+ }
70
+ /** The stop glyph: `⏹` (nerdfont) / `■` (plain). */
71
+ export function stopIcon(set = resolvedIconSet) {
72
+ return STOP_GLYPHS[set === 'auto' ? resolvedIconSet : set];
73
+ }
74
+ /** The subagent glyph: `⭘` (nerdfont) / `●` (plain). */
75
+ export function sunglassesIcon(set = resolvedIconSet) {
76
+ return SUNGLASSES_GLYPHS[set === 'auto' ? resolvedIconSet : set];
77
+ }
78
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAWH,2DAA2D;AAC3D,MAAM,kBAAkB,GAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAC9E,wDAAwD;AACxD,MAAM,WAAW,GAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AACvE,wDAAwD;AACxD,MAAM,iBAAiB,GAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAE7E;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,iBAA0B;IACtE,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAA;IACpE,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,IAAI,eAAe,GAAoB,UAAU,CAAA;AAEjD,0EAA0E;AAC1E,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,0EAA0E;IAC1E,mEAAmE;IACnE,eAAe,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAA;AAC1D,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB;IAChC,OAAO,eAAe,CAAA;AACxB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,MAAe,eAAe;IACvD,OAAO,kBAAkB,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AACnE,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,QAAQ,CAAC,MAAe,eAAe;IACrD,OAAO,WAAW,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAC5D,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,cAAc,CAAC,MAAe,eAAe;IAC3D,OAAO,iBAAiB,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAClE,CAAC"}
package/lib/index.js CHANGED
@@ -22,7 +22,9 @@ import { displayPermissionPreset } from "./permission.js";
22
22
  import { pickEffort, pickModel, pickPermission, pickSkill, pickTheme } from "./selectors.js";
23
23
  import { parseSkillCommand, skillGesture } from "./skills.js";
24
24
  import { DshSessionBridge, persistDefaultModel, stashSessionIdForReload, takeStashedSessionId } from "./session.js";
25
- import { currentThemePreference, readFooterHintsPreference, readPanelHeightPreference, readThemePreference, registerThemeSettings, writeThemePreference, } from "./theme-settings.js";
25
+ import { currentThemePreference, readFooterHintsPreference, readIconSetPreference, readPanelHeightPreference, readSubagentLimits, readThemePreference, registerThemeSettings, writeThemePreference, } from "./theme-settings.js";
26
+ import { applyIconSet, resolveIconSet, stopIcon } from "./icons.js";
27
+ import { detectNerdFontAvailable } from "./font-detect.js";
26
28
  import { openAgentManager } from "./agents.js";
27
29
  import { openSettingsBrowser } from "./settings.js";
28
30
  import { openLoginFlow, openLogoutFlow } from "./login.js";
@@ -90,6 +92,14 @@ export function apply(ctx) {
90
92
  * the new segment selection. Armed inside runTui once the TUI exists.
91
93
  */
92
94
  let applyFooterHintsRef;
95
+ /**
96
+ * Live icon-set hot-reload sink, wired to the same watch hook: a committed
97
+ * `dsh-tui` iconSet change re-resolves the risky glyphs (an 'auto' change
98
+ * resolves against the startup font-detection snapshot) and repaints the
99
+ * footer/notices/panels that carry them. Armed inside runTui once the TUI
100
+ * exists.
101
+ */
102
+ let applyIconSetRef;
93
103
  ctx.effect(async () => {
94
104
  // The theme bundle is built once at TUI startup and held by every
95
105
  // component, so the persisted preference must land before startTui — the
@@ -105,17 +115,26 @@ export function apply(ctx) {
105
115
  // setTheme replay that follows already renders at that new height.
106
116
  // applyTheme carries the theme-bundle identity guard, so a height-only
107
117
  // commit never triggers a second rebuild.
108
- registerThemeSettings(ctx, (pref, height, footerHints) => {
118
+ registerThemeSettings(ctx, (pref, height, footerHints, iconSet) => {
109
119
  applyPanelHeightRef?.(height);
110
120
  applyThemeRef?.(pref);
111
121
  applyFooterHintsRef?.(footerHints);
122
+ applyIconSetRef?.(iconSet);
112
123
  });
113
124
  const themePreference = await readThemePreference(ctx);
114
125
  const panelHeight = await readPanelHeightPreference(ctx);
115
126
  const footerHints = await readFooterHintsPreference(ctx);
127
+ // Icon-set self-adaptation: probe the platform once at startup (the
128
+ // memoised snapshot shared with every later 'auto' resolution), resolve
129
+ // the persisted mode against it and push the result into src/icons.ts
130
+ // BEFORE the TUI's first frame — so the footer renders the right
131
+ // separator from frame one, never a late plain→powerline flicker.
132
+ const iconSetPreference = await readIconSetPreference(ctx);
133
+ const nerdfontAvailable = await detectNerdFontAvailable();
134
+ applyIconSet(resolveIconSet(iconSetPreference, nerdfontAvailable));
116
135
  let disposer;
117
136
  try {
118
- disposer = runTui(themePreference, panelHeight, footerHints);
137
+ disposer = runTui(themePreference, panelHeight, footerHints, nerdfontAvailable);
119
138
  }
120
139
  catch (error) {
121
140
  // An async-effect failure after startTui would otherwise orphan the
@@ -136,7 +155,7 @@ export function apply(ctx) {
136
155
  * reaches cordis. Returns the effect disposer handed back to cordis on
137
156
  * teardown.
138
157
  */
139
- function runTui(themePreference, panelHeight, footerHints) {
158
+ function runTui(themePreference, panelHeight, footerHints, nerdfontAvailable) {
140
159
  // User keybindings (`~/.dsh/keybindings.json`): a partial map of the app
141
160
  // keys, read once per TUI start — `/reload` re-runs apply() and re-reads
142
161
  // it. Broken entries surface as notices instead of breaking startup.
@@ -185,7 +204,7 @@ export function apply(ctx) {
185
204
  void stopTask();
186
205
  break;
187
206
  }
188
- renderer.renderNotice('⏹ stopping — Esc was double-pressed', 'info');
207
+ renderer.renderNotice(`${stopIcon()} stopping — Esc was double-pressed`, 'info');
189
208
  stopConfirmTimer = setTimeout(() => {
190
209
  stopConfirmTimer = undefined;
191
210
  void stopTask();
@@ -226,7 +245,7 @@ export function apply(ctx) {
226
245
  void disposeAndExit(0);
227
246
  break;
228
247
  }
229
- renderer.renderNotice('⏹ Ctrl+C ×2 — quitting…', 'info');
248
+ renderer.renderNotice(`${stopIcon()} Ctrl+C ×2 — quitting…`, 'info');
230
249
  quitConfirmTimer = setTimeout(() => {
231
250
  quitConfirmTimer = undefined;
232
251
  void disposeAndExit(0);
@@ -291,7 +310,7 @@ export function apply(ctx) {
291
310
  * ESC/Ctrl+C double-press guards); the notice renders immediately.
292
311
  */
293
312
  const stopTask = async () => {
294
- renderer.renderNotice('⏹ canceling current turn…', 'info');
313
+ renderer.renderNotice(`${stopIcon()} canceling current turn…`, 'info');
295
314
  const cancelled = await bridge.cancelActiveTurn();
296
315
  // State raced idle between the decision and the cancel call — nothing
297
316
  // to cancel (e.g. the turn settled inside the confirm window).
@@ -318,7 +337,10 @@ export function apply(ctx) {
318
337
  // into the last-request area BELOW the editor. Owned here — fed by
319
338
  // session events and the bridge's subagent fold, ticked by the live
320
339
  // timer, recolored by applyTheme.
321
- const liveWidgets = new LiveWidgets(ui.widgets, ui.lastRequest, ui.theme, () => ui.requestRender(), panelHeight);
340
+ const liveWidgets = new LiveWidgets(ui.widgets, ui.lastRequest, ui.theme, () => ui.requestRender(), panelHeight,
341
+ // Live maxRounds for the compact running-agent lines' `round N/M` — read
342
+ // at every rebuild (the /agents limits panel hot-applies).
343
+ () => readSubagentLimits(ctx).maxRounds);
322
344
  // Arm the panel-height watch sink now that the widgets exist: a committed
323
345
  // panelHeight change re-budgets the think/tool panels — they are
324
346
  // self-drawing, so the next frame already renders at the new height.
@@ -392,15 +414,16 @@ export function apply(ctx) {
392
414
  // Subagent fine-grained control, all in-process (see subagent-policy.ts):
393
415
  // a tools.guard denies spawn-tool calls once `maxAgents` children run
394
416
  // (workflow fan-out, which bypasses the tool pipeline, is pruned on
395
- // `subagent/start`), and when a child's completed turns reach `maxRounds`
396
- // the policy queues one wrap-up message into its next turn. Limits are
397
- // read live from the `dsh-tui` settings namespace (/agents → l limits).
417
+ // `subagent/start`), and when a child's assistant-message count reaches
418
+ // `maxRounds` the policy queues one wrap-up message into its next turn.
419
+ // Limits are read live from the `dsh-tui` settings namespace
420
+ // (/agents → l limits).
398
421
  const subagentPolicy = applySubagentPolicy(ctx, {
399
422
  getLive: () => bridge.getLiveChildren(),
400
- getTurnCount: childId => bridge.getTurnCount(childId),
423
+ getRoundCount: childId => bridge.getRoundCount(childId),
401
424
  isSettled: childId => bridge.isChildSettled(childId),
402
425
  });
403
- bridgeCallbacks.onTurnCount = (childId, count) => subagentPolicy.onTurnCount(childId, count);
426
+ bridgeCallbacks.onRoundCount = (childId, count) => subagentPolicy.onRoundCount(childId, count);
404
427
  /**
405
428
  * One O(events) fold of the session log into the effective preset, stored
406
429
  * for the badge provider. Runs once per session (ensure/resume, see the
@@ -975,6 +998,14 @@ export function apply(ctx) {
975
998
  footerHintsRef = hints;
976
999
  ui.requestRender();
977
1000
  };
1001
+ // Arm the icon-set watch sink: a committed iconSet change hot-applies the
1002
+ // risky glyphs (an 'auto' change resolves against the startup font-
1003
+ // detection snapshot, matching the startup glyph choice) and repaints the
1004
+ // footer/notices/panels that carry them on the next frame.
1005
+ applyIconSetRef = (set) => {
1006
+ applyIconSet(resolveIconSet(set, nerdfontAvailable));
1007
+ ui.requestRender();
1008
+ };
978
1009
  /**
979
1010
  * Hot-apply a theme bundle to the running TUI: the transcript rebuilds
980
1011
  * from its replay buffer, the dock/editor swap to the new bundle, and the