wtt-connect 0.2.53 → 0.2.54
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/package.json +1 -1
- package/src/terminal-session.js +92 -7
package/package.json
CHANGED
package/src/terminal-session.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
5
|
import { createRequire } from 'node:module';
|
|
5
6
|
import { log } from './logger.js';
|
|
6
7
|
|
|
7
8
|
const require = createRequire(import.meta.url);
|
|
9
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
8
10
|
let nodePty = null;
|
|
11
|
+
let nodePtyPackageJson = null;
|
|
9
12
|
|
|
10
13
|
export class TerminalSessionManager {
|
|
11
14
|
constructor(config, sendJson) {
|
|
@@ -31,8 +34,8 @@ export class TerminalSessionManager {
|
|
|
31
34
|
const rows = clampInt(msg.rows, 10, 80, 28);
|
|
32
35
|
|
|
33
36
|
try {
|
|
34
|
-
ensureNodePtyHelperExecutable();
|
|
35
37
|
const pty = await loadNodePty();
|
|
38
|
+
ensureNodePtyHelperExecutable();
|
|
36
39
|
const proc = pty.spawn(shell, [], {
|
|
37
40
|
name: 'xterm-256color',
|
|
38
41
|
cols,
|
|
@@ -122,12 +125,24 @@ export class TerminalSessionManager {
|
|
|
122
125
|
|
|
123
126
|
async function loadNodePty() {
|
|
124
127
|
if (nodePty) return nodePty;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
const errors = [];
|
|
129
|
+
for (const candidate of nodePtyCandidates()) {
|
|
130
|
+
try {
|
|
131
|
+
if (candidate.kind === 'require') {
|
|
132
|
+
nodePty = require(candidate.spec);
|
|
133
|
+
} else {
|
|
134
|
+
nodePty = await import(candidate.spec);
|
|
135
|
+
}
|
|
136
|
+
nodePtyPackageJson = candidate.packageJson || resolveNodePtyPackageJson(candidate.spec);
|
|
137
|
+
return nodePty.default && nodePty.default.spawn ? nodePty.default : nodePty;
|
|
138
|
+
} catch (err) {
|
|
139
|
+
errors.push(`${candidate.label}: ${err.message}`);
|
|
140
|
+
}
|
|
130
141
|
}
|
|
142
|
+
|
|
143
|
+
throw new Error(
|
|
144
|
+
`node-pty is not installed or failed to load; terminal sessions are unavailable in this runtime: ${errors.join('; ')}`,
|
|
145
|
+
);
|
|
131
146
|
}
|
|
132
147
|
|
|
133
148
|
function resolveDir(dir) {
|
|
@@ -153,7 +168,7 @@ function clampInt(value, min, max, fallback) {
|
|
|
153
168
|
function ensureNodePtyHelperExecutable() {
|
|
154
169
|
if (os.platform() !== 'darwin') return;
|
|
155
170
|
try {
|
|
156
|
-
const pkg =
|
|
171
|
+
const pkg = nodePtyPackageJson || resolveNodePtyPackageJson('node-pty');
|
|
157
172
|
const arch = os.arch() === 'arm64' ? 'arm64' : 'x64';
|
|
158
173
|
const helper = path.join(path.dirname(pkg), 'prebuilds', `darwin-${arch}`, 'spawn-helper');
|
|
159
174
|
if (fs.existsSync(helper)) fs.chmodSync(helper, 0o755);
|
|
@@ -161,3 +176,73 @@ function ensureNodePtyHelperExecutable() {
|
|
|
161
176
|
// node-pty may be source-built or installed in a different layout.
|
|
162
177
|
}
|
|
163
178
|
}
|
|
179
|
+
|
|
180
|
+
function nodePtyCandidates() {
|
|
181
|
+
const candidates = [
|
|
182
|
+
{ kind: 'import', spec: 'node-pty', label: 'default node resolution', packageJson: null },
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
for (const root of globalModuleRoots()) {
|
|
186
|
+
addNodePtyCandidate(candidates, path.join(root, 'node-pty'));
|
|
187
|
+
addNodePtyCandidate(candidates, path.join(root, '@google', 'gemini-cli', 'node_modules', 'node-pty'));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return candidates;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function addNodePtyCandidate(candidates, packageDir) {
|
|
194
|
+
const packageJson = path.join(packageDir, 'package.json');
|
|
195
|
+
if (!fs.existsSync(packageJson)) return;
|
|
196
|
+
candidates.push({
|
|
197
|
+
kind: 'require',
|
|
198
|
+
spec: packageDir,
|
|
199
|
+
label: packageDir,
|
|
200
|
+
packageJson,
|
|
201
|
+
});
|
|
202
|
+
const libIndex = path.join(packageDir, 'lib', 'index.js');
|
|
203
|
+
if (fs.existsSync(libIndex)) {
|
|
204
|
+
candidates.push({
|
|
205
|
+
kind: 'import',
|
|
206
|
+
spec: pathToFileURL(libIndex).href,
|
|
207
|
+
label: libIndex,
|
|
208
|
+
packageJson,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function globalModuleRoots() {
|
|
214
|
+
const roots = new Set();
|
|
215
|
+
const addRoot = (root) => {
|
|
216
|
+
if (root && fs.existsSync(root)) roots.add(fs.realpathSync(root));
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const localRoot = path.resolve(moduleDir, '..', '..');
|
|
220
|
+
addRoot(localRoot);
|
|
221
|
+
addRoot(path.join(process.execPath ? path.dirname(path.dirname(process.execPath)) : '', 'lib', 'node_modules'));
|
|
222
|
+
|
|
223
|
+
if (process.env.npm_config_prefix) {
|
|
224
|
+
addRoot(path.join(process.env.npm_config_prefix, 'lib', 'node_modules'));
|
|
225
|
+
}
|
|
226
|
+
if (process.env.PREFIX) {
|
|
227
|
+
addRoot(path.join(process.env.PREFIX, 'lib', 'node_modules'));
|
|
228
|
+
}
|
|
229
|
+
if (process.env.HOME) {
|
|
230
|
+
addRoot(path.join(process.env.HOME, '.local', 'lib', 'node_modules'));
|
|
231
|
+
addRoot(path.join(process.env.HOME, '.npm-global', 'lib', 'node_modules'));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return Array.from(roots);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function resolveNodePtyPackageJson(spec) {
|
|
238
|
+
try {
|
|
239
|
+
return require.resolve('node-pty/package.json');
|
|
240
|
+
} catch {
|
|
241
|
+
if (spec && spec !== 'node-pty') {
|
|
242
|
+
const packageDir = spec.endsWith('node-pty') ? spec : path.dirname(path.dirname(fileURLToPath(spec)));
|
|
243
|
+
const packageJson = path.join(packageDir, 'package.json');
|
|
244
|
+
if (fs.existsSync(packageJson)) return packageJson;
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|