@monotykamary/localterm-server 0.1.0 → 0.1.1
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/dist/constants.d.ts +0 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -4
- package/dist/constants.js.map +1 -1
- package/dist/session.d.ts +2 -22
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +45 -95
- package/dist/session.js.map +1 -1
- package/dist/utils/parse-alt-screen.d.ts +2 -0
- package/dist/utils/parse-alt-screen.d.ts.map +1 -0
- package/dist/utils/parse-alt-screen.js +37 -0
- package/dist/utils/parse-alt-screen.js.map +1 -0
- package/dist/utils/parse-osc-title.d.ts +2 -0
- package/dist/utils/parse-osc-title.d.ts.map +1 -0
- package/dist/utils/parse-osc-title.js +44 -0
- package/dist/utils/parse-osc-title.js.map +1 -0
- package/package.json +1 -1
package/dist/constants.d.ts
CHANGED
|
@@ -5,10 +5,6 @@ export declare const DEFAULT_ROWS = 32;
|
|
|
5
5
|
export declare const DEFAULT_SHELL_FALLBACK = "/bin/sh";
|
|
6
6
|
export declare const TERM_TYPE = "xterm-256color";
|
|
7
7
|
export declare const COLORTERM_VALUE = "truecolor";
|
|
8
|
-
export declare const TITLE_POLL_INTERVAL_MS = 500;
|
|
9
|
-
export declare const CWD_RESOLVE_TIMEOUT_MS = 250;
|
|
10
|
-
export declare const CWD_RESOLVE_BACKOFF_MS = 30000;
|
|
11
|
-
export declare const CWD_RESOLVE_COOLDOWN_MS = 5000;
|
|
12
8
|
export declare const TITLE_MAX_PATH_SEGMENTS = 1;
|
|
13
9
|
/**
|
|
14
10
|
* Strip terminal-emulator identity env vars inherited from the daemon's parent.
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,OAAO,CAAC;AACjC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,OAAO,CAAC;AACjC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,UAe5B,CAAC;AAEF,eAAO,MAAM,eAAe,QAAY,CAAC;AACzC,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAChD,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,gBAAgB,QAAW,CAAC;AACzC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAO1C,eAAO,MAAM,kCAAkC,QAAkB,CAAC;AAClE,eAAO,MAAM,kCAAkC,QAAkB,CAAC;AAClE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C,eAAO,MAAM,+BAA+B,QAAmB,CAAC;AAOhE,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAK9C,eAAO,MAAM,oBAAoB,OAAQ,CAAC;AAE1C,eAAO,MAAM,cAAc,aAMzB,CAAC;AAEH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAC9C,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,yBAAyB,OAAO,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -5,10 +5,6 @@ export const DEFAULT_ROWS = 32;
|
|
|
5
5
|
export const DEFAULT_SHELL_FALLBACK = "/bin/sh";
|
|
6
6
|
export const TERM_TYPE = "xterm-256color";
|
|
7
7
|
export const COLORTERM_VALUE = "truecolor";
|
|
8
|
-
export const TITLE_POLL_INTERVAL_MS = 500;
|
|
9
|
-
export const CWD_RESOLVE_TIMEOUT_MS = 250;
|
|
10
|
-
export const CWD_RESOLVE_BACKOFF_MS = 30_000;
|
|
11
|
-
export const CWD_RESOLVE_COOLDOWN_MS = 5_000;
|
|
12
8
|
export const TITLE_MAX_PATH_SEGMENTS = 1;
|
|
13
9
|
/**
|
|
14
10
|
* Strip terminal-emulator identity env vars inherited from the daemon's parent.
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AACtC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAC/B,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAEhD,MAAM,CAAC,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAE3C,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AACjC,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AACtC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAC/B,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAEhD,MAAM,CAAC,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAE3C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,wBAAwB;IACxB,cAAc;IACd,sBAAsB;IACtB,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,iBAAiB;IACjB,WAAW;IACX,YAAY;IACZ,eAAe;IACf,uBAAuB;IACvB,iBAAiB;IACjB,kBAAkB;IAClB,uBAAuB;CACxB,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,CAAC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC;AACzC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAC7B,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAC7B,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAClE,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAClE,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAC5C,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhE,8EAA8E;AAC9E,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAC9E,sEAAsE;AACtE,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAC/C,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAC9C,yEAAyE;AACzE,8EAA8E;AAC9E,2EAA2E;AAC3E,8BAA8B;AAC9B,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAE1C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IACpC,WAAW;IACX,WAAW;IACX,KAAK;IACL,OAAO;IACP,iBAAiB;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AACrC,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC"}
|
package/dist/session.d.ts
CHANGED
|
@@ -17,12 +17,9 @@ export declare class Session extends EventEmitter<SessionEvents> {
|
|
|
17
17
|
private currentRows;
|
|
18
18
|
private exited;
|
|
19
19
|
private paused;
|
|
20
|
-
private titlePollTimer;
|
|
21
20
|
private lastEmittedTitle;
|
|
22
21
|
private lastEmittedCwd;
|
|
23
22
|
private lastEmittedForeground;
|
|
24
|
-
private nextCwdResolveAt;
|
|
25
|
-
private osc7Detected;
|
|
26
23
|
constructor(input: SpawnPtyInput);
|
|
27
24
|
get pid(): number;
|
|
28
25
|
get shellBaseName(): string;
|
|
@@ -31,31 +28,14 @@ export declare class Session extends EventEmitter<SessionEvents> {
|
|
|
31
28
|
get isExited(): boolean;
|
|
32
29
|
get isPaused(): boolean;
|
|
33
30
|
write(data: string): void;
|
|
34
|
-
/**
|
|
35
|
-
* Stop reading data from the PTY. node-pty buffers further child output in
|
|
36
|
-
* the OS pipe; once that fills, write() in the child process blocks, which
|
|
37
|
-
* propagates flow control all the way back to the producing program (e.g.
|
|
38
|
-
* `cat large_file`). Used by the WS layer to pause heavy output streams
|
|
39
|
-
* when the outbound socket buffer is filling, so we don't have to kill the
|
|
40
|
-
* connection just to recover memory.
|
|
41
|
-
*/
|
|
42
31
|
pause(): void;
|
|
43
|
-
/**
|
|
44
|
-
* Reverse of `pause()`. Buffered child output starts flowing again and the
|
|
45
|
-
* child process unblocks if it was stuck in write().
|
|
46
|
-
*/
|
|
47
32
|
resume(): void;
|
|
48
33
|
resize(cols: number, rows: number): void;
|
|
49
34
|
kill(signal?: NodeJS.Signals): void;
|
|
50
35
|
dispose(): void;
|
|
36
|
+
private emitInitialMetadata;
|
|
51
37
|
private onPtyOutput;
|
|
52
|
-
private
|
|
53
|
-
private runTitlePoll;
|
|
54
|
-
private foregroundProcess;
|
|
55
|
-
private pollForeground;
|
|
56
|
-
private computeTitle;
|
|
57
|
-
private resolveLiveCwd;
|
|
58
|
-
private stopTitlePolling;
|
|
38
|
+
private inferForegroundProcess;
|
|
59
39
|
}
|
|
60
40
|
export {};
|
|
61
41
|
//# sourceMappingURL=session.d.ts.map
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkB3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,UAAU,aAAa;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACnB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACtC;AAED,qBAAa,OAAQ,SAAQ,YAAY,CAAC,aAAa,CAAC;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAO;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,qBAAqB,CAAwC;gBAEzD,KAAK,EAAE,aAAa;IA6ChC,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzB,KAAK,IAAI,IAAI;IAUb,MAAM,IAAI,IAAI;IAUd,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAaxC,IAAI,CAAC,MAAM,GAAE,MAAM,CAAC,OAAkB,GAAG,IAAI;IAS7C,OAAO,IAAI,IAAI;IAMf,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,WAAW;IAkCnB,OAAO,CAAC,sBAAsB;CAI/B"}
|
package/dist/session.js
CHANGED
|
@@ -2,17 +2,18 @@ import { EventEmitter } from "node:events";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { spawn } from "node-pty";
|
|
5
|
-
import { COLORTERM_VALUE,
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
5
|
+
import { COLORTERM_VALUE, DEFAULT_COLS, DEFAULT_ROWS, PTY_ENV_DENYLIST, TERM_TYPE, } from "./constants.js";
|
|
6
|
+
// Titles are emitted on a dedicated `title` event so they travel as a separate
|
|
7
|
+
// WebSocket frame. We deliberately do NOT splice OSC sequences into the PTY
|
|
8
|
+
// output stream — doing so corrupts in-flight escape sequences from modern
|
|
9
|
+
// TUIs (e.g. Cursor Agent / Claude Code use DECSET 2026 synchronized output
|
|
10
|
+
// mode and any byte landing inside that frame breaks the parser state).
|
|
11
11
|
import { ensureSpawnHelperExecutable } from "./ensure-spawn-helper-executable.js";
|
|
12
12
|
import { getDefaultShell } from "./default-shell.js";
|
|
13
13
|
import { formatWorkingDirectoryTitle } from "./utils/format-working-directory-title.js";
|
|
14
|
+
import { parseAltScreenFromChunk } from "./utils/parse-alt-screen.js";
|
|
14
15
|
import { parseOsc7FromChunk } from "./utils/parse-osc7.js";
|
|
15
|
-
import {
|
|
16
|
+
import { parseOscTitleFromChunk } from "./utils/parse-osc-title.js";
|
|
16
17
|
export class Session extends EventEmitter {
|
|
17
18
|
shell;
|
|
18
19
|
cwd;
|
|
@@ -23,15 +24,9 @@ export class Session extends EventEmitter {
|
|
|
23
24
|
currentRows;
|
|
24
25
|
exited = false;
|
|
25
26
|
paused = false;
|
|
26
|
-
titlePollTimer = null;
|
|
27
27
|
lastEmittedTitle = "";
|
|
28
28
|
lastEmittedCwd = "";
|
|
29
29
|
lastEmittedForeground = undefined;
|
|
30
|
-
nextCwdResolveAt = 0;
|
|
31
|
-
// Set to true once OSC 7 is observed from the PTY output. Once the shell
|
|
32
|
-
// advertises its working directory via OSC 7 we stop polling lsof entirely —
|
|
33
|
-
// the stream is the source of truth and lsof is just an expensive fallback.
|
|
34
|
-
osc7Detected = false;
|
|
35
30
|
constructor(input) {
|
|
36
31
|
super();
|
|
37
32
|
ensureSpawnHelperExecutable();
|
|
@@ -69,10 +64,9 @@ export class Session extends EventEmitter {
|
|
|
69
64
|
});
|
|
70
65
|
this.pty.onExit(({ exitCode }) => {
|
|
71
66
|
this.exited = true;
|
|
72
|
-
this.stopTitlePolling();
|
|
73
67
|
this.emit("exit", exitCode);
|
|
74
68
|
});
|
|
75
|
-
this.
|
|
69
|
+
this.emitInitialMetadata();
|
|
76
70
|
}
|
|
77
71
|
get pid() {
|
|
78
72
|
return this.pty.pid;
|
|
@@ -97,14 +91,6 @@ export class Session extends EventEmitter {
|
|
|
97
91
|
return;
|
|
98
92
|
this.pty.write(data);
|
|
99
93
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Stop reading data from the PTY. node-pty buffers further child output in
|
|
102
|
-
* the OS pipe; once that fills, write() in the child process blocks, which
|
|
103
|
-
* propagates flow control all the way back to the producing program (e.g.
|
|
104
|
-
* `cat large_file`). Used by the WS layer to pause heavy output streams
|
|
105
|
-
* when the outbound socket buffer is filling, so we don't have to kill the
|
|
106
|
-
* connection just to recover memory.
|
|
107
|
-
*/
|
|
108
94
|
pause() {
|
|
109
95
|
if (this.exited || this.paused)
|
|
110
96
|
return;
|
|
@@ -116,10 +102,6 @@ export class Session extends EventEmitter {
|
|
|
116
102
|
/* PTY may have died between the exited check and the call */
|
|
117
103
|
}
|
|
118
104
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Reverse of `pause()`. Buffered child output starts flowing again and the
|
|
121
|
-
* child process unblocks if it was stuck in write().
|
|
122
|
-
*/
|
|
123
105
|
resume() {
|
|
124
106
|
if (this.exited || !this.paused)
|
|
125
107
|
return;
|
|
@@ -160,86 +142,54 @@ export class Session extends EventEmitter {
|
|
|
160
142
|
dispose() {
|
|
161
143
|
this.kill();
|
|
162
144
|
this.exited = true;
|
|
163
|
-
this.stopTitlePolling();
|
|
164
145
|
this.removeAllListeners();
|
|
165
146
|
}
|
|
147
|
+
emitInitialMetadata() {
|
|
148
|
+
const initialTitle = formatWorkingDirectoryTitle(this.cwd);
|
|
149
|
+
if (initialTitle) {
|
|
150
|
+
this.lastEmittedTitle = initialTitle;
|
|
151
|
+
this.emit("title", initialTitle);
|
|
152
|
+
}
|
|
153
|
+
this.lastEmittedCwd = this.cwd;
|
|
154
|
+
this.emit("cwd", this.cwd);
|
|
155
|
+
this.lastEmittedForeground = null;
|
|
156
|
+
this.emit("foreground", null);
|
|
157
|
+
}
|
|
166
158
|
onPtyOutput(data) {
|
|
167
159
|
const osc7Path = parseOsc7FromChunk(data);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
160
|
+
let cwdChanged = false;
|
|
161
|
+
if (osc7Path && osc7Path !== this.lastEmittedCwd) {
|
|
162
|
+
this.lastEmittedCwd = osc7Path;
|
|
163
|
+
this.emit("cwd", osc7Path);
|
|
164
|
+
cwdChanged = true;
|
|
174
165
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}, delayMs);
|
|
182
|
-
this.titlePollTimer.unref();
|
|
183
|
-
}
|
|
184
|
-
async runTitlePoll() {
|
|
185
|
-
if (this.exited)
|
|
186
|
-
return;
|
|
187
|
-
try {
|
|
188
|
-
// Once the shell advertises its CWD via OSC 7 we skip lsof — the stream
|
|
189
|
-
// is authoritative and lsof is expensive (spawns a child process that
|
|
190
|
-
// triggers syspolicyd validation on every call).
|
|
191
|
-
const liveCwd = this.osc7Detected ? this.lastEmittedCwd || null : await this.resolveLiveCwd();
|
|
192
|
-
if (this.exited)
|
|
193
|
-
return;
|
|
194
|
-
if (!this.osc7Detected && liveCwd && liveCwd !== this.lastEmittedCwd) {
|
|
195
|
-
this.lastEmittedCwd = liveCwd;
|
|
196
|
-
this.emit("cwd", liveCwd);
|
|
197
|
-
}
|
|
198
|
-
const nextTitle = this.computeTitle(this.osc7Detected ? this.lastEmittedCwd || this.cwd : (liveCwd ?? this.cwd));
|
|
199
|
-
if (nextTitle && nextTitle !== this.lastEmittedTitle) {
|
|
200
|
-
this.lastEmittedTitle = nextTitle;
|
|
201
|
-
this.emit("title", nextTitle);
|
|
166
|
+
const oscTitle = parseOscTitleFromChunk(data);
|
|
167
|
+
if (oscTitle) {
|
|
168
|
+
const trimmed = oscTitle.trim();
|
|
169
|
+
if (trimmed && trimmed !== this.lastEmittedTitle) {
|
|
170
|
+
this.lastEmittedTitle = trimmed;
|
|
171
|
+
this.emit("title", trimmed);
|
|
202
172
|
}
|
|
203
|
-
this.pollForeground();
|
|
204
173
|
}
|
|
205
|
-
|
|
206
|
-
|
|
174
|
+
else if (cwdChanged) {
|
|
175
|
+
const cwdTitle = formatWorkingDirectoryTitle(this.lastEmittedCwd);
|
|
176
|
+
if (cwdTitle && cwdTitle !== this.lastEmittedTitle) {
|
|
177
|
+
this.lastEmittedTitle = cwdTitle;
|
|
178
|
+
this.emit("title", cwdTitle);
|
|
179
|
+
}
|
|
207
180
|
}
|
|
208
|
-
|
|
209
|
-
|
|
181
|
+
const altScreen = parseAltScreenFromChunk(data);
|
|
182
|
+
if (altScreen !== null) {
|
|
183
|
+
const nextForeground = altScreen ? this.inferForegroundProcess() : null;
|
|
184
|
+
if (nextForeground !== this.lastEmittedForeground) {
|
|
185
|
+
this.lastEmittedForeground = nextForeground;
|
|
186
|
+
this.emit("foreground", nextForeground);
|
|
187
|
+
}
|
|
210
188
|
}
|
|
211
189
|
}
|
|
212
|
-
|
|
190
|
+
inferForegroundProcess() {
|
|
213
191
|
const raw = this.pty.process?.trim() ?? "";
|
|
214
192
|
return raw && raw !== this.shellName ? raw : null;
|
|
215
193
|
}
|
|
216
|
-
pollForeground() {
|
|
217
|
-
const next = this.foregroundProcess();
|
|
218
|
-
if (next === this.lastEmittedForeground)
|
|
219
|
-
return;
|
|
220
|
-
this.lastEmittedForeground = next;
|
|
221
|
-
this.emit("foreground", next);
|
|
222
|
-
}
|
|
223
|
-
computeTitle(liveCwd) {
|
|
224
|
-
const foreground = this.foregroundProcess();
|
|
225
|
-
if (foreground)
|
|
226
|
-
return foreground;
|
|
227
|
-
return formatWorkingDirectoryTitle(liveCwd);
|
|
228
|
-
}
|
|
229
|
-
async resolveLiveCwd() {
|
|
230
|
-
const now = Date.now();
|
|
231
|
-
if (now < this.nextCwdResolveAt)
|
|
232
|
-
return null;
|
|
233
|
-
const liveCwd = await resolveCwdForPid(this.pid).catch(() => null);
|
|
234
|
-
this.nextCwdResolveAt =
|
|
235
|
-
now + (liveCwd === null ? CWD_RESOLVE_BACKOFF_MS : CWD_RESOLVE_COOLDOWN_MS);
|
|
236
|
-
return liveCwd;
|
|
237
|
-
}
|
|
238
|
-
stopTitlePolling() {
|
|
239
|
-
if (this.titlePollTimer === null)
|
|
240
|
-
return;
|
|
241
|
-
clearTimeout(this.titlePollTimer);
|
|
242
|
-
this.titlePollTimer = null;
|
|
243
|
-
}
|
|
244
194
|
}
|
|
245
195
|
//# sourceMappingURL=session.js.map
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAa,MAAM,UAAU,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-alt-screen.d.ts","sourceRoot":"","sources":["../../src/utils/parse-alt-screen.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,KAAG,OAAO,GAAG,IAsBhE,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// DECSET 1049 (Enter Alternate Screen Buffer) and DECRST 1049 (Exit Alternate
|
|
2
|
+
// Screen Buffer) detection from PTY output. These are emitted by TUIs like
|
|
3
|
+
// vim, less, htop when they take over the screen, and again when they return
|
|
4
|
+
// control to the shell.
|
|
5
|
+
//
|
|
6
|
+
// Formats:
|
|
7
|
+
// DECSET: CSI ? 1049 h → ESC [ ? 1049 h
|
|
8
|
+
// DECRST: CSI ? 1049 l → ESC [ ? 1049 l
|
|
9
|
+
//
|
|
10
|
+
// Returns true if the chunk contains a DECSET 1049h (enter), false if it
|
|
11
|
+
// contains a DECRST 1049l (exit), or null if neither is found. When both are
|
|
12
|
+
// present, the last one wins — matching the terminal's actual state.
|
|
13
|
+
const DECSET_1049 = "\x1b[?1049h";
|
|
14
|
+
const DECRST_1049 = "\x1b[?1049l";
|
|
15
|
+
export const parseAltScreenFromChunk = (data) => {
|
|
16
|
+
let result = null;
|
|
17
|
+
let searchFrom = 0;
|
|
18
|
+
while (searchFrom < data.length) {
|
|
19
|
+
const setIndex = data.indexOf(DECSET_1049, searchFrom);
|
|
20
|
+
const rstIndex = data.indexOf(DECRST_1049, searchFrom);
|
|
21
|
+
if (setIndex === -1 && rstIndex === -1)
|
|
22
|
+
break;
|
|
23
|
+
if (setIndex !== -1 && (rstIndex === -1 || setIndex < rstIndex)) {
|
|
24
|
+
result = true;
|
|
25
|
+
searchFrom = setIndex + DECSET_1049.length;
|
|
26
|
+
}
|
|
27
|
+
else if (rstIndex !== -1) {
|
|
28
|
+
result = false;
|
|
29
|
+
searchFrom = rstIndex + DECRST_1049.length;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=parse-alt-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-alt-screen.js","sourceRoot":"","sources":["../../src/utils/parse-alt-screen.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAC3E,6EAA6E;AAC7E,wBAAwB;AACxB,EAAE;AACF,WAAW;AACX,6CAA6C;AAC7C,6CAA6C;AAC7C,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,qEAAqE;AAErE,MAAM,WAAW,GAAG,aAAa,CAAC;AAClC,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAkB,EAAE;IACtE,IAAI,MAAM,GAAmB,IAAI,CAAC;IAClC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,OAAO,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAEvD,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,QAAQ,KAAK,CAAC,CAAC;YAAE,MAAM;QAE9C,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC;YAChE,MAAM,GAAG,IAAI,CAAC;YACd,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC;QAC7C,CAAC;aAAM,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,KAAK,CAAC;YACf,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-osc-title.d.ts","sourceRoot":"","sources":["../../src/utils/parse-osc-title.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,sBAAsB,GAAI,MAAM,MAAM,KAAG,MAAM,GAAG,IAgC9D,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// OSC 0 (Set Icon Name and Window Title) and OSC 2 (Set Window Title) format:
|
|
2
|
+
// ESC ] 0 ; TITLE ST
|
|
3
|
+
// ESC ] 2 ; TITLE ST
|
|
4
|
+
// where ST is either BEL (0x07) or ESC \ (0x1b 0x5c).
|
|
5
|
+
//
|
|
6
|
+
// This parser scans a chunk of PTY output for the last OSC 0/2 in that chunk,
|
|
7
|
+
// returning the title string (or null if none found).
|
|
8
|
+
const OSC0_PREFIX = "\x1b]0;";
|
|
9
|
+
const OSC2_PREFIX = "\x1b]2;";
|
|
10
|
+
const BEL = "\x07";
|
|
11
|
+
const ST = "\x1b\\";
|
|
12
|
+
export const parseOscTitleFromChunk = (data) => {
|
|
13
|
+
const matches = [];
|
|
14
|
+
for (const prefix of [OSC0_PREFIX, OSC2_PREFIX]) {
|
|
15
|
+
let searchFrom = 0;
|
|
16
|
+
while (searchFrom < data.length) {
|
|
17
|
+
const start = data.indexOf(prefix, searchFrom);
|
|
18
|
+
if (start === -1)
|
|
19
|
+
break;
|
|
20
|
+
const payloadStart = start + prefix.length;
|
|
21
|
+
const belIndex = data.indexOf(BEL, payloadStart);
|
|
22
|
+
const stIndex = data.indexOf(ST, payloadStart);
|
|
23
|
+
let payloadEnd;
|
|
24
|
+
if (belIndex !== -1 && (stIndex === -1 || belIndex < stIndex)) {
|
|
25
|
+
payloadEnd = belIndex;
|
|
26
|
+
}
|
|
27
|
+
else if (stIndex !== -1) {
|
|
28
|
+
payloadEnd = stIndex;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
const payload = data.slice(payloadStart, payloadEnd);
|
|
34
|
+
if (payload)
|
|
35
|
+
matches.push({ offset: start, title: payload });
|
|
36
|
+
searchFrom = payloadEnd + 1;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (matches.length === 0)
|
|
40
|
+
return null;
|
|
41
|
+
matches.sort((a, b) => a.offset - b.offset);
|
|
42
|
+
return matches[matches.length - 1].title;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=parse-osc-title.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-osc-title.js","sourceRoot":"","sources":["../../src/utils/parse-osc-title.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uBAAuB;AACvB,uBAAuB;AACvB,sDAAsD;AACtD,EAAE;AACF,8EAA8E;AAC9E,sDAAsD;AAEtD,MAAM,WAAW,GAAG,SAAS,CAAC;AAC9B,MAAM,WAAW,GAAG,SAAS,CAAC;AAC9B,MAAM,GAAG,GAAG,MAAM,CAAC;AACnB,MAAM,EAAE,GAAG,QAAQ,CAAC;AAOpB,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,IAAY,EAAiB,EAAE;IACpE,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,KAAK,MAAM,MAAM,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;QAChD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,OAAO,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC/C,IAAI,KAAK,KAAK,CAAC,CAAC;gBAAE,MAAM;YAExB,MAAM,YAAY,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;YAE/C,IAAI,UAAkB,CAAC;YACvB,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC;gBAC9D,UAAU,GAAG,QAAQ,CAAC;YACxB,CAAC;iBAAM,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC1B,UAAU,GAAG,OAAO,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YACrD,IAAI,OAAO;gBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAE7D,UAAU,GAAG,UAAU,GAAG,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3C,CAAC,CAAC"}
|