Skip to content

Tweaks and primarily changes for podman and cli mate fork#60

Merged
GordonBeeming merged 8 commits intomainfrom
cli-mate
Feb 4, 2026
Merged

Tweaks and primarily changes for podman and cli mate fork#60
GordonBeeming merged 8 commits intomainfrom
cli-mate

Conversation

@GordonBeeming
Copy link
Owner

This pull request introduces major improvements to container runtime support and image/tag management, along with enhanced documentation and configuration options. The most significant changes are the addition of multi-runtime container support (Docker, OrbStack, Podman), a new runtime configuration system, and a migration to more consistent image naming/tagging conventions. There are also updates to the documentation and workflow files to reflect these enhancements.

Container Runtime Support and Configuration

  • Added multi-runtime support for Docker, OrbStack, and Podman, including automatic detection and per-project/global configuration via .copilot_here/runtime.conf and ~/.config/copilot_here/runtime.conf (README.md, .github/copilot-instructions.md) [1] [2] [3] [4] [5] [6] [7].
  • Introduced runtime management commands: --show-runtime, --list-runtimes, --set-runtime, and --set-runtime-global (README.md, .github/copilot-instructions.md) [1] [2].
  • All container operations now use a unified ContainerRunner abstraction instead of DockerRunner, with runtime detection handled by ContainerRuntimeConfig (app/Commands/Model/ListModels.cs, .github/copilot-instructions.md) [1] [2] [3] [4].

Image Tagging and Build Process

  • Updated GitHub Actions workflows to use new image/tag naming conventions with a copilot- prefix for variants and more descriptive tags for main and variant images (.github/workflows/publish.yml) [1] [2] [3] [4] [5] [6] [7].
  • Updated Docker build context and Dockerfile paths to reflect the new structure (.github/workflows/publish.yml) [1] [2].

Documentation and Developer Experience

  • Expanded and clarified documentation to describe supported runtimes, configuration priorities, and new commands (README.md, .github/copilot-instructions.md) [1] [2] [3] [4].
  • Updated project structure documentation to reflect new files and naming (.github/copilot-instructions.md).

CLI Enhancements

  • Added a --tool option to the RunCommand to allow overriding the CLI tool, with validation and error reporting for unknown tools (app/Commands/Run/RunCommand.cs) [1] [2] [3] [4].

Miscellaneous

  • Added .copilot_here/runtime.conf to support local runtime configuration.

These changes collectively make the project more flexible, easier to configure, and better documented, especially for users working across different container environments.

Copilot AI review requested due to automatic review settings February 4, 2026 10:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a multi-tool abstraction layer and multi-runtime container support (Docker, OrbStack, Podman), refactors container execution to be runtime-agnostic, updates Docker image/tag naming and build workflows, and adds substantial test coverage and documentation describing these new behaviors.

Changes:

  • Added a tool abstraction (ICliTool, ToolRegistry, GitHubCopilotTool, EchoTool plus auth/model providers) and wired it through AppContext, RunCommand, and new tool-management commands (--list-tools, --show-tool, --set-tool, --set-tool-local).
  • Implemented ContainerRuntimeConfig and ContainerRunner to support Docker/OrbStack/Podman, with runtime listing/show/set commands and updated dependency checks, Airlock, and dev-build tooling to be runtime-aware.
  • Updated Dockerfiles, shared entrypoints, GitHub Actions workflow, and docs (README, instructions, task doc) to use new image/tag conventions (copilot-*), shared entrypoints, and to document container runtime support and configuration.

Reviewed changes

