@mmmbuto/nexuscli 0.9.11 → 0.9.12

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
@@ -2,14 +2,12 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## [0.9.10] - 2026-01-09
5
+ ## [0.9.12] - 2026-01-09
6
6
  ### Fixed
7
- - Added PTY dependency check in postinstall to verify node-pty installation
8
- - Added pty-termux-utils verification to ensure .cjs files are built
9
- - Platform detection now installs correct PTY provider:
10
- - `@mmmbuto/node-pty-android-arm64` for Termux
11
- - `@lydell/node-pty-linux-arm64` for Linux ARM64
12
- - Provides helpful error messages when PTY dependencies are missing
7
+ - Guard PTY utils loading to avoid hard crash when dependency is broken or missing
8
+ - Safer fallback adapter when native PTY stack is unavailable
9
+ - Updated @mmmbuto/pty-termux-utils to ^1.1.3
10
+
13
11
  ## [0.9.11] - 2026-01-09
14
12
  ### Fixed
15
13
  - Added PTY dependency verification in postinstall
@@ -18,6 +16,14 @@ All notable changes to this project will be documented in this file.
18
16
  - All PTY dependencies now verified during npm install
19
17
  - Updated @mmmbuto/pty-termux-utils to ^1.1.2
20
18
 
19
+ ## [0.9.10] - 2026-01-09
20
+ ### Fixed
21
+ - Added PTY dependency check in postinstall to verify node-pty installation
22
+ - Added pty-termux-utils verification to ensure .cjs files are built
23
+ - Platform detection now installs correct PTY provider:
24
+ - `@mmmbuto/node-pty-android-arm64` for Termux
25
+ - `@lydell/node-pty-linux-arm64` for Linux ARM64
26
+ - Provides helpful error messages when PTY dependencies are missing
21
27
 
22
28
 
23
29
  ## [0.9.9] - 2026-01-01
package/README.md CHANGED
@@ -1,20 +1,15 @@
1
- # NexusCLI — AI Terminal Cockpit
2
-
3
- <p align="center">
4
- <img src=".github/header/header.png" width="900" />
5
- </p>
6
-
7
- ---
1
+ ## Overview
8
2
 
