From 19c02e7f702499e57fbc43bdf0e22c6c197b7ed3 Mon Sep 17 00:00:00 2001 From: tobixlea Date: Wed, 8 Oct 2025 10:43:15 -0700 Subject: [PATCH 1/7] add finch installation to walkthrough --- packages/core/package.nls.json | 3 +- .../src/awsService/appBuilder/activation.ts | 3 ++ .../core/src/shared/utilities/cliUtils.ts | 26 ++++++++-- .../awsService/appBuilder/walkthrough.test.ts | 52 +++++++++++++++++++ packages/toolkit/package.json | 13 ++++- 5 files changed, 92 insertions(+), 5 deletions(-) diff --git a/packages/core/package.nls.json b/packages/core/package.nls.json index 1be74632591..5b2513fa65a 100644 --- a/packages/core/package.nls.json +++ b/packages/core/package.nls.json @@ -476,7 +476,8 @@ "AWS.toolkit.lambda.walkthrough.title": "Get started building your application", "AWS.toolkit.lambda.walkthrough.description": "Your quick guide to build an application visually, iterate locally, and deploy to the cloud!", "AWS.toolkit.lambda.walkthrough.toolInstall.title": "Complete installation", - "AWS.toolkit.lambda.walkthrough.toolInstall.description": "Manage your AWS services and resources with the AWS Command Line Interface (AWS CLI). \n\n[Install AWS CLI](command:aws.toolkit.installAWSCLI)\n\nBuild locally, invoke, and deploy your functions with the Serverless Application Model (SAM) CLI. \n\n[Install SAM CLI](command:aws.toolkit.installSAMCLI)\n\nDocker is an optional, third party tool that assists with local AWS Lambda runtime emulation. Docker is required to invoke Lambda functions on your local machine. \n\n[Install Docker (optional)](command:aws.toolkit.installDocker)\n\nEmulate your AWS cloud services locally with LocalStack to streamline testing in VS Code and CI environments. [Learn more](https://docs.localstack.cloud/aws/). \n\n[Install LocalStack (optional)](command:aws.toolkit.installLocalStack)", + "AWS.toolkit.lambda.walkthrough.toolInstall.description.windows": "Manage your AWS services and resources with the AWS Command Line Interface (AWS CLI). \n\n[Install AWS CLI](command:aws.toolkit.installAWSCLI)\n\nBuild locally, invoke, and deploy your functions with the Serverless Application Model (SAM) CLI. \n\n[Install SAM CLI](command:aws.toolkit.installSAMCLI)\n\nDocker is an optional, third party tool that assists with local AWS Lambda runtime emulation. Docker is required to invoke Lambda functions on your local machine. \n\n[Install Docker (optional)](command:aws.toolkit.installDocker)\n\nEmulate your AWS cloud services locally with LocalStack to streamline testing in VS Code and CI environments. [Learn more](https://docs.localstack.cloud/aws/). \n\n[Install LocalStack (optional)](command:aws.toolkit.installLocalStack)", + "AWS.toolkit.lambda.walkthrough.toolInstall.description": "Manage your AWS services and resources with the AWS Command Line Interface (AWS CLI). \n\n[Install AWS CLI](command:aws.toolkit.installAWSCLI)\n\nBuild locally, invoke, and deploy your functions with the Serverless Application Model (SAM) CLI. \n\n[Install SAM CLI](command:aws.toolkit.installSAMCLI)\n\nDocker is an optional, third party tool that assists with local AWS Lambda runtime emulation. Docker is required to invoke Lambda functions on your local machine. \n\n[Install Docker (optional)](command:aws.toolkit.installDocker)\n\nEmulate your AWS cloud services locally with LocalStack to streamline testing in VS Code and CI environments. [Learn more]((https://docs.localstack.cloud/aws/). \n\n[Install LocalStack (optional)](command:aws.toolkit.installLocalStack)\n\nFinch is an open source tool for local container development. Finch aims to help promote innovative upstream container projects by making it easy to install and use them. [Learn more](https://runfinch.com/) \n\n[Install Finch (optional)](command:aws.toolkit.installFinch)", "AWS.toolkit.lambda.walkthrough.chooseTemplate.title": "Choose your application template", "AWS.toolkit.lambda.walkthrough.chooseTemplate.description": "Select a starter application, visually compose an application from scratch, open an existing application, or browse more application examples. \n\nInfrastructure Composer allows you to visually compose modern applications in the cloud. It will define the necessary permissions between resources when you drag a connection between them. \n\n[Initialize your project](command:aws.toolkit.lambda.initializeWalkthroughProject)", "AWS.toolkit.lambda.walkthrough.step1.title": "Iterate locally", diff --git a/packages/core/src/awsService/appBuilder/activation.ts b/packages/core/src/awsService/appBuilder/activation.ts index 01f01a1b4c8..93cf1119448 100644 --- a/packages/core/src/awsService/appBuilder/activation.ts +++ b/packages/core/src/awsService/appBuilder/activation.ts @@ -150,6 +150,9 @@ async function registerAppBuilderCommands(context: ExtContext): Promise { Commands.register('aws.toolkit.installLocalStack', async () => { await installLocalStackExtension(source) }), + Commands.register('aws.toolkit.installFinch', async () => { + await getOrInstallCliWrapper('finch', source) + }), Commands.register('aws.toolkit.lambda.setWalkthroughToAPI', async () => { await setWalkthrough('API') }), diff --git a/packages/core/src/shared/utilities/cliUtils.ts b/packages/core/src/shared/utilities/cliUtils.ts index a37a7228687..141368baad3 100644 --- a/packages/core/src/shared/utilities/cliUtils.ts +++ b/packages/core/src/shared/utilities/cliUtils.ts @@ -55,7 +55,7 @@ interface Cli { exec?: string } -export type AwsClis = Extract +export type AwsClis = Extract /** * CLIs and their full filenames and download paths for their respective OSes @@ -170,6 +170,25 @@ export const awsClis: { [cli in AwsClis]: Cli } = { manualInstallLink: 'https://docs.docker.com/desktop', exec: 'docker', }, + // Currently Finch is available for MacOS and Linux; Windows support will be added when available + finch: { + command: { + unix: ['finch', path.join('/', 'usr', 'bin', 'finch'), path.join('/', 'usr', 'local', 'bin', 'finch')], + }, + source: { + macos: { + x86: 'https://github.com/runfinch/finch/releases/download/v1.11.0/Finch-v1.11.0-x86_64.pkg', + arm: 'https://github.com/runfinch/finch/releases/download/v1.11.0/Finch-v1.11.0-aarch64.pkg', + }, + linux: { + x86: 'https://github.com/runfinch/finch/releases/download/v1.11.0/runfinch-finch_1.11.0_amd64.deb', + arm: 'https://github.com/runfinch/finch/releases/download/v1.11.0/runfinch-finch_1.11.0_arm64.deb', + }, + }, + name: 'Finch', + manualInstallLink: 'https://runfinch.com/docs/getting-started/installation/', + exec: 'finch', + }, } /** @@ -185,7 +204,7 @@ export async function installCli( ): Promise { const cliToInstall = awsClis[cli] if (!cliToInstall) { - throw new InstallerError(`Invalid not found for CLI: ${cli}`) + throw new InstallerError(`Installer not found for CLI: ${cli}`) } let result: Result = 'Succeeded' let reason: string = '' @@ -247,10 +266,11 @@ export async function installCli( case 'aws-cli': case 'sam-cli': case 'docker': + case 'finch': cliPath = await installGui(cli, tempDir, progress, timeout) break default: - throw new InstallerError(`Invalid not found for CLI: ${cli}`) + throw new InstallerError(`Installer not found for CLI: ${cli}`) } } finally { timeout.dispose() diff --git a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts index 988f01902fd..80cba1e88a6 100644 --- a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts +++ b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts @@ -9,6 +9,7 @@ import assert from 'assert' import { openApplicationComposerAfterReload, templateToOpenAppComposer, + activate, } from '../../../awsService/appBuilder/activation' import globals from '../../../shared/extensionGlobals' import { @@ -28,6 +29,7 @@ import { HttpResourceFetcher } from '../../../shared/resourcefetcher/node/httpRe import { SamCliInfoInvocation } from '../../../shared/sam/cli/samCliInfo' import type { ToolId } from '../../../shared/telemetry/telemetry' import { CodeScansState } from '../../../codewhisperer' +import { FakeExtensionContext } from '../../fakeExtensionContext' interface TestScenario { toolID: AwsClis @@ -51,6 +53,11 @@ const scenarios: TestScenario[] = [ platform: 'win32', shouldSucceed: true, }, + { + toolID: 'finch', + platform: 'win32', + shouldSucceed: false, + }, { toolID: 'aws-cli', platform: 'darwin', @@ -66,6 +73,11 @@ const scenarios: TestScenario[] = [ platform: 'darwin', shouldSucceed: true, }, + { + toolID: 'finch', + platform: 'darwin', + shouldSucceed: true, + }, { toolID: 'aws-cli', platform: 'linux', @@ -81,6 +93,11 @@ const scenarios: TestScenario[] = [ platform: 'linux', shouldSucceed: false, }, + { + toolID: 'finch', + platform: 'linux', + shouldSucceed: true, + }, ] describe('AppBuilder Walkthrough', function () { @@ -556,3 +573,38 @@ describe('AppBuilder Walkthrough', function () { }) }) }) +describe('Platform-specific walkthrough ID', function () { + let sandbox: sinon.SinonSandbox + const originalPlatform = process.platform + beforeEach(function () { + sandbox = sinon.createSandbox() + }) + afterEach(function () { + sandbox.restore() + Object.defineProperty(process, 'platform', { value: originalPlatform }) + }) + it('uses standard walkthrough ID on non-Windows platforms', async function () { + Object.defineProperty(process, 'platform', { value: 'darwin' }) + const executeCommandSpy = sandbox.spy(vscode.commands, 'executeCommand') + const mockContext = await FakeExtensionContext.getFakeExtContext() + await activate(mockContext) + await vscode.commands.executeCommand('aws.toolkit.lambda.openWalkthrough') + sandbox.assert.calledWith( + executeCommandSpy, + 'workbench.action.openWalkthrough', + 'amazonwebservices.aws-toolkit-vscode#aws.toolkit.lambda.walkthrough' + ) + }) + it('uses Windows-specific walkthrough ID on Windows platform', async function () { + Object.defineProperty(process, 'platform', { value: 'win32' }) + const executeCommandSpy = sandbox.spy(vscode.commands, 'executeCommand') + const mockContext = await FakeExtensionContext.getFakeExtContext() + await activate(mockContext) + await vscode.commands.executeCommand('aws.toolkit.lambda.openWalkthrough') + sandbox.assert.calledWith( + executeCommandSpy, + 'workbench.action.openWalkthrough', + 'amazonwebservices.aws-toolkit-vscode#aws.toolkit.lambda.walkthrough.windows' + ) + }) +}) diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index 6fed7a747fa..98ef59421e5 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -4531,6 +4531,16 @@ "description": "%AWS.toolkit.lambda.walkthrough.description%", "when": "workspacePlatform != webworker", "steps": [ + { + "id": "toolInstallWindows", + "title": "%AWS.toolkit.lambda.walkthrough.toolInstall.title%", + "description": "%AWS.toolkit.lambda.walkthrough.toolInstall.description.windows%", + "media": { + "image": "./resources/walkthrough/appBuilder/install.png", + "altText": "Showing GUI installer" + }, + "when": "isWindows" + }, { "id": "toolInstall", "title": "%AWS.toolkit.lambda.walkthrough.toolInstall.title%", @@ -4538,7 +4548,8 @@ "media": { "image": "./resources/walkthrough/appBuilder/install.png", "altText": "Showing GUI installer" - } + }, + "when": "!isWindows" }, { "id": "chooseTemplate", From 869fcd550ad7e8b23976b84d2ea44a8076e727cb Mon Sep 17 00:00:00 2001 From: tobixlea Date: Wed, 8 Oct 2025 10:58:14 -0700 Subject: [PATCH 2/7] package.json update after run npm test --- packages/amazonq/package.json | 41 ++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index 834022b587c..3f7d138651d 100644 --- a/packages/amazonq/package.json +++ b/packages/amazonq/package.json @@ -1393,26 +1393,61 @@ "fontCharacter": "\\f1e0" } }, - "aws-schemas-registry": { + "aws-sagemakerunifiedstudio-catalog": { "description": "AWS Contributed Icon", "default": { "fontPath": "./resources/fonts/aws-toolkit-icons.woff", "fontCharacter": "\\f1e1" } }, - "aws-schemas-schema": { + "aws-sagemakerunifiedstudio-spaces": { "description": "AWS Contributed Icon", "default": { "fontPath": "./resources/fonts/aws-toolkit-icons.woff", "fontCharacter": "\\f1e2" } }, - "aws-stepfunctions-preview": { + "aws-sagemakerunifiedstudio-spaces-dark": { "description": "AWS Contributed Icon", "default": { "fontPath": "./resources/fonts/aws-toolkit-icons.woff", "fontCharacter": "\\f1e3" } + }, + "aws-sagemakerunifiedstudio-symbol-int": { + "description": "AWS Contributed Icon", + "default": { + "fontPath": "./resources/fonts/aws-toolkit-icons.woff", + "fontCharacter": "\\f1e4" + } + }, + "aws-sagemakerunifiedstudio-table": { + "description": "AWS Contributed Icon", + "default": { + "fontPath": "./resources/fonts/aws-toolkit-icons.woff", + "fontCharacter": "\\f1e5" + } + }, + "aws-schemas-registry": { + "description": "AWS Contributed Icon", + "default": { + "fontPath": "./resources/fonts/aws-toolkit-icons.woff", + "fontCharacter": "\\f1e6" + } + }, + "aws-schemas-schema": { + "description": "AWS Contributed Icon", + "default": { + "fontPath": "./resources/fonts/aws-toolkit-icons.woff", + "fontCharacter": "\\f1e7" + } + }, + "aws-stepfunctions-preview": { + "description": "AWS Contributed Icon", + "default": { + "fontPath": "./resources/fonts/aws-toolkit-icons.woff", + "fontCharacter": "\\f1e8" + } } }, "walkthroughs": [ From 823c237fa1c15f4629b21f19b4062d73cd5e9e2e Mon Sep 17 00:00:00 2001 From: tobixlea Date: Wed, 8 Oct 2025 15:48:27 -0700 Subject: [PATCH 3/7] Add toolId to vscodeTelemtry.json --- .../core/src/shared/telemetry/vscodeTelemetry.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/core/src/shared/telemetry/vscodeTelemetry.json b/packages/core/src/shared/telemetry/vscodeTelemetry.json index 6fbfa22e394..35aed899e1c 100644 --- a/packages/core/src/shared/telemetry/vscodeTelemetry.json +++ b/packages/core/src/shared/telemetry/vscodeTelemetry.json @@ -1,5 +1,19 @@ { "types": [ + { + "name": "toolId", + "type": "string", + "description": "The tool being installed", + "allowedValues": [ + "session-manager-plugin", + "dotnet-lambda-deploy", + "dotnet-deploy-cli", + "aws-cli", + "sam-cli", + "docker", + "finch" + ] + }, { "name": "amazonQProfileRegion", "type": "string", From 02a67f4a399201e6969e33ae7e4d50004c8bce9c Mon Sep 17 00:00:00 2001 From: tobixlea Date: Thu, 9 Oct 2025 09:53:26 -0700 Subject: [PATCH 4/7] update tests after PR review changes --- .../awsService/appBuilder/walkthrough.test.ts | 37 +------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts index 80cba1e88a6..07d23138eca 100644 --- a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts +++ b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts @@ -96,7 +96,7 @@ const scenarios: TestScenario[] = [ { toolID: 'finch', platform: 'linux', - shouldSucceed: true, + shouldSucceed: false, }, ] @@ -573,38 +573,3 @@ describe('AppBuilder Walkthrough', function () { }) }) }) -describe('Platform-specific walkthrough ID', function () { - let sandbox: sinon.SinonSandbox - const originalPlatform = process.platform - beforeEach(function () { - sandbox = sinon.createSandbox() - }) - afterEach(function () { - sandbox.restore() - Object.defineProperty(process, 'platform', { value: originalPlatform }) - }) - it('uses standard walkthrough ID on non-Windows platforms', async function () { - Object.defineProperty(process, 'platform', { value: 'darwin' }) - const executeCommandSpy = sandbox.spy(vscode.commands, 'executeCommand') - const mockContext = await FakeExtensionContext.getFakeExtContext() - await activate(mockContext) - await vscode.commands.executeCommand('aws.toolkit.lambda.openWalkthrough') - sandbox.assert.calledWith( - executeCommandSpy, - 'workbench.action.openWalkthrough', - 'amazonwebservices.aws-toolkit-vscode#aws.toolkit.lambda.walkthrough' - ) - }) - it('uses Windows-specific walkthrough ID on Windows platform', async function () { - Object.defineProperty(process, 'platform', { value: 'win32' }) - const executeCommandSpy = sandbox.spy(vscode.commands, 'executeCommand') - const mockContext = await FakeExtensionContext.getFakeExtContext() - await activate(mockContext) - await vscode.commands.executeCommand('aws.toolkit.lambda.openWalkthrough') - sandbox.assert.calledWith( - executeCommandSpy, - 'workbench.action.openWalkthrough', - 'amazonwebservices.aws-toolkit-vscode#aws.toolkit.lambda.walkthrough.windows' - ) - }) -}) From a1eb54cd9a34aa172f6f7a602599924e9c75e63b Mon Sep 17 00:00:00 2001 From: tobixlea Date: Thu, 9 Oct 2025 10:00:45 -0700 Subject: [PATCH 5/7] remove unused imports in walkthrough.test.ts --- .../core/src/test/awsService/appBuilder/walkthrough.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts index 07d23138eca..f295f5eb58d 100644 --- a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts +++ b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts @@ -9,7 +9,6 @@ import assert from 'assert' import { openApplicationComposerAfterReload, templateToOpenAppComposer, - activate, } from '../../../awsService/appBuilder/activation' import globals from '../../../shared/extensionGlobals' import { @@ -29,7 +28,6 @@ import { HttpResourceFetcher } from '../../../shared/resourcefetcher/node/httpRe import { SamCliInfoInvocation } from '../../../shared/sam/cli/samCliInfo' import type { ToolId } from '../../../shared/telemetry/telemetry' import { CodeScansState } from '../../../codewhisperer' -import { FakeExtensionContext } from '../../fakeExtensionContext' interface TestScenario { toolID: AwsClis From 4bb272e62adca61e798037c85a750d13fe83faf7 Mon Sep 17 00:00:00 2001 From: tobixlea Date: Thu, 9 Oct 2025 10:45:30 -0700 Subject: [PATCH 6/7] Add linux case for gui installer for finch --- packages/core/src/shared/utilities/cliUtils.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/core/src/shared/utilities/cliUtils.ts b/packages/core/src/shared/utilities/cliUtils.ts index 141368baad3..3df64a9cdb7 100644 --- a/packages/core/src/shared/utilities/cliUtils.ts +++ b/packages/core/src/shared/utilities/cliUtils.ts @@ -541,6 +541,9 @@ async function installGui( case 'win32': await new TimedProcess(guiInstaller, []).run() return await getCliCommand(awsClis[cli]) + case 'linux': + await new TimedProcess('dpkg', ['-i', guiInstaller]).run() + return await getCliCommand(awsClis[cli]) // customer shouldn't reach this point as they will be directed to manual install link in entrypoint. default: throw new InvalidPlatformError( From 7b975f7115257a07fb2fe383a5589a2a92aa52ab Mon Sep 17 00:00:00 2001 From: tobixlea Date: Thu, 9 Oct 2025 11:22:41 -0700 Subject: [PATCH 7/7] Follow awsCli format of other cli installers --- packages/core/src/shared/utilities/cliUtils.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/core/src/shared/utilities/cliUtils.ts b/packages/core/src/shared/utilities/cliUtils.ts index 3df64a9cdb7..bf19cd19791 100644 --- a/packages/core/src/shared/utilities/cliUtils.ts +++ b/packages/core/src/shared/utilities/cliUtils.ts @@ -170,7 +170,7 @@ export const awsClis: { [cli in AwsClis]: Cli } = { manualInstallLink: 'https://docs.docker.com/desktop', exec: 'docker', }, - // Currently Finch is available for MacOS and Linux; Windows support will be added when available + // Currently Finch is available for MacOS and Linux; Windows support will be added if/when available finch: { command: { unix: ['finch', path.join('/', 'usr', 'bin', 'finch'), path.join('/', 'usr', 'local', 'bin', 'finch')], @@ -180,10 +180,6 @@ export const awsClis: { [cli in AwsClis]: Cli } = { x86: 'https://github.com/runfinch/finch/releases/download/v1.11.0/Finch-v1.11.0-x86_64.pkg', arm: 'https://github.com/runfinch/finch/releases/download/v1.11.0/Finch-v1.11.0-aarch64.pkg', }, - linux: { - x86: 'https://github.com/runfinch/finch/releases/download/v1.11.0/runfinch-finch_1.11.0_amd64.deb', - arm: 'https://github.com/runfinch/finch/releases/download/v1.11.0/runfinch-finch_1.11.0_arm64.deb', - }, }, name: 'Finch', manualInstallLink: 'https://runfinch.com/docs/getting-started/installation/', @@ -541,9 +537,6 @@ async function installGui( case 'win32': await new TimedProcess(guiInstaller, []).run() return await getCliCommand(awsClis[cli]) - case 'linux': - await new TimedProcess('dpkg', ['-i', guiInstaller]).run() - return await getCliCommand(awsClis[cli]) // customer shouldn't reach this point as they will be directed to manual install link in entrypoint. default: throw new InvalidPlatformError(