Copilot reviewed 52 out of 52 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/CopilotHere.UnitTests/ToolRegistryTests.cs New unit tests validating ToolRegistry lookups, default tool behavior, error messages, and instance uniqueness.
tests/CopilotHere.UnitTests/ToolConfigTests.cs Integration-style tests around tool.conf file layout (new/legacy, local/global) and ConfigFile read/write semantics.
tests/CopilotHere.UnitTests/GitHubCopilotToolTests.cs Tests for GitHubCopilotTool image naming, Dockerfile/network rules paths, command-building behavior (YOLO, model, interactive, passthrough).
tests/CopilotHere.UnitTests/EchoToolTests.cs Tests for EchoTool image selection, Dockerfile/network rules paths, generated debug script content, and capability flags/dependencies.
tests/CopilotHere.UnitTests/DependencyCheckTests.cs Updated tests to use GitHubCopilotTool + ContainerRuntimeConfig, asserting presence of GitHub CLI and a runtime/daemon regardless of Docker vs Podman.
tests/CopilotHere.UnitTests/ContainerRuntimeConfigTests.cs New tests covering runtime auto-detection, config precedence, save/load, available runtime listing, and version/command-availability helpers.
tests/CopilotHere.UnitTests/AppContextToolLoadingTests.cs Integration tests for AppContext.Create tool selection priority (CLI override vs local/global vs legacy), plus ensuring other configs and providers are loaded.
docs/tasks/20260204-01-container-runtime-support.md Task doc summarizing design, usage, testing, and future enhancements for multi-runtime container support.
docker/variants/Dockerfile.rust Now builds Rust variant from a generic base ${BASE_IMAGE_TAG} defaulting to copilot-latest, allowing reuse across tools.
docker/variants/Dockerfile.playwright Similar change to use a generic base ${BASE_IMAGE_TAG} (default copilot-latest) for Playwright variant.
docker/variants/Dockerfile.dotnet8 Uses generic ${BASE_IMAGE_TAG} (default copilot-latest) to layer .NET 8 SDK on top of any tool’s base image.
docker/variants/Dockerfile.dotnet9 Same generic base-tag pattern for .NET 9 SDK variant.
docker/variants/Dockerfile.dotnet10 Same generic base-tag pattern for .NET 10 SDK variant.
docker/variants/Dockerfile.dotnet Uses ${BASE_IMAGE_TAG}=copilot-latest and builds a combined .NET 8/9/10 SDK image for any tool.
docker/tools/github-copilot/default-airlock-rules.json Default Airlock network rules tailored to GitHub Copilot APIs (GitHub and Copilot endpoints).
docker/tools/github-copilot/Dockerfile Base image for the GitHub Copilot tool; now copies shared entrypoints from docker/shared and session-info script.
docker/tools/echo/default-airlock-rules.json Minimal Airlock ruleset (logging disabled, no allowed hosts) for the Echo test tool.
docker/shared/entrypoint.sh New shared entrypoint that normalizes UID/GID inside the container and prepares the appuser environment and home directories.
docker/shared/entrypoint-airlock.sh Shared Airlock entrypoint that waits for proxy CA, trusts it, sets NODE_EXTRA_CA_CERTS, then delegates to the main entrypoint.
docker/compound-variants/Dockerfile.dotnet-rust Compound image to add Rust on top of a generic dotnet variant (${DOTNET_IMAGE_TAG}, default copilot-dotnet).
docker/compound-variants/Dockerfile.dotnet-playwright Compound image to add Playwright on top of a generic dotnet variant (${DOTNET_IMAGE_TAG}, default copilot-dotnet).
dev-build.sh Refactored to detect a container runtime (local/global runtime.conf or docker/podman presence), use it for ps, stop, build, images, and align build tags with copilot-* naming.
app/Tools/GitHubCopilotTool.cs Implements ICliTool for GitHub Copilot (image naming, command building, yolo/interactive flags, auth/model providers, dependencies, Airlock rules path).
app/Tools/GitHubCopilotModelProvider.cs IModelProvider that pulls the Copilot image and introspects Copilot CLI error output to extract available models.
app/Tools/GitHubAuthProvider.cs IAuthProvider implementation for GitHub, validating required scopes, warning on privileged scopes, surfacing elevate commands, and exposing token/env vars.
app/Tools/EchoTool.cs ICliTool implementation for a test “echo” provider that reuses Copilot images and prints a rich debug summary instead of calling an AI tool.
app/Tools/EchoModelProvider.cs Simple mock model provider returning fixed “echo-*” models with validation.
app/Tools/EchoAuthProvider.cs No-op auth provider for Echo that always succeeds and exposes a simple env var.
app/Program.cs Wires new RuntimeCommands and ToolCommands into the root command and adds normalized aliases for the runtime flags.
app/Infrastructure/ToolRegistry.cs Central registry of ICliTool implementations, with lookup, default tool, existence checks, and enumeration of tool names.
app/Infrastructure/IModelProvider.cs New abstraction for listing and validating models for a given tool.
app/Infrastructure/ICliTool.cs Core tool abstraction (naming, image/Dockerfile, command building, config directory, auth/model providers, dependencies, Airlock rules, capability flags) and CommandContext record.
app/Infrastructure/IAuthProvider.cs Abstraction for tool-specific auth (validation, token retrieval, scopes, elevate command, env vars).
app/Infrastructure/DependencyCheck.cs Generalized to accept ICliTool and ContainerRuntimeConfig, checking the configured runtime (binary + daemon) plus tool-specific deps (currently GitHub CLI).
app/Infrastructure/ContainerRuntimeConfig.cs New runtime config that auto-detects docker/podman, distinguishes Docker/OrbStack flavor, manages compose command/default network, and supports local/global runtime.conf.
app/Infrastructure/ContainerRunner.cs Renamed and generalized DockerRunner; all run/pull/cleanup/capture operations now target the configured runtime instead of hard-coded docker.
app/Infrastructure/AppContext.cs Extended to carry ActiveTool and RuntimeConfig, and to resolve the active tool by CLI override, new/legacy local/global tool.conf, or default.
app/Infrastructure/AirlockRunner.cs Updated to use ContainerRuntimeConfig (runtime, compose command, default network) and runtime-friendly network naming while keeping Airlock orchestration behavior otherwise intact.
app/Commands/Tool/_ToolCommands.cs Command group wiring for tool-management commands.
app/Commands/Tool/ShowTool.cs Implements --show-tool, printing the active tool, source (local/global/default), capabilities, and dependencies.
app/Commands/Tool/SetTool.cs Implements --set-tool (global) and --set-tool-local (project) commands that validate tool names and write tool.conf in the appropriate config dir.
app/Commands/Tool/ListTools.cs Implements --list-tools command listing all registered tools, marking the default and showing capabilities plus usage hints.
app/Commands/Runtime/_RuntimeCommands.cs Command group wiring for runtime-management commands.
app/Commands/Runtime/ShowRuntime.cs Implements --show-runtime, showing runtime, command, version, source, config values, capabilities, and discovered runtimes.
app/Commands/Runtime/SetRuntime.cs Implements --set-runtime / --set-runtime-global, validating docker/podman/auto, verifying availability, and writing .copilot_here/runtime.conf or global config.
app/Commands/Runtime/ListRuntimes.cs Implements --list-runtimes, enumerating available runtimes with commands, versions, compose commands, and usage hints.
app/Commands/Run/RunCommand.cs Integrates tool selection (--tool and config), uses ICliTool/ContainerRuntimeConfig throughout, reworks argument and model handling, and passes auth via the selected tool’s provider.
app/Commands/Model/ListModels.cs Updated to use ActiveTool.GetImageName and ContainerRunner for runtime-aware image pulling and model introspection.
README.md Prerequisites and configuration docs updated for container runtimes and new --show-runtime/--list-runtimes/set-runtime commands.
.github/workflows/publish.yml Switched base build to the GitHub Copilot tool Dockerfile and updated tags/build args to the new copilot-* naming scheme, including variants and compound variants.
.github/copilot-instructions.md Updated high-level architecture to describe container runtimes, ContainerRunner/ContainerRuntimeConfig, and the Runtime commands.
.copilot_here/runtime.conf New default runtime config file in the repo root set to auto, matching the new runtime configuration system.
Comments suppressed due to low confidence (2)

