Skip to content

kamal-*: support git-style external commands in .kamal/bin and on PATH#1784

Open
jeremy wants to merge 1 commit intomainfrom
ext
Open

kamal-*: support git-style external commands in .kamal/bin and on PATH#1784
jeremy wants to merge 1 commit intomainfrom
ext

Conversation

@jeremy
Copy link
Copy Markdown
Member

@jeremy jeremy commented Feb 20, 2026

Summary

  • Resolve unknown commands as external executables before falling through to aliases/errors — same pattern as git-foo on PATH
  • Lookup order: .kamal/bin/<name> (project-local), then kamal-<name> on PATH
  • Builtins (including prefix matches like depdeploy) are never shadowed
  • External commands bypass config loading, so they work even with broken/missing deploy.yml
  • Guards against directories, non-executable files, path traversal, and flags

Test plan

  • Local .kamal/bin/foo → exec called with correct path
  • PATH kamal-bar → exec called
  • Local takes priority over PATH when both exist
  • Builtins not shadowed (version with .kamal/bin/version present)
  • Prefix builtins not shadowed (ver with .kamal/bin/ver present)
  • Arguments passed through to external command
  • Non-executable file skipped
  • Directory in .kamal/bin skipped
  • Directory on PATH skipped
  • Path traversal (../foo) rejected
  • Existing test suite passes (55 runs, 376 assertions)

Copilot AI review requested due to automatic review settings February 20, 2026 04:07
@jeremy jeremy changed the title Support external commands in .kamal/bin and on PATH kamal-*: support git-style external commands in .kamal/bin and on PATH Feb 20, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c7a409ecdc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
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 adds support for external commands that can extend Kamal's functionality, following a plugin pattern similar to Git's git-foo extension model. External commands are resolved when no builtin command matches, looking first in .kamal/bin/<name> (project-local), then for kamal-<name> on PATH. These external commands bypass config loading, allowing them to work even with broken or missing configuration files, while builtin commands (including prefix matches) are never shadowed.

Changes:

  • Added dispatch override in Kamal::Cli::Main to resolve and execute external commands
  • Implemented resolve_external_command method with security guards against path traversal, directories, non-executable files, and flags
  • Added comprehensive test coverage for external command resolution, priority, and security scenarios

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
lib/kamal/cli/main.rb Implements dispatch override and external command resolution with security checks
test/cli/main_test.rb Adds 11 comprehensive tests covering external command behavior and security

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Unknown commands are resolved as external executables before falling
through to aliases or the error handler. Lookup order:

  1. .kamal/bin/<name>  (project-local)
  2. kamal-<name> on PATH  (system-wide)

Builtin commands and unambiguous prefix matches are never shadowed.
The external command is exec'd with remaining argv, replacing the
kamal process.
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.

2 participants