diff --git a/patched-vscode/extensions/sagemaker-idle-extension/src/extension.ts b/patched-vscode/extensions/sagemaker-idle-extension/src/extension.ts index 2a11ca447..ccf6fed1d 100644 --- a/patched-vscode/extensions/sagemaker-idle-extension/src/extension.ts +++ b/patched-vscode/extensions/sagemaker-idle-extension/src/extension.ts @@ -2,22 +2,14 @@ import * as vscode from "vscode"; import * as fs from "fs"; import * as path from "path"; -let idleFilePath: string -let terminalActivityInterval: NodeJS.Timeout | undefined -const LOG_PREFIX = "[sagemaker-idle-extension]" -const CHECK_INTERVAL = 60000; // 60 seconds interval +let idleFilePath: string; export function activate(context: vscode.ExtensionContext) { initializeIdleFilePath(); registerEventListeners(context); - startMonitoringTerminalActivity(); } -export function deactivate() { - if(terminalActivityInterval) { - clearInterval(terminalActivityInterval) - } -} +export function deactivate() {} /** * Initializes the file path where the idle timestamp will be stored. @@ -28,7 +20,7 @@ function initializeIdleFilePath() { idleFilePath = path.join(tmpDirectory, ".sagemaker-last-active-timestamp"); // Set initial lastActivetimestamp - updateLastActivityTimestamp() + updateLastActivityTimestamp(); } /** @@ -56,52 +48,6 @@ function registerEventListeners(context: vscode.ExtensionContext) { ); } -/** - * Starts monitoring terminal activity by setting an interval to check for activity in the /dev/pts directory. - */ -const startMonitoringTerminalActivity = () => { - terminalActivityInterval = setInterval(checkTerminalActivity, CHECK_INTERVAL); -}; - - -/** - * Checks for terminal activity by reading the /dev/pts directory and comparing modification times of the files. - * - * The /dev/pts directory is used in Unix-like operating systems to represent pseudo-terminal (PTY) devices. - * Each active terminal session is assigned a PTY device. These devices are represented as files within the /dev/pts directory. - * When a terminal session has activity, such as when a user inputs commands or output is written to the terminal, - * the modification time (mtime) of the corresponding PTY device file is updated. By monitoring the modification - * times of the files in the /dev/pts directory, we can detect terminal activity. - * - * If activity is detected (i.e., if any PTY device file was modified within the CHECK_INTERVAL), this function - * updates the last activity timestamp. - */ -const checkTerminalActivity = () => { - fs.readdir("/dev/pts", (err, files) => { - if (err) { - console.error(`${LOG_PREFIX} Error reading /dev/pts directory:`, err); - return; - } - - const now = Date.now(); - const activityDetected = files.some((file) => { - const filePath = path.join("/dev/pts", file); - try { - const stats = fs.statSync(filePath); - const mtime = new Date(stats.mtime).getTime(); - return now - mtime < CHECK_INTERVAL; - } catch (error) { - console.error(`${LOG_PREFIX} Error reading file stats:`, error); - return false; - } - }); - - if (activityDetected) { - updateLastActivityTimestamp(); - } - }); -}; - /** * Updates the last activity timestamp by recording the current timestamp in the idle file and * refreshing the status bar. The timestamp should be in ISO 8601 format and set to the UTC timezone. diff --git a/patched-vscode/src/vs/server/node/webClientServer.ts b/patched-vscode/src/vs/server/node/webClientServer.ts index 4c0951b91..5ababf981 100644 --- a/patched-vscode/src/vs/server/node/webClientServer.ts +++ b/patched-vscode/src/vs/server/node/webClientServer.ts @@ -99,8 +99,41 @@ export async function serveFile(filePath: string, cacheControl: CacheControl, lo } } +const CHECK_INTERVAL = 60000; // 60 seconds interval const APP_ROOT = dirname(FileAccess.asFileUri('').fsPath); +/** + * Checks for terminal activity by reading the /dev/pts directory and comparing modification times of the files. + * + * The /dev/pts directory is used in Unix-like operating systems to represent pseudo-terminal (PTY) devices. + * Each active terminal session is assigned a PTY device. These devices are represented as files within the /dev/pts directory. + * When a terminal session has activity, such as when a user inputs commands or output is written to the terminal, + * the modification time (mtime) of the corresponding PTY device file is updated. By monitoring the modification + * times of the files in the /dev/pts directory, we can detect terminal activity. + * + * If activity is detected (i.e., if any PTY device file was modified within the CHECK_INTERVAL), this function + * updates the last activity timestamp. + */ +function checkTerminalActivity(idleFilePath: string) { + try { + const files: string[] = fs.readdirSync('/dev/pts'); + const now = new Date(); + + const activityDetected = files.some((file: string) => { + const filePath = path.join('/dev/pts', file); + const stats = fs.statSync(filePath); + const mtime = new Date(stats.mtime).getTime(); + return now.getTime() - mtime < CHECK_INTERVAL; + }); + + if (activityDetected) { + fs.writeFileSync(idleFilePath, now.toISOString()); + } + } catch (err) { + console.error('Error checking terminal activity:', err); + } +} + export class WebClientServer { private readonly _webExtensionResourceUrlTemplate: URI | undefined; @@ -481,6 +514,8 @@ export class WebClientServer { writeFileSync(idleFilePath, timestamp); } + checkTerminalActivity(idleFilePath); + const data = await readFile(idleFilePath, 'utf8'); res.statusCode = 200; diff --git a/patches/custom-extensions-marketplace.diff b/patches/custom-extensions-marketplace.diff index 1a2d800b2..af27d948c 100644 --- a/patches/custom-extensions-marketplace.diff +++ b/patches/custom-extensions-marketplace.diff @@ -98,7 +98,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- sagemaker-code-editor.orig/vscode/src/vs/server/node/webClientServer.ts +++ sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts -@@ -331,14 +331,7 @@ export class WebClientServer { +@@ -364,14 +364,7 @@ export class WebClientServer { const productConfiguration = { rootEndpoint: base, embedderIdentifier: 'server-distro', diff --git a/patches/display-language.patch b/patches/display-language.patch index 762378d50..f818be772 100644 --- a/patches/display-language.patch +++ b/patches/display-language.patch @@ -304,7 +304,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts import { CharCode } from 'vs/base/common/charCode'; import { IExtensionManifest } from 'vs/platform/extensions/common/extensions'; -@@ -362,6 +363,8 @@ export class WebClientServer { +@@ -395,6 +396,8 @@ export class WebClientServer { callbackRoute: this._callbackRoute }; @@ -313,7 +313,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts const nlsBaseUrl = this._productService.extensionsGallery?.nlsBaseUrl; const values: { [key: string]: string } = { WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration), -@@ -370,6 +373,7 @@ export class WebClientServer { +@@ -403,6 +406,7 @@ export class WebClientServer { WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''), BASE: base, VS_BASE: vscodeBase, @@ -321,7 +321,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts }; if (useTestResolver) { -@@ -401,7 +405,7 @@ export class WebClientServer { +@@ -434,7 +438,7 @@ export class WebClientServer { `frame-src 'self' https://*.vscode-cdn.net data:;`, 'worker-src \'self\' data: blob:;', 'style-src \'self\' \'unsafe-inline\';', diff --git a/patches/sagemaker-extensions-sync.patch b/patches/sagemaker-extensions-sync.patch index 2d6e6315b..ff972a0cf 100644 --- a/patches/sagemaker-extensions-sync.patch +++ b/patches/sagemaker-extensions-sync.patch @@ -9,7 +9,7 @@ Index: sagemaker-code-editor/vscode/build/gulpfile.extensions.js + 'extensions/sagemaker-extensions-sync/tsconfig.json', 'extensions/sagemaker-terminal-crash-mitigation/tsconfig.json', 'extensions/sagemaker-open-notebook-extension/tsconfig.json', - 'extensions/tunnel-forwarding/tsconfig.json', + 'extensions/sagemaker-ui-dark-theme/tsconfig.json', Index: sagemaker-code-editor/vscode/build/npm/dirs.js =================================================================== --- sagemaker-code-editor.orig/vscode/build/npm/dirs.js diff --git a/patches/sagemaker-idle-extension.patch b/patches/sagemaker-idle-extension.patch index 4dd98f639..049cce6c7 100644 --- a/patches/sagemaker-idle-extension.patch +++ b/patches/sagemaker-idle-extension.patch @@ -147,27 +147,19 @@ Index: sagemaker-code-editor/vscode/extensions/sagemaker-idle-extension/src/exte =================================================================== --- /dev/null +++ sagemaker-code-editor/vscode/extensions/sagemaker-idle-extension/src/extension.ts -@@ -0,0 +1,112 @@ +@@ -0,0 +1,58 @@ +import * as vscode from "vscode"; +import * as fs from "fs"; +import * as path from "path"; + -+let idleFilePath: string -+let terminalActivityInterval: NodeJS.Timeout | undefined -+const LOG_PREFIX = "[sagemaker-idle-extension]" -+const CHECK_INTERVAL = 60000; // 60 seconds interval ++let idleFilePath: string; + +export function activate(context: vscode.ExtensionContext) { + initializeIdleFilePath(); + registerEventListeners(context); -+ startMonitoringTerminalActivity(); +} + -+export function deactivate() { -+ if(terminalActivityInterval) { -+ clearInterval(terminalActivityInterval) -+ } -+} ++export function deactivate() {} + +/** + * Initializes the file path where the idle timestamp will be stored. @@ -178,7 +170,7 @@ Index: sagemaker-code-editor/vscode/extensions/sagemaker-idle-extension/src/exte + idleFilePath = path.join(tmpDirectory, ".sagemaker-last-active-timestamp"); + + // Set initial lastActivetimestamp -+ updateLastActivityTimestamp() ++ updateLastActivityTimestamp(); +} + +/** @@ -207,52 +199,6 @@ Index: sagemaker-code-editor/vscode/extensions/sagemaker-idle-extension/src/exte +} + +/** -+ * Starts monitoring terminal activity by setting an interval to check for activity in the /dev/pts directory. -+ */ -+const startMonitoringTerminalActivity = () => { -+ terminalActivityInterval = setInterval(checkTerminalActivity, CHECK_INTERVAL); -+}; -+ -+ -+/** -+ * Checks for terminal activity by reading the /dev/pts directory and comparing modification times of the files. -+ * -+ * The /dev/pts directory is used in Unix-like operating systems to represent pseudo-terminal (PTY) devices. -+ * Each active terminal session is assigned a PTY device. These devices are represented as files within the /dev/pts directory. -+ * When a terminal session has activity, such as when a user inputs commands or output is written to the terminal, -+ * the modification time (mtime) of the corresponding PTY device file is updated. By monitoring the modification -+ * times of the files in the /dev/pts directory, we can detect terminal activity. -+ * -+ * If activity is detected (i.e., if any PTY device file was modified within the CHECK_INTERVAL), this function -+ * updates the last activity timestamp. -+ */ -+const checkTerminalActivity = () => { -+ fs.readdir("/dev/pts", (err, files) => { -+ if (err) { -+ console.error(`${LOG_PREFIX} Error reading /dev/pts directory:`, err); -+ return; -+ } -+ -+ const now = Date.now(); -+ const activityDetected = files.some((file) => { -+ const filePath = path.join("/dev/pts", file); -+ try { -+ const stats = fs.statSync(filePath); -+ const mtime = new Date(stats.mtime).getTime(); -+ return now - mtime < CHECK_INTERVAL; -+ } catch (error) { -+ console.error(`${LOG_PREFIX} Error reading file stats:`, error); -+ return false; -+ } -+ }); -+ -+ if (activityDetected) { -+ updateLastActivityTimestamp(); -+ } -+ }); -+}; -+ -+/** + * Updates the last activity timestamp by recording the current timestamp in the idle file and + * refreshing the status bar. The timestamp should be in ISO 8601 format and set to the UTC timezone. + */ @@ -289,7 +235,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- sagemaker-code-editor.orig/vscode/src/vs/server/node/webClientServer.ts +++ sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts -@@ -3,7 +3,8 @@ +@@ -3,8 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ @@ -297,9 +243,53 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts +import { createReadStream, existsSync, writeFileSync } from 'fs'; +import {readFile } from 'fs/promises'; import { Promises } from 'vs/base/node/pfs'; ++import * as fs from 'fs'; import * as path from 'path'; import * as http from 'http'; -@@ -100,6 +101,7 @@ export class WebClientServer { + import * as url from 'url'; +@@ -91,8 +93,41 @@ export async function serveFile(filePath + } + } + ++const CHECK_INTERVAL = 60000; // 60 seconds interval + const APP_ROOT = dirname(FileAccess.asFileUri('').fsPath); + ++/** ++ * Checks for terminal activity by reading the /dev/pts directory and comparing modification times of the files. ++ * ++ * The /dev/pts directory is used in Unix-like operating systems to represent pseudo-terminal (PTY) devices. ++ * Each active terminal session is assigned a PTY device. These devices are represented as files within the /dev/pts directory. ++ * When a terminal session has activity, such as when a user inputs commands or output is written to the terminal, ++ * the modification time (mtime) of the corresponding PTY device file is updated. By monitoring the modification ++ * times of the files in the /dev/pts directory, we can detect terminal activity. ++ * ++ * If activity is detected (i.e., if any PTY device file was modified within the CHECK_INTERVAL), this function ++ * updates the last activity timestamp. ++ */ ++function checkTerminalActivity(idleFilePath: string) { ++ try { ++ const files: string[] = fs.readdirSync('/dev/pts'); ++ const now = new Date(); ++ ++ const activityDetected = files.some((file: string) => { ++ const filePath = path.join('/dev/pts', file); ++ const stats = fs.statSync(filePath); ++ const mtime = new Date(stats.mtime).getTime(); ++ return now.getTime() - mtime < CHECK_INTERVAL; ++ }); ++ ++ if (activityDetected) { ++ fs.writeFileSync(idleFilePath, now.toISOString()); ++ } ++ } catch (err) { ++ console.error('Error checking terminal activity:', err); ++ } ++} ++ + export class WebClientServer { + + private readonly _webExtensionResourceUrlTemplate: URI | undefined; +@@ -100,6 +135,7 @@ export class WebClientServer { private readonly _staticRoute: string; private readonly _callbackRoute: string; private readonly _webExtensionRoute: string; @@ -307,7 +297,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts constructor( private readonly _connectionToken: ServerConnectionToken, -@@ -115,6 +117,7 @@ export class WebClientServer { +@@ -115,6 +151,7 @@ export class WebClientServer { this._staticRoute = `${serverRootPath}/static`; this._callbackRoute = `${serverRootPath}/callback`; this._webExtensionRoute = `${serverRootPath}/web-extension-resource`; @@ -315,7 +305,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts } /** -@@ -132,6 +135,9 @@ export class WebClientServer { +@@ -132,6 +169,9 @@ export class WebClientServer { if (pathname === this._basePath) { return this._handleRoot(req, res, parsedUrl); } @@ -325,7 +315,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts if (pathname === this._callbackRoute) { // callback support return this._handleCallback(res); -@@ -451,6 +457,31 @@ export class WebClientServer { +@@ -451,6 +491,33 @@ export class WebClientServer { }); return void res.end(data); } @@ -345,6 +335,8 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts + writeFileSync(idleFilePath, timestamp); + } + ++ checkTerminalActivity(idleFilePath); ++ + const data = await readFile(idleFilePath, 'utf8'); + + res.statusCode = 200; diff --git a/patches/sagemaker-ui-post-startup.patch b/patches/sagemaker-ui-post-startup.patch index 56e5ba58e..43fd35886 100644 --- a/patches/sagemaker-ui-post-startup.patch +++ b/patches/sagemaker-ui-post-startup.patch @@ -2,16 +2,15 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- sagemaker-code-editor.orig/vscode/src/vs/server/node/webClientServer.ts +++ sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts -@@ -6,6 +6,8 @@ +@@ -6,6 +6,7 @@ import { createReadStream, existsSync, writeFileSync } from 'fs'; import {readFile } from 'fs/promises'; import { Promises } from 'vs/base/node/pfs'; +import { spawn } from 'child_process'; -+import * as fs from 'fs'; + import * as fs from 'fs'; import * as path from 'path'; import * as http from 'http'; - import * as url from 'url'; -@@ -39,6 +41,10 @@ const textMimeType: { [ext: string]: str +@@ -40,6 +41,10 @@ const textMimeType: { [ext: string]: str '.svg': 'image/svg+xml', }; @@ -22,7 +21,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts /** * Return an error to the client. */ -@@ -102,6 +108,7 @@ export class WebClientServer { +@@ -136,6 +141,7 @@ export class WebClientServer { private readonly _callbackRoute: string; private readonly _webExtensionRoute: string; private readonly _idleRoute: string; @@ -30,7 +29,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts constructor( private readonly _connectionToken: ServerConnectionToken, -@@ -118,6 +125,7 @@ export class WebClientServer { +@@ -152,6 +158,7 @@ export class WebClientServer { this._callbackRoute = `${serverRootPath}/callback`; this._webExtensionRoute = `${serverRootPath}/web-extension-resource`; this._idleRoute = '/api/idle'; @@ -38,7 +37,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts } /** -@@ -146,6 +154,9 @@ export class WebClientServer { +@@ -180,6 +187,9 @@ export class WebClientServer { // extension resource support return this._handleWebExtensionResource(req, res, parsedUrl); } @@ -48,7 +47,7 @@ Index: sagemaker-code-editor/vscode/src/vs/server/node/webClientServer.ts return serveError(req, res, 404, 'Not found.'); } catch (error) { -@@ -482,6 +493,41 @@ export class WebClientServer { +@@ -518,6 +528,41 @@ export class WebClientServer { serveError(req, res, 500, error.message) } }