ciphermesh 2.7.0 → 2.7.2

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,36 @@
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.2
7
+
8
+ ### Fixed
9
+
10
+ - **The standalone binaries now run on machines other than the one that built
11
+ them.** `sodium-native` resolves its prebuilt addon at runtime, which bun
12
+ cannot follow, so the addon was never embedded — the binary kept an absolute
13
+ path back to the build checkout and died with `Cannot find addon` anywhere
14
+ else. Every binary published before this, including the relay binaries dating
15
+ back to 2.3.0, was affected (#427).
16
+
17
+ The verification was the deeper problem: it ran the binary _on the runner that
18
+ built it_, where the addon resolved through `node_modules`, so every check
19
+ passed while every download was broken. CI now hides the build tree before
20
+ running anything, and the cross-compiled binary is executed under Rosetta
21
+ rather than merely asserting its architecture.
22
+
23
+ **If you downloaded a binary from an earlier release, replace it.**
24
+
25
+ ## 2.7.1
26
+
27
+ ### Fixed
28
+
29
+ - The banner no longer reads a font from disk. `figlet.textSync` loads
30
+ `fonts/ANSI Shadow.flf` at startup — fine under Node, fatal inside a compiled
31
+ binary, where the file does not exist and the process died before printing
32
+ anything. The word never changes, so the art is now the constant it always
33
+ was, pinned against figlet's own output by a test. figlet moved to a
34
+ devDependency and the 1.11.4 hold is gone (#414).
35
+
6
36
  ## 2.7.0
7
37
 
8
38
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ciphermesh",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
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) {