From df46ec538e4dc0189aaff48b51d6d7acf62d4c95 Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 20 Aug 2025 10:21:48 -0700 Subject: [PATCH 1/5] handle home dir --- .../rush/browser-approved-packages.json | 4 + .../config/subspaces/default/pnpm-lock.yaml | 23 ++--- .../config/subspaces/default/repo-state.json | 2 +- .../package.json | 7 +- .../src/extension.ts | 40 +++++---- .../src/terminal.ts | 89 +++++++++++++++++++ .../rush-vscode-command-webview/package.json | 2 +- .../rush-vscode-extension/package.json | 4 +- vscode-extensions/vscode-shared/package.json | 2 +- 9 files changed, 140 insertions(+), 33 deletions(-) create mode 100644 vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts diff --git a/common/config/rush/browser-approved-packages.json b/common/config/rush/browser-approved-packages.json index 15e248ddeba..90b1703a76e 100644 --- a/common/config/rush/browser-approved-packages.json +++ b/common/config/rush/browser-approved-packages.json @@ -90,6 +90,10 @@ "name": "scheduler", "allowedCategories": [ "vscode-extensions" ] }, + { + "name": "strip-ansi", + "allowedCategories": [ "vscode-extensions" ] + }, { "name": "tslib", "allowedCategories": [ "libraries", "tests", "vscode-extensions" ] diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index 926ccedf493..37f8e8e0856 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -4633,6 +4633,9 @@ importers: '@rushstack/vscode-shared': specifier: workspace:* version: link:../vscode-shared + strip-ansi: + specifier: ~7.1.0 + version: 7.1.0 tslib: specifier: ~2.3.1 version: 2.3.1 @@ -4647,8 +4650,8 @@ importers: specifier: 20.17.19 version: 20.17.19 '@types/vscode': - specifier: ^1.63.0 - version: 1.87.0 + specifier: 1.103.0 + version: 1.103.0 '@types/webpack-env': specifier: 1.18.8 version: 1.18.8 @@ -4702,8 +4705,8 @@ importers: specifier: ~7.1.22 version: 7.1.33 '@types/vscode': - specifier: ^1.63.0 - version: 1.87.0 + specifier: 1.103.0 + version: 1.103.0 eslint: specifier: ~9.25.1 version: 9.25.1(supports-color@8.1.1) @@ -4754,8 +4757,8 @@ importers: specifier: 10.0.6 version: 10.0.6 '@types/vscode': - specifier: ^1.63.0 - version: 1.87.0 + specifier: 1.103.0 + version: 1.103.0 '@types/webpack-env': specifier: 1.18.8 version: 1.18.8 @@ -4791,8 +4794,8 @@ importers: specifier: 20.17.19 version: 20.17.19 '@types/vscode': - specifier: ^1.63.0 - version: 1.87.0 + specifier: 1.103.0 + version: 1.103.0 ../../../webpack/hashed-folder-copy-plugin: dependencies: @@ -14172,8 +14175,8 @@ packages: resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} dev: true - /@types/vscode@1.87.0: - resolution: {integrity: sha512-y3yYJV2esWr8LNjp3VNbSMWG7Y43jC8pCldG8YwiHGAQbsymkkMMt0aDT1xZIOFM2eFcNiUc+dJMx1+Z0UT8fg==} + /@types/vscode@1.103.0: + resolution: {integrity: sha512-o4hanZAQdNfsKecexq9L3eHICd0AAvdbLk6hA60UzGXbGH/q8b/9xv2RgR7vV3ZcHuyKVq7b37IGd/+gM4Tu+Q==} dev: true /@types/watchpack@2.4.0: diff --git a/common/config/subspaces/default/repo-state.json b/common/config/subspaces/default/repo-state.json index f46f92b78d4..3493f574552 100644 --- a/common/config/subspaces/default/repo-state.json +++ b/common/config/subspaces/default/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "58011e1085f2aad3dc842a758d45841ef7b79c4e", + "pnpmShrinkwrapHash": "bf42ec3e79f384de8e702662661546c4a52798fe", "preferredVersionsHash": "61cd419c533464b580f653eb5f5a7e27fe7055ca" } diff --git a/vscode-extensions/debug-certificate-manager-vscode-extension/package.json b/vscode-extensions/debug-certificate-manager-vscode-extension/package.json index 41f8903908d..2584308c383 100644 --- a/vscode-extensions/debug-certificate-manager-vscode-extension/package.json +++ b/vscode-extensions/debug-certificate-manager-vscode-extension/package.json @@ -25,7 +25,7 @@ "theme": "light" }, "engines": { - "vscode": "^1.98.0" + "vscode": "^1.103.0" }, "main": "./extension.js", "scripts": { @@ -114,13 +114,14 @@ "@rushstack/node-core-library": "workspace:*", "@rushstack/terminal": "workspace:*", "@rushstack/vscode-shared": "workspace:*", - "tslib": "~2.3.1" + "tslib": "~2.3.1", + "strip-ansi": "~7.1.0" }, "devDependencies": { "@rushstack/heft-vscode-extension-rig": "workspace:*", "@rushstack/heft": "workspace:*", "@types/node": "20.17.19", - "@types/vscode": "^1.63.0", + "@types/vscode": "1.103.0", "@types/webpack-env": "1.18.8" } } diff --git a/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts b/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts index e92ec302edc..a7c2de7dbc1 100644 --- a/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts +++ b/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts @@ -25,6 +25,7 @@ import { EXTENSION_ID, VSCODE_COMMAND_WORKSPACE_OPEN_SETTINGS } from './constants'; +import { runWorkspaceCommandAsync } from './terminal'; export function activate(context: vscode.ExtensionContext): void { const outputChannel: vscode.OutputChannel = vscode.window.createOutputChannel(EXTENSION_DISPLAY_NAME); @@ -205,26 +206,34 @@ export function activate(context: vscode.ExtensionContext): void { let resolvedWorkspaceStorePath: string; if (storePath.startsWith('/')) { resolvedWorkspaceStorePath = storePath; - } else { - resolvedWorkspaceStorePath = vscode.Uri.joinPath(workspaceUri, storePath).path; - } - - let storePathUri: vscode.Uri | undefined; - if (vscode.env.remoteName) { - storePathUri = vscode.Uri.from({ - scheme: 'vscode-remote', + } else if (storePath.startsWith('~')) { + let homeDir: string; + if (vscode.env.remoteName) { + homeDir = await runWorkspaceCommandAsync({ + terminalOptions: { name: 'debug-certificate-manager', hideFromUser: true }, + commandLine: `node -e "console.log(require('os').homedir())"`, + terminal + }); + } else { + homeDir = require('os').homedir(); + } + terminal.writeLine(`Resolved home directory: ${homeDir}`); + const homeDirUri: vscode.Uri = vscode.Uri.from({ + scheme: workspaceUri.scheme, authority: workspaceUri.authority, - path: resolvedWorkspaceStorePath + path: homeDir }); + resolvedWorkspaceStorePath = vscode.Uri.joinPath(homeDirUri, storePath.slice(1)).path; } else { - storePathUri = vscode.Uri.file(resolvedWorkspaceStorePath); - } - if (!storePathUri) { - terminal.writeLine('Failed to resolve store path URI.'); - void vscode.window.showErrorMessage('Failed to resolve store path URI.'); - return; + resolvedWorkspaceStorePath = vscode.Uri.joinPath(workspaceUri, storePath).path; } + const storePathUri: vscode.Uri = vscode.Uri.from({ + scheme: workspaceUri.scheme, + authority: workspaceUri.authority, + path: resolvedWorkspaceStorePath + }); + const caCertificateUri: vscode.Uri = vscode.Uri.joinPath(storePathUri, caCertificateFilename); const certificateUri: vscode.Uri = vscode.Uri.joinPath(storePathUri, certificateFilename); const keyUri: vscode.Uri = vscode.Uri.joinPath(storePathUri, keyFilename); @@ -252,6 +261,7 @@ export function activate(context: vscode.ExtensionContext): void { const { autoSync } = getConfig(terminal); if (autoSync) { terminal.writeLine(`Auto-sync is enabled. Synchronizing certificates on activation...`); + void handleSync(); } context.subscriptions.push( diff --git a/vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts b/vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts new file mode 100644 index 00000000000..91bf74fa331 --- /dev/null +++ b/vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import { ITerminal } from '@rushstack/terminal'; +import * as vscode from 'vscode'; +import stripAnsi from 'strip-ansi'; + +export async function runWorkspaceCommandAsync({ + terminalOptions, + commandLine, + terminal +}: { + terminalOptions: vscode.TerminalOptions; + commandLine: string; + terminal: ITerminal; +}): Promise { + const vsTerminal: vscode.Terminal = vscode.window.createTerminal(terminalOptions); + + // wait for shell to bootup and vs code shell integration to kick-in + const shellIntegration: vscode.TerminalShellIntegration = + vsTerminal.shellIntegration ?? + (await new Promise((resolve, reject) => { + let timeoutId: NodeJS.Timeout | undefined; + const shellIntegrationDisposable: vscode.Disposable = vscode.window.onDidChangeTerminalShellIntegration( + (event) => { + if (event.terminal !== vsTerminal) { + return; + } + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = undefined; + } + resolve(event.shellIntegration); + shellIntegrationDisposable?.dispose(); + } + ); + timeoutId = setTimeout(() => { + shellIntegrationDisposable?.dispose(); + reject(new Error('Shell integration timeout')); + }, 5000); + })); + + // Run the command through shell integration and grab output + return new Promise((resolve, reject) => { + let outputStream: string = ''; + + // start output capturing with the start execution event + const startExecutionDisposable: vscode.Disposable = vscode.window.onDidStartTerminalShellExecution( + async (event) => { + if (event.terminal !== vsTerminal) { + return; + } + terminal.writeLine(`Terminal shell execution started`); + + for await (const chunk of event.execution.read()) { + outputStream += chunk; + } + } + ); + + // collect output and exit code + const endExecutionDisposable: vscode.Disposable = vscode.window.onDidEndTerminalShellExecution( + (event) => { + if (event.terminal !== vsTerminal) { + return; + } + + terminal.writeLine(`Terminal shell execution ended with exit code ${event.exitCode}`); + outputStream = outputStream.trim(); + outputStream = stripAnsi(outputStream); + terminal.writeLine(`Terminal output: ${outputStream}`); + + endExecutionDisposable.dispose(); + startExecutionDisposable.dispose(); + + if (event.exitCode === 0) { + resolve(outputStream); + } else { + reject(outputStream); + } + } + ); + + shellIntegration.executeCommand(commandLine); + terminal.writeLine(`Executing command: ${commandLine}`); + }).finally(() => { + vsTerminal.dispose(); + }); +} diff --git a/vscode-extensions/rush-vscode-command-webview/package.json b/vscode-extensions/rush-vscode-command-webview/package.json index 6a1eaddbfa6..c43c71bc3be 100644 --- a/vscode-extensions/rush-vscode-command-webview/package.json +++ b/vscode-extensions/rush-vscode-command-webview/package.json @@ -35,7 +35,7 @@ "@types/react": "17.0.74", "@types/react-dom": "17.0.25", "@types/react-redux": "~7.1.22", - "@types/vscode": "^1.63.0", + "@types/vscode": "1.103.0", "eslint": "~9.25.1", "html-webpack-plugin": "~5.5.0", "local-web-rig": "workspace:*", diff --git a/vscode-extensions/rush-vscode-extension/package.json b/vscode-extensions/rush-vscode-extension/package.json index 3f9117a32a6..765e397f718 100644 --- a/vscode-extensions/rush-vscode-extension/package.json +++ b/vscode-extensions/rush-vscode-extension/package.json @@ -264,7 +264,7 @@ "@rushstack/heft": "workspace:*", "@types/glob": "7.1.1", "@types/mocha": "10.0.6", - "@types/vscode": "^1.63.0", + "@types/vscode": "1.103.0", "@types/webpack-env": "1.18.8", "@vscode/test-electron": "^1.6.2", "eslint": "~9.25.1", @@ -273,6 +273,6 @@ "mocha": "^10.1.0" }, "engines": { - "vscode": "^1.63.0" + "vscode": "^1.103.0" } } diff --git a/vscode-extensions/vscode-shared/package.json b/vscode-extensions/vscode-shared/package.json index b7bac7806c7..afc7acdb9fd 100644 --- a/vscode-extensions/vscode-shared/package.json +++ b/vscode-extensions/vscode-shared/package.json @@ -23,6 +23,6 @@ "@rushstack/heft-node-rig": "workspace:*", "@rushstack/heft": "workspace:*", "@types/node": "20.17.19", - "@types/vscode": "^1.63.0" + "@types/vscode": "1.103.0" } } From fc4d2697cf9bc3586b23bc476dcb0452f53a9a84 Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 20 Aug 2025 10:22:18 -0700 Subject: [PATCH 2/5] bump version --- .../debug-certificate-manager-vscode-extension/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vscode-extensions/debug-certificate-manager-vscode-extension/package.json b/vscode-extensions/debug-certificate-manager-vscode-extension/package.json index 2584308c383..1cb61b62e3d 100644 --- a/vscode-extensions/debug-certificate-manager-vscode-extension/package.json +++ b/vscode-extensions/debug-certificate-manager-vscode-extension/package.json @@ -1,6 +1,6 @@ { "name": "debug-certificate-manager", - "version": "0.0.1", + "version": "0.0.2", "repository": { "type": "git", "url": "https://github.com/microsoft/rushstack.git", From 2b728fa06f414a5c9712b2c12966425c12521b9a Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 20 Aug 2025 10:27:34 -0700 Subject: [PATCH 3/5] fixup --- common/config/rush/browser-approved-packages.json | 4 ---- common/config/rush/nonbrowser-approved-packages.json | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/config/rush/browser-approved-packages.json b/common/config/rush/browser-approved-packages.json index 90b1703a76e..15e248ddeba 100644 --- a/common/config/rush/browser-approved-packages.json +++ b/common/config/rush/browser-approved-packages.json @@ -90,10 +90,6 @@ "name": "scheduler", "allowedCategories": [ "vscode-extensions" ] }, - { - "name": "strip-ansi", - "allowedCategories": [ "vscode-extensions" ] - }, { "name": "tslib", "allowedCategories": [ "libraries", "tests", "vscode-extensions" ] diff --git a/common/config/rush/nonbrowser-approved-packages.json b/common/config/rush/nonbrowser-approved-packages.json index 9f344afc501..84a8167a448 100644 --- a/common/config/rush/nonbrowser-approved-packages.json +++ b/common/config/rush/nonbrowser-approved-packages.json @@ -930,6 +930,10 @@ "name": "string-argv", "allowedCategories": [ "libraries" ] }, + { + "name": "strip-ansi", + "allowedCategories": [ "vscode-extensions" ] + }, { "name": "strip-json-comments", "allowedCategories": [ "libraries" ] From 4d0501a60f23a87882912e9c757c3e83a3144185 Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 20 Aug 2025 14:11:38 -0700 Subject: [PATCH 4/5] use node util to remove ansi characters --- common/config/rush/nonbrowser-approved-packages.json | 4 ---- common/config/subspaces/default/pnpm-lock.yaml | 3 --- .../debug-certificate-manager-vscode-extension/package.json | 3 +-- .../src/terminal.ts | 4 ++-- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/common/config/rush/nonbrowser-approved-packages.json b/common/config/rush/nonbrowser-approved-packages.json index 84a8167a448..9f344afc501 100644 --- a/common/config/rush/nonbrowser-approved-packages.json +++ b/common/config/rush/nonbrowser-approved-packages.json @@ -930,10 +930,6 @@ "name": "string-argv", "allowedCategories": [ "libraries" ] }, - { - "name": "strip-ansi", - "allowedCategories": [ "vscode-extensions" ] - }, { "name": "strip-json-comments", "allowedCategories": [ "libraries" ] diff --git a/common/config/subspaces/default/pnpm-lock.yaml b/common/config/subspaces/default/pnpm-lock.yaml index 37f8e8e0856..7a99d14f796 100644 --- a/common/config/subspaces/default/pnpm-lock.yaml +++ b/common/config/subspaces/default/pnpm-lock.yaml @@ -4633,9 +4633,6 @@ importers: '@rushstack/vscode-shared': specifier: workspace:* version: link:../vscode-shared - strip-ansi: - specifier: ~7.1.0 - version: 7.1.0 tslib: specifier: ~2.3.1 version: 2.3.1 diff --git a/vscode-extensions/debug-certificate-manager-vscode-extension/package.json b/vscode-extensions/debug-certificate-manager-vscode-extension/package.json index 1cb61b62e3d..76fb49e3639 100644 --- a/vscode-extensions/debug-certificate-manager-vscode-extension/package.json +++ b/vscode-extensions/debug-certificate-manager-vscode-extension/package.json @@ -114,8 +114,7 @@ "@rushstack/node-core-library": "workspace:*", "@rushstack/terminal": "workspace:*", "@rushstack/vscode-shared": "workspace:*", - "tslib": "~2.3.1", - "strip-ansi": "~7.1.0" + "tslib": "~2.3.1" }, "devDependencies": { "@rushstack/heft-vscode-extension-rig": "workspace:*", diff --git a/vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts b/vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts index 91bf74fa331..9def626f78b 100644 --- a/vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts +++ b/vscode-extensions/debug-certificate-manager-vscode-extension/src/terminal.ts @@ -3,7 +3,7 @@ import { ITerminal } from '@rushstack/terminal'; import * as vscode from 'vscode'; -import stripAnsi from 'strip-ansi'; +import { stripVTControlCharacters } from 'node:util'; export async function runWorkspaceCommandAsync({ terminalOptions, @@ -67,7 +67,7 @@ export async function runWorkspaceCommandAsync({ terminal.writeLine(`Terminal shell execution ended with exit code ${event.exitCode}`); outputStream = outputStream.trim(); - outputStream = stripAnsi(outputStream); + outputStream = stripVTControlCharacters(outputStream); terminal.writeLine(`Terminal output: ${outputStream}`); endExecutionDisposable.dispose(); From 4713fb1a7374315a6b7df768c1c2e7516511ab65 Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 20 Aug 2025 17:08:51 -0700 Subject: [PATCH 5/5] use node -p --- .../debug-certificate-manager-vscode-extension/src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts b/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts index a7c2de7dbc1..806f7183dea 100644 --- a/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts +++ b/vscode-extensions/debug-certificate-manager-vscode-extension/src/extension.ts @@ -211,7 +211,7 @@ export function activate(context: vscode.ExtensionContext): void { if (vscode.env.remoteName) { homeDir = await runWorkspaceCommandAsync({ terminalOptions: { name: 'debug-certificate-manager', hideFromUser: true }, - commandLine: `node -e "console.log(require('os').homedir())"`, + commandLine: `node -p "require('os').homedir()"`, terminal }); } else {