@aiwayds/dsh-tui-pi 0.9.0 → 0.9.1

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.
@@ -4,20 +4,28 @@
4
4
  * render the powerline PUA glyph U+E0B0 (and the other weak-terminal glyphs)
5
5
  * before the `auto` icon-set mode picks between 'nerdfont' and 'plain'.
6
6
  *
7
- * Detection is per-platform and deliberately approximate:
7
+ * Detection has two layers:
8
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).
9
+ * 1. Terminal whitelist: some terminal emulators ship a built-in Nerd /
10
+ * Symbols font fallback they can render powerline glyphs regardless of
11
+ * which font the user has installed system-wide. When `TERM_PROGRAM`
12
+ * matches a known whitelisted terminal, the probe short-circuits to
13
+ * `true` without touching the filesystem. See `NERD_FONT_TERMINALS`.
14
+ *
15
+ * 2. Font-directory / fc-list scan (the original heuristic):
16
+ * - Linux: `fc-list -q <name>` for each candidate family. fc-list exits
17
+ * 0 when the family is installed (quiet mode prints nothing either way).
18
+ * When `fc-list` itself is missing (ENOENT a fontconfig-less system),
19
+ * every probe fails and the probe reports "no Nerd Font".
20
+ * - macOS: scan `~/Library/Fonts` and `/Library/Fonts` and match file
21
+ * names against a Nerd/Powerline heuristic (the real Core Text registry
22
+ * is not reachable without Objective-C bindings — a file-name scan is
23
+ * the reasonable zero-dependency approximation; it also recognises the
24
+ * TUI's own bundled font `dsh-tui-pi-nerd.ttf`, so
25
+ * `node scripts/install-font.mjs` flipping the terminal to it is enough
26
+ * to flip `auto` → nerdfont).
27
+ * - Windows / anything else: false (no free probe; the conservative
28
+ * answer is the plain glyphs).
21
29
  *
22
30
  * The result is memoised at module level — the TUI probes once at startup and
23
31
  * hot-applied 'auto' settings changes resolve against that same snapshot. All
@@ -31,6 +39,26 @@ export declare const NERD_FONT_CANDIDATES: readonly string[];
31
39
  * Linux candidate list (MesloLGS NF ships as `MesloLGS NF Regular.ttf`).
32
40
  */
33
41
  export declare const NERD_FONT_FILE_RE: RegExp;
42
+ /**
43
+ * Terminal emulators that ship a built-in Nerd / Symbols font fallback — they
44
+ * can render U+E0B0 and other PUA glyphs even when no Nerd Font is installed
45
+ * system-wide. The probe short-circuits to `true` when `TERM_PROGRAM` matches
46
+ * one of these, before touching the filesystem. The values are the terminals'
47
+ * own hardcoded, case-exact TERM_PROGRAM strings (locked by a test) — do not
48
+ * normalise case on a hunch.
49
+ *
50
+ * - `ghostty`: bundles Symbols Nerd Font as a built-in fallback for missing
51
+ * glyphs (https://ghostty.org/docs/install/release-notes/1-2-0).
52
+ * - `WezTerm`: bundles Nerd Font Symbols and always appends its default
53
+ * fallback, even with a user font chain
54
+ * (https://wezterm.org/config/fonts.html).
55
+ *
56
+ * Residual gap, accepted: tmux 3.3+ rewrites TERM_PROGRAM to `tmux` inside
57
+ * panes, so the whitelist does not apply there — the probe falls through to
58
+ * the (conservative, tofu-free) directory scan. Users under tmux should set
59
+ * `dsh-tui.iconSet` explicitly.
60
+ */
61
+ export declare const NERD_FONT_TERMINALS: readonly string[];
34
62
  /**
35
63
  * The environment the probe reads — injected for tests (see
36
64
  * test/font-detect.test.mjs), defaulting to the real platform/fs.
@@ -48,11 +76,14 @@ export interface FontDetectEnv {
48
76
  execFile: (file: string, args: readonly string[], options?: {
49
77
  timeout?: number;
50
78
  }) => Promise<unknown>;
79
+ /** `process.env.TERM_PROGRAM` — used for the terminal-whitelist check. */
80
+ termProgram?: string;
51
81
  }
52
82
  /**
53
- * The full probe against an injected environment: Linux uses fc-list, macOS
54
- * uses the font-directory scan, every other platform reports `false`. Never
55
- * throws — every platform path is wrapped or falls through to `false`.
83
+ * The full probe against an injected environment: first checks the terminal
84
+ * whitelist (built-in Nerd symbol fallback), then falls back to the
85
+ * platform-specific font-directory / fc-list scan. Never throws every
86
+ * platform path is wrapped or falls through to `false`.
56
87
  */
57
88
  export declare function probeNerdFont(env: FontDetectEnv): Promise<boolean>;
