tabminal 1.1.21 → 1.2.4
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 +7 -8
- package/src/terminal-manager.mjs +32 -8
- package/src/terminal-session.mjs +16 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tabminal",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "A modern, persistent web terminal with multi-tab support and real-time system monitoring.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,18 +33,17 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@fontsource/monaspace-neon": "^5.2.5",
|
|
36
|
-
"@koa/router": "^15.
|
|
36
|
+
"@koa/router": "^15.3.0",
|
|
37
37
|
"@mozilla/readability": "^0.6.0",
|
|
38
|
-
"
|
|
39
|
-
"jsdom": "^27.2.0",
|
|
38
|
+
"jsdom": "^27.4.0",
|
|
40
39
|
"koa": "^3.1.1",
|
|
41
40
|
"koa-bodyparser": "^4.4.1",
|
|
42
41
|
"koa-static": "^5.0.0",
|
|
43
42
|
"node-ansiparser": "^2.2.1",
|
|
44
|
-
"node-pty": "^1.
|
|
45
|
-
"openai": "^6.
|
|
46
|
-
"utilitas": "^
|
|
47
|
-
"ws": "^8.
|
|
43
|
+
"node-pty": "^1.1.0",
|
|
44
|
+
"openai": "^6.17.0",
|
|
45
|
+
"utilitas": "^2001.1.117",
|
|
46
|
+
"ws": "^8.19.0"
|
|
48
47
|
},
|
|
49
48
|
"repository": {
|
|
50
49
|
"type": "git",
|
package/src/terminal-manager.mjs
CHANGED
|
@@ -138,14 +138,38 @@ precmd_functions+=(_tabminal_zsh_apply_prompt_marker)
|
|
|
138
138
|
const cols = restoredData ? restoredData.cols : this.lastCols;
|
|
139
139
|
const rows = restoredData ? restoredData.rows : this.lastRows;
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
141
|
+
let ptyProcess;
|
|
142
|
+
try {
|
|
143
|
+
ptyProcess = pty.spawn(shell, args, {
|
|
144
|
+
name: 'xterm-256color',
|
|
145
|
+
cols: cols,
|
|
146
|
+
rows: rows,
|
|
147
|
+
cwd: initialCwd,
|
|
148
|
+
env: env,
|
|
149
|
+
encoding: 'utf8'
|
|
150
|
+
});
|
|
151
|
+
} catch (err) {
|
|
152
|
+
const spawnInfo = {
|
|
153
|
+
shell,
|
|
154
|
+
args,
|
|
155
|
+
cwd: initialCwd,
|
|
156
|
+
cols,
|
|
157
|
+
rows,
|
|
158
|
+
env: {
|
|
159
|
+
SHELL: env.SHELL,
|
|
160
|
+
TERM: env.TERM,
|
|
161
|
+
PATH: env.PATH,
|
|
162
|
+
HOME: env.HOME
|
|
163
|
+
},
|
|
164
|
+
error: {
|
|
165
|
+
message: err?.message,
|
|
166
|
+
code: err?.code,
|
|
167
|
+
errno: err?.errno
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
console.error('[Manager] Failed to spawn PTY', spawnInfo);
|
|
171
|
+
throw err;
|
|
172
|
+
}
|
|
149
173
|
|
|
150
174
|
const session = new TerminalSession(ptyProcess, {
|
|
151
175
|
id,
|
package/src/terminal-session.mjs
CHANGED
|
@@ -287,6 +287,10 @@ export class TerminalSession {
|
|
|
287
287
|
this.write(data);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
_isAiEnabled() {
|
|
291
|
+
return Boolean(config.openrouterKey && String(config.openrouterKey).trim());
|
|
292
|
+
}
|
|
293
|
+
|
|
290
294
|
write(data) {
|
|
291
295
|
if (typeof data === 'string' && data.startsWith('\x1b')) {
|
|
292
296
|
this.pty.write(data);
|
|
@@ -300,6 +304,7 @@ export class TerminalSession {
|
|
|
300
304
|
}
|
|
301
305
|
|
|
302
306
|
let startIndex = 0;
|
|
307
|
+
const aiEnabled = this._isAiEnabled();
|
|
303
308
|
for (let i = 0; i < data.length; i++) {
|
|
304
309
|
const char = data[i];
|
|
305
310
|
|
|
@@ -307,14 +312,16 @@ export class TerminalSession {
|
|
|
307
312
|
if (char === '\r') {
|
|
308
313
|
// Smart detection for AI command (#)
|
|
309
314
|
// Ignore prefix if it only contains whitespace or terminal control artifacts (CPR)
|
|
310
|
-
const idx = this.inputBuffer.indexOf('#');
|
|
311
315
|
let line = null;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
316
|
+
if (aiEnabled) {
|
|
317
|
+
const idx = this.inputBuffer.indexOf('#');
|
|
318
|
+
|
|
319
|
+
if (idx !== -1) {
|
|
320
|
+
const prefix = this.inputBuffer.substring(0, idx);
|
|
321
|
+
// Allow whitespace, ESC, [, digits, ;, R (typical CPR response)
|
|
322
|
+
if (/^[\s\x1b\[\d;R]*$/.test(prefix)) {
|
|
323
|
+
line = this.inputBuffer.substring(idx);
|
|
324
|
+
}
|
|
318
325
|
}
|
|
319
326
|
}
|
|
320
327
|
|
|
@@ -533,11 +540,11 @@ export class TerminalSession {
|
|
|
533
540
|
this.captureStartedAt = null;
|
|
534
541
|
|
|
535
542
|
// Auto-Fix: If command failed, ask AI for help
|
|
536
|
-
if (exitCode !== 0 && entry.command) {
|
|
543
|
+
if (exitCode !== 0 && entry.command && this._isAiEnabled()) {
|
|
537
544
|
// Don't trigger on simple interruptions (SIGINT=130) or common non-errors?
|
|
538
545
|
// 130 = Ctrl+C. Usually user intention.
|
|
539
546
|
if (exitCode !== 130) {
|
|
540
|
-
this._handleAiCommand('The previous command failed. Please analyze the error in the history and provide a fix.', { isAutoFix: true });
|
|
547
|
+
this._handleAiCommand('The previous command failed. Please analyze the error in the history and provide a fix. Keep your answers concise and accurate. Resolve the issue clearly and provide the reasoning while avoiding lengthy elaborations.', { isAutoFix: true });
|
|
541
548
|
}
|
|
542
549
|
}
|
|
543
550
|
}
|