@gtchakama/wa-tui 1.0.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.
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # wa-tui
2
+
3
+ Terminal UI for WhatsApp Web, built with [neo-blessed](https://www.npmjs.com/package/neo-blessed) and [whatsapp-web.js](https://wwebjs.dev/). Scan a QR code in the terminal, then browse chats, read messages, reply, and download media without leaving your shell.
4
+
5
+ ## Requirements
6
+
7
+ - **Node.js** 18 or newer
8
+ - **Google Chrome** or **Chromium** installed locally — `whatsapp-web.js` drives a headless browser session; if startup fails, install Chrome or point Puppeteer at your binary (see [whatsapp-web.js docs](https://docs.wwebjs.dev/)).
9
+
10
+ Session data and cache are stored under `.wwebjs_auth` and `.wwebjs_cache` in the current working directory (and settings under `~/.wa-tui/`).
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install -g @gtchakama/wa-tui
16
+ ```
17
+
18
+ Or run without a global install:
19
+
20
+ ```bash
21
+ npx @gtchakama/wa-tui
22
+ ```
23
+
24
+ From a git checkout:
25
+
26
+ ```bash
27
+ npm install
28
+ npm start
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ```bash
34
+ wa-tui
35
+ ```
36
+
37
+ On first run, scan the QR code shown in the terminal with WhatsApp on your phone (**Linked devices**).
38
+
39
+ ### Environment variables
40
+
41
+ | Variable | Description |
42
+ | -------- | ----------- |
43
+ | `WA_TUI_RESIZE` | Set to `1` to enable resize-related behavior used during development (`npm run start:resize`). |
44
+ | `WA_TUI_NO_SOUND` | Set to `1` to disable the incoming-message notification sound. |
45
+ | `WA_TUI_SOUND` | Optional path to an audio file (macOS: `afplay`; Linux: `paplay` / `aplay`). Overrides the default tone. |
46
+
47
+ Incoming messages play a short sound when you are **not** viewing that chat. Defaults: **macOS** — `Ping.aiff` via `afplay`; **Windows** — short two-tone console beep; **Linux** — freedesktop `complete.oga` or `message.oga`, then WAV fallback; otherwise the terminal bell. There is no sound for your own messages or for messages in the chat you currently have open.
48
+
49
+ ## Scripts (development)
50
+
51
+ | Command | Description |
52
+ | ------- | ----------- |
53
+ | `npm start` | Run the TUI |
54
+ | `npm run start:resize` | Run with `WA_TUI_RESIZE=1` |
55
+
56
+ ## Publishing
57
+
58
+ This package lists only the `bin`, `src`, and `README.md` files when published (`files` field in `package.json`). To try a pack locally:
59
+
60
+ ```bash
61
+ npm pack
62
+ tar -tzvf gtchakama-wa-tui-*.tgz
63
+ ```
64
+
65
+ Then:
66
+
67
+ ```bash
68
+ npm publish --access public
69
+ ```
70
+
71
+ Scoped packages must use `--access public` for a free public listing on the npm registry.
72
+
73
+ ## Disclaimer
74
+
75
+ WhatsApp’s terms of service apply to any client you use. This project is an unofficial interface; use it at your own risk.
76
+
77
+ ## License
78
+
79
+ ISC
package/bin/wa-tui.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('../src/index.js');
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@gtchakama/wa-tui",
3
+ "version": "1.0.0",
4
+ "description": "Terminal UI for WhatsApp Web (blessed + whatsapp-web.js)",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "wa-tui": "bin/wa-tui.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "src",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "start": "node src/index.js",
16
+ "start:resize": "WA_TUI_RESIZE=1 node src/index.js",
17
+ "test": "echo \"Error: no test specified\" && exit 1"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/gtchakama/wa-tui.git"
22
+ },
23
+ "keywords": [
24
+ "whatsapp",
25
+ "whatsapp-web",
26
+ "tui",
27
+ "terminal",
28
+ "cli",
29
+ "blessed",
30
+ "chat"
31
+ ],
32
+ "author": "gtchakama",
33
+ "license": "ISC",
34
+ "type": "commonjs",
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/gtchakama/wa-tui/issues"
40
+ },
41
+ "homepage": "https://github.com/gtchakama/wa-tui#readme",
42
+ "dependencies": {
43
+ "chromium-bidi": "^15.0.0",
44
+ "neo-blessed": "^0.2.0",
45
+ "puppeteer-core": "^24.40.0",
46
+ "qrcode-terminal": "^0.12.0",
47
+ "whatsapp-web.js": "^1.34.6"
48
+ }
49
+ }
@@ -0,0 +1,87 @@
1
+ /** Named colour palettes for the TUI (hex strings, blessed-safe). Foreground-only — terminal background comes from the host (e.g. VS Code theme). */
2
+
3
+ const PALETTES = {
4
+ ocean: {
5
+ label: 'Ocean (default)',
6
+ fg: '#68C5DB',
7
+ fgDim: '#448FA3',
8
+ accent: '#0197F6',
9
+ selfMsg: '#68C5DB',
10
+ peerMsg: '#448FA3',
11
+ error: '#D7263D',
12
+ unread: '#D7263D'
13
+ },
14
+ matrix: {
15
+ label: 'Matrix',
16
+ fg: '#3dff7a',
17
+ fgDim: '#2a8f4a',
18
+ accent: '#00ff66',
19
+ selfMsg: '#7dff9a',
20
+ peerMsg: '#5fcc7a',
21
+ error: '#ff3333',
22
+ unread: '#ff4444'
23
+ },
24
+ amber: {
25
+ label: 'Amber terminal',
26
+ fg: '#eebb6d',
27
+ fgDim: '#9a7a4a',
28
+ accent: '#ffb020',
29
+ selfMsg: '#ffcc77',
30
+ peerMsg: '#c9a060',
31
+ error: '#e05040',
32
+ unread: '#ff6644'
33
+ },
34
+ nord: {
35
+ label: 'Nord frost',
36
+ fg: '#eceff4',
37
+ fgDim: '#88c0d0',
38
+ accent: '#81a1c1',
39
+ selfMsg: '#8fbcbb',
40
+ peerMsg: '#d8dee9',
41
+ error: '#bf616a',
42
+ unread: '#bf616a'
43
+ },
44
+ paper: {
45
+ label: 'Paper (light)',
46
+ fg: '#2c2824',
47
+ fgDim: '#6b6560',
48
+ accent: '#2563eb',
49
+ selfMsg: '#1d6b4a',
50
+ peerMsg: '#4a5568',
51
+ error: '#b91c1c',
52
+ unread: '#b91c1c'
53
+ }
54
+ };
55
+
56
+ /** Stable order in the settings picker. */
57
+ const PALETTE_ORDER = ['ocean', 'matrix', 'amber', 'nord', 'paper'];
58
+
59
+ const DEFAULT_PALETTE_ID = 'ocean';
60
+
61
+ function normalizePaletteId(id) {
62
+ if (id && typeof id === 'string' && PALETTES[id]) return id;
63
+ return DEFAULT_PALETTE_ID;
64
+ }
65
+
66
+ function buildTheme(paletteId) {
67
+ const id = normalizePaletteId(paletteId);
68
+ const p = PALETTES[id];
69
+ return {
70
+ paletteId: id,
71
+ fg: p.fg,
72
+ fgDim: p.fgDim,
73
+ accent: p.accent,
74
+ selfMsg: p.selfMsg,
75
+ peerMsg: p.peerMsg,
76
+ error: p.error,
77
+ unread: p.unread
78
+ };
79
+ }
80
+
81
+ module.exports = {
82
+ PALETTES,
83
+ PALETTE_ORDER,
84
+ DEFAULT_PALETTE_ID,
85
+ normalizePaletteId,
86
+ buildTheme
87
+ };
@@ -0,0 +1,35 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ const SETTINGS_DIR = path.join(os.homedir(), '.wa-tui');
6
+ const SETTINGS_PATH = path.join(SETTINGS_DIR, 'settings.json');
7
+
8
+ function loadSettings() {
9
+ try {
10
+ const raw = fs.readFileSync(SETTINGS_PATH, 'utf8');
11
+ const data = JSON.parse(raw);
12
+ return data && typeof data === 'object' ? data : {};
13
+ } catch {
14
+ return {};
15
+ }
16
+ }
17
+
18
+ function saveSettings(partial) {
19
+ try {
20
+ fs.mkdirSync(SETTINGS_DIR, { recursive: true });
21
+ const prev = loadSettings();
22
+ const next = { ...prev, ...partial };
23
+ fs.writeFileSync(SETTINGS_PATH, JSON.stringify(next, null, 2), 'utf8');
24
+ return next;
25
+ } catch (e) {
26
+ console.error('wa-tui: could not save settings', e.message);
27
+ return loadSettings();
28
+ }
29
+ }
30
+
31
+ module.exports = {
32
+ SETTINGS_PATH,
33
+ loadSettings,
34
+ saveSettings
35
+ };
package/src/index.js ADDED
@@ -0,0 +1,26 @@
1
+ const waService = require('./whatsapp/service');
2
+ const renderer = require('./ui/renderer');
3
+
4
+ async function main() {
5
+ renderer.init();
6
+
7
+ await waService.initialize(
8
+ // onQr
9
+ (qr) => {
10
+ renderer.showQr(qr);
11
+ },
12
+ // onReady
13
+ () => {
14
+ renderer.handleReady();
15
+ },
16
+ // onAuth
17
+ () => {
18
+ console.log('Authenticated!');
19
+ }
20
+ );
21
+ }
22
+
23
+ main().catch(err => {
24
+ console.error('Fatal Error:', err);
25
+ process.exit(1);
26
+ });