@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 +13 -7
- package/README.md +9 -23
- package/lib/server/lib/getPty.js +4 -1
- package/lib/server/lib/pty-adapter.js +5 -4
- package/lib/server/lib/pty-provider.js +10 -3
- package/lib/server/lib/pty-utils-loader.js +136 -0
- package/package.json +3 -3
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.
|
|
5
|
+
## [0.9.12] - 2026-01-09
|
|
6
6
|
### Fixed
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
<img src=".github/header/header.png" width="900" />
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
|
-
---
|
|
1
|
+
## Overview
|
|
8
2
|
|
|
9
|
-
|
|
10
|
-
[](https://www.npmjs.com/package/@mmmbuto/nexuscli)
|
|
11
|
-
[](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
|
-
##
|
|
7
|
+
## Screenshots
|
|
16
8
|
|
|
17
|
-
|
|
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
|
package/lib/server/lib/getPty.js
CHANGED
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
* @version 1.1.0
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const {
|
|
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 {
|
|
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 =
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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
|
+
}
|