Tweaks and primarily changes for podman and cli mate fork#60
Merged
GordonBeeming merged 8 commits intomainfrom Feb 4, 2026
Merged
Tweaks and primarily changes for podman and cli mate fork#60GordonBeeming merged 8 commits intomainfrom
GordonBeeming merged 8 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
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,EchoToolplus auth/model providers) and wired it throughAppContext,RunCommand, and new tool-management commands (--list-tools,--show-tool,--set-tool,--set-tool-local). - Implemented
ContainerRuntimeConfigandContainerRunnerto 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.05in 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";
}
… variable support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
.copilot_here/runtime.confand~/.config/copilot_here/runtime.conf(README.md,.github/copilot-instructions.md) [1] [2] [3] [4] [5] [6] [7].--show-runtime,--list-runtimes,--set-runtime, and--set-runtime-global(README.md,.github/copilot-instructions.md) [1] [2].ContainerRunnerabstraction instead ofDockerRunner, with runtime detection handled byContainerRuntimeConfig(app/Commands/Model/ListModels.cs,.github/copilot-instructions.md) [1] [2] [3] [4].Image Tagging and Build Process
copilot-prefix for variants and more descriptive tags for main and variant images (.github/workflows/publish.yml) [1] [2] [3] [4] [5] [6] [7]..github/workflows/publish.yml) [1] [2].Documentation and Developer Experience
README.md,.github/copilot-instructions.md) [1] [2] [3] [4]..github/copilot-instructions.md).CLI Enhancements
--tooloption to theRunCommandto allow overriding the CLI tool, with validation and error reporting for unknown tools (app/Commands/Run/RunCommand.cs) [1] [2] [3] [4].Miscellaneous
.copilot_here/runtime.confto 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.