9
- [![npm](https://img.shields.io/npm/v/@mmmbuto/nexuscli?style=flat-square&logo=npm)](https://www.npmjs.com/package/@mmmbuto/nexuscli)
10
- [![downloads](https://img.shields.io/npm/dt/@mmmbuto/nexuscli?style=flat-square)](https://www.npmjs.com/package/@mmmbuto/nexuscli)
11
- [![ko-fi](https://img.shields.io/badge/☕_Support-Ko--fi-FF5E5B?style=flat-square&logo=ko-fi)](https://ko-fi.com/dionanos)
3
+ NexusCLI is a lightweight, Termux-first AI cockpit that orchestrates Claude Code, Codex CLI, Gemini CLI, and Qwen Code CLI from a single web/terminal UI. It supports live streaming, interrupts, session resume, workspace isolation, and remote voice input with auto HTTPS setup.
12
4
 
13
5
  ---
14
6
 
15
- ## Overview
7
+ ## Screenshots
16
8
 
17
- NexusCLI is a lightweight, Termux-first AI cockpit that orchestrates Claude Code, Codex CLI, Gemini CLI, and Qwen Code CLI from a single web/terminal UI. It supports live streaming, interrupts, session resume, workspace isolation, and remote voice input with auto HTTPS setup.
9
+ <p align="center">
10
+ <img src="docs/assets/screenshots/nexuscli-multilang-preview.png" width="45%" />
11
+ <img src="docs/assets/screenshots/nexuscli-mobile-glm.png" width="45%" />
12
+ </p>
18
13
 
19
14
  ---
20
15
 
@@ -46,20 +41,11 @@ NexusCLI is a lightweight, Termux-first AI cockpit that orchestrates Claude Code
46
41
 
47
42
  ---
48
43
 
49
- ## Screenshots
50
-
51
- <p align="center">
52
- <img src="docs/assets/screenshots/nexuscli-multilang-preview.png" width="45%" />
53
- <img src="docs/assets/screenshots/nexuscli-mobile-glm.png" width="45%" />
54
- </p>
55
-
56
- ---
57
-
58
44
  ## Install
59
45
 
60
46
  ```bash
61
47
  # From npm
62
- npm install -g @mmmbuto/nexuscli
48
+ npm install -g @mmmbuto/nexuscli@0.9.12
63
49
 
64
50
  # From GitHub
65
51
  npm install -g github:DioNanos/nexuscli
@@ -69,7 +55,7 @@ npm install -g github:DioNanos/nexuscli
69
55
 
70
56
  ```bash
71
57
  # Latest (default)
72
- npm install -g @mmmbuto/nexuscli
58
+ npm install -g @mmmbuto/nexuscli@0.9.12
73
59
 
74
60
  # Stable channel (pinned)
75
61
  npm install -g @mmmbuto/nexuscli@stable
@@ -10,7 +10,10 @@
10
10
  * @version 1.1.0
11
11
  */
12
12
 
13
- const { getPty: getSharedPty, logDebug } = require('@mmmbuto/pty-termux-utils');
13
+ const { getPtyFn, getLogDebugFn } = require('./pty-utils-loader');
14
+
15
+ const getSharedPty = getPtyFn();
16
+ const logDebug = getLogDebugFn();
14
17
  const tryRequire = (moduleName) => {
15
18
  try {
16
19
  require(moduleName);
@@ -6,7 +6,9 @@
6
6
  * @version 1.0.0
7
7
  */
8
8
 
9
- const { createFallbackAdapter } = require('@mmmbuto/pty-termux-utils');
9
+ const { getPtyFn, getFallbackAdapter } = require('./pty-utils-loader');
10
+
11
+ const getSharedPty = getPtyFn();
10
12
  const tryRequire = (moduleName) => {
11
13
  try {
12
14
  require(moduleName);
@@ -17,7 +19,7 @@ const tryRequire = (moduleName) => {
17
19
  };
18
20
 
19
21
  // Create shared fallback adapter (always uses child_process)
20
- const fallbackAdapter = createFallbackAdapter();
22
+ const fallbackAdapter = getFallbackAdapter();
21
23
 
22
24
  // Cache for native PTY (sync access)
23
25
  let cachedNativePty = null;
@@ -31,8 +33,7 @@ async function initNativePty() {
31
33
  }
32
34
 
33
35
  try {
34
- const { getPty } = require('@mmmbuto/pty-termux-utils');
35
- cachedNativePty = await getPty();
36
+ cachedNativePty = await getSharedPty();
36
37
  return cachedNativePty;
37
38
  } catch (e) {
38
39
  cachedNativePty = false; // Error loading
@@ -6,7 +6,14 @@
6
6
  * @version 1.0.0
7
7
  */
8
8
 
9
- const { getPty: getSharedPty, createFallbackAdapter } = require('@mmmbuto/pty-termux-utils');
9
+ const {
10
+ getPtyFn,
11
+ getSpawnPtyFn,
12
+ getFallbackAdapter: getSafeFallbackAdapter
13
+ } = require('./pty-utils-loader');
14
+
15
+ const getSharedPty = getPtyFn();
16
+ const spawnPty = getSpawnPtyFn();
10
17
  const tryRequire = (moduleName) => {
11
18
  try {
12
19
  require(moduleName);
@@ -33,7 +40,7 @@ async function getPty() {
33
40
  * @returns {Object} Adapter with spawn method
34
41
  */
35
42
  function getFallbackAdapter() {
36
- return createFallbackAdapter();
43
+ return getSafeFallbackAdapter();
37
44
  }
38
45
 
39
46
  /**
@@ -52,5 +59,5 @@ module.exports = {
52
59
  getFallbackAdapter,
53
60
  isPtyAvailable,
54
61
  // Re-export from shared library
55
- spawnPty: require('@mmmbuto/pty-termux-utils').spawnPty,
62
+ spawnPty,
56
63
  };
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Safe loader for @mmmbuto/pty-termux-utils with fallback adapter.
3
+ * Prevents hard crashes if the dependency is missing or broken.
4
+ */
5
+
6
+ const { spawn } = require('child_process');
7
+
8
+ let cachedUtils;
9
+ let warned = false;
10
+
11
+ function warnOnce(error) {
12
+ if (warned) return;
13
+ warned = true;
14
+ const message = error && error.message ? error.message : String(error);
15
+ console.warn('[PTY] Failed to load @mmmbuto/pty-termux-utils. Using fallback adapter.');
16
+ console.warn(`[PTY] Reason: ${message}`);
17
+ }
18
+
19
+ function loadPtyUtils() {
20
+ if (cachedUtils !== undefined) return cachedUtils;
21
+ try {
22
+ cachedUtils = require('@mmmbuto/pty-termux-utils');
23
+ } catch (err) {
24
+ warnOnce(err);
25
+ cachedUtils = null;
26
+ }
27
+ return cachedUtils;
28
+ }
29
+
30
+ function ensurePtyInterface(proc) {
31
+ if (!proc) return proc;
32
+ if (typeof proc.onData === 'function' && typeof proc.onExit === 'function') {
33
+ return proc;
34
+ }
35
+
36
+ const hasChildStd = !!(proc.stdout || proc.stderr);
37
+ const dataHandlers = [];
38
+ const exitHandlers = [];
39
+
40
+ if (typeof proc.on === 'function' && !hasChildStd) {
41
+ proc.on('data', (data) => {
42
+ dataHandlers.forEach((fn) => fn(data));
43
+ });
44
+ proc.on('exit', (code, signal) => {
45
+ exitHandlers.forEach((fn) => fn({ exitCode: code, signal }));
46
+ });
47
+ } else {
48
+ proc.stdout?.on('data', (data) => {
49
+ dataHandlers.forEach((fn) => fn(data.toString()));
50
+ });
51
+ proc.stderr?.on('data', (data) => {
52
+ dataHandlers.forEach((fn) => fn(data.toString()));
53
+ });
54
+ proc.on?.('exit', (code, signal) => {
55
+ exitHandlers.forEach((fn) => fn({ exitCode: code ?? -1, signal }));
56
+ });
57
+ }
58
+
59
+ proc.onData = (fn) => dataHandlers.push(fn);
60
+ proc.onExit = (fn) => exitHandlers.push(fn);
61
+
62
+ if (typeof proc.onError !== 'function' && typeof proc.on === 'function') {
63
+ proc.onError = (fn) => proc.on('error', fn);
64
+ }
65
+ if (typeof proc.write !== 'function') {
66
+ proc.write = (data) => proc.stdin?.write(data);
67
+ }
68
+ if (typeof proc.sendEsc !== 'function') {
69
+ proc.sendEsc = () => {
70
+ if (proc.stdin?.writable) {
71
+ proc.stdin.write('\x1B');
72
+ return true;
73
+ }
74
+ return false;
75
+ };
76
+ }
77
+ if (typeof proc.resize !== 'function') {
78
+ proc.resize = () => {};
79
+ }
80
+ if (typeof proc.kill !== 'function' && proc.process?.kill) {
81
+ proc.kill = (signal = 'SIGTERM') => proc.process.kill(signal);
82
+ }
83
+ if (proc.pid == null && proc.process?.pid != null) {
84
+ proc.pid = proc.process.pid;
85
+ }
86
+
87
+ return proc;
88
+ }
89
+
90
+ function createLocalFallbackAdapter() {
91
+ return {
92
+ spawn: (file, args, options = {}) => {
93
+ const child = spawn(file, args, {
94
+ cwd: options.cwd,
95
+ env: options.env ? { ...process.env, ...options.env } : undefined,
96
+ });
97
+ return ensurePtyInterface(child);
98
+ }
99
+ };
100
+ }
101
+
102
+ function getPtyFn() {
103
+ const utils = loadPtyUtils();
104
+ return utils?.getPty ? utils.getPty : async () => null;
105
+ }
106
+
107
+ function getSpawnPtyFn() {
108
+ const utils = loadPtyUtils();
109
+ return utils?.spawnPty
110
+ ? utils.spawnPty
111
+ : async () => { throw new Error('Native PTY utilities unavailable'); };
112
+ }
113
+
114
+ function getLogDebugFn() {
115
+ const utils = loadPtyUtils();
116
+ return utils?.logDebug ? utils.logDebug : () => {};
117
+ }
118
+
119
+ function getFallbackAdapter() {
120
+ const utils = loadPtyUtils();
121
+ if (utils?.createFallbackAdapter) {
122
+ const base = utils.createFallbackAdapter();
123
+ return {
124
+ spawn: (...args) => ensurePtyInterface(base.spawn(...args))
125
+ };
126
+ }
127
+ return createLocalFallbackAdapter();
128
+ }
129
+
130
+ module.exports = {
131
+ getPtyFn,
132
+ getSpawnPtyFn,
133
+ getLogDebugFn,
134
+ getFallbackAdapter,
135
+ ensurePtyInterface
136
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmmbuto/nexuscli",
3
- "version": "0.9.11",
3
+ "version": "0.9.12",
4
4
  "description": "NexusCLI - TRI CLI Control Plane (Claude/Codex/Gemini/Qwen)",
5
5
  "main": "lib/server/server.js",
6
6
  "bin": {
@@ -59,7 +59,7 @@
59
59
  "x64"
60
60
  ],
61
61
  "dependencies": {
62
- "@mmmbuto/pty-termux-utils": "^1.1.2",
62
+ "@mmmbuto/pty-termux-utils": "^1.1.3",
63
63
  "bcryptjs": "^3.0.3",
64
64
  "chalk": "^4.1.2",
65
65
  "commander": "^12.1.0",
@@ -81,4 +81,4 @@
81
81
  "optionalDependencies": {
82
82
  "@mmmbuto/node-pty-android-arm64": "~1.1.0"
83
83
  }
84
- }
84
+ }