app/Commands/Run/RunCommand.cs:256

  • This PR makes significant functional changes to the CLI (new tool abstraction, runtime config, dependency checks, etc.) but the central version remains 2026.01.05 in all versioned files (copilot_here.sh, copilot_here.ps1, Directory.Build.props, BuildInfo.cs, and .github/copilot-instructions.md). Per the repo’s Script Versioning rules, any functionality change must bump this version in all five locations to a new date (or same-day .1, .2, etc.) so that users get the updated binary and scripts. Please increment the shared version and update all version fields consistently in the same commit.
    root.Add(_passthroughArgs);

    root.SetAction(parseResult =>
    {
      var toolOverride = parseResult.GetValue(_toolOption);
      
      // Validate tool if specified
      if (!string.IsNullOrWhiteSpace(toolOverride) && !ToolRegistry.Exists(toolOverride))
      {
        Console.WriteLine($"❌ Unknown tool: {toolOverride}");
        Console.WriteLine();
        Console.WriteLine("Available tools:");
        foreach (var name in ToolRegistry.GetToolNames())
        {
          Console.WriteLine($"  • {name}");
        }
        return 1;
      }
      
      var ctx = Infrastructure.AppContext.Create(toolOverride);

      var dotnet = parseResult.GetValue(_dotnetOption);
      var dotnet8 = parseResult.GetValue(_dotnet8Option);
      var dotnet9 = parseResult.GetValue(_dotnet9Option);
      var dotnet10 = parseResult.GetValue(_dotnet10Option);
      var playwright = parseResult.GetValue(_playwrightOption);
      var dotnetPlaywright = parseResult.GetValue(_dotnetPlaywrightOption);
      var rust = parseResult.GetValue(_rustOption);
      var dotnetRust = parseResult.GetValue(_dotnetRustOption);
      var golang = parseResult.GetValue(_golangOption);
      var cliMountsRo = parseResult.GetValue(_mountOption) ?? [];
      var cliMountsRw = parseResult.GetValue(_mountRwOption) ?? [];
      var noCleanup = parseResult.GetValue(_noCleanupOption);
      var noPull = parseResult.GetValue(_noPullOption);
      var help2 = parseResult.GetValue(_help2Option);
      var updateScripts = parseResult.GetValue(_updateScriptsOption);
      var installShells = parseResult.GetValue(_installShellsOption);

      // Copilot passthrough options
      var prompt = parseResult.GetValue(_promptOption);
      var model = parseResult.GetValue(_modelOption);
      var continueSession = parseResult.GetValue(_continueOption);
      var resumeSession = parseResult.GetValue(_resumeOption);
      var silent = parseResult.GetValue(_silentOption);
      var agent = parseResult.GetValue(_agentOption);
      var noColor = parseResult.GetValue(_noColorOption);
      var allowTools = parseResult.GetValue(_allowToolOption) ?? [];
      var denyTools = parseResult.GetValue(_denyToolOption) ?? [];
      var stream = parseResult.GetValue(_streamOption);
      var logLevel = parseResult.GetValue(_logLevelOption);
      var screenReader = parseResult.GetValue(_screenReaderOption);
      var noCustomInstructions = parseResult.GetValue(_noCustomInstructionsOption);
      var additionalMcpConfigs = parseResult.GetValue(_additionalMcpConfigOption) ?? [];
      var passthroughArgs = parseResult.GetValue(_passthroughArgs) ?? [];

      // Handle --install-shells
      if (installShells)
      {
        DebugLogger.Log("--install-shells flag detected");
        return ShellIntegration.InstallAll();
      }

      // Handle --update - show message that it's handled by shell wrapper
      if (updateScripts)
      {
        DebugLogger.Log("--update flag detected (handled by shell wrapper)");
        Console.WriteLine("ℹ️  Update is handled by the shell wrapper (copilot_here function).");
        Console.WriteLine("   If running the binary directly, please use the shell function:");
        Console.WriteLine("");
        Console.WriteLine("   copilot_here --update");
        Console.WriteLine("");
        Console.WriteLine("   Or manually re-source the script to get updates.");
        return 0;

app/Infrastructure/AirlockRunner.cs:283

  • Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better.
      if (externalNetwork == runtimeConfig.DefaultNetworkName)
      {
        networksYaml = $@"networks:
  airlock:
    internal: true
  {runtimeConfig.DefaultNetworkName}:";
      }
      else
      {
        networksYaml = $@"networks:
  airlock:
    internal: true
  {externalNetwork}:
    external: true";
      }

@GordonBeeming GordonBeeming merged commit e1240a7 into main Feb 4, 2026
25 checks passed
@GordonBeeming GordonBeeming deleted the cli-mate branch February 4, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant