Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ CVE-2025-14505
# Library is used in nested dependencies and not directly used by our codebase. No fix released by the author.
CVE-2025-69873

# Library is used in nested dependencies and not directly used by our codebase. No fix released by the author.
CVE-2026-26996
# used in nested dependencies and not directly used by our codebase. No fix released by the author.
CVE-2026-26996
1 change: 1 addition & 0 deletions common/autoinstallers/rush-plugins/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"pnpm": {
"overrides": {
"fast-xml-parser": "5.3.7"
}
},
"dependencies": {
Expand Down
11 changes: 7 additions & 4 deletions common/autoinstallers/rush-plugins/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions common/config/rush/.pnpmfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = {
pkg.dependencies['eslint'] = '^9.27.0';
}
if (pkg.dependencies['fast-xml-parser']) {
pkg.dependencies['fast-xml-parser'] = '5.3.6';
pkg.dependencies['fast-xml-parser'] = '5.3.7';
}
if (pkg.dependencies['lodash']) {
pkg.dependencies['lodash'] = '4.17.23';
Expand Down Expand Up @@ -92,7 +92,7 @@ module.exports = {
pkg.devDependencies['eslint'] = '^9.27.0';
}
if (pkg.devDependencies['fast-xml-parser']) {
pkg.devDependencies['fast-xml-parser'] = '5.3.6';
pkg.devDependencies['fast-xml-parser'] = '5.3.7';
}
if (pkg.devDependencies['lodash']) {
pkg.devDependencies['lodash'] = '4.17.23';
Expand Down
26 changes: 13 additions & 13 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion workspaces/ballerina/ballerina-extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
- **Copilot & Agent Flow** — Fixed multi-turn chat state persistence, chat agent creation with listener support, config-collector placeholder handling, and login notification issues for default model provider configuration.
- **Security** — Applied vulnerability and dependency security fixes across BI extension components.

## [5.8.1](https://github.com/wso2/vscode-extensions/compare/ballerina-integrator-1.7.0...ballerina-5.8.1) - 2026-02-25

### Fixed

- **Installation** — Enhanced Windows environment detection to properly identify Ballerina distributions on Windows.

## [5.8.0](https://github.com/wso2/vscode-extensions/compare/ballerina-5.7.3...ballerina-5.8.0) - 2026-02-14
## [5.8.0](https://github.com/wso2/vscode-extensions/compare/ballerina-5.7.3...ballerina-integrator-1.7.0) - 2026-02-14

### Added

Expand Down
2 changes: 1 addition & 1 deletion workspaces/ballerina/ballerina-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ballerina",
"displayName": "Ballerina",
"description": "Ballerina Language support, debugging, graphical visualization, AI-based data-mapping and many more.",
"version": "5.8.0",
"version": "5.8.1",
"publisher": "wso2",
"icon": "resources/images/ballerina.png",
"homepage": "https://wso2.com/ballerina/vscode/docs",
Expand Down
104 changes: 102 additions & 2 deletions workspaces/ballerina/ballerina-extension/src/core/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,18 @@ export class BallerinaExtension {
if (distPath) { break; }
}
}
} else if (isWindows() && !ballerinaHome) {
// On Windows, if syncEnvironment() already merged the User+Machine PATH the
// 'bal.bat version' call below will just work via PATH lookup (distPath stays
// empty). But for restricted environments (where even User
// PATH is locked, or where VSCode's inherited PATH is still stale), we run a
// proactive directory search here so that we can use an absolute path instead
// of relying on PATH resolution.
const detectedBinPath = findWindowsBallerinaPath();
if (detectedBinPath) {
distPath = detectedBinPath;
debug(`[VERSION] Windows fallback search found Ballerina bin: ${distPath}`);
}
}

let exeExtension = "";
Expand Down Expand Up @@ -2690,6 +2702,83 @@ function updateProcessEnv(newEnv: NodeJS.ProcessEnv): void {
debug("[UPDATE_ENV] Process environment update completed");
}

/**
* Searches for the Ballerina bin directory on Windows using two strategies:
* 1. Read the User-scope and Machine-scope PATH entries from the registry and look
* for a directory that contains bal.bat.
* 2. Check well-known installation directories (LOCALAPPDATA, ProgramFiles, etc.).
*
* Returns the bin directory path (with trailing separator) or an empty string when
* nothing is found. This is used as a last-resort fallback for environments where the
* process PATH was not updated (e.g. company laptops with restricted System PATH, or
* VS Code opened before the installer ran).
*/
function findWindowsBallerinaPath(): string {
debug('[WIN_BAL_FIND] Searching for Ballerina installation on Windows...');

// --- Strategy 1: scan PATH entries from User + Machine registry scopes ---
try {
const psCommand =
'[Environment]::GetEnvironmentVariable(\'Path\',\'Machine\') + \';\' + ' +
'[Environment]::GetEnvironmentVariable(\'Path\',\'User\')';
const rawPaths = execSync(
`powershell.exe -NoProfile -Command "${psCommand}"`,
{ encoding: 'utf8', timeout: 10000 }
).trim();

debug(`[WIN_BAL_FIND] Registry PATH (Machine+User) length: ${rawPaths.length} chars`);

const pathEntries = rawPaths.split(';').map(p => p.trim()).filter(Boolean);
for (const entry of pathEntries) {
const candidate = path.join(entry, 'bal.bat');
if (fs.existsSync(candidate)) {
debug(`[WIN_BAL_FIND] Found bal.bat in registry PATH entry: ${entry}`);
return entry + path.sep;
}
}
debug('[WIN_BAL_FIND] bal.bat not found in registry PATH entries');
} catch (err) {
debug(`[WIN_BAL_FIND] Failed to read registry PATH: ${err}`);
}

// --- Strategy 2: check well-known Ballerina installation directories ---
const localAppData = process.env.LOCALAPPDATA || '';
const programFiles = process.env.ProgramFiles || 'C:\\Program Files';
const programFilesX86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)';

const searchRoots = [
localAppData ? path.join(localAppData, 'Programs', 'Ballerina') : '',
path.join(programFiles, 'Ballerina'),
path.join(programFilesX86, 'Ballerina'),
'C:\\Ballerina',
].filter(Boolean);

for (const root of searchRoots) {
const directBin = path.join(root, 'bin');
if (fs.existsSync(path.join(directBin, 'bal.bat'))) {
debug(`[WIN_BAL_FIND] Found bal.bat in common directory: ${directBin}`);
return directBin + path.sep;
}
// Handle versioned subdirectory layout, e.g. Ballerina\ballerina-2.x.x\bin
try {
const children = fs.readdirSync(root);
for (const child of children) {
const versionedBin = path.join(root, child, 'bin');
if (fs.existsSync(path.join(versionedBin, 'bal.bat'))) {
debug(`[WIN_BAL_FIND] Found bal.bat in versioned directory: ${versionedBin}`);
return versionedBin + path.sep;
}
}
} catch (err) {
// Directory doesn't exist or isn't readable — skip
debug(`[WIN_BAL_FIND] Failed to read directory "${root}" for versioned Ballerina installations: ${err}`);
}
}

debug('[WIN_BAL_FIND] Ballerina installation not found via fallback search');
return '';
}

