ciphermesh 2.7.0 → 2.7.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  Notable changes per release. Older versions are reconstructed from the git
4
4
  history — the commit bodies and pull requests remain the fuller record.
5
5
 
6
+ ## 2.7.1
7
+
8
+ ### Fixed
9
+
10
+ - The banner no longer reads a font from disk. `figlet.textSync` loads
11
+ `fonts/ANSI Shadow.flf` at startup — fine under Node, fatal inside a compiled
12
+ binary, where the file does not exist and the process died before printing
13
+ anything. The word never changes, so the art is now the constant it always
14
+ was, pinned against figlet's own output by a test. figlet moved to a
15
+ devDependency and the 1.11.4 hold is gone (#414).
16
+
6
17
  ## 2.7.0
7
18
 
8
19
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciphermesh",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "description": "Secure terminal chat for the local network (LAN) with real end-to-end encryption (E2EE) using libsodium",
5
5
  "type": "module",
6
6
  "main": "src/client/index.js",
@@ -57,7 +57,6 @@
57
57
  "bonjour-service": "1.4.4",
58
58
  "boxen": "8.0.1",
59
59
  "chalk": "^5.4.1",
60
- "figlet": "1.11.3",
61
60
  "gradient-string": "3.0.0",
62
61
  "jimp": "1.6.1",
63
62
  "node-notifier": "10.0.1",
@@ -68,6 +67,7 @@
68
67
  "devDependencies": {
69
68
  "@eslint/js": "10.0.1",
70
69
  "eslint": "10.8.0",
70
+ "figlet": "^1.11.4",
71
71
  "globals": "^17.7.0",
72
72
  "prettier": "^3.9.5"
73
73
  },
@@ -1,4 +1,3 @@
1
- import figlet from 'figlet';
2
1
  import gradient from 'gradient-string';
3
2
  import chalk from 'chalk';
4
3
  import boxen from 'boxen';
@@ -7,8 +6,36 @@ const neon = gradient(['#00ff9f', '#00b8ff', '#7b2dff', '#ff2dff']);
7
6
  const cyber = gradient(['#f72585', '#7209b7', '#3a0ca3', '#4361ee', '#4cc9f0']);
8
7
  const mint = gradient(['#00ff9f', '#00b8ff']);
9
8
 
9
+ /**
10
+ * "CipherMesh" in figlet's ANSI Shadow, rendered once and kept.
11
+ *
12
+ * It used to be generated at startup with `figlet.textSync`, which reads the
13
+ * font file from disk — fine under Node, fatal inside a compiled binary, where
14
+ * `fonts/ANSI Shadow.flf` does not exist and the process dies before printing
15
+ * anything (issue #414). The word never changes, so there is nothing to
16
+ * generate: the art is the constant it always was.
17
+ *
18
+ * `test/banner.test.js` pins it against figlet's own output, so a change here
19
+ * has to be deliberate.
20
+ */
21
+ const ART = [
22
+ ' ██████╗██╗██████╗ ██╗ ██╗███████╗██████╗ ███╗ ███╗███████╗███████╗██╗ ██╗',
23
+ '██╔════╝██║██╔══██╗██║ ██║██╔════╝██╔══██╗████╗ ████║██╔════╝██╔════╝██║ ██║',
24
+ '██║ ██║██████╔╝███████║█████╗ ██████╔╝██╔████╔██║█████╗ ███████╗███████║',
25
+ '██║ ██║██╔═══╝ ██╔══██║██╔══╝ ██╔══██╗██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║',
26
+ '╚██████╗██║██║ ██║ ██║███████╗██║ ██║██║ ╚═╝ ██║███████╗███████║██║ ██║',
27
+ ' ╚═════╝╚═╝╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝',
28
+ // figlet pads the block to a seventh, blank line. It is not decoration: the
29
+ // animations count lines to move the cursor back up (`\x1b[${N + 1}A`), so
30
+ // dropping it would shift every redraw by one row.
31
+ ' '.repeat(78),
32
+ ].join('\n');
33
+
34
+ /** Byte-for-byte what `figlet.textSync('CipherMesh', { font: 'ANSI Shadow' })` returns. */
35
+ export const LOGO_ART = ART;
36
+
10
37
  function logo() {
11
- return neon(figlet.textSync('CipherMesh', { font: 'ANSI Shadow' }));
38
+ return neon(LOGO_ART);
12
39
  }
13
40
 
14
41
  export function serverBanner(port, network, tls = false) {
@@ -80,7 +107,7 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
80
107
  // Animated splash: the neon gradient "flows" through the ANSI-Shadow logo for
81
108
  // ~1s, then settles. Runs before the TUI (plain terminal output).
82
109
  export async function animatedBanner(subtitle = ' ░▒▓ End-to-End Encrypted Chat ▓▒░') {
83
- const art = figlet.textSync('CipherMesh', { font: 'ANSI Shadow' }).replace(/\n+$/, '');
110
+ const art = ART;
84
111
  const artLines = art.split('\n');
85
112
  const N = artLines.length;
86
113
 
@@ -132,7 +159,7 @@ function mixHex(a, b, t) {
132
159
  // Goodbye animation on /quit: the neon logo fades to black over ~0.8s while a
133
160
  // farewell line shows, then the process exits. Static fallback on non-TTY.
134
161
  export async function farewellBanner(message = ' 🔒 Session ended — keys wiped from memory') {
135
- const art = figlet.textSync('CipherMesh', { font: 'ANSI Shadow' }).replace(/\n+$/, '');
162
+ const art = ART;
136
163
  const N = art.split('\n').length;
137
164
 
138
165
  if (!process.stdout.isTTY) {