diff --git a/.github/workflows/lint-ext-azure-logicappsstandard.yml b/.github/workflows/lint-ext-azure-logicappsstandard.yml
new file mode 100644
index 00000000000..57f8dd4dabb
--- /dev/null
+++ b/.github/workflows/lint-ext-azure-logicappsstandard.yml
@@ -0,0 +1,22 @@
+name: ext-azure-logicappsstandard-ci
+
+on:
+ pull_request:
+ paths:
+ - "cli/azd/extensions/azure.logicappsstandard/**"
+ - ".github/workflows/lint-ext-azure-logicappsstandard.yml"
+ branches: [main]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ lint:
+ uses: ./.github/workflows/lint-go.yml
+ with:
+ working-directory: cli/azd/extensions/azure.logicappsstandard
diff --git a/cli/azd/extensions/azure.logicappsstandard/.golangci.yaml b/cli/azd/extensions/azure.logicappsstandard/.golangci.yaml
new file mode 100644
index 00000000000..b88a74c6a0b
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/.golangci.yaml
@@ -0,0 +1,17 @@
+version: "2"
+
+linters:
+ default: none
+ enable:
+ - gosec
+ - lll
+ - unused
+ - errorlint
+ settings:
+ lll:
+ line-length: 220
+ tab-width: 4
+
+formatters:
+ enable:
+ - gofmt
diff --git a/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md
new file mode 100644
index 00000000000..f942c9989b3
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Release History
+
+## 0.0.1
+
+- Initial release with support for packaging Logic App Standard projects via `language: logicappsstandard` in `azure.yaml`, and optional custom code projects using `customCodeProject` property.
\ No newline at end of file
diff --git a/cli/azd/extensions/azure.logicappsstandard/README.md b/cli/azd/extensions/azure.logicappsstandard/README.md
new file mode 100644
index 00000000000..4c3dc0d51af
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/README.md
@@ -0,0 +1,155 @@
+# Azure Logic Apps Standard extension
+
+This azd extension makes it possible to package Logic Apps Standard projects and includes support for custom code projects.
+
+
+## Installing
+
+Assuming 'azd' is in your path, run the following commands to install the extension for the first time:
+
+```shell
+azd ext install azure.logicappsstandard
+```
+
+Or, if you already have the `azure.logicappsstandard` extension installed, and you want to upgrade to the latest version:
+
+```shell
+azd ext upgrade azure.logicappsstandard
+```
+
+## Usage
+
+This extension introduces the `logicappsstandard` language which can package Logic Apps Standard projects.
+
+For example, if your template has a Logic App Standard project with the following structure:
+
+```
+└── src
+ └── logicapp
+ ├── .vscode
+ ├── artifacts
+ ├── lib
+ ├── workflow1
+ │ └── workflow.json
+ ├── workflow2
+ │ └── workflow.json
+ ├── workflow-designtime
+ ├── .funcignore
+ ├── .gitignore
+ ├── host.json
+ └── local.settings.json
+```
+
+Use the following snippet in your `azure.yaml` file to configure the Logic App:
+
+```yaml
+services:
+ logicapp:
+ project: ./src/logicapp
+ host: function
+ language: logicappsstandard
+```
+
+This will package everything under the `src/logicapp` folder in a .zip file. Because `function` is used as the host, the exclusions in `.funcignore` are respected and only the relevant files are packaged.
+
+The extension also supports Logic App Standard projects with a .NET 8 or .NET Framework custom code project. For example, if your template has a Logic App Standard project with custom code project following this structure:
+
+```
+└── src
+ └── logicapp
+ ├── Functions
+ │ ├── MyFunctions.cs
+ │ ├── Functions.csproj
+ │ └── ...
+ └── Workflows
+ ├── workflow1
+ │ └── workflow.json
+ ├── workflow2
+ │ └── workflow.json
+ ├── host.json
+ └── ...
+```
+
+You can use the following snippet in your `azure.yaml` file to configure the Logic App:
+
+```yaml
+services:
+ logicapp:
+ project: ./src/logicapp
+ dist: Workflows
+ host: function
+ language: logicappsstandard
+ customCodeProject: Functions/Functions.csproj
+```
+
+This will first build the custom code project and then package the Logic App Standard artifacts.
+
+> [!NOTE]
+> When using `customCodeProject`, make sure the required build toolchain is installed: .NET 8 SDK for .NET 8 projects, or .NET Framework/MSBuild tools for .NET Framework projects.
+
+- The `project` property contains the root folder of the Logic App Standard project.
+- The `dist` property is the relative path to the folder with the Logic App Standard files that will be packaged.
+- The `customCodeProject` property is the path to the custom code project's `.csproj` file.
+
+
+## Troubleshooting
+
+### Language 'logicappsstandard' is not supported
+
+If you see the following error while packaging a Logic App Standard project, azd could not find an installed extension that provides the `logicappsstandard` language. Make sure to install the `azure.logicappsstandard` extension.
+
+```
+ERROR: initializing service '...', getting framework service: language 'logicappsstandard' is not supported by built-in framework services and no extensions are currently providing it
+```
+
+## Local Development
+
+### Prerequisites
+
+1. **Install developer kit extension** (if not already installed):
+ ```bash
+ azd ext install microsoft.azd.extensions
+ ```
+
+ > **Note**: If you encounter an error about the extension not being in the registry, verify you have the default source configured:
+ > ```bash
+ > azd ext source list
+ > ```
+ > If missing, add it:
+ > ```bash
+ > azd ext source add -n azd -t url -l "https://aka.ms/azd/extensions/registry"
+ > ```
+
+### Building and Installing
+
+1. **Navigate to the extension directory**:
+ ```bash
+ cd cli/azd/extensions/azure.logicappsstandard
+ ```
+
+2. **Initial setup** (first time only):
+ ```bash
+ azd x build
+ azd x pack
+ azd x publish
+ ```
+
+3. **Install the extension**:
+ ```bash
+ azd ext install azure.logicappsstandard
+ ```
+
+4. **For subsequent development** (after initial setup):
+ ```bash
+ azd x watch
+ ```
+ This automatically watches for file changes, rebuilds, and installs updates locally.
+
+ Or for manual builds:
+ ```bash
+ azd x build
+ ```
+ This builds and automatically installs the updated extension.
+
+> [!NOTE]
+> The `pack` and `publish` steps are only required for the first time setup. For ongoing development, `azd x watch` or `azd x build` handles all updates automatically.
diff --git a/cli/azd/extensions/azure.logicappsstandard/build.ps1 b/cli/azd/extensions/azure.logicappsstandard/build.ps1
new file mode 100644
index 00000000000..7e3727a9671
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/build.ps1
@@ -0,0 +1,78 @@
+# Ensure script fails on any error
+$ErrorActionPreference = 'Stop'
+
+# Get the directory of the script
+$EXTENSION_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
+
+# Change to the script directory
+Set-Location -Path $EXTENSION_DIR
+
+# Create a safe version of EXTENSION_ID replacing dots with dashes
+$EXTENSION_ID_SAFE = $env:EXTENSION_ID -replace '\.', '-'
+
+# Define output directory
+$OUTPUT_DIR = if ($env:OUTPUT_DIR) { $env:OUTPUT_DIR } else { Join-Path $EXTENSION_DIR "bin" }
+
+# Create output directory if it doesn't exist
+if (-not (Test-Path -Path $OUTPUT_DIR)) {
+ New-Item -ItemType Directory -Path $OUTPUT_DIR | Out-Null
+}
+
+# Get Git commit hash and build date
+$COMMIT = git rev-parse HEAD
+if ($LASTEXITCODE -ne 0) {
+ Write-Host "Error: Failed to get git commit hash"
+ exit 1
+}
+$BUILD_DATE = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")
+
+# List of OS and architecture combinations
+if ($env:EXTENSION_PLATFORM) {
+ $PLATFORMS = @($env:EXTENSION_PLATFORM)
+}
+else {
+ $PLATFORMS = @(
+ "windows/amd64",
+ "windows/arm64",
+ "darwin/amd64",
+ "darwin/arm64",
+ "linux/amd64",
+ "linux/arm64"
+ )
+}
+
+$VERSION_PATH = "azurelogicappsstandard/internal/version"
+
+# Loop through platforms and build
+foreach ($PLATFORM in $PLATFORMS) {
+ $OS, $ARCH = $PLATFORM -split '/'
+
+ $OUTPUT_NAME = Join-Path $OUTPUT_DIR "$EXTENSION_ID_SAFE-$OS-$ARCH"
+
+ if ($OS -eq "windows") {
+ $OUTPUT_NAME += ".exe"
+ }
+
+ Write-Host "Building for $OS/$ARCH..."
+
+ # Delete the output file if it already exists
+ if (Test-Path -Path $OUTPUT_NAME) {
+ Remove-Item -Path $OUTPUT_NAME -Force
+ }
+
+ # Set environment variables for Go build
+ $env:GOOS = $OS
+ $env:GOARCH = $ARCH
+
+ go build `
+ -ldflags="-X '$VERSION_PATH.Version=$env:EXTENSION_VERSION' -X '$VERSION_PATH.Commit=$COMMIT' -X '$VERSION_PATH.BuildDate=$BUILD_DATE'" `
+ -o $OUTPUT_NAME
+
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "An error occurred while building for $OS/$ARCH"
+ exit 1
+ }
+}
+
+Write-Host "Build completed successfully!"
+Write-Host "Binaries are located in the $OUTPUT_DIR directory."
diff --git a/cli/azd/extensions/azure.logicappsstandard/build.sh b/cli/azd/extensions/azure.logicappsstandard/build.sh
new file mode 100644
index 00000000000..5e48da51567
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/build.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+# Get the directory of the script
+EXTENSION_DIR="$(cd "$(dirname "$0")" && pwd)"
+
+# Change to the script directory
+cd "$EXTENSION_DIR" || exit
+
+# Create a safe version of EXTENSION_ID replacing dots with dashes
+EXTENSION_ID_SAFE="${EXTENSION_ID//./-}"
+
+# Define output directory
+OUTPUT_DIR="${OUTPUT_DIR:-$EXTENSION_DIR/bin}"
+
+# Create output and target directories if they don't exist
+mkdir -p "$OUTPUT_DIR"
+
+# Get Git commit hash and build date
+COMMIT=$(git rev-parse HEAD)
+BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
+
+# List of OS and architecture combinations
+if [ -n "$EXTENSION_PLATFORM" ]; then
+ PLATFORMS=("$EXTENSION_PLATFORM")
+else
+ PLATFORMS=(
+ "windows/amd64"
+ "windows/arm64"
+ "darwin/amd64"
+ "darwin/arm64"
+ "linux/amd64"
+ "linux/arm64"
+ )
+fi
+
+VERSION_PATH="azurelogicappsstandard/internal/version"
+
+# Loop through platforms and build
+for PLATFORM in "${PLATFORMS[@]}"; do
+ OS=$(echo "$PLATFORM" | cut -d'/' -f1)
+ ARCH=$(echo "$PLATFORM" | cut -d'/' -f2)
+
+ OUTPUT_NAME="$OUTPUT_DIR/$EXTENSION_ID_SAFE-$OS-$ARCH"
+
+ if [ "$OS" = "windows" ]; then
+ OUTPUT_NAME+='.exe'
+ fi
+
+ echo "Building for $OS/$ARCH..."
+
+ # Delete the output file if it already exists
+ [ -f "$OUTPUT_NAME" ] && rm -f "$OUTPUT_NAME"
+
+ # Set environment variables for Go build
+ GOOS=$OS GOARCH=$ARCH go build \
+ -ldflags="-X '$VERSION_PATH.Version=$EXTENSION_VERSION' -X '$VERSION_PATH.Commit=$COMMIT' -X '$VERSION_PATH.BuildDate=$BUILD_DATE'" \
+ -o "$OUTPUT_NAME"
+
+ if [ $? -ne 0 ]; then
+ echo "An error occurred while building for $OS/$ARCH"
+ exit 1
+ fi
+done
+
+echo "Build completed successfully!"
+echo "Binaries are located in the $OUTPUT_DIR directory."
diff --git a/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1 b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1
new file mode 100644
index 00000000000..8d5753bb803
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/ci-build.ps1
@@ -0,0 +1,142 @@
+param(
+ [string] $Version = (Get-Content "$PSScriptRoot/version.txt"),
+ [string] $SourceVersion = (git rev-parse HEAD),
+ [switch] $CodeCoverageEnabled,
+ [switch] $BuildRecordMode,
+ [string] $MSYS2Shell, # path to msys2_shell.cmd
+ [string] $OutputFileName
+)
+
+# Remove any previously built binaries
+go clean
+
+if ($LASTEXITCODE) {
+ Write-Host "Error running go clean"
+ exit $LASTEXITCODE
+}
+
+# Run `go help build` to obtain detailed information about `go build` flags.
+$buildFlags = @(
+ # remove all file system paths from the resulting executable.
+ # Instead of absolute file system paths, the recorded file names
+ # will begin either a module path@version (when using modules),
+ # or a plain import path (when using the standard library, or GOPATH).
+ "-trimpath",
+
+ # Use buildmode=pie (Position Independent Executable) for enhanced security across platforms
+ # against memory corruption exploits across all major platforms.
+ #
+ # On Windows, the -buildmode=pie flag enables Address Space Layout
+ # Randomization (ASLR) and automatically sets DYNAMICBASE and HIGH-ENTROPY-VA flags in the PE header.
+ "-buildmode=pie"
+)
+
+if ($CodeCoverageEnabled) {
+ $buildFlags += "-cover"
+}
+
+# Build constraint tags
+# cfi: Enable Control Flow Integrity (CFI),
+# cfg: Enable Control Flow Guard (CFG),
+# osusergo: Optimize for OS user accounts
+$tagsFlag = "-tags=cfi,cfg,osusergo"
+
+# ld linker flags
+# -s: Omit symbol table and debug information
+# -w: Omit DWARF symbol table
+# -X: Set variable at link time. Used to set the version in source.
+
+$ldFlag = "-ldflags=-s -w -X 'azurelogicappsstandard/internal/version.Version=$Version' -X 'azurelogicappsstandard/internal/version.Commit=$SourceVersion' -X 'azurelogicappsstandard/internal/version.BuildDate=$(Get-Date -Format o)' "
+
+if ($IsWindows) {
+ $msg = "Building for Windows"
+ Write-Host $msg
+}
+elseif ($IsLinux) {
+ Write-Host "Building for linux"
+}
+elseif ($IsMacOS) {
+ Write-Host "Building for macOS"
+}
+
+# Add output file flag based on specified output file name
+$outputFlag = "-o=$OutputFileName"
+
+# collect flags
+$buildFlags += @(
+ $tagsFlag,
+ $ldFlag,
+ $outputFlag
+)
+
+function PrintFlags() {
+ param(
+ [string] $flags
+ )
+
+ # Attempt to format flags so that they are easily copy-pastable to be ran inside pwsh
+ $i = 0
+ foreach ($buildFlag in $buildFlags) {
+ # If the flag has a value, wrap it in quotes. This is not required when invoking directly below,
+ # but when repasted into a shell for execution, the quotes can help escape special characters such as ','.
+ $argWithValue = $buildFlag.Split('=', 2)
+ if ($argWithValue.Length -eq 2 -and !$argWithValue[1].StartsWith("`"")) {
+ $buildFlag = "$($argWithValue[0])=`"$($argWithValue[1])`""
+ }
+
+ # Write each flag on a newline with '`' acting as the multiline separator
+ if ($i -eq $buildFlags.Length - 1) {
+ Write-Host " $buildFlag"
+ }
+ else {
+ Write-Host " $buildFlag ``"
+ }
+ $i++
+ }
+}
+
+$oldGOEXPERIMENT = $env:GOEXPERIMENT
+# Enable the loopvar experiment, which makes the loop variable for go loops like `range` behave as most folks would expect.
+# the go team is exploring making this default in the future, and we'd like to opt into the behavior now.
+$env:GOEXPERIMENT = "loopvar"
+
+try {
+ Write-Host "Running: go build ``"
+ PrintFlags -flags $buildFlags
+ go build @buildFlags
+ if ($LASTEXITCODE) {
+ Write-Host "Error running go build"
+ exit $LASTEXITCODE
+ }
+
+ if ($BuildRecordMode) {
+ # Modify build tags to include record
+ $recordTagPatched = $false
+ for ($i = 0; $i -lt $buildFlags.Length; $i++) {
+ if ($buildFlags[$i].StartsWith("-tags=")) {
+ $buildFlags[$i] += ",record"
+ $recordTagPatched = $true
+ }
+ }
+ if (-not $recordTagPatched) {
+ $buildFlags += "-tags=record"
+ }
+ # Add output file flag for record mode
+ $recordOutput = "-o=$OutputFileName-record"
+ if ($IsWindows) { $recordOutput += ".exe" }
+ $buildFlags += $recordOutput
+
+ Write-Host "Running: go build (record) ``"
+ PrintFlags -flags $buildFlags
+ go build @buildFlags
+ if ($LASTEXITCODE) {
+ Write-Host "Error running go build (record)"
+ exit $LASTEXITCODE
+ }
+ }
+
+ Write-Host "go build succeeded"
+}
+finally {
+ $env:GOEXPERIMENT = $oldGOEXPERIMENT
+}
\ No newline at end of file
diff --git a/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1 b/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1
new file mode 100644
index 00000000000..cfb399136f3
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/ci-test.ps1
@@ -0,0 +1,27 @@
+$gopath = go env GOPATH
+$gotestsumBinary = "gotestsum"
+if ($IsWindows) {
+ $gotestsumBinary += ".exe"
+}
+$gotestsum = Join-Path $gopath "bin" $gotestsumBinary
+
+Write-Host "Running unit tests..."
+
+if (Test-Path $gotestsum) {
+ # Use gotestsum for better output formatting and summary
+ & $gotestsum --format testname -- ./... -count=1
+} else {
+ # Fallback to go test if gotestsum is not installed
+ Write-Host "gotestsum not found, using go test..." -ForegroundColor Yellow
+ go test ./... -v -count=1
+}
+
+if ($LASTEXITCODE -ne 0) {
+ Write-Host ""
+ Write-Host "Tests failed with exit code: $LASTEXITCODE" -ForegroundColor Red
+ exit $LASTEXITCODE
+}
+
+Write-Host ""
+Write-Host "All tests passed!" -ForegroundColor Green
+exit 0
\ No newline at end of file
diff --git a/cli/azd/extensions/azure.logicappsstandard/cspell.yaml b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml
new file mode 100644
index 00000000000..4d8530cabe7
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/cspell.yaml
@@ -0,0 +1,7 @@
+import: ../../.vscode/cspell.yaml
+words:
+ - azurelogicappsstandard
+ - designtime
+ - logicapp
+ - logicappsstandard
+
\ No newline at end of file
diff --git a/cli/azd/extensions/azure.logicappsstandard/extension.yaml b/cli/azd/extensions/azure.logicappsstandard/extension.yaml
new file mode 100644
index 00000000000..f6663a3210c
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/extension.yaml
@@ -0,0 +1,11 @@
+# yaml-language-server: $schema=../extension.schema.json
+id: azure.logicappsstandard
+namespace: logicappsstandard
+displayName: Azure Logic Apps Standard
+description: Extension for packaging Logic Apps Standard projects, including support for custom code projects
+usage: Use logicappsstandard as language in your service configuration. If your Logic App has a custom code project, configure that path to the .csproj file using the customCodeProject property.
+# NOTE: Make sure version.txt is in sync with this version.
+version: 0.0.1
+language: go
+capabilities:
+ - framework-service-provider
\ No newline at end of file
diff --git a/cli/azd/extensions/azure.logicappsstandard/go.mod b/cli/azd/extensions/azure.logicappsstandard/go.mod
new file mode 100644
index 00000000000..d6c8ffb1842
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/go.mod
@@ -0,0 +1,104 @@
+module azurelogicappsstandard
+
+go 1.26.1
+
+require (
+ github.com/azure/azure-dev/cli/azd v1.25.1
+ github.com/spf13/cobra v1.10.2
+ github.com/stretchr/testify v1.11.1
+ google.golang.org/protobuf v1.36.11
+)
+
+require (
+ github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect
+ github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 // indirect
+ github.com/Masterminds/semver/v3 v3.5.0 // indirect
+ github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b // indirect
+ github.com/alecthomas/chroma/v2 v2.24.1 // indirect
+ github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
+ github.com/aymerick/douceur v0.2.0 // indirect
+ github.com/bahlo/generic-list-go v0.2.0 // indirect
+ github.com/blang/semver/v4 v4.0.0 // indirect
+ github.com/braydonk/yaml v0.9.0 // indirect
+ github.com/buger/goterm v1.0.4 // indirect
+ github.com/buger/jsonparser v1.2.0 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/charmbracelet/colorprofile v0.4.3 // indirect
+ github.com/charmbracelet/glamour v1.0.0 // indirect
+ github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect
+ github.com/charmbracelet/x/ansi v0.11.7 // indirect
+ github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
+ github.com/charmbracelet/x/exp/slice v0.0.0-20260519012233-798e623c8447 // indirect
+ github.com/charmbracelet/x/term v0.2.2 // indirect
+ github.com/cli/browser v1.3.0 // indirect
+ github.com/clipperhouse/displaywidth v0.11.0 // indirect
+ github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/dlclark/regexp2 v1.12.0 // indirect
+ github.com/drone/envsubst v1.0.3 // indirect
+ github.com/fatih/color v1.19.0 // indirect
+ github.com/go-logr/logr v1.4.3 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
+ github.com/gofrs/flock v0.13.0 // indirect
+ github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
+ github.com/golobby/container/v3 v3.3.2 // indirect
+ github.com/google/jsonschema-go v0.4.3 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/gorilla/css v1.0.1 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/invopop/jsonschema v0.14.0 // indirect
+ github.com/jmespath-community/go-jmespath v1.1.1 // indirect
+ github.com/joho/godotenv v1.5.1 // indirect
+ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
+ github.com/kylelemons/godebug v1.1.0 // indirect
+ github.com/lucasb-eyer/go-colorful v1.4.0 // indirect
+ github.com/mark3labs/mcp-go v0.54.0 // indirect
+ github.com/mattn/go-colorable v0.1.14 // indirect
+ github.com/mattn/go-isatty v0.0.22 // indirect
+ github.com/mattn/go-runewidth v0.0.23 // indirect
+ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
+ github.com/microcosm-cc/bluemonday v1.0.27 // indirect
+ github.com/microsoft/ApplicationInsights-Go v0.4.4 // indirect
+ github.com/microsoft/go-deviceid v1.0.0 // indirect
+ github.com/muesli/reflow v0.3.0 // indirect
+ github.com/muesli/termenv v0.16.0 // indirect
+ github.com/nathan-fiscaletti/consolesize-go v0.0.0-20260406063853-3bac975de715 // indirect
+ github.com/pb33f/ordered-map/v2 v2.3.1 // indirect
+ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+ github.com/rivo/uniseg v0.4.7 // indirect
+ github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
+ github.com/sethvargo/go-retry v0.3.0 // indirect
+ github.com/spf13/cast v1.10.0 // indirect
+ github.com/spf13/pflag v1.0.10 // indirect
+ github.com/theckman/yacspin v0.13.12 // indirect
+ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
+ github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
+ github.com/yuin/goldmark v1.8.2 // indirect
+ github.com/yuin/goldmark-emoji v1.0.6 // indirect
+ go.opentelemetry.io/auto/sdk v1.2.1 // indirect
+ go.opentelemetry.io/otel v1.43.0 // indirect
+ go.opentelemetry.io/otel/metric v1.43.0 // indirect
+ go.opentelemetry.io/otel/sdk v1.43.0 // indirect
+ go.opentelemetry.io/otel/trace v1.43.0 // indirect
+ go.uber.org/atomic v1.11.0 // indirect
+ go.uber.org/multierr v1.11.0 // indirect
+ go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect
+ golang.org/x/crypto v0.51.0 // indirect
+ golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a // indirect
+ golang.org/x/net v0.54.0 // indirect
+ golang.org/x/sys v0.44.0 // indirect
+ golang.org/x/term v0.43.0 // indirect
+ golang.org/x/text v0.37.0 // indirect
+ golang.org/x/time v0.15.0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20260519071638-aa98bba5eb94 // indirect
+ google.golang.org/grpc v1.81.1 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/cli/azd/extensions/azure.logicappsstandard/go.sum b/cli/azd/extensions/azure.logicappsstandard/go.sum
new file mode 100644
index 00000000000..f6b13b080f8
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/go.sum
@@ -0,0 +1,314 @@
+code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8=
+github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
+github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 h1:jHb/wfvRikGdxMXYV3QG/SzUOPYN9KEUUuC0Yd0/vC0=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1/go.mod h1:pzBXCYn05zvYIrwLgtK8Ap8QcjRg+0i76tMQdWN6wOk=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0 h1:2qsIIvxVT+uE6yrNldntJKlLRgxGbZ85kgtz5SNBhMw=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0/go.mod h1:AW8VEadnhw9xox+VaVd9sP7NjzOAnaZBLRH6Tq3cJ38=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0 h1:nnQ9vXH039UrEFxi08pPuZBE7VfqSJt343uJLw0rhWI=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0/go.mod h1:4YIVtzMFVsPwBvitCDX7J9sqthSj43QD1sP6fYc1egc=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 h1:wxQx2Bt4xzPIKvW59WQf1tJNx/ZZKPfN+EhPX3Z6CYY=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0/go.mod h1:TpiwjwnW/khS0LKs4vW5UmmT9OWcxaveS8U7+tlknzo=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 h1:/g8S6wk65vfC6m3FIxJ+i5QDyN9JWwXI8Hb0Img10hU=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0/go.mod h1:gpl+q95AzZlKVI3xSoseF9QPrypk0hQqBiJYeB/cR/I=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA=
+github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
+github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 h1:RHK7bS+HQMslb1sZpAokUt+zTVmue0hKSs2C791hhzU=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
+github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
+github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
+github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
+github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b h1:g9SuFmxM/WucQFKTMSP+irxyf5m0RiUJreBDhGI6jSA=
+github.com/adam-lavrik/go-imath v0.0.0-20210910152346-265a42a96f0b/go.mod h1:XjvqMUpGd3Xn9Jtzk/4GEBCSoBX0eB2RyriXgne0IdM=
+github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
+github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
+github.com/alecthomas/chroma/v2 v2.24.1 h1:m5ffpfZbIb++k8AqFEKy9uVgY12xIQtBsQlc6DfZJQM=
+github.com/alecthomas/chroma/v2 v2.24.1/go.mod h1:l+ohZ9xRXIbGe7cIW+YZgOGbvuVLjMps/FYN/CwuabI=
+github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
+github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
+github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
+github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
+github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
+github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
+github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
+github.com/azure/azure-dev/cli/azd v1.25.1 h1:FLU+KVGwQBmSwADN8GuKQvYdFLpclc8SX6c4md+5b0Y=
+github.com/azure/azure-dev/cli/azd v1.25.1/go.mod h1:Q8S2cdn6ArpzaHTjwRFLbGFgS6rU09rOF7k5gsBTTso=
+github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
+github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
+github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
+github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
+github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
+github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
+github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
+github.com/braydonk/yaml v0.9.0 h1:ewGMrVmEVpsm3VwXQDR388sLg5+aQ8Yihp6/hc4m+h4=
+github.com/braydonk/yaml v0.9.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4=
+github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY=
+github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE=
+github.com/buger/jsonparser v1.2.0 h1:4EFcvK1kD4jyj6YqNK6skK6w+y7FHHBR+XBCtxwu/6g=
+github.com/buger/jsonparser v1.2.0/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q=
+github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q=
+github.com/charmbracelet/glamour v1.0.0 h1:AWMLOVFHTsysl4WV8T8QgkQ0s/ZNZo7CiE4WKhk8l08=
+github.com/charmbracelet/glamour v1.0.0/go.mod h1:DSdohgOBkMr2ZQNhw4LZxSGpx3SvpeujNoXrQyH2hxo=
+github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE=
+github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA=
+github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI=
+github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ=
+github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI=
+github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q=
+github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
+github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
+github.com/charmbracelet/x/exp/slice v0.0.0-20260519012233-798e623c8447 h1:dZNZoFaaoQYXmtAOz4ovm0kISwcKX5Xt29ZLqhNYQKc=
+github.com/charmbracelet/x/exp/slice v0.0.0-20260519012233-798e623c8447/go.mod h1:vqEfX6xzqW1pKKZUUiFOKg0OQ7bCh54Q2vR/tserrRA=
+github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
+github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
+github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
+github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
+github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8=
+github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0=
+github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
+github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
+github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
+github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g=
+github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g=
+github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
+github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
+github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
+github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
+github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/golobby/container/v3 v3.3.2 h1:7u+RgNnsdVlhGoS8gY4EXAG601vpMMzLZlYqSp77Quw=
+github.com/golobby/container/v3 v3.3.2/go.mod h1:RDdKpnKpV1Of11PFBe7Dxc2C1k2KaLE4FD47FflAmj0=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=
+github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
+github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
+github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
+github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
+github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
+github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/invopop/jsonschema v0.14.0 h1:MHQqLhvpNUZfw+hM3AZDYK7jxO8FZoQeQM77g8iyZjg=
+github.com/invopop/jsonschema v0.14.0/go.mod h1:ygm6C2EaVNMBDPpaPlnOA2pFAxBnxGjFlMZABxm9n2I=
+github.com/jmespath-community/go-jmespath v1.1.1 h1:bFikPhsi/FdmlZhVgSCd2jj1e7G/rw+zyQfyg5UF+L4=
+github.com/jmespath-community/go-jmespath v1.1.1/go.mod h1:4gOyFJsR/Gk+05RgTKYrifT7tBPWD8Lubtb5jRrfy9I=
+github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
+github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU=
+github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
+github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/mark3labs/mcp-go v0.54.0 h1:PZhQvd+5xrT43cUoiaKn/hDcvLUhcLc1twSEKYPTcTA=
+github.com/mark3labs/mcp-go v0.54.0/go.mod h1:+8WclSK1ZUweCP3hvktSji8n8ABG/95QaEkeVE/Uwas=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
+github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
+github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
+github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
+github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw=
+github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
+github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
+github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
+github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
+github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
+github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
+github.com/microsoft/ApplicationInsights-Go v0.4.4 h1:G4+H9WNs6ygSCe6sUyxRc2U81TI5Es90b2t/MwX5KqY=
+github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U=
+github.com/microsoft/go-deviceid v1.0.0 h1:i5AQ654Xk9kfvwJeKQm3w2+eT1+ImBDVEpAR0AjpP40=
+github.com/microsoft/go-deviceid v1.0.0/go.mod h1:KY13FeVdHkzD8gy+6T8+kVmD/7RMpTaWW75K+T4uZWg=
+github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
+github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
+github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
+github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
+github.com/nathan-fiscaletti/consolesize-go v0.0.0-20260406063853-3bac975de715 h1:FiSC3sz/k2SYB32YJ1bLlBVB7Li0N7n6jcYa9Knq/60=
+github.com/nathan-fiscaletti/consolesize-go v0.0.0-20260406063853-3bac975de715/go.mod h1:DQpEqvLUU3b35AJUVu5P6LFn/RY3qj4WtMjvrcE8gto=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pb33f/ordered-map/v2 v2.3.1 h1:5319HDO0aw4DA4gzi+zv4FXU9UlSs3xGZ40wcP1nBjY=
+github.com/pb33f/ordered-map/v2 v2.3.1/go.mod h1:qxFQgd0PkVUtOMCkTapqotNgzRhMPL7VvaHKbd1HnmQ=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
+github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
+github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=
+github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
+github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
+github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
+github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
+github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
+github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
+github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0=
+github.com/theckman/yacspin v0.13.12 h1:CdZ57+n0U6JMuh2xqjnjRq5Haj6v1ner2djtLQRzJr4=
+github.com/theckman/yacspin v0.13.12/go.mod h1:Rd2+oG2LmQi5f3zC3yeZAOl245z8QOvrH4OPOJNZxLg=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
+github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
+github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
+github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
+github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs=
+github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA=
+go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
+go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
+go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
+go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
+go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
+go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
+go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
+go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
+go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
+go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
+go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
+go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U=
+go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
+golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
+golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a h1:+3jdDGGB8NGb1Zktc737jlt3/A5f6UlwSzmvqUuufxw=
+golang.org/x/exp v0.0.0-20260508232706-74f9aab9d74a/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
+golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
+golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
+golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
+golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
+golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
+golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
+gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260519071638-aa98bba5eb94 h1:eZCjr/aAF8c5ccm5pb6T4EXgIei5MlAAPWPJk+5ArfY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260519071638-aa98bba5eb94/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
+google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
+google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go
new file mode 100644
index 00000000000..cf37704f18f
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/listen.go
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package cmd
+
+import (
+ "github.com/azure/azure-dev/cli/azd/pkg/azdext"
+
+ "azurelogicappsstandard/internal/project"
+)
+
+// configureListen is called by NewListenCommand to register event handlers.
+func configureListen(host *azdext.ExtensionHost) {
+ host.WithFrameworkService("logicappsstandard", func() azdext.FrameworkServiceProvider {
+ return project.NewLogicAppsStandardFrameworkServiceProvider()
+ })
+}
diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go
new file mode 100644
index 00000000000..f6b1120a3be
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/internal/cmd/root.go
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package cmd
+
+import (
+ "github.com/azure/azure-dev/cli/azd/pkg/azdext"
+ "github.com/spf13/cobra"
+
+ "azurelogicappsstandard/internal/version"
+)
+
+const (
+ extensionID = "azure.logicappsstandard"
+)
+
+// NewRootCommand creates the root command for the Logic Apps Standard extension.
+func NewRootCommand() *cobra.Command {
+ rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{
+ Name: extensionID,
+ Version: version.Version,
+ Short: "Extension for packaging Logic Apps Standard projects, including support for custom code projects",
+ })
+
+ // Standard lifecycle, metadata, and version commands
+ rootCmd.AddCommand(azdext.NewListenCommand(configureListen))
+ rootCmd.AddCommand(azdext.NewMetadataCommand("1.0", extensionID, NewRootCommand))
+ rootCmd.AddCommand(azdext.NewVersionCommand(extensionID, version.Version, &extCtx.OutputFormat))
+
+ return rootCmd
+}
diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go
new file mode 100644
index 00000000000..42275feda79
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard.go
@@ -0,0 +1,237 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package project
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/azure/azure-dev/cli/azd/pkg/azdext"
+)
+
+// Ensure LogicAppsStandardFrameworkServiceProvider implements FrameworkServiceProvider interface
+var _ azdext.FrameworkServiceProvider = &LogicAppsStandardFrameworkServiceProvider{}
+
+// LogicAppsStandardFrameworkServiceProvider introduces the custom language 'logicappsstandard',
+// which makes it possible to package Logic Apps Standard projects, including those with custom code components.
+type LogicAppsStandardFrameworkServiceProvider struct {
+ serviceConfig *azdext.ServiceConfig
+}
+
+// NewLogicAppsStandardFrameworkServiceProvider creates a Logic Apps Standard framework service provider.
+func NewLogicAppsStandardFrameworkServiceProvider() azdext.FrameworkServiceProvider {
+ return &LogicAppsStandardFrameworkServiceProvider{}
+}
+
+// Initialize initializes the framework service provider with service configuration
+func (p *LogicAppsStandardFrameworkServiceProvider) Initialize(
+ ctx context.Context,
+ serviceConfig *azdext.ServiceConfig,
+) error {
+ p.serviceConfig = serviceConfig
+
+ if serviceConfig.Host != "function" {
+ return fmt.Errorf("Logic Apps Standard requires the host to be 'function', but found '%s'", serviceConfig.Host)
+ }
+
+ if hasCustomCodeProjectConfigured(serviceConfig) {
+ csProjPath, err := p.resolveCustomCodeProjectPath(serviceConfig)
+ if err != nil {
+ return err
+ }
+ projectInfo, err := os.Stat(csProjPath)
+ if err != nil {
+ return fmt.Errorf("custom code project not found at '%s': %w", csProjPath, err)
+ }
+ if projectInfo.IsDir() {
+ return fmt.Errorf("custom code project path '%s' must point to a file", csProjPath)
+ }
+ }
+
+ return nil
+}
+
+// Returns dotnet as required external tool if a custom code project is configured
+func (p *LogicAppsStandardFrameworkServiceProvider) RequiredExternalTools(
+ ctx context.Context,
+ serviceConfig *azdext.ServiceConfig,
+) ([]*azdext.ExternalTool, error) {
+ if hasCustomCodeProjectConfigured(serviceConfig) {
+ return []*azdext.ExternalTool{
+ {
+ Name: "dotnet",
+ InstallUrl: "https://dotnet.microsoft.com/download",
+ },
+ }, nil
+ }
+ return nil, nil
+}
+
+// Requirements returns the framework requirements (whether restore/build are needed)
+func (p *LogicAppsStandardFrameworkServiceProvider) Requirements() (*azdext.FrameworkRequirements, error) {
+ hasCustomCodeProject := p.serviceConfig != nil && hasCustomCodeProjectConfigured(p.serviceConfig)
+ return &azdext.FrameworkRequirements{
+ Package: &azdext.FrameworkPackageRequirements{
+ RequireRestore: hasCustomCodeProject,
+ RequireBuild: hasCustomCodeProject,
+ },
+ }, nil
+}
+
+// Restores the dependencies for the custom code project if specified in the service configuration.
+func (p *LogicAppsStandardFrameworkServiceProvider) Restore(
+ ctx context.Context,
+ serviceConfig *azdext.ServiceConfig,
+ serviceContext *azdext.ServiceContext,
+ progress azdext.ProgressReporter,
+) (*azdext.ServiceRestoreResult, error) {
+ if hasCustomCodeProjectConfigured(serviceConfig) {
+ progress("Restoring .NET project dependencies")
+ csProjPath, err := p.resolveCustomCodeProjectPath(serviceConfig)
+ if err != nil {
+ return nil, err
+ }
+ if err := runDotNet(ctx, "restore", csProjPath); err != nil {
+ return nil, fmt.Errorf("restoring custom code project '%s': %w", csProjPath, err)
+ }
+ }
+ return &azdext.ServiceRestoreResult{}, nil
+}
+
+// Builds the custom code project if specified in the service configuration.
+func (p *LogicAppsStandardFrameworkServiceProvider) Build(
+ ctx context.Context,
+ serviceConfig *azdext.ServiceConfig,
+ serviceContext *azdext.ServiceContext,
+ progress azdext.ProgressReporter,
+) (*azdext.ServiceBuildResult, error) {
+ if hasCustomCodeProjectConfigured(serviceConfig) {
+ progress("Building .NET project")
+ csProjPath, err := p.resolveCustomCodeProjectPath(serviceConfig)
+ if err != nil {
+ return nil, err
+ }
+ if err := runDotNet(ctx, "build", csProjPath, "--configuration", "Release"); err != nil {
+ return nil, fmt.Errorf("building custom code project '%s': %w", csProjPath, err)
+ }
+ }
+ return &azdext.ServiceBuildResult{}, nil
+}
+
+// Packages the Logic Apps Standard project, including any custom code components, into a deployable artifact.
+func (p *LogicAppsStandardFrameworkServiceProvider) Package(
+ ctx context.Context,
+ serviceConfig *azdext.ServiceConfig,
+ serviceContext *azdext.ServiceContext,
+ progress azdext.ProgressReporter,
+) (*azdext.ServicePackageResult, error) {
+ progress("Creating Logic Apps Standard deployment package")
+
+ projectDir, err := azdext.GetProjectDir()
+ if err != nil {
+ return nil, fmt.Errorf("getting project directory: %w", err)
+ }
+
+ packageParts := []string{serviceConfig.RelativePath}
+
+ // If an output path is specified, append it to the package path.
+ // This allows for subdirectories like "Workflows" to be the root of the zip.
+ if serviceConfig.OutputPath != "" {
+ packageParts = append(packageParts, serviceConfig.OutputPath)
+ }
+
+ packagePath, err := resolvePathWithinBase(projectDir, packageParts...)
+ if err != nil {
+ return nil, fmt.Errorf("resolving package path: %w", err)
+ }
+
+ // Return a DIRECTORY artifact pointing to the resolved package directory for the service.
+ // azd's packaging pipeline will handle creating the zip archive from this directory.
+ // By specifying an absolute path, azd will use the host specific ignore file (e.g. .funcignore) for exclusions.
+ return &azdext.ServicePackageResult{
+ Artifacts: []*azdext.Artifact{
+ {
+ Kind: azdext.ArtifactKind_ARTIFACT_KIND_DIRECTORY,
+ Location: packagePath,
+ LocationKind: azdext.LocationKind_LOCATION_KIND_LOCAL,
+ },
+ },
+ }, nil
+}
+
+func (p *LogicAppsStandardFrameworkServiceProvider) resolveCustomCodeProjectPath(
+ serviceConfig *azdext.ServiceConfig,
+) (string, error) {
+ projectDir, err := azdext.GetProjectDir()
+ if err != nil {
+ return "", fmt.Errorf("getting project directory: %w", err)
+ }
+
+ customCodeProjectPath, err := resolvePathWithinBase(
+ projectDir,
+ serviceConfig.RelativePath,
+ getAdditionalProperty(serviceConfig, "customCodeProject"),
+ )
+ if err != nil {
+ return "", fmt.Errorf("resolving custom code project path: %w", err)
+ }
+
+ return customCodeProjectPath, nil
+}
+
+// resolvePathWithinBase joins path parts and validates the resolved path remains under baseDir.
+func resolvePathWithinBase(baseDir string, pathParts ...string) (string, error) {
+ baseAbs, err := filepath.Abs(baseDir)
+ if err != nil {
+ return "", fmt.Errorf("resolving base directory '%s': %w", baseDir, err)
+ }
+
+ resolvedPath := filepath.Join(append([]string{baseAbs}, pathParts...)...)
+ resolvedAbs, err := filepath.Abs(resolvedPath)
+ if err != nil {
+ return "", fmt.Errorf("resolving path '%s': %w", resolvedPath, err)
+ }
+
+ rel, err := filepath.Rel(baseAbs, resolvedAbs)
+ if err != nil {
+ return "", fmt.Errorf("getting relative path from '%s' to '%s': %w", baseAbs, resolvedAbs, err)
+ }
+
+ if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
+ return "", fmt.Errorf("path '%s' is outside project directory '%s'", resolvedAbs, baseAbs)
+ }
+
+ return resolvedAbs, nil
+}
+
+// getAdditionalProperty retrieves a custom property from the service configuration's additional properties.
+func getAdditionalProperty(serviceConfig *azdext.ServiceConfig, key string) string {
+ if serviceConfig == nil {
+ return ""
+ }
+
+ props := serviceConfig.GetAdditionalProperties()
+ if props == nil {
+ return ""
+ }
+ if v, ok := props.Fields[key]; ok && v != nil {
+ return v.GetStringValue()
+ }
+ return ""
+}
+
+func hasCustomCodeProjectConfigured(serviceConfig *azdext.ServiceConfig) bool {
+ return getAdditionalProperty(serviceConfig, "customCodeProject") != ""
+}
+
+// runDotNet executes the dotnet CLI with the given arguments, forwarding output to stdout/stderr.
+func runDotNet(ctx context.Context, args ...string) error {
+ cmd := azdext.ExecCommand(ctx, "dotnet", args...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ return cmd.Run()
+}
diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go
new file mode 100644
index 00000000000..dbdd8d04edd
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/internal/project/framework_service_logicappsstandard_test.go
@@ -0,0 +1,413 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package project
+
+import (
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+
+ "github.com/azure/azure-dev/cli/azd/pkg/azdext"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "google.golang.org/protobuf/types/known/structpb"
+)
+
+func TestGetAdditionalProperty(t *testing.T) {
+ t.Run("returns empty for nil service config", func(t *testing.T) {
+ assert.Equal(t, "", getAdditionalProperty(nil, "customCodeProject"))
+ })
+
+ t.Run("returns empty for nil additional properties", func(t *testing.T) {
+ svc := &azdext.ServiceConfig{}
+ assert.Equal(t, "", getAdditionalProperty(svc, "customCodeProject"))
+ })
+
+ t.Run("returns property value when present", func(t *testing.T) {
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Functions.csproj",
+ })
+
+ assert.Equal(t, "Functions/Functions.csproj", getAdditionalProperty(svc, "customCodeProject"))
+ })
+}
+
+func TestHasCustomCodeProjectConfigured(t *testing.T) {
+ t.Run("returns false for nil service config", func(t *testing.T) {
+ assert.False(t, hasCustomCodeProjectConfigured(nil))
+ })
+
+ t.Run("returns false when customCodeProject is absent", func(t *testing.T) {
+ assert.False(t, hasCustomCodeProjectConfigured(newServiceConfig("logicApp", "src/logicApp", nil)))
+ })
+
+ t.Run("returns true when customCodeProject is present", func(t *testing.T) {
+ assert.True(t, hasCustomCodeProjectConfigured(newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Functions.csproj",
+ })))
+ })
+}
+
+func TestRequiredExternalTools(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+
+ t.Run("returns nil when custom code is not configured", func(t *testing.T) {
+ tools, err := provider.RequiredExternalTools(t.Context(), newServiceConfig("logicApp", "src/logicApp", nil))
+ require.NoError(t, err)
+ assert.Nil(t, tools)
+ })
+
+ t.Run("returns dotnet when custom code is configured", func(t *testing.T) {
+ tools, err := provider.RequiredExternalTools(
+ t.Context(),
+ newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Functions.csproj",
+ }))
+ require.NoError(t, err)
+ require.Len(t, tools, 1)
+ assert.Equal(t, "dotnet", tools[0].Name)
+ assert.Equal(t, "https://dotnet.microsoft.com/download", tools[0].InstallUrl)
+ })
+}
+
+func TestRequirements(t *testing.T) {
+ t.Run("disables restore and build when service config is not initialized", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ reqs, err := provider.Requirements()
+ require.NoError(t, err)
+ require.NotNil(t, reqs.Package)
+ assert.False(t, reqs.Package.RequireRestore)
+ assert.False(t, reqs.Package.RequireBuild)
+ })
+
+ t.Run("disables restore and build when initialized without customCodeProject", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ provider.serviceConfig = newServiceConfig("logicApp", "src/logicApp", nil)
+ reqs, err := provider.Requirements()
+ require.NoError(t, err)
+ require.NotNil(t, reqs.Package)
+ assert.False(t, reqs.Package.RequireRestore)
+ assert.False(t, reqs.Package.RequireBuild)
+ })
+
+ t.Run("enables restore and build when customCodeProject is configured", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ provider.serviceConfig = newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Functions.csproj",
+ })
+ reqs, err := provider.Requirements()
+ require.NoError(t, err)
+ require.NotNil(t, reqs.Package)
+ assert.True(t, reqs.Package.RequireRestore)
+ assert.True(t, reqs.Package.RequireBuild)
+ })
+}
+
+func TestInitializeValidatesCustomCodeProjectPath(t *testing.T) {
+ projectDir := t.TempDir()
+ createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n")
+
+ t.Run("fails when host is not function", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", nil)
+ svc.Host = "appservice"
+
+ err := provider.Initialize(t.Context(), svc)
+ require.Error(t, err)
+ assert.Equal(t, "Logic Apps Standard requires the host to be 'function', but found 'appservice'", err.Error())
+ })
+
+ t.Run("succeeds without customCodeProject and sets serviceConfig", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", nil)
+
+ err := provider.Initialize(t.Context(), svc)
+ require.NoError(t, err)
+ assert.Equal(t, svc, provider.serviceConfig)
+ })
+
+ t.Run("succeeds when custom code project file exists", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Functions.csproj",
+ })
+
+ createFile(t, filepath.Join(projectDir, "src/logicApp/Functions/Functions.csproj"), "\n")
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ err := provider.Initialize(t.Context(), svc)
+ require.NoError(t, err)
+ })
+ })
+
+ t.Run("fails when custom code project is a directory", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions",
+ })
+
+ err := os.MkdirAll(filepath.Join(projectDir, "src/logicApp/Functions"), 0o750)
+ require.NoError(t, err)
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ err := provider.Initialize(t.Context(), svc)
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "must point to a file")
+ })
+ })
+
+ t.Run("fails when custom code project file is missing", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Missing.csproj",
+ })
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ err := provider.Initialize(t.Context(), svc)
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "custom code project not found")
+ })
+ })
+
+ t.Run("fails when custom code project escapes project directory", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "../../../outside.csproj",
+ })
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ err := provider.Initialize(t.Context(), svc)
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "outside project directory")
+ })
+ })
+
+ t.Run("fails when custom code project path is invalid", func(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Bad\x00Name.csproj",
+ })
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ err := provider.Initialize(t.Context(), svc)
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "custom code project")
+ })
+ })
+}
+
+func TestPackageUsesProjectAndOutputPaths(t *testing.T) {
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ projectDir := t.TempDir()
+ createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n")
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ result, err := provider.Package(t.Context(), newServiceConfig("logicApp", "src/logicApp", nil), nil, func(string) {})
+ require.NoError(t, err)
+ require.Len(t, result.Artifacts, 1)
+
+ artifact := result.Artifacts[0]
+ expectedPath := filepath.Join(projectDir, "src/logicApp")
+ assert.Equal(t, expectedPath, artifact.Location)
+ assert.Equal(t, azdext.ArtifactKind_ARTIFACT_KIND_DIRECTORY, artifact.Kind)
+ assert.Equal(t, azdext.LocationKind_LOCATION_KIND_LOCAL, artifact.LocationKind)
+ })
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ svc := newServiceConfig("logicApp", "src/logicApp", nil)
+ svc.OutputPath = "Workflows"
+
+ result, err := provider.Package(t.Context(), svc, nil, func(string) {})
+ require.NoError(t, err)
+ expectedPath := filepath.Join(projectDir, "src/logicApp", "Workflows")
+ require.NotEmpty(t, result.Artifacts)
+ assert.Equal(t, expectedPath, result.Artifacts[0].Location)
+ })
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ svc := newServiceConfig("logicApp", "src/logicApp", nil)
+ svc.OutputPath = "../../../outside"
+
+ _, err := provider.Package(t.Context(), svc, nil, func(string) {})
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "outside project directory")
+ })
+}
+
+func TestRestoreAndBuildInvokeDotNetForCustomCodeProject(t *testing.T) {
+ projectDir := t.TempDir()
+ createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n")
+ csprojPath := filepath.Join(projectDir, "src/logicApp/Functions/Functions.csproj")
+ createFile(t, csprojPath, "\n")
+
+ logFile := filepath.Join(t.TempDir(), "dotnet.log")
+ fakeBinDir := t.TempDir()
+ createFakeDotnetStub(t, fakeBinDir)
+
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Functions.csproj",
+ })
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ withEnv(t, "DOTNET_ARGS_LOG", logFile, func() {
+ withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() {
+ _, err := provider.Restore(t.Context(), svc, nil, func(string) {})
+ require.NoError(t, err)
+ _, err = provider.Build(t.Context(), svc, nil, func(string) {})
+ require.NoError(t, err)
+ })
+ })
+ })
+
+ // #nosec G304 -- logFile points to a test-controlled file under t.TempDir().
+ contents, err := os.ReadFile(logFile)
+ require.NoError(t, err)
+ normalized := strings.ReplaceAll(string(contents), "\r\n", "\n")
+ logLines := strings.Split(strings.TrimSpace(normalized), "\n")
+ require.Len(t, logLines, 2, "expected two dotnet invocations: %q", string(contents))
+
+ expectedRestore := "restore " + csprojPath
+ assert.Equal(t, expectedRestore, logLines[0])
+
+ expectedBuild := "build " + csprojPath + " --configuration Release"
+ assert.Equal(t, expectedBuild, logLines[1])
+}
+
+func TestRestoreAndBuildSkipDotNetWhenNoCustomCodeProject(t *testing.T) {
+ logFile := filepath.Join(t.TempDir(), "dotnet.log")
+ fakeBinDir := t.TempDir()
+ createFakeDotnetStub(t, fakeBinDir)
+
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+ svc := newServiceConfig("logicApp", "src/logicApp", nil)
+
+ withEnv(t, "DOTNET_ARGS_LOG", logFile, func() {
+ withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() {
+ _, err := provider.Restore(t.Context(), svc, nil, func(string) {})
+ require.NoError(t, err)
+ _, err = provider.Build(t.Context(), svc, nil, func(string) {})
+ require.NoError(t, err)
+ })
+ })
+
+ if _, statErr := os.Stat(logFile); statErr == nil {
+ // #nosec G304 -- logFile points to a test-controlled file under t.TempDir().
+ contents, readErr := os.ReadFile(logFile)
+ require.NoError(t, readErr)
+ assert.Empty(
+ t,
+ strings.TrimSpace(string(contents)),
+ "dotnet should not be invoked when customCodeProject is not configured")
+ } else {
+ require.ErrorIs(t, statErr, os.ErrNotExist)
+ }
+}
+
+func TestRestoreAndBuildReturnErrorWhenDotNetFails(t *testing.T) {
+ projectDir := t.TempDir()
+ createFile(t, filepath.Join(projectDir, "azure.yaml"), "name: test-project\n")
+ csprojPath := filepath.Join(projectDir, "src/logicApp/Functions/Functions.csproj")
+ createFile(t, csprojPath, "\n")
+
+ fakeBinDir := t.TempDir()
+ createFailingFakeDotnetStub(t, fakeBinDir)
+
+ svc := newServiceConfig("logicApp", "src/logicApp", map[string]any{
+ "customCodeProject": "Functions/Functions.csproj",
+ })
+ provider := &LogicAppsStandardFrameworkServiceProvider{}
+
+ withEnv(t, "AZD_EXEC_PROJECT_DIR", projectDir, func() {
+ withEnv(t, "PATH", fakeBinDir+string(os.PathListSeparator)+os.Getenv("PATH"), func() {
+ _, err := provider.Restore(t.Context(), svc, nil, func(string) {})
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "restoring custom code project")
+ assert.Contains(t, err.Error(), csprojPath)
+
+ _, err = provider.Build(t.Context(), svc, nil, func(string) {})
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "building custom code project")
+ assert.Contains(t, err.Error(), csprojPath)
+ })
+ })
+}
+
+func newServiceConfig(name, relativePath string, additionalProps map[string]any) *azdext.ServiceConfig {
+ svc := &azdext.ServiceConfig{
+ Name: name,
+ RelativePath: relativePath,
+ Host: "function",
+ }
+
+ if additionalProps != nil {
+ props, err := structpb.NewStruct(additionalProps)
+ if err != nil {
+ panic(err)
+ }
+ svc.AdditionalProperties = props
+ }
+
+ return svc
+}
+
+func withEnv(t *testing.T, key, value string, fn func()) {
+ t.Helper()
+ original, existed := os.LookupEnv(key)
+ err := os.Setenv(key, value)
+ require.NoError(t, err, "failed to set %s", key)
+ t.Cleanup(func() {
+ if !existed {
+ _ = os.Unsetenv(key)
+ return
+ }
+ _ = os.Setenv(key, original)
+ })
+
+ fn()
+}
+
+// createFakeDotnetStub places a fake dotnet executable in fakeBinDir.
+// On Windows it creates dotnet.cmd (a batch file) so that cmd.exe can find
+// and execute it via PATHEXT; on Unix it creates a dotnet shell script.
+// Both stubs append their arguments to the file named by DOTNET_ARGS_LOG.
+func createFakeDotnetStub(t *testing.T, fakeBinDir string) {
+ t.Helper()
+ stubName := "dotnet"
+ stubContent := "#!/bin/sh\nprintf '%s\n' \"$*\" >> \"$DOTNET_ARGS_LOG\"\n"
+ stubMode := os.FileMode(0o755)
+ if runtime.GOOS == "windows" {
+ stubName = "dotnet.cmd"
+ stubContent = "@echo off\r\necho %* >> %DOTNET_ARGS_LOG%\r\n"
+ stubMode = 0o644
+ }
+ stubPath := filepath.Join(fakeBinDir, stubName)
+ err := os.WriteFile(stubPath, []byte(stubContent), stubMode)
+ require.NoError(t, err, "failed writing fake dotnet stub %q", stubPath)
+}
+
+func createFailingFakeDotnetStub(t *testing.T, fakeBinDir string) {
+ t.Helper()
+ stubName := "dotnet"
+ stubContent := "#!/bin/sh\nexit 1\n"
+ stubMode := os.FileMode(0o755)
+ if runtime.GOOS == "windows" {
+ stubName = "dotnet.cmd"
+ stubContent = "@echo off\r\nexit /b 1\r\n"
+ stubMode = 0o644
+ }
+ stubPath := filepath.Join(fakeBinDir, stubName)
+ err := os.WriteFile(stubPath, []byte(stubContent), stubMode)
+ require.NoError(t, err, "failed writing failing fake dotnet stub %q", stubPath)
+}
+
+func createFile(t *testing.T, filePath, content string) {
+ t.Helper()
+ err := os.MkdirAll(filepath.Dir(filePath), 0o750)
+ require.NoError(t, err, "failed creating directory %q", filepath.Dir(filePath))
+ err = os.WriteFile(filePath, []byte(content), 0o600)
+ require.NoError(t, err, "failed writing file %q", filePath)
+}
diff --git a/cli/azd/extensions/azure.logicappsstandard/internal/version/version.go b/cli/azd/extensions/azure.logicappsstandard/internal/version/version.go
new file mode 100644
index 00000000000..52188c90118
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/internal/version/version.go
@@ -0,0 +1,11 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package version
+
+var (
+ // Populated at build time
+ Version = "dev" // Default value for development builds
+ Commit = "none"
+ BuildDate = "unknown"
+)
diff --git a/cli/azd/extensions/azure.logicappsstandard/main.go b/cli/azd/extensions/azure.logicappsstandard/main.go
new file mode 100644
index 00000000000..1166cd3800e
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/main.go
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package main
+
+import (
+ "github.com/azure/azure-dev/cli/azd/pkg/azdext"
+
+ "azurelogicappsstandard/internal/cmd"
+)
+
+func main() {
+ azdext.Run(cmd.NewRootCommand())
+}
diff --git a/cli/azd/extensions/azure.logicappsstandard/version.txt b/cli/azd/extensions/azure.logicappsstandard/version.txt
new file mode 100644
index 00000000000..8acdd82b765
--- /dev/null
+++ b/cli/azd/extensions/azure.logicappsstandard/version.txt
@@ -0,0 +1 @@
+0.0.1
diff --git a/eng/pipelines/release-ext-azure-logicappsstandard.yml b/eng/pipelines/release-ext-azure-logicappsstandard.yml
new file mode 100644
index 00000000000..7987664d997
--- /dev/null
+++ b/eng/pipelines/release-ext-azure-logicappsstandard.yml
@@ -0,0 +1,33 @@
+# Continuous deployment trigger
+trigger:
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - go.mod
+ - cli/azd/extensions/azure.logicappsstandard
+ - eng/pipelines/release-azd-extension.yml
+ - /eng/pipelines/templates/jobs/build-azd-extension.yml
+ - /eng/pipelines/templates/jobs/cross-build-azd-extension.yml
+ - /eng/pipelines/templates/variables/image.yml
+
+pr:
+ paths:
+ include:
+ - cli/azd/extensions/azure.logicappsstandard
+ - eng/pipelines/release-ext-azure-logicappsstandard.yml
+ - eng/pipelines/release-azd-extension.yml
+ - eng/pipelines/templates/steps/publish-cli.yml
+ exclude:
+ - cli/azd/docs/**
+
+extends:
+ template: /eng/pipelines/templates/stages/1es-redirect.yml
+ parameters:
+ stages:
+ - template: /eng/pipelines/templates/stages/release-azd-extension.yml
+ parameters:
+ AzdExtensionId: azure.logicappsstandard
+ SanitizedExtensionId: azure-logicappsstandard
+ AzdExtensionDirectory: cli/azd/extensions/azure.logicappsstandard