Skip to content
This repository was archived by the owner on May 18, 2026. It is now read-only.
This repository was archived by the owner on May 18, 2026. It is now read-only.

refactor: unify Key Vault environment resolution between CLI and MCP paths #101

@jongio

Description

@jongio

Code Smell: Duplicated Code (Dispensables)

Severity: HIGH
Category: Dispensables > Duplicated Code
Files: cli/src/cmd/exec/commands/mcp.go, cli/src/internal/executor/executor.go

Description

The Key Vault environment resolution logic is duplicated between two independent implementations:

  1. prepareEnvironmentForMCP() in mcp.go (lines 325-354) — used by MCP handlers
  2. prepareEnvironment() + hasKeyVaultReferences() in executor.go (lines 186-250) — used by CLI executor

Both functions perform the same steps:

  • Call os.Environ() to get environment variables
  • Check if any variables contain Key Vault references using keyvault.IsKeyVaultReference()
  • Create a keyvault.NewKeyVaultResolver()
  • Call ResolveEnvironmentVariables() with best-effort or fail-fast semantics
  • Fall back to the original environment on error

The MCP version is a simplified copy that always uses best-effort mode, while the CLI version supports configurable StopOnKeyVaultError. A comment in the MCP version explicitly states it "mirrors the CLI execution path."

Refactoring Recommendation

Extract the shared logic into a reusable function in the executor package or a new internal/envresolver package:

type ResolveOptions struct {
    StopOnError bool
    OnWarning   func(key string, err error) // CLI uses cliout.Warning; MCP uses stderr
}

func ResolveKeyVaultEnv(ctx context.Context, envVars []string, opts ResolveOptions) ([]string, error) {
    // Single implementation with configurable behavior
}

The CLI and MCP paths would both call this function with their respective options.

Impact

  • Consistency risk: Bug fixes to one path may not be applied to the other
  • Feature parity: New resolution features must be implemented twice
  • The comment itself is a smell: When code comments reference another implementation to stay in sync, the duplication should be removed

Metadata

Metadata

Assignees

No one assigned

    Labels

    automatedCreated by automationsmellsCode smell detection

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions