Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
b5802ac
Reduced loading time of the connections pane, added caching to reduce…
lambrianmsft Jan 1, 2026
6a812da
Updated onboarding to properly await calls. Updated lsp server and ad…
lambrianmsft Jan 3, 2026
44430b5
Fixed issue where state was incorrectly kept which can cause undefine…
lambrianmsft Jan 9, 2026
b7841f2
Run history and overview are able to display workflow runs. If a trig…
lambrianmsft Jan 13, 2026
170ab76
Updated namespace to use logic app name, corrected create workflow ex…
lambrianmsft Jan 14, 2026
4193f08
Updated LSP server, updated deploy to remove unnecessary local settings
lambrianmsft Jan 16, 2026
45b032e
Updating nuget package
lambrianmsft Feb 3, 2026
29c3292
Auto start for codeful projects
lambrianmsft Feb 19, 2026
547d2a1
Updating sdk
lambrianmsft Feb 19, 2026
92c5ad4
fix bundleFeed tests
andrew-eldridge Feb 24, 2026
0ab6364
Merge branch 'ccastrotrejo/csharpLSPServer' of github.com:Azure/Logic…
andrew-eldridge Feb 25, 2026
5f8ca2f
use runtime apis to get codeful workflow/trigger data
andrew-eldridge Feb 26, 2026
abdcb0a
add retry for workflows not found
andrew-eldridge Feb 26, 2026
1254545
Updated LSPServer and sdk
lambrianmsft Feb 26, 2026
647a3ec
Update to a working stateful sample
lambrianmsft Feb 26, 2026
6c7520d
Attempt to filter code completion results
lambrianmsft Feb 26, 2026
9cf6655
Updated the agentic connections to prevent overwriting existing conne…
lambrianmsft Feb 27, 2026
36589d6
fix codeful and custom code launch.json, add test
andrew-eldridge Feb 28, 2026
79485f1
update targetFramework type
andrew-eldridge Feb 28, 2026
e49f658
fix default codeful stateful workflow template
andrew-eldridge Feb 28, 2026
ac433d8
Update the isCodeless flag to be more reliable
lambrianmsft Mar 2, 2026
375a8ba
Merge branch 'main' of https://github.com/lambrianmsft/LogicAppsUX in…
lambrianmsft Mar 2, 2026
a27a107
fix hanging insert_connection on connectionView
andrew-eldridge Mar 3, 2026
9f93ab5
fix invalid codeful class name with hyphens
andrew-eldridge Mar 3, 2026
50ea77d
Merge branch 'ccastrotrejo/csharpLSPServer' of https://github.com/lam…
lambrianmsft Mar 3, 2026
88f0f7a
fix codeful stateful template
andrew-eldridge Mar 3, 2026
49ba327
Merge branch 'ccastrotrejo/csharpLSPServer' of https://github.com/lam…
lambrianmsft Mar 3, 2026
891afba
Revert "Merge branch 'main' of https://github.com/lambrianmsft/LogicA…
lambrianmsft Mar 3, 2026
c39cdeb
Updated LSPServer
lambrianmsft Mar 3, 2026
387148c
Reapply "Merge branch 'main' of https://github.com/lambrianmsft/Logic…
andrew-eldridge Mar 10, 2026
beb73d5
increase timeout on long-running test
andrew-eldridge Mar 10, 2026
7afa7d1
fix issue with multiple dotnet cleans/builds on codeful debug
andrew-eldridge Mar 10, 2026
3a2bbcf
fix codeful custom code debugger attaching to wrong process
andrew-eldridge Mar 10, 2026
28ecbf6
require explicit isCodeful setting in launch to use codeful configura…
andrew-eldridge Mar 10, 2026
ceed552
Updated vsix process to prevent need for build before, updated flow t…
lambrianmsft Mar 10, 2026
adccf73
Merge branch 'ccastrotrejo/csharpLSPServer' of https://github.com/lam…
lambrianmsft Mar 11, 2026
097b04e
code cleanup
andrew-eldridge Mar 11, 2026
593554e
combine addConnection and insert_connection commands into single atom…
andrew-eldridge Mar 11, 2026
8c2e7d3
We need to invalidate azure connections details after a user signs in…
lambrianmsft Mar 11, 2026
928d319
Merge branch 'aeldridge/csharpLSPServer' of github.com:Azure/LogicApp…
andrew-eldridge Mar 11, 2026
54170c8
Map connections properly in webview pane and have updated lsp server …
lambrianmsft Mar 11, 2026
78bbab1
Merge branch 'ccastrotrejo/csharpLSPServer' of https://github.com/lam…
lambrianmsft Mar 11, 2026
49188dc
Fixed another func launching when create connection webview is starte…
lambrianmsft Mar 12, 2026
447ed5a
Latest sdk and corresponding lsp server
lambrianmsft Mar 12, 2026
ad3da41
update codeful extension bundle source
andrew-eldridge Mar 13, 2026
9f5ed74
fix workspace folder prompt on empty workspace
andrew-eldridge Mar 17, 2026
b2e0655
Update to latest sdk
lambrianmsft Apr 23, 2026
913fe7a
Centralize codeful workflow overview
lambrianmsft May 6, 2026
99f54eb
Fix stateful codeful workflow template startup
lambrianmsft May 6, 2026
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
2 changes: 1 addition & 1 deletion apps/vs-code-designer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
},
"private": true,
"scripts": {
"build:extension": "tsup && pnpm run copyFiles",
"build:extension": "tsup && pnpm run copyFiles && cd dist && npm install --ignore-scripts",
"build:ui": "tsup --config tsup.e2e.test.config.ts",
"copyFiles": "node extension-copy-svgs.js",
"vscode:designer:pack": "pnpm run vscode:designer:pack:step1 && pnpm run vscode:designer:pack:step2",
Expand Down
34 changes: 19 additions & 15 deletions apps/vs-code-designer/src/__test__/devContainerIntegration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,21 +150,25 @@ describe('devContainer Integration Tests', () => {
});

describe('useBinariesDependencies - devContainer override', () => {
it('should return false in devContainer regardless of global setting', async () => {
// Use importActual to run the REAL useBinariesDependencies logic.
// Its dependencies (isDevContainerWorkspace, getGlobalSetting) are still mocked.
const { useBinariesDependencies: realUseBinariesDependencies } =
await vi.importActual<typeof import('../app/utils/binaries')>('../app/utils/binaries');
const { isDevContainerWorkspace } = await import('../app/utils/devContainerUtils');
const settingsModule = await import('../app/utils/vsCodeConfig/settings');

vi.mocked(isDevContainerWorkspace).mockResolvedValue(true);
vi.mocked(settingsModule.getGlobalSetting).mockReturnValue(true);

const result = await realUseBinariesDependencies();

expect(result).toBe(false);
});
it(
'should return false in devContainer regardless of global setting',
async () => {
// Use importActual to run the REAL useBinariesDependencies logic.
// Its dependencies (isDevContainerWorkspace, getGlobalSetting) are still mocked.
const { useBinariesDependencies: realUseBinariesDependencies } =
await vi.importActual<typeof import('../app/utils/binaries')>('../app/utils/binaries');
const { isDevContainerWorkspace } = await import('../app/utils/devContainerUtils');
const settingsModule = await import('../app/utils/vsCodeConfig/settings');

vi.mocked(isDevContainerWorkspace).mockResolvedValue(true);
vi.mocked(settingsModule.getGlobalSetting).mockReturnValue(true);

const result = await realUseBinariesDependencies();

expect(result).toBe(false);
},
{ timeout: 10000 }
);

it('should respect global setting in non-devContainer workspace', async () => {
const { useBinariesDependencies: realUseBinariesDependencies } =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import * as vscode from 'vscode';
import { pickCustomCodeNetHostProcess, pickCustomCodeNetHostProcessInternal } from '../pickCustomCodeWorkerProcess';
import {
pickCustomCodeNetHostProcess,
pickCustomCodeNetHostProcessInternal,
pickCustomCodeWorkerChildProcess,
} from '../pickCustomCodeWorkerProcess';
import * as validatePreDebug from '../../debug/validatePreDebug';
import { IRunningFuncTask, runningFuncTaskMap } from '../../utils/funcCoreTools/funcHostTask';
import * as pickFuncProcessModule from '../pickFuncProcess';
Expand Down Expand Up @@ -143,6 +147,7 @@ describe('pickCustomCodeNetHostProcessInternal', () => {

describe('pickCustomCodeWorkerChildProcess', async () => {
const testFuncPid = 12345;
const testChildFuncPid = 54321;
const testDotnetPid = 67890;
const testLogicAppName = 'LogicApp';
const testLogicAppPath = path.join('path', 'to', testLogicAppName);
Expand Down Expand Up @@ -177,8 +182,7 @@ describe('pickCustomCodeWorkerChildProcess', async () => {
]);

// Re-import to get the mocked version
const { pickCustomCodeWorkerChildProcess: pickCustomCodeWorkerChildProcessMocked } = await import('../pickCustomCodeWorkerProcess');
const result = await pickCustomCodeWorkerChildProcessMocked(testFuncTask, false);
const result = await pickCustomCodeWorkerChildProcess(testFuncTask, false);
expect(result).toBe(testDotnetPid.toString());
});

Expand All @@ -190,27 +194,35 @@ describe('pickCustomCodeWorkerChildProcess', async () => {
{ command: 'other2', pid: 11112 },
]);

const { pickCustomCodeWorkerChildProcess: pickCustomCodeWorkerChildProcessMocked } = await import('../pickCustomCodeWorkerProcess');
const result = await pickCustomCodeWorkerChildProcessMocked(testFuncTask, false);
const result = await pickCustomCodeWorkerChildProcess(testFuncTask, false);
expect(result).toBe(testDotnetPid.toString());
});

it('should return the pid of a child process matching func on Unix', async () => {
it('should return the pid of a codeful child process matching dotnet on Unix', async () => {
vi.stubGlobal('process', { platform: 'linux' });
vi.spyOn(pickFuncProcessModule, 'getUnixChildren').mockResolvedValue([
{ command: 'func.exe', pid: testDotnetPid },
{ command: 'other', pid: 11111 },
]);
vi.spyOn(pickFuncProcessModule, 'getUnixChildren').mockImplementation((pid: Number) => {
if (pid === Number(testFuncPid)) {
return Promise.resolve([
{ command: 'func', pid: testChildFuncPid },
{ command: 'other', pid: 11111 },
]);
} else if (pid === Number(testChildFuncPid)) {
return Promise.resolve([
{ command: 'dotnet', pid: testDotnetPid },
{ command: 'other', pid: 22222 },
]);
} else {
return Promise.resolve([]);
}
});

const { pickCustomCodeWorkerChildProcess: pickCustomCodeWorkerChildProcessMocked } = await import('../pickCustomCodeWorkerProcess');
const result = await pickCustomCodeWorkerChildProcessMocked(testFuncTask, false);
const result = await pickCustomCodeWorkerChildProcess(testFuncTask, false /* isNetFxWorker */, false /* isCodeless */);
expect(result).toBe(testDotnetPid.toString());
});

it('should return undefined if no matching child process is found', async () => {
vi.stubGlobal('process', { platform: 'win32' });
const { pickCustomCodeWorkerChildProcess: pickCustomCodeWorkerChildProcessMocked } = await import('../pickCustomCodeWorkerProcess');
const result = await pickCustomCodeWorkerChildProcessMocked(testFuncTask, false);
const result = await pickCustomCodeWorkerChildProcess(testFuncTask, false);
expect(result).toBeUndefined();
});

Expand All @@ -220,8 +232,7 @@ describe('pickCustomCodeWorkerChildProcess', async () => {
const getUnixChildren = vi.fn();
vi.spyOn(pickFuncProcessModule, 'pickChildProcess').mockResolvedValue(undefined as any);

const { pickCustomCodeWorkerChildProcess: pickCustomCodeWorkerChildProcessMocked } = await import('../pickCustomCodeWorkerProcess');
const result = await pickCustomCodeWorkerChildProcessMocked(testFuncTask, false);
const result = await pickCustomCodeWorkerChildProcess(testFuncTask, false);
expect(result).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

const mockGetChildProcessesWithScript = vi.fn();

vi.mock('../../utils/findChildProcess/findChildProcess', () => ({
getChildProcessesWithScript: mockGetChildProcessesWithScript,
}));

const pickFuncProcessModule = await import('../pickFuncProcess');

describe('findChildProcess', () => {
beforeEach(() => {
vi.clearAllMocks();
});

afterEach(() => {
vi.restoreAllMocks();
});

it('returns the func.exe descendant pid on Windows', async () => {
vi.spyOn(process, 'platform', 'get').mockReturnValue('win32');
mockGetChildProcessesWithScript.mockResolvedValue([
{ processId: 6312, name: 'conhost.exe', parentProcessId: 17884 },
{ processId: 31696, name: 'func.exe', parentProcessId: 17884 },
{ processId: 33904, name: 'node.exe', parentProcessId: 31696 },
]);

const result = await pickFuncProcessModule.findChildProcess(17884);

expect(result).toBe('31696');
expect(mockGetChildProcessesWithScript).toHaveBeenCalledWith(17884);
});

it('returns undefined on Windows when no func.exe descendant is found', async () => {
vi.spyOn(process, 'platform', 'get').mockReturnValue('win32');
mockGetChildProcessesWithScript.mockResolvedValue([
{ processId: 6312, name: 'conhost.exe', parentProcessId: 17884 },
{ processId: 33904, name: 'node.exe', parentProcessId: 31696 },
]);

const result = await pickFuncProcessModule.findChildProcess(17884);

expect(result).toBeUndefined();
});

it('returns a matching child pid on Unix and does not fall back to the parent pid', async () => {
vi.spyOn(process, 'platform', 'get').mockReturnValue('linux');
vi.spyOn(pickFuncProcessModule, 'getUnixChildren').mockResolvedValue([
{ command: 'bash', pid: 1000 },
{ command: 'func', pid: 2000 },
{ command: 'dotnet', pid: 3000 },
]);

const result = await pickFuncProcessModule.findChildProcess(1234);

expect(result).toBe('3000');
});

it('returns undefined on Unix when no matching child process is found', async () => {
vi.spyOn(process, 'platform', 'get').mockReturnValue('linux');
vi.spyOn(pickFuncProcessModule, 'getUnixChildren').mockResolvedValue([{ command: 'bash', pid: 1000 }]);

const result = await pickFuncProcessModule.findChildProcess(1234);

expect(result).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { localSettingsFileName, logicAppFilter, ProjectDirectoryPathKey, workflowCodefulEnabled } from '../../../constants';
import { localSettingsFileName, logicAppFilter } from '../../../constants';
import { ext } from '../../../extensionVariables';
import { localize } from '../../../localize';
import { getLocalSettingsJson } from '../../utils/appSettings/localSettings';
Expand Down Expand Up @@ -66,9 +66,6 @@ export async function uploadAppSettings(
}

ext.outputChannel.appendLog(localize('uploadingSettings', 'Uploading settings...'), { resourceName: client.fullName });
if (localSettings.Values[workflowCodefulEnabled] === 'true') {
localSettings.Values[ProjectDirectoryPathKey] = 'C:\\home\\site\\wwwroot\\lib\\codeful';
}
await confirmOverwriteSettings(context, localSettings.Values, remoteSettings.properties, client.fullName);

if (excludedAppSettings.length) {
Expand Down
23 changes: 23 additions & 0 deletions apps/vs-code-designer/src/app/commands/convertToWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,29 @@ export async function createWorkspaceFile(context: IActionContext, options: any)

const webviewProjectContext: IWebviewProjectContext = options;

// Add telemetry properties for debugging
context.telemetry.properties.hasWorkspaceProjectPath = String(!!webviewProjectContext.workspaceProjectPath);
context.telemetry.properties.workspaceProjectPathType = typeof webviewProjectContext.workspaceProjectPath;
context.telemetry.properties.receivedOptionsKeys = Object.keys(options || {}).join(',');

// Validate that workspaceProjectPath exists and has required properties
if (!webviewProjectContext.workspaceProjectPath || !webviewProjectContext.workspaceProjectPath.fsPath) {
const errorMessage = `[ConvertToWorkspace] Invalid workspaceProjectPath: ${JSON.stringify(
{
hasWorkspaceProjectPath: !!webviewProjectContext.workspaceProjectPath,
workspaceProjectPathType: typeof webviewProjectContext.workspaceProjectPath,
workspaceProjectPathValue: webviewProjectContext.workspaceProjectPath,
contextKeys: Object.keys(options || {}),
},
null,
2
)}`;
ext.outputChannel.appendLog(errorMessage);
throw new Error(
`workspaceProjectPath is required and must have an fsPath property. Received: ${JSON.stringify(webviewProjectContext.workspaceProjectPath)}`
);
}

const workspaceFolderPath = path.join(webviewProjectContext.workspaceProjectPath.fsPath, webviewProjectContext.workspaceName);

await fse.ensureDir(workspaceFolderPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export async function createLogicAppProject(context: IActionContext, options: an
const mySubContext: IFunctionWizardContext = context as IFunctionWizardContext;
mySubContext.logicAppName = options.logicAppName;
mySubContext.projectPath = logicAppFolderPath;
mySubContext.projectType = webviewProjectContext.logicAppType as ProjectType;
mySubContext.projectType = webviewProjectContext.logicAppType;
mySubContext.functionFolderName = options.functionFolderName;
mySubContext.functionAppName = options.functionName;
mySubContext.functionAppNamespace = options.functionNamespace;
Expand Down
Loading
Loading