@ai-support-agent/cli 0.1.25-beta.0 → 0.1.25-beta.2
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/base-websocket.d.ts +21 -0
- package/dist/base-websocket.d.ts.map +1 -1
- package/dist/base-websocket.js +48 -0
- package/dist/base-websocket.js.map +1 -1
- package/dist/cli/auth-commands.d.ts.map +1 -1
- package/dist/cli/auth-commands.js +8 -16
- package/dist/cli/auth-commands.js.map +1 -1
- package/dist/cli/validators.d.ts.map +1 -1
- package/dist/cli/validators.js +3 -5
- package/dist/cli/validators.js.map +1 -1
- package/dist/terminal/constants.d.ts +14 -1
- package/dist/terminal/constants.d.ts.map +1 -1
- package/dist/terminal/constants.js +15 -2
- package/dist/terminal/constants.js.map +1 -1
- package/dist/terminal/index.d.ts +2 -1
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js.map +1 -1
- package/dist/terminal/terminal-session-manager.d.ts +32 -1
- package/dist/terminal/terminal-session-manager.d.ts.map +1 -1
- package/dist/terminal/terminal-session-manager.js +47 -5
- package/dist/terminal/terminal-session-manager.js.map +1 -1
- package/dist/terminal/terminal-session.d.ts +51 -5
- package/dist/terminal/terminal-session.d.ts.map +1 -1
- package/dist/terminal/terminal-session.js +75 -26
- package/dist/terminal/terminal-session.js.map +1 -1
- package/dist/terminal/terminal-websocket.d.ts +36 -2
- package/dist/terminal/terminal-websocket.d.ts.map +1 -1
- package/dist/terminal/terminal-websocket.js +76 -11
- package/dist/terminal/terminal-websocket.js.map +1 -1
- package/dist/vscode/vscode-tunnel-websocket.d.ts.map +1 -1
- package/dist/vscode/vscode-tunnel-websocket.js +4 -0
- package/dist/vscode/vscode-tunnel-websocket.js.map +1 -1
- package/package.json +1 -1
package/dist/base-websocket.d.ts
CHANGED
|
@@ -34,6 +34,14 @@ export declare abstract class BaseWebSocketConnection<TMessage> {
|
|
|
34
34
|
*/
|
|
35
35
|
private heartbeatAlive;
|
|
36
36
|
private heartbeatMissed;
|
|
37
|
+
/**
|
|
38
|
+
* ALB sticky-session cookies (AWSALB / AWSALBCORS etc.) captured from the
|
|
39
|
+
* WS handshake (upgrade) response's Set-Cookie headers, keyed by cookie
|
|
40
|
+
* name. Re-sent as a Cookie header on reconnect so the agent lands on the
|
|
41
|
+
* SAME API task when the API is scaled out behind an ALB. In-memory only —
|
|
42
|
+
* stickiness across agent restarts is not needed.
|
|
43
|
+
*/
|
|
44
|
+
private readonly stickyCookies;
|
|
37
45
|
constructor(options: BaseWebSocketOptions);
|
|
38
46
|
connect(): Promise<void>;
|
|
39
47
|
disconnect(): void;
|
|
@@ -50,6 +58,19 @@ export declare abstract class BaseWebSocketConnection<TMessage> {
|
|
|
50
58
|
protected sendMessage(msg: unknown): void;
|
|
51
59
|
/** 再接続成功時のコールバック(サブクラスでオーバーライド可能) */
|
|
52
60
|
protected onReconnected(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Cookie request header assembled from the sticky cookies captured on the
|
|
63
|
+
* previous handshake, or undefined when none were received. Subclasses that
|
|
64
|
+
* build their own handshake headers in createWebSocket() should include
|
|
65
|
+
* this so reconnects stick to the same ALB target.
|
|
66
|
+
*/
|
|
67
|
+
protected getStickyCookieHeader(): string | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Capture Set-Cookie headers from the WS handshake (upgrade) response.
|
|
70
|
+
* Only the `name=value` pair is kept (attributes like Path/Expires are
|
|
71
|
+
* request-irrelevant); a later handshake overwrites cookies by name.
|
|
72
|
+
*/
|
|
73
|
+
private captureStickyCookies;
|
|
53
74
|
protected doConnect(): Promise<void>;
|
|
54
75
|
/**
|
|
55
76
|
* ハートビート (ping/pong) を開始する。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-websocket.d.ts","sourceRoot":"","sources":["../src/base-websocket.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"base-websocket.d.ts","sourceRoot":"","sources":["../src/base-websocket.ts"],"names":[],"mappings":"AAEA,OAAO,SAAS,MAAM,IAAI,CAAA;AAO1B,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,oCAAoC;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;GAKG;AACH,8BAAsB,uBAAuB,CAAC,QAAQ;IACpD,SAAS,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAAO;IACrC,SAAS,CAAC,MAAM,UAAQ;IACxB,SAAS,CAAC,QAAQ,CAAC,oBAAoB;;MAAiB;IACxD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;IAChD,OAAO,CAAC,cAAc,CAA8C;IACpE;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,eAAe,CAAI;IAC3B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;gBAE9C,OAAO,EAAE,oBAAoB;IAIzC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAMxB,UAAU,IAAI,IAAI;IAUlB,8BAA8B;IAC9B,SAAS,CAAC,QAAQ,CAAC,eAAe,IAAI,SAAS;IAE/C,mDAAmD;IACnD,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAE9E,uBAAuB;IACvB,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAExF,iCAAiC;IACjC,SAAS,CAAC,YAAY,IAAI,IAAI;IAI9B,sCAAsC;IACtC,SAAS,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAQ7C,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IASzC,qCAAqC;IACrC,SAAS,CAAC,aAAa,IAAI,IAAI;IAI/B;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,IAAI,MAAM,GAAG,SAAS;IAOrD;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAiB5B,SAAS,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAoDpC;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,cAAc;IAuCtB,gCAAgC;IAChC,OAAO,CAAC,aAAa;IASrB,kDAAkD;IAClD,SAAS,CAAC,gBAAgB,IAAI,IAAI;YAIpB,WAAW;CAW1B"}
|
package/dist/base-websocket.js
CHANGED
|
@@ -31,6 +31,14 @@ class BaseWebSocketConnection {
|
|
|
31
31
|
*/
|
|
32
32
|
heartbeatAlive = false;
|
|
33
33
|
heartbeatMissed = 0;
|
|
34
|
+
/**
|
|
35
|
+
* ALB sticky-session cookies (AWSALB / AWSALBCORS etc.) captured from the
|
|
36
|
+
* WS handshake (upgrade) response's Set-Cookie headers, keyed by cookie
|
|
37
|
+
* name. Re-sent as a Cookie header on reconnect so the agent lands on the
|
|
38
|
+
* SAME API task when the API is scaled out behind an ALB. In-memory only —
|
|
39
|
+
* stickiness across agent restarts is not needed.
|
|
40
|
+
*/
|
|
41
|
+
stickyCookies = new Map();
|
|
34
42
|
constructor(options) {
|
|
35
43
|
this.options = options;
|
|
36
44
|
}
|
|
@@ -75,9 +83,49 @@ class BaseWebSocketConnection {
|
|
|
75
83
|
onReconnected() {
|
|
76
84
|
// default: no-op
|
|
77
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Cookie request header assembled from the sticky cookies captured on the
|
|
88
|
+
* previous handshake, or undefined when none were received. Subclasses that
|
|
89
|
+
* build their own handshake headers in createWebSocket() should include
|
|
90
|
+
* this so reconnects stick to the same ALB target.
|
|
91
|
+
*/
|
|
92
|
+
getStickyCookieHeader() {
|
|
93
|
+
if (this.stickyCookies.size === 0)
|
|
94
|
+
return undefined;
|
|
95
|
+
return Array.from(this.stickyCookies.entries())
|
|
96
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
97
|
+
.join('; ');
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Capture Set-Cookie headers from the WS handshake (upgrade) response.
|
|
101
|
+
* Only the `name=value` pair is kept (attributes like Path/Expires are
|
|
102
|
+
* request-irrelevant); a later handshake overwrites cookies by name.
|
|
103
|
+
*/
|
|
104
|
+
captureStickyCookies(response) {
|
|
105
|
+
const setCookies = response.headers['set-cookie'];
|
|
106
|
+
if (!setCookies || setCookies.length === 0)
|
|
107
|
+
return;
|
|
108
|
+
for (const setCookie of setCookies) {
|
|
109
|
+
const pair = setCookie.split(';')[0];
|
|
110
|
+
const eq = pair.indexOf('=');
|
|
111
|
+
if (eq <= 0)
|
|
112
|
+
continue;
|
|
113
|
+
const name = pair.slice(0, eq).trim();
|
|
114
|
+
const value = pair.slice(eq + 1).trim();
|
|
115
|
+
if (!name)
|
|
116
|
+
continue;
|
|
117
|
+
this.stickyCookies.set(name, value);
|
|
118
|
+
}
|
|
119
|
+
logger_1.logger.debug(`${this.options.logPrefix} Captured ${this.stickyCookies.size} sticky cookie(s) from handshake`);
|
|
120
|
+
}
|
|
78
121
|
doConnect() {
|
|
79
122
|
return new Promise((resolve, reject) => {
|
|
80
123
|
const ws = this.createWebSocket();
|
|
124
|
+
ws.on('upgrade', (response) => {
|
|
125
|
+
// ALB sticky cookies (AWSALB / AWSALBCORS) arrive on the handshake
|
|
126
|
+
// response; keep them so the next reconnect targets the same task.
|
|
127
|
+
this.captureStickyCookies(response);
|
|
128
|
+
});
|
|
81
129
|
ws.on('open', () => {
|
|
82
130
|
this.startHeartbeat(ws);
|
|
83
131
|
this.onOpen(ws, resolve);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-websocket.js","sourceRoot":"","sources":["../src/base-websocket.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"base-websocket.js","sourceRoot":"","sources":["../src/base-websocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-commands.d.ts","sourceRoot":"","sources":["../../src/cli/auth-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"auth-commands.d.ts","sourceRoot":"","sources":["../../src/cli/auth-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAmFxC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+D3D"}
|
|
@@ -54,15 +54,13 @@ async function performBrowserAuth(opts) {
|
|
|
54
54
|
const port = opts.port ? (() => {
|
|
55
55
|
const parsed = parseInt(opts.port, 10);
|
|
56
56
|
if (isNaN(parsed) || parsed < 1 || parsed > 65535) {
|
|
57
|
-
|
|
58
|
-
process.exit(1);
|
|
57
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('auth.invalidPort', { port: opts.port }));
|
|
59
58
|
}
|
|
60
59
|
return parsed;
|
|
61
60
|
})() : undefined;
|
|
62
61
|
const urlError = (0, utils_1.validateApiUrl)(opts.url);
|
|
63
62
|
if (urlError) {
|
|
64
|
-
|
|
65
|
-
process.exit(1);
|
|
63
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('auth.invalidProtocol'));
|
|
66
64
|
}
|
|
67
65
|
const origin = new URL(opts.url).origin;
|
|
68
66
|
const { url: serverUrl, nonce, waitForCallback, stop } = await (0, auth_server_1.startAuthServer)(port, origin);
|
|
@@ -77,12 +75,10 @@ async function performBrowserAuth(opts) {
|
|
|
77
75
|
stop();
|
|
78
76
|
const apiUrl = opts.apiUrl ?? result.apiUrl;
|
|
79
77
|
if (!apiUrl) {
|
|
80
|
-
|
|
81
|
-
process.exit(1);
|
|
78
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('auth.noApiUrl'));
|
|
82
79
|
}
|
|
83
80
|
if (!result.tenantCode) {
|
|
84
|
-
|
|
85
|
-
process.exit(1);
|
|
81
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('auth.noTenantCode'));
|
|
86
82
|
}
|
|
87
83
|
const projectCode = result.projectCode ?? constants_1.PROJECT_CODE_DEFAULT;
|
|
88
84
|
const registration = { tenantCode: result.tenantCode, projectCode, token: result.token, apiUrl };
|
|
@@ -96,8 +92,7 @@ async function handleBrowserAuthCommand(opts, successMessageKey) {
|
|
|
96
92
|
logger_1.logger.success((0, i18n_1.t)(successMessageKey, { projectCode }));
|
|
97
93
|
}
|
|
98
94
|
catch (error) {
|
|
99
|
-
|
|
100
|
-
process.exit(1);
|
|
95
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('auth.failed', { message: (0, utils_1.getErrorMessage)(error) }));
|
|
101
96
|
}
|
|
102
97
|
}
|
|
103
98
|
function registerAuthCommands(program) {
|
|
@@ -124,8 +119,7 @@ function registerAuthCommands(program) {
|
|
|
124
119
|
.action(async (opts) => {
|
|
125
120
|
const apiUrlError = (0, utils_1.validateApiUrl)(opts.apiUrl);
|
|
126
121
|
if (apiUrlError) {
|
|
127
|
-
|
|
128
|
-
process.exit(1);
|
|
122
|
+
(0, utils_1.exitWithError)(apiUrlError);
|
|
129
123
|
}
|
|
130
124
|
let projectCode = opts.projectCode;
|
|
131
125
|
let tenantCode;
|
|
@@ -141,12 +135,10 @@ function registerAuthCommands(program) {
|
|
|
141
135
|
logger_1.logger.info((0, i18n_1.t)('config.resolvedProject', { projectCode }));
|
|
142
136
|
}
|
|
143
137
|
catch (error) {
|
|
144
|
-
|
|
145
|
-
process.exit(1);
|
|
138
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('config.resolveProjectFailed', { message: (0, utils_1.getErrorMessage)(error) }));
|
|
146
139
|
}
|
|
147
140
|
if (!tenantCode) {
|
|
148
|
-
|
|
149
|
-
process.exit(1);
|
|
141
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('config.resolveProjectFailed', { message: 'tenantCode not returned from API' }));
|
|
150
142
|
}
|
|
151
143
|
const registration = {
|
|
152
144
|
tenantCode,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-commands.js","sourceRoot":"","sources":["../../src/cli/auth-commands.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"auth-commands.js","sourceRoot":"","sources":["../../src/cli/auth-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/cli/validators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/cli/validators.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAG9C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAID,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAM7F"}
|
package/dist/cli/validators.js
CHANGED
|
@@ -4,12 +4,11 @@ exports.parseIntervalOrExit = parseIntervalOrExit;
|
|
|
4
4
|
exports.validateUpdateChannel = validateUpdateChannel;
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
6
|
const i18n_1 = require("../i18n");
|
|
7
|
-
const
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
8
|
function parseIntervalOrExit(value, name) {
|
|
9
9
|
const parsed = parseInt(value, 10);
|
|
10
10
|
if (isNaN(parsed) || parsed < constants_1.MIN_INTERVAL || parsed > constants_1.MAX_INTERVAL) {
|
|
11
|
-
|
|
12
|
-
process.exit(1);
|
|
11
|
+
(0, utils_1.exitWithError)((0, i18n_1.t)('config.invalidInterval', { name, value, min: constants_1.MIN_INTERVAL, max: constants_1.MAX_INTERVAL }));
|
|
13
12
|
}
|
|
14
13
|
return parsed;
|
|
15
14
|
}
|
|
@@ -18,8 +17,7 @@ function validateUpdateChannel(channel) {
|
|
|
18
17
|
if (!channel)
|
|
19
18
|
return undefined;
|
|
20
19
|
if (!VALID_CHANNELS.includes(channel)) {
|
|
21
|
-
|
|
22
|
-
process.exit(1);
|
|
20
|
+
(0, utils_1.exitWithError)(`Invalid update channel: ${channel}. Must be one of: ${VALID_CHANNELS.join(', ')}`);
|
|
23
21
|
}
|
|
24
22
|
return channel;
|
|
25
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/cli/validators.ts"],"names":[],"mappings":";;AAKA,
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/cli/validators.ts"],"names":[],"mappings":";;AAKA,kDAMC;AAID,sDAMC;AArBD,4CAAyD;AACzD,kCAA2B;AAE3B,oCAAwC;AAExC,SAAgB,mBAAmB,CAAC,KAAa,EAAE,IAAY;IAC7D,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAClC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,wBAAY,IAAI,MAAM,GAAG,wBAAY,EAAE,CAAC;QACpE,IAAA,qBAAa,EAAC,IAAA,QAAC,EAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,wBAAY,EAAE,GAAG,EAAE,wBAAY,EAAE,CAAC,CAAC,CAAA;IACnG,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,cAAc,GAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AAErE,SAAgB,qBAAqB,CAAC,OAA2B;IAC/D,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAA;IAC9B,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,IAAA,qBAAa,EAAC,2BAA2B,OAAO,qBAAqB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACnG,CAAC;IACD,OAAO,OAAyB,CAAA;AAClC,CAAC"}
|
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
export declare const SESSION_IDLE_TIMEOUT_MS: number;
|
|
2
1
|
/**
|
|
3
2
|
* Grace window kept after a transient WebSocket disconnect before the PTY is
|
|
4
3
|
* killed. A reconnect with the same sessionId within this window resumes the
|
|
5
4
|
* still-alive PTY instead of spawning a new one. This prevents an API heartbeat
|
|
6
5
|
* false-positive terminate from destroying the user's live shell.
|
|
6
|
+
*
|
|
7
|
+
* The PTY has no idle timeout — it stays alive as long as the WebSocket is
|
|
8
|
+
* connected. Cleanup is handled solely by this grace window on disconnect.
|
|
9
|
+
* MAX_CONCURRENT_SESSIONS caps the number of concurrently open sessions, so
|
|
10
|
+
* the blast radius of a permanently-open WS holding a session is bounded.
|
|
7
11
|
*/
|
|
8
12
|
export declare const SESSION_GRACE_TIMEOUT_MS: number;
|
|
9
13
|
export declare const MAX_CONCURRENT_SESSIONS = 5;
|
|
14
|
+
/**
|
|
15
|
+
* Upper bound (in bytes) of the per-session scrollback ring buffer kept by
|
|
16
|
+
* TerminalSession. PTY output is appended to the buffer alongside the live
|
|
17
|
+
* stdout relay; when the total exceeds this cap the OLDEST bytes are dropped.
|
|
18
|
+
* On a successful resume the buffer is replayed (base64 `replay` message)
|
|
19
|
+
* right after `ready` and before any subsequent live `stdout`, so the web
|
|
20
|
+
* client can restore the screen content lost during the disconnect.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SCROLLBACK_BUFFER_MAX_BYTES: number;
|
|
10
23
|
export declare const TERMINAL_DEFAULT_COLS = 80;
|
|
11
24
|
export declare const TERMINAL_DEFAULT_ROWS = 24;
|
|
12
25
|
export declare const TERMINAL_WS_RECONNECT_BASE_DELAY_MS = 1000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/terminal/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/terminal/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,QAAa,CAAA;AAClD,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,QAAa,CAAA;AACrD,eAAO,MAAM,qBAAqB,KAAK,CAAA;AACvC,eAAO,MAAM,qBAAqB,KAAK,CAAA;AACvC,eAAO,MAAM,mCAAmC,OAAO,CAAA;AACvD,eAAO,MAAM,iCAAiC,QAA2B,CAAA"}
|
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TERMINAL_WS_MAX_RECONNECT_RETRIES = exports.TERMINAL_WS_RECONNECT_BASE_DELAY_MS = exports.TERMINAL_DEFAULT_ROWS = exports.TERMINAL_DEFAULT_COLS = exports.
|
|
4
|
-
exports.SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
|
|
3
|
+
exports.TERMINAL_WS_MAX_RECONNECT_RETRIES = exports.TERMINAL_WS_RECONNECT_BASE_DELAY_MS = exports.TERMINAL_DEFAULT_ROWS = exports.TERMINAL_DEFAULT_COLS = exports.SCROLLBACK_BUFFER_MAX_BYTES = exports.MAX_CONCURRENT_SESSIONS = exports.SESSION_GRACE_TIMEOUT_MS = void 0;
|
|
5
4
|
/**
|
|
6
5
|
* Grace window kept after a transient WebSocket disconnect before the PTY is
|
|
7
6
|
* killed. A reconnect with the same sessionId within this window resumes the
|
|
8
7
|
* still-alive PTY instead of spawning a new one. This prevents an API heartbeat
|
|
9
8
|
* false-positive terminate from destroying the user's live shell.
|
|
9
|
+
*
|
|
10
|
+
* The PTY has no idle timeout — it stays alive as long as the WebSocket is
|
|
11
|
+
* connected. Cleanup is handled solely by this grace window on disconnect.
|
|
12
|
+
* MAX_CONCURRENT_SESSIONS caps the number of concurrently open sessions, so
|
|
13
|
+
* the blast radius of a permanently-open WS holding a session is bounded.
|
|
10
14
|
*/
|
|
11
15
|
exports.SESSION_GRACE_TIMEOUT_MS = 300 * 1000; // 5 minutes
|
|
12
16
|
exports.MAX_CONCURRENT_SESSIONS = 5;
|
|
17
|
+
/**
|
|
18
|
+
* Upper bound (in bytes) of the per-session scrollback ring buffer kept by
|
|
19
|
+
* TerminalSession. PTY output is appended to the buffer alongside the live
|
|
20
|
+
* stdout relay; when the total exceeds this cap the OLDEST bytes are dropped.
|
|
21
|
+
* On a successful resume the buffer is replayed (base64 `replay` message)
|
|
22
|
+
* right after `ready` and before any subsequent live `stdout`, so the web
|
|
23
|
+
* client can restore the screen content lost during the disconnect.
|
|
24
|
+
*/
|
|
25
|
+
exports.SCROLLBACK_BUFFER_MAX_BYTES = 256 * 1024; // 256KB per session
|
|
13
26
|
exports.TERMINAL_DEFAULT_COLS = 80;
|
|
14
27
|
exports.TERMINAL_DEFAULT_ROWS = 24;
|
|
15
28
|
exports.TERMINAL_WS_RECONNECT_BASE_DELAY_MS = 1000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/terminal/constants.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/terminal/constants.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;GAUG;AACU,QAAA,wBAAwB,GAAG,GAAG,GAAG,IAAI,CAAA,CAAC,YAAY;AAClD,QAAA,uBAAuB,GAAG,CAAC,CAAA;AAExC;;;;;;;GAOG;AACU,QAAA,2BAA2B,GAAG,GAAG,GAAG,IAAI,CAAA,CAAC,oBAAoB;AAC7D,QAAA,qBAAqB,GAAG,EAAE,CAAA;AAC1B,QAAA,qBAAqB,GAAG,EAAE,CAAA;AAC1B,QAAA,mCAAmC,GAAG,IAAI,CAAA;AAC1C,QAAA,iCAAiC,GAAG,MAAM,CAAC,iBAAiB,CAAA"}
|
package/dist/terminal/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { buildSandboxInitScript, isZshShell, buildBashRcContent, buildZshRcContent, buildOpenFolderDisableKeybindings, } from './sandbox-init-script';
|
|
2
2
|
export { TerminalSession, isNodePtyAvailable } from './terminal-session';
|
|
3
|
-
export type { TerminalSessionInfo, TerminalSessionOptions } from './terminal-session';
|
|
3
|
+
export type { TerminalSessionInfo, TerminalSessionOptions, TerminalSessionMeta } from './terminal-session';
|
|
4
4
|
export { TerminalSessionManager } from './terminal-session-manager';
|
|
5
|
+
export type { ResumeFailureReason, ResumeResult } from './terminal-session-manager';
|
|
5
6
|
export { TerminalWebSocket } from './terminal-websocket';
|
|
6
7
|
export type { TerminalAgentMessage, TerminalServerMessage } from './terminal-websocket';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,iCAAiC,GAClC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,iCAAiC,GAClC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAC1G,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AACnE,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":";;;AAAA,6DAM8B;AAL5B,6HAAA,sBAAsB,OAAA;AACtB,iHAAA,UAAU,OAAA;AACV,yHAAA,kBAAkB,OAAA;AAClB,wHAAA,iBAAiB,OAAA;AACjB,wIAAA,iCAAiC,OAAA;AAEnC,uDAAwE;AAA/D,mHAAA,eAAe,OAAA;AAAE,sHAAA,kBAAkB,OAAA;AAE5C,uEAAmE;AAA1D,kIAAA,sBAAsB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":";;;AAAA,6DAM8B;AAL5B,6HAAA,sBAAsB,OAAA;AACtB,iHAAA,UAAU,OAAA;AACV,yHAAA,kBAAkB,OAAA;AAClB,wHAAA,iBAAiB,OAAA;AACjB,wIAAA,iCAAiC,OAAA;AAEnC,uDAAwE;AAA/D,mHAAA,eAAe,OAAA;AAAE,sHAAA,kBAAkB,OAAA;AAE5C,uEAAmE;AAA1D,kIAAA,sBAAsB,OAAA;AAE/B,2DAAwD;AAA/C,uHAAA,iBAAiB,OAAA"}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { TerminalSession, TerminalSessionOptions } from './terminal-session';
|
|
2
|
-
import type { TerminalSessionInfo } from './terminal-session';
|
|
2
|
+
import type { TerminalSessionInfo, TerminalSessionMeta } from './terminal-session';
|
|
3
|
+
/**
|
|
4
|
+
* Why a resume-only open could not reattach to an existing PTY.
|
|
5
|
+
* Mirrors the `resume_failed.reason` protocol field (3-repo contract):
|
|
6
|
+
* - 'not_found' — no session with this sessionId exists
|
|
7
|
+
* - 'dead' — the session exists but its PTY already exited
|
|
8
|
+
* - 'meta_mismatch' — the presented meta does not exactly match the recorded one
|
|
9
|
+
*/
|
|
10
|
+
export type ResumeFailureReason = 'not_found' | 'meta_mismatch' | 'dead';
|
|
11
|
+
export type ResumeResult = {
|
|
12
|
+
ok: true;
|
|
13
|
+
session: TerminalSession;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
reason: ResumeFailureReason;
|
|
17
|
+
};
|
|
3
18
|
export declare class TerminalSessionManager {
|
|
4
19
|
private readonly sessions;
|
|
5
20
|
/**
|
|
@@ -9,6 +24,22 @@ export declare class TerminalSessionManager {
|
|
|
9
24
|
private readonly graceTimers;
|
|
10
25
|
private sessionCounter;
|
|
11
26
|
createSession(options?: TerminalSessionOptions): TerminalSession | null;
|
|
27
|
+
/**
|
|
28
|
+
* Resume-only lookup: NEVER spawns a new PTY (no-fallback rule). A resume
|
|
29
|
+
* open (`resume: true`) must route here — createSessionWithId() is the
|
|
30
|
+
* create-or-legacy-grace-resume path for non-resume opens.
|
|
31
|
+
*
|
|
32
|
+
* Succeeds only when the session exists, its PTY is alive, AND the presented
|
|
33
|
+
* meta exactly matches the meta recorded at creation. On success the pending
|
|
34
|
+
* grace timer (if any) is cancelled and the existing session is returned.
|
|
35
|
+
*/
|
|
36
|
+
resumeSession(sessionId: string, meta?: TerminalSessionMeta): ResumeResult;
|
|
37
|
+
/**
|
|
38
|
+
* Create-or-legacy-grace-resume path for NON-resume opens. A reconnect that
|
|
39
|
+
* explicitly asks for a resume (`resume: true`) must use resumeSession()
|
|
40
|
+
* instead — this method spawns a new PTY when no live session exists, which
|
|
41
|
+
* a resume-only open must never do.
|
|
42
|
+
*/
|
|
12
43
|
createSessionWithId(sessionId: string, options?: TerminalSessionOptions): TerminalSession | null;
|
|
13
44
|
getSession(sessionId: string): TerminalSession | undefined;
|
|
14
45
|
closeSession(sessionId: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-session-manager.d.ts","sourceRoot":"","sources":["../../src/terminal/terminal-session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAG5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"terminal-session-manager.d.ts","sourceRoot":"","sources":["../../src/terminal/terminal-session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAG5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAElF;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,eAAe,GAAG,MAAM,CAAA;AAExE,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GACtC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAE9C,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmD;IAC/E,OAAO,CAAC,cAAc,CAAI;IAE1B,aAAa,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,GAAG,IAAI;IAM3E;;;;;;;;OAQG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,YAAY;IAgB1E;;;;;OAKG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,eAAe,GAAG,IAAI;IAgCpG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI1D,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IASxC,YAAY,IAAI,mBAAmB,EAAE;IAIrC;;;OAGG;IACH,QAAQ,IAAI,IAAI;IAUhB;;;;;OAKG;IACH,kBAAkB,IAAI,IAAI;IAM1B,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,eAAe;IAQvB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -17,6 +17,36 @@ class TerminalSessionManager {
|
|
|
17
17
|
const sessionId = `term-${Date.now()}-${this.sessionCounter}`;
|
|
18
18
|
return this.createSessionWithId(sessionId, options);
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Resume-only lookup: NEVER spawns a new PTY (no-fallback rule). A resume
|
|
22
|
+
* open (`resume: true`) must route here — createSessionWithId() is the
|
|
23
|
+
* create-or-legacy-grace-resume path for non-resume opens.
|
|
24
|
+
*
|
|
25
|
+
* Succeeds only when the session exists, its PTY is alive, AND the presented
|
|
26
|
+
* meta exactly matches the meta recorded at creation. On success the pending
|
|
27
|
+
* grace timer (if any) is cancelled and the existing session is returned.
|
|
28
|
+
*/
|
|
29
|
+
resumeSession(sessionId, meta) {
|
|
30
|
+
const session = this.sessions.get(sessionId);
|
|
31
|
+
if (!session) {
|
|
32
|
+
return { ok: false, reason: 'not_found' };
|
|
33
|
+
}
|
|
34
|
+
if (!session.isAlive()) {
|
|
35
|
+
return { ok: false, reason: 'dead' };
|
|
36
|
+
}
|
|
37
|
+
if (!metaMatches(session.getMeta(), meta)) {
|
|
38
|
+
return { ok: false, reason: 'meta_mismatch' };
|
|
39
|
+
}
|
|
40
|
+
this.clearGraceTimer(sessionId);
|
|
41
|
+
logger_1.logger.debug(`[terminal] Resume validated; reattaching session: ${sessionId}`);
|
|
42
|
+
return { ok: true, session };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create-or-legacy-grace-resume path for NON-resume opens. A reconnect that
|
|
46
|
+
* explicitly asks for a resume (`resume: true`) must use resumeSession()
|
|
47
|
+
* instead — this method spawns a new PTY when no live session exists, which
|
|
48
|
+
* a resume-only open must never do.
|
|
49
|
+
*/
|
|
20
50
|
createSessionWithId(sessionId, options = {}) {
|
|
21
51
|
// Any reconnect with this sessionId invalidates a pending grace timer: we
|
|
22
52
|
// either resume the existing PTY or replace it with a new one. Clearing
|
|
@@ -40,11 +70,6 @@ class TerminalSessionManager {
|
|
|
40
70
|
this.clearGraceTimer(sessionId);
|
|
41
71
|
this.sessions.delete(sessionId);
|
|
42
72
|
});
|
|
43
|
-
session.setOnIdleTimeout(() => {
|
|
44
|
-
this.clearGraceTimer(sessionId);
|
|
45
|
-
session.kill();
|
|
46
|
-
this.sessions.delete(sessionId);
|
|
47
|
-
});
|
|
48
73
|
this.sessions.set(sessionId, session);
|
|
49
74
|
return session;
|
|
50
75
|
}
|
|
@@ -119,4 +144,21 @@ class TerminalSessionManager {
|
|
|
119
144
|
}
|
|
120
145
|
}
|
|
121
146
|
exports.TerminalSessionManager = TerminalSessionManager;
|
|
147
|
+
/**
|
|
148
|
+
* Strict meta comparison for resume validation.
|
|
149
|
+
* - Either side absent → mismatch. A resume-capable API always attaches meta
|
|
150
|
+
* to `resume: true` opens, and a legacy API never sends `resume: true` at
|
|
151
|
+
* all (its reconnects go through the createSessionWithId grace-resume path),
|
|
152
|
+
* so a meta-less resume is never a legitimate request. Refusing it closes
|
|
153
|
+
* the takeover hole where a meta-less PTY could be claimed by anyone who
|
|
154
|
+
* learned its sessionId.
|
|
155
|
+
* - Both present → every field must be strictly equal (no partial matching).
|
|
156
|
+
*/
|
|
157
|
+
function metaMatches(recorded, presented) {
|
|
158
|
+
if (!recorded || !presented)
|
|
159
|
+
return false;
|
|
160
|
+
return (recorded.tenantCode === presented.tenantCode &&
|
|
161
|
+
recorded.projectCode === presented.projectCode &&
|
|
162
|
+
recorded.userId === presented.userId);
|
|
163
|
+
}
|
|
122
164
|
//# sourceMappingURL=terminal-session-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-session-manager.js","sourceRoot":"","sources":["../../src/terminal/terminal-session-manager.ts"],"names":[],"mappings":";;;AAAA,yDAA4E;AAC5E,2CAA+E;AAC/E,sCAAkC;
|
|
1
|
+
{"version":3,"file":"terminal-session-manager.js","sourceRoot":"","sources":["../../src/terminal/terminal-session-manager.ts"],"names":[],"mappings":";;;AAAA,yDAA4E;AAC5E,2CAA+E;AAC/E,sCAAkC;AAgBlC,MAAa,sBAAsB;IAChB,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAA;IAC9D;;;OAGG;IACc,WAAW,GAAG,IAAI,GAAG,EAAyC,CAAA;IACvE,cAAc,GAAG,CAAC,CAAA;IAE1B,aAAa,CAAC,UAAkC,EAAE;QAChD,IAAI,CAAC,cAAc,EAAE,CAAA;QACrB,MAAM,SAAS,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAA;QAC7D,OAAO,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACrD,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CAAC,SAAiB,EAAE,IAA0B;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;QAC3C,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;QACtC,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;YAC1C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;QAC/C,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAC/B,eAAM,CAAC,KAAK,CAAC,qDAAqD,SAAS,EAAE,CAAC,CAAA;QAC9E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC9B,CAAC;IAED;;;;;OAKG;IACH,mBAAmB,CAAC,SAAiB,EAAE,UAAkC,EAAE;QACzE,0EAA0E;QAC1E,wEAAwE;QACxE,oEAAoE;QACpE,6CAA6C;QAC7C,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAE/B,2EAA2E;QAC3E,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,QAAQ,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YACnC,eAAM,CAAC,KAAK,CAAC,oDAAoD,SAAS,EAAE,CAAC,CAAA;YAC7E,OAAO,QAAQ,CAAA;QACjB,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,mCAAuB,EAAE,CAAC;YAClD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,kCAAe,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAEvD,2EAA2E;QAC3E,yDAAyD;QACzD,OAAO,CAAC,iBAAiB,CAAC,GAAG,EAAE;YAC7B,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;YAC/B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QACrC,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACrC,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAA;QAC1B,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAC/B,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,YAAY;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACnE,CAAC;IAED;;;OAGG;IACH,QAAQ;QACN,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,OAAO,CAAC,IAAI,EAAE,CAAA;QAChB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC;IAED;;;;;OAKG;IACH,kBAAkB;QAChB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,SAAiB;QAC1C,8EAA8E;QAC9E,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YAClC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;YAC5C;;iEAEqD;YACrD,IAAI,OAAO,EAAE,CAAC;gBACZ,eAAM,CAAC,KAAK,CAAC,qDAAqD,SAAS,EAAE,CAAC,CAAA;gBAC9E,OAAO,CAAC,IAAI,EAAE,CAAA;gBACd,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YACjC,CAAC;QACH,CAAC,EAAE,oCAAwB,CAAC,CAAA;QAC5B,kEAAkE;QAClE,4FAA4F;QAC5F,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;QACf,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;IACxC,CAAC;IAEO,eAAe,CAAC,SAAiB;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAA;IAC3B,CAAC;CACF;AAzJD,wDAyJC;AAED;;;;;;;;;GASG;AACH,SAAS,WAAW,CAClB,QAAoC,EACpC,SAA0C;IAE1C,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAA;IACzC,OAAO,CACL,QAAQ,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU;QAC5C,QAAQ,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW;QAC9C,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,CACrC,CAAA;AACH,CAAC"}
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
* node-pty が利用可能か確認する
|
|
3
3
|
*/
|
|
4
4
|
export declare function isNodePtyAvailable(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Resume-validation metadata recorded at PTY creation time.
|
|
7
|
+
*
|
|
8
|
+
* The API includes `meta` in the `open` message; the session stores it and a
|
|
9
|
+
* later resume `open` must present an EXACTLY matching meta to reattach to
|
|
10
|
+
* this PTY (see TerminalSessionManager.resumeSession). This prevents an
|
|
11
|
+
* API-restart resume from handing an existing PTY to a different tenant /
|
|
12
|
+
* project / user.
|
|
13
|
+
*/
|
|
14
|
+
export interface TerminalSessionMeta {
|
|
15
|
+
tenantCode: string;
|
|
16
|
+
projectCode: string;
|
|
17
|
+
userId: string;
|
|
18
|
+
}
|
|
5
19
|
export interface TerminalSessionOptions {
|
|
6
20
|
cols?: number;
|
|
7
21
|
rows?: number;
|
|
@@ -14,6 +28,12 @@ export interface TerminalSessionOptions {
|
|
|
14
28
|
* 含まれないキーは PTY が継承する process.env をそのまま残す。
|
|
15
29
|
*/
|
|
16
30
|
envVarsOverride?: Record<string, string>;
|
|
31
|
+
/**
|
|
32
|
+
* Resume 検証用メタ(tenantCode / projectCode / userId)。
|
|
33
|
+
* open メッセージの meta をそのまま記録し、resume open の meta と完全一致
|
|
34
|
+
* した場合のみ既存 PTY への再接続を許可する。
|
|
35
|
+
*/
|
|
36
|
+
meta?: TerminalSessionMeta;
|
|
17
37
|
}
|
|
18
38
|
export interface TerminalSessionInfo {
|
|
19
39
|
sessionId: string;
|
|
@@ -56,8 +76,15 @@ export declare class TerminalSession {
|
|
|
56
76
|
*/
|
|
57
77
|
private internalExitCallback;
|
|
58
78
|
private exited;
|
|
59
|
-
|
|
60
|
-
private
|
|
79
|
+
/** Resume-validation meta recorded at creation (null when the open had no meta). */
|
|
80
|
+
private readonly meta;
|
|
81
|
+
/**
|
|
82
|
+
* Scrollback ring buffer: PTY output chunks appended alongside the live
|
|
83
|
+
* stdout relay, capped at SCROLLBACK_BUFFER_MAX_BYTES by dropping the OLDEST
|
|
84
|
+
* bytes. Replayed to the client on a successful resume.
|
|
85
|
+
*/
|
|
86
|
+
private readonly scrollbackChunks;
|
|
87
|
+
private scrollbackBytes;
|
|
61
88
|
/**
|
|
62
89
|
* 過去の terminal-sandbox-* ディレクトリを一括削除する。
|
|
63
90
|
*
|
|
@@ -73,14 +100,35 @@ export declare class TerminalSession {
|
|
|
73
100
|
*/
|
|
74
101
|
static cleanupStaleSandboxes(maxAgeMs?: number): number;
|
|
75
102
|
constructor(sessionId: string, options?: TerminalSessionOptions);
|
|
103
|
+
/**
|
|
104
|
+
* Register the (single) live data relay callback. Registration REPLACES any
|
|
105
|
+
* previous callback — it does not add a listener — so re-registering on a
|
|
106
|
+
* resume cannot double-send stdout.
|
|
107
|
+
*/
|
|
76
108
|
onData(callback: DataCallback): void;
|
|
109
|
+
/** Resume-validation meta recorded at creation, or null if none was given. */
|
|
110
|
+
getMeta(): TerminalSessionMeta | null;
|
|
111
|
+
/**
|
|
112
|
+
* Snapshot of the scrollback ring buffer (oldest → newest), at most
|
|
113
|
+
* SCROLLBACK_BUFFER_MAX_BYTES bytes. Returns an empty Buffer when no output
|
|
114
|
+
* has been produced yet.
|
|
115
|
+
*/
|
|
116
|
+
getScrollbackBuffer(): Buffer;
|
|
117
|
+
/**
|
|
118
|
+
* Append PTY output to the ring buffer, evicting the OLDEST bytes once the
|
|
119
|
+
* total exceeds SCROLLBACK_BUFFER_MAX_BYTES. Eviction may slice a chunk in
|
|
120
|
+
* the middle; the cut is then advanced to the next UTF-8 character boundary
|
|
121
|
+
* (a buffer starting mid-sequence would replay as U+FFFD mojibake at the
|
|
122
|
+
* top of the restored scrollback), so the kept total may fall a few bytes
|
|
123
|
+
* under the cap.
|
|
124
|
+
*/
|
|
125
|
+
private appendScrollback;
|
|
77
126
|
onExit(callback: ExitCallback): void;
|
|
78
127
|
/**
|
|
79
128
|
* Register the manager-owned exit cleanup. Separate from the public onExit so
|
|
80
129
|
* it survives the websocket handler re-registering onExit on open/resume.
|
|
81
130
|
*/
|
|
82
131
|
setOnExitInternal(callback: () => void): void;
|
|
83
|
-
setOnIdleTimeout(callback: () => void): void;
|
|
84
132
|
write(data: string): void;
|
|
85
133
|
resize(cols: number, rows: number): void;
|
|
86
134
|
kill(): void;
|
|
@@ -88,8 +136,6 @@ export declare class TerminalSession {
|
|
|
88
136
|
isAlive(): boolean;
|
|
89
137
|
getInfo(): TerminalSessionInfo;
|
|
90
138
|
private touchActivity;
|
|
91
|
-
private resetIdleTimer;
|
|
92
|
-
private clearIdleTimer;
|
|
93
139
|
}
|
|
94
140
|
export {};
|
|
95
141
|
//# sourceMappingURL=terminal-session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-session.d.ts","sourceRoot":"","sources":["../../src/terminal/terminal-session.ts"],"names":[],"mappings":"AAgEA;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"terminal-session.d.ts","sourceRoot":"","sources":["../../src/terminal/terminal-session.ts"],"names":[],"mappings":"AAgEA;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxC;;;;OAIG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAA;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;AAC1C,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,+BAA+B,CAAA;AAEhE,qBAAa,eAAe;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAM;IACjC,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,YAAY,CAA4B;IAChD;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB,CAA4B;IACxD,OAAO,CAAC,MAAM,CAAQ;IACtB,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,eAAe,CAAI;IAE3B;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,qBAAqB,CAAC,QAAQ,GAAE,MAA4B,GAAG,MAAM;gBAyBhE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B;IAyHnE;;;;OAIG;IACH,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAIpC,8EAA8E;IAC9E,OAAO,IAAI,mBAAmB,GAAG,IAAI;IAIrC;;;;OAIG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IA2BxB,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAIpC;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAI7C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMzB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAQxC,IAAI,IAAI,IAAI;IAMZ,OAAO,CAAC,aAAa;IAmBrB,OAAO,IAAI,OAAO;IAIlB,OAAO,IAAI,mBAAmB;IAc9B,OAAO,CAAC,aAAa;CAGtB"}
|