function getShellEnvironment(): Promise<NodeJS.ProcessEnv> {
return new Promise((resolve, reject) => {
debug('[SHELL_ENV] Starting shell environment retrieval...');
Expand All @@ -2699,8 +2788,19 @@ function getShellEnvironment(): Promise<NodeJS.ProcessEnv> {

if (isWindowsPlatform) {
debug('[SHELL_ENV] Windows platform detected');
// Windows: use PowerShell to get environment
command = 'powershell.exe -Command "[Environment]::GetEnvironmentVariables(\'Process\') | ConvertTo-Json"';
// Windows: read from registry (Machine + User scopes) so that paths added by
// a fresh Ballerina install (which goes to the User PATH registry key) are
// picked up even when VS Code's process was launched before the installation.
// We start with the current Process environment so that VS Code-internal
// variables are preserved, but we override Path with the merged registry value.
command = 'powershell.exe -NoProfile -Command "' +
'$e=[Environment]::GetEnvironmentVariables(\'Process\');' +
'$mp=[Environment]::GetEnvironmentVariable(\'Path\',\'Machine\');' +
'$up=[Environment]::GetEnvironmentVariable(\'Path\',\'User\');' +
'if($mp -and $up){$e[\'Path\']=$mp+\';\'+$up}' +
'elseif($mp){$e[\'Path\']=$mp}' +
'elseif($up){$e[\'Path\']=$up};' +
'$e | ConvertTo-Json"';
debug(`[SHELL_ENV] Windows command: ${command}`);
} else if (isWSL()) {
debug("[SHELL_ENV] Windows WSL platform, using non-interactive shell");
Expand Down
Loading