58
89
  /**
@@ -4,20 +4,28 @@
4
4
  * render the powerline PUA glyph U+E0B0 (and the other weak-terminal glyphs)
5
5
  * before the `auto` icon-set mode picks between 'nerdfont' and 'plain'.
6
6
  *
7
- * Detection is per-platform and deliberately approximate:
7
+ * Detection has two layers:
8
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).
9
+ * 1. Terminal whitelist: some terminal emulators ship a built-in Nerd /
10
+ * Symbols font fallback they can render powerline glyphs regardless of
11
+ * which font the user has installed system-wide. When `TERM_PROGRAM`
12
+ * matches a known whitelisted terminal, the probe short-circuits to
13
+ * `true` without touching the filesystem. See `NERD_FONT_TERMINALS`.
14
+ *
15
+ * 2. Font-directory / fc-list scan (the original heuristic):
16
+ * - Linux: `fc-list -q <name>` for each candidate family. fc-list exits
17
+ * 0 when the family is installed (quiet mode prints nothing either way).
18
+ * When `fc-list` itself is missing (ENOENT a fontconfig-less system),
19
+ * every probe fails and the probe reports "no Nerd Font".
20
+ * - macOS: scan `~/Library/Fonts` and `/Library/Fonts` and match file
21
+ * names against a Nerd/Powerline heuristic (the real Core Text registry
22
+ * is not reachable without Objective-C bindings — a file-name scan is
23
+ * the reasonable zero-dependency approximation; it also recognises the
24
+ * TUI's own bundled font `dsh-tui-pi-nerd.ttf`, so
25
+ * `node scripts/install-font.mjs` flipping the terminal to it is enough
26
+ * to flip `auto` → nerdfont).
27
+ * - Windows / anything else: false (no free probe; the conservative
28
+ * answer is the plain glyphs).
21
29
  *
22
30
  * The result is memoised at module level — the TUI probes once at startup and
23
31
  * hot-applied 'auto' settings changes resolve against that same snapshot. All
@@ -45,12 +53,36 @@ export const NERD_FONT_CANDIDATES = [
45
53
  * Linux candidate list (MesloLGS NF ships as `MesloLGS NF Regular.ttf`).
46
54
  */
47
55
  export const NERD_FONT_FILE_RE = /Nerd|Powerline|Cascadia.*PL|MesloLGS|dsh-tui-pi-nerd/i;
56
+ /**
57
+ * Terminal emulators that ship a built-in Nerd / Symbols font fallback — they
58
+ * can render U+E0B0 and other PUA glyphs even when no Nerd Font is installed
59
+ * system-wide. The probe short-circuits to `true` when `TERM_PROGRAM` matches
60
+ * one of these, before touching the filesystem. The values are the terminals'
61
+ * own hardcoded, case-exact TERM_PROGRAM strings (locked by a test) — do not
62
+ * normalise case on a hunch.
63
+ *
64
+ * - `ghostty`: bundles Symbols Nerd Font as a built-in fallback for missing
65
+ * glyphs (https://ghostty.org/docs/install/release-notes/1-2-0).
66
+ * - `WezTerm`: bundles Nerd Font Symbols and always appends its default
67
+ * fallback, even with a user font chain
68
+ * (https://wezterm.org/config/fonts.html).
69
+ *
70
+ * Residual gap, accepted: tmux 3.3+ rewrites TERM_PROGRAM to `tmux` inside
71
+ * panes, so the whitelist does not apply there — the probe falls through to
72
+ * the (conservative, tofu-free) directory scan. Users under tmux should set
73
+ * `dsh-tui.iconSet` explicitly.
74
+ */
75
+ export const NERD_FONT_TERMINALS = [
76
+ 'ghostty',
77
+ 'WezTerm',
78
+ ];
48
79
  /** The real environment: this process's platform, home and filesystem. */
49
80
  const realEnv = {
50
81
  platform: process.platform,
51
82
  home: homedir(),
52
83
  readdir: (dir) => readdir(dir),
53
84
  execFile: (file, args, options) => execFile(file, args, options),
85
+ termProgram: process.env.TERM_PROGRAM,
54
86
  };
55
87
  /** Probe one platform with `fc-list -q`; `false` when fc-list is absent. */
56
88
  async function probeLinux(env) {
@@ -86,11 +118,16 @@ async function probeDarwin(env) {
86
118
  return false;
87
119
  }
88
120
  /**
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`.
121
+ * The full probe against an injected environment: first checks the terminal
122
+ * whitelist (built-in Nerd symbol fallback), then falls back to the
123
+ * platform-specific font-directory / fc-list scan. Never throws every
124
+ * platform path is wrapped or falls through to `false`.
92
125
  */
93
126
  export async function probeNerdFont(env) {
127
+ // Short-circuit: terminals with built-in Nerd symbol fallback can render
128
+ // U+E0B0 regardless of system-installed fonts.
129
+ if (env.termProgram && NERD_FONT_TERMINALS.includes(env.termProgram))
130
+ return true;
94
131
  switch (env.platform) {
95
132
  case 'linux':
96
133
  return probeLinux(env);
@@ -1 +1 @@
1
- {"version":3,"file":"font-detect.js","sourceRoot":"","sources":["../src/font-detect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"font-detect.js","sourceRoot":"","sources":["../src/font-detect.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwayds/dsh-tui-pi",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "pi-style terminal UI for DeepSeek Harness (dsh) — pi-tui look & feel, dsh slash commands, GitHub light/dark themes, powerline footer",
5
5
  "repository": {
6
6
  "